@layers/client 0.1.0-alpha.0 → 0.1.1-alpha.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.
@@ -313,6 +313,8 @@ declare class LayersClient {
313
313
  private queueConfig;
314
314
  private queueStorage;
315
315
  private rateLimitState;
316
+ private logLevel;
317
+ private shouldLog;
316
318
  constructor(config: LayersConfig);
317
319
  private generateSessionId;
318
320
  private initializeDeviceInfo;
@@ -367,4 +369,4 @@ declare class LayersClient {
367
369
  }
368
370
  //#endregion
369
371
  export { APIResponse, AppBackgroundEvent, AppInstallEvent, AppOpenEvent, BaseEvent, BookmarkAddEvent, ConsentOptions, ConsentPayload, ContentOpenEvent, DeeplinkOpenEvent, EventData, EventsBatchPayload, EventsIngestResponse, LayersClient, LayersConfig, LayersEvent, PaywallDismissEvent, PaywallShowEvent, PurchaseAttemptEvent, PurchaseFailEvent, PurchaseSuccessEvent, QueueOptions, QueueStorage, RefundEvent, RemoteConfig, RemoteConfigResponse, SKANPostbackPayload, ScreenViewEvent, SearchEvent, StoredQueueSnapshot, StoredQueuedRequest, SubscriptionCancelEvent, SubscriptionRenewEvent, SubscriptionStartEvent, TrialConvertEvent, TrialStartEvent, UserProperties, UserPropertiesPayload };
370
- //# sourceMappingURL=index.d.ts.map
372
+ //# sourceMappingURL=index-NMBS3y1V.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-NMBS3y1V.d.ts","names":[],"sources":["../src/api-types.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  //#region src/index.ts
2
- const SDK_VERSION = "0.0.1";
3
- const DEFAULT_BASE_URL = "http://c9badd27.layers.com";
2
+ const SDK_VERSION = "0.0.0";
3
+ const DEFAULT_BASE_URL = "https://in.layers.com";
4
4
  const SYSTEM_EVENTS = new Set(["consent_updated", "att_status_changed"]);
5
5
  const DEFAULT_CONSENT = {
6
6
  advertising: true,
@@ -37,6 +37,22 @@ var LayersClient = class {
37
37
  global: {},
38
38
  perEvent: /* @__PURE__ */ new Map()
39
39
  };
40
+ logLevel() {
41
+ if (typeof process !== "undefined" && process.env?.LOG_LEVEL) return process.env.LOG_LEVEL.toLowerCase();
42
+ if (this.config.enableDebug) return "debug";
43
+ return "info";
44
+ }
45
+ shouldLog(level) {
46
+ const currentLevel = this.logLevel();
47
+ const levels = [
48
+ "error",
49
+ "warn",
50
+ "info",
51
+ "debug",
52
+ "trace"
53
+ ];
54
+ return levels.indexOf(currentLevel) >= levels.indexOf(level);
55
+ }
40
56
  constructor(config) {
41
57
  this.queueConfig = {
42
58
  ...DEFAULT_QUEUE_CONFIG,
@@ -86,7 +102,7 @@ var LayersClient = class {
86
102
  };
87
103
  this.resetRateLimitState();
88
104
  } catch (error) {
89
- if (this.config.enableDebug) console.warn("Failed to fetch remote config:", error);
105
+ if (this.shouldLog("debug")) console.warn("[Layers] Failed to fetch remote config:", error);
90
106
  }
91
107
  }
92
108
  extractRemoteConfigSettings(envelope) {
@@ -182,7 +198,7 @@ var LayersClient = class {
182
198
  this.eventQueue = limited;
183
199
  if (trimmed || limited.length !== snapshot.items.length) await this.persistQueue();
184
200
  } catch (error) {
185
- if (this.config.enableDebug) console.warn("Failed to hydrate queue", error);
201
+ if (this.shouldLog("debug")) console.warn("[Layers] Failed to hydrate queue", error);
186
202
  }
187
203
  }
188
204
  async persistQueue() {
@@ -203,16 +219,16 @@ var LayersClient = class {
203
219
  if (snapshot.items.length === 0) await this.queueStorage.clear();
204
220
  else await this.queueStorage.save(snapshot);
205
221
  } catch (error) {
206
- if (this.config.enableDebug) console.warn("Failed to persist queue", error);
222
+ if (this.shouldLog("debug")) console.warn("[Layers] Failed to persist queue", error);
207
223
  }
208
224
  }
209
225
  async track(eventName, properties) {
210
226
  if (!this.shouldProcessEvent(eventName)) {
211
- if (this.config.enableDebug) console.log(`Event '${eventName}' dropped due to consent or config gating`);
227
+ if (this.shouldLog("debug")) console.log(`[Layers] Event '${eventName}' dropped due to consent or config gating`);
212
228
  return;
213
229
  }
214
230
  if (!this.passesSampling(eventName)) {
215
- if (this.config.enableDebug) console.log(`Event '${eventName}' sampled out`);
231
+ if (this.shouldLog("debug")) console.log(`[Layers] Event '${eventName}' sampled out`);
216
232
  return;
217
233
  }
218
234
  const batchPayload = {
@@ -235,6 +251,8 @@ var LayersClient = class {
235
251
  batch_id: this.generateBatchId(),
236
252
  sent_at: (/* @__PURE__ */ new Date()).toISOString()
237
253
  };
254
+ const appUserId = this.resolveAppUserId();
255
+ console.log(`[Layers] Tracking event: ${eventName}${appUserId ? ` (user: ${appUserId})` : " (no user)"}`);
238
256
  await this.enqueue("/events", batchPayload);
239
257
  }
240
258
  shouldProcessEvent(eventName) {
@@ -336,21 +354,21 @@ var LayersClient = class {
336
354
  }, item.requestId);
337
355
  } catch (err) {
338
356
  if (!item.retryable) {
339
- if (this.config.enableDebug) console.warn("Dropping non-retryable item", {
357
+ if (this.shouldLog("debug")) console.warn("[Layers] Dropping non-retryable item", {
340
358
  endpoint: item.endpoint,
341
359
  error: err
342
360
  });
343
361
  } else {
344
362
  item.attempts += 1;
345
363
  if (item.attempts > this.queueConfig.maxRetries) {
346
- if (this.config.enableDebug) console.warn("Dropping item after max retries", {
364
+ if (this.shouldLog("debug")) console.warn("[Layers] Dropping item after max retries", {
347
365
  endpoint: item.endpoint,
348
366
  error: err
349
367
  });
350
368
  } else {
351
369
  item.nextAttemptAt = now() + this.getBackoffDelay(item.attempts);
352
370
  shouldRequeue = true;
353
- if (this.config.enableDebug) console.warn("Retry scheduled", {
371
+ if (this.shouldLog("debug")) console.warn("[Layers] Retry scheduled", {
354
372
  endpoint: item.endpoint,
355
373
  nextAttemptAt: item.nextAttemptAt,
356
374
  error: err
@@ -368,7 +386,7 @@ var LayersClient = class {
368
386
  const cutoff = now() - this.queueConfig.maxItemAgeMs;
369
387
  if (this.eventQueue.length === 0) return;
370
388
  const retained = this.eventQueue.filter((item) => item.queuedAt >= cutoff);
371
- if (this.config.enableDebug && retained.length !== this.eventQueue.length) console.warn("Dropped stale queue items", { dropped: this.eventQueue.length - retained.length });
389
+ if (this.shouldLog("debug") && retained.length !== this.eventQueue.length) console.warn("[Layers] Dropped stale queue items", { dropped: this.eventQueue.length - retained.length });
372
390
  this.eventQueue = retained;
373
391
  this.persistQueue();
374
392
  }
@@ -406,11 +424,11 @@ var LayersClient = class {
406
424
  const perEventRules = rateLimits.perEvent;
407
425
  const eventRule = perEventRules?.get(eventName) ?? perEventRules?.get("*");
408
426
  if (eventRule && !this.canConsumeRateLimit(eventRule, this.getEventRateCounter(eventName), timestamp)) {
409
- if (this.config.enableDebug) console.warn("Rate limit reached for event", { event: eventName });
427
+ if (this.shouldLog("debug")) console.warn("[Layers] Rate limit reached for event", { event: eventName });
410
428
  return false;
411
429
  }
412
430
  if (rateLimits.global && !this.canConsumeRateLimit(rateLimits.global, this.rateLimitState.global, timestamp)) {
413
- if (this.config.enableDebug) console.warn("Global rate limit reached", { event: eventName });
431
+ if (this.shouldLog("debug")) console.warn("[Layers] Global rate limit reached", { event: eventName });
414
432
  return false;
415
433
  }
416
434
  if (eventRule) this.recordRateLimit(eventRule, this.getEventRateCounter(eventName), timestamp);
@@ -472,18 +490,31 @@ var LayersClient = class {
472
490
  }, this.queueConfig.requestTimeoutMs);
473
491
  }
474
492
  try {
493
+ if (this.shouldLog("trace")) {
494
+ console.log(`[Layers] → ${options.method || "GET"} ${url}`);
495
+ if (options.method === "POST" && options.body) console.log(`[Layers] Request body:`, JSON.parse(options.body));
496
+ }
475
497
  const response = await fetch(url, {
476
498
  ...options,
477
499
  headers
478
500
  });
501
+ if (this.shouldLog("trace")) console.log(`[Layers] ← ${response.status} ${response.statusText}`);
479
502
  if (!response.ok) {
480
- if (!this.isRetryableStatus(response.status)) throw Object.assign(/* @__PURE__ */ new Error(`HTTP ${response.status}: ${response.statusText}`), { status: response.status });
481
- throw Object.assign(/* @__PURE__ */ new Error(`Retryable HTTP ${response.status}`), { status: response.status });
503
+ if (!this.isRetryableStatus(response.status)) {
504
+ const error$1 = Object.assign(/* @__PURE__ */ new Error(`HTTP ${response.status}: ${response.statusText}`), { status: response.status });
505
+ if (this.shouldLog("debug")) console.warn(`[Layers] Non-retryable error for ${url}:`, error$1);
506
+ throw error$1;
507
+ }
508
+ const error = Object.assign(/* @__PURE__ */ new Error(`Retryable HTTP ${response.status}`), { status: response.status });
509
+ if (this.shouldLog("debug")) console.warn(`[Layers] Retryable error for ${url}:`, error);
510
+ throw error;
482
511
  }
483
512
  if (response.status === 204) return;
484
513
  const text = await response.text();
485
514
  if (!text) return;
486
- return JSON.parse(text);
515
+ const parsed = JSON.parse(text);
516
+ if (this.shouldLog("trace")) console.log(`[Layers] Response:`, parsed);
517
+ return parsed;
487
518
  } finally {
488
519
  if (timeoutHandle) clearTimeout(timeoutHandle);
489
520
  }
@@ -509,6 +540,7 @@ var LayersClient = class {
509
540
  }
510
541
  setAppUserId(appUserId) {
511
542
  this.config.appUserId = appUserId;
543
+ if (this.shouldLog("info")) console.log(`[Layers] App user ID set: ${appUserId || "(cleared)"}`);
512
544
  }
513
545
  /** @deprecated Use setAppUserId instead */
514
546
  setUserId(userId) {
@@ -547,8 +579,7 @@ function createDefaultQueueStorage(appId) {
547
579
  } catch {
548
580
  return null;
549
581
  }
550
- const storageKey = `layers_queue_${appId}`;
551
- return createLocalStorageQueueStorage(storageKey);
582
+ return createLocalStorageQueueStorage(`layers_queue_${appId}`);
552
583
  }
553
584
  function createLocalStorageQueueStorage(storageKey) {
554
585
  return {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["DEFAULT_CONSENT: Required<ConsentOptions>","DEFAULT_QUEUE_CONFIG: QueueConfig","meta: RemoteConfigMeta","samplingEntries: Record<string, number>","perEventRules: Map<string, RateLimitRule> | undefined","rateLimits: { global?: RateLimitRule; perEvent?: Map<string, RateLimitRule> }","hydrated: QueuedRequest[]","snapshot: StoredQueueSnapshot","batchPayload: EventsBatchPayload","payload: UserPropertiesPayload","payload: ConsentPayload","pending: QueuedRequest[]","rule: RateLimitRule","headers: Record<string, string>","timeoutHandle: ReturnType<typeof setTimeout> | undefined"],"sources":["../src/index.ts"],"sourcesContent":["import type {\n BaseEvent,\n ConsentPayload,\n EventsBatchPayload,\n RemoteConfigResponse,\n UserPropertiesPayload\n} from './api-types.js';\n\nexport interface QueueOptions {\n flushIntervalMs?: number;\n maxQueueSize?: number;\n maxItemAgeMs?: number;\n requestTimeoutMs?: number;\n maxRetries?: number;\n baseRetryDelayMs?: number;\n maxRetryDelayMs?: number;\n}\n\nexport interface LayersConfig {\n apiKey: string;\n appId: string;\n environment: 'development' | 'staging' | 'production';\n appUserId?: string | undefined;\n enableDebug?: boolean;\n baseUrl?: string;\n queueOptions?: QueueOptions;\n queueStorage?: QueueStorage | null;\n}\n\nexport interface EventData {\n [key: string]: unknown;\n}\n\nexport interface UserProperties {\n [key: string]: unknown;\n}\n\nexport interface ConsentOptions {\n advertising?: boolean;\n analytics?: boolean;\n}\n\nexport type RemoteConfig = RemoteConfigResponse['config'];\n\nexport * from './api-types.js';\n\nconst SDK_VERSION = '0.0.1';\nconst DEFAULT_BASE_URL = 'http://c9badd27.layers.com';\nconst SYSTEM_EVENTS = new Set(['consent_updated', 'att_status_changed']);\nconst DEFAULT_CONSENT: Required<ConsentOptions> = {\n advertising: true,\n analytics: true\n};\n\ninterface QueueConfig {\n flushIntervalMs: number;\n maxQueueSize: number;\n maxItemAgeMs: number;\n requestTimeoutMs: number;\n maxRetries: number;\n baseRetryDelayMs: number;\n maxRetryDelayMs: number;\n}\n\ninterface QueuedRequest {\n endpoint: string;\n data: unknown;\n attempts: number;\n queuedAt: number;\n nextAttemptAt: number;\n requestId: string;\n retryable: boolean;\n}\n\nexport interface StoredQueuedRequest extends QueuedRequest {}\n\nexport interface StoredQueueSnapshot {\n version: number;\n items: StoredQueuedRequest[];\n}\n\nexport interface QueueStorage {\n load(): Promise<StoredQueueSnapshot | null>;\n save(snapshot: StoredQueueSnapshot): Promise<void>;\n clear(): Promise<void>;\n}\n\ntype RemoteConfigEnvelope = RemoteConfigResponse;\n\ninterface RateLimitRule {\n perMinute?: number;\n perHour?: number;\n}\n\ninterface RateWindowCounter {\n windowStart: number;\n count: number;\n}\n\ninterface RateLimitCounter {\n perMinute?: RateWindowCounter;\n perHour?: RateWindowCounter;\n}\n\ninterface RemoteConfigMeta {\n version?: string;\n etag?: string;\n expiresAt?: number;\n analyticsEnabled?: boolean;\n advertisingEnabled?: boolean;\n eventAllowlist?: Set<string>;\n eventDenylist?: Set<string>;\n samplingRates?: Record<string, number>;\n rateLimits?: {\n global?: RateLimitRule;\n perEvent?: Map<string, RateLimitRule>;\n };\n}\n\nconst DEFAULT_QUEUE_CONFIG: QueueConfig = {\n flushIntervalMs: 10_000,\n maxQueueSize: 200,\n maxItemAgeMs: 5 * 60_000,\n requestTimeoutMs: 10_000,\n maxRetries: 5,\n baseRetryDelayMs: 1_000,\n maxRetryDelayMs: 30_000\n};\n\nfunction now(): number {\n return Date.now();\n}\n\nfunction generateId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}_${now()}`;\n}\n\nexport class LayersClient {\n private config: LayersConfig;\n private remoteConfig: RemoteConfig | null = null;\n private remoteConfigMeta: RemoteConfigMeta = {};\n private eventQueue: QueuedRequest[] = [];\n private isOnline = true;\n private consentState: Required<ConsentOptions> = { ...DEFAULT_CONSENT };\n private sessionId: string;\n private deviceInfo: Partial<BaseEvent> = {};\n private queueTimer: ReturnType<typeof setTimeout> | null = null;\n private queueConfig: QueueConfig;\n private queueStorage: QueueStorage | null;\n private rateLimitState: {\n global: RateLimitCounter;\n perEvent: Map<string, RateLimitCounter>;\n } = {\n global: {},\n perEvent: new Map<string, RateLimitCounter>()\n };\n\n constructor(config: LayersConfig) {\n this.queueConfig = { ...DEFAULT_QUEUE_CONFIG, ...(config.queueOptions || {}) };\n this.queueStorage = config.queueStorage ?? createDefaultQueueStorage(config.appId);\n\n const resolvedAppUserId = config.appUserId;\n\n this.config = {\n ...config,\n baseUrl: (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, ''),\n appUserId: resolvedAppUserId\n };\n this.sessionId = this.generateSessionId();\n this.resetRateLimitState();\n this.initializeDeviceInfo();\n }\n\n private generateSessionId(): string {\n return generateId('sess');\n }\n\n private initializeDeviceInfo(): void {\n this.deviceInfo = {\n platform: 'react-native' as const,\n os_version: 'unknown',\n app_version: 'unknown',\n locale: 'en-US',\n device_model: 'unknown'\n };\n }\n\n async init(): Promise<void> {\n await this.hydrateQueue();\n await this.fetchRemoteConfig();\n this.setupNetworkListener();\n this.scheduleQueueFlush(this.eventQueue.length > 0);\n }\n\n private async fetchRemoteConfig(force = false): Promise<void> {\n const expired = !this.remoteConfigMeta.expiresAt || this.remoteConfigMeta.expiresAt < now();\n if (!force && this.remoteConfig && !expired) {\n return;\n }\n\n try {\n const response = await this.makeRequest<RemoteConfigEnvelope>('/config', {\n method: 'GET'\n });\n\n if (!response?.config) {\n return;\n }\n\n this.remoteConfig = response.config;\n const ttlMs = (response.cache_ttl ?? 300) * 1000;\n this.remoteConfigMeta = {\n version: response.version,\n expiresAt: now() + ttlMs,\n ...this.extractRemoteConfigSettings(response)\n };\n this.resetRateLimitState();\n } catch (error) {\n if (this.config.enableDebug) {\n console.warn('Failed to fetch remote config:', error);\n }\n }\n }\n\n private extractRemoteConfigSettings(envelope: RemoteConfigEnvelope): RemoteConfigMeta {\n const meta: RemoteConfigMeta = {};\n const config = envelope.config ?? {};\n\n if (config.privacy) {\n if (typeof config.privacy.analytics_enabled === 'boolean') {\n meta.analyticsEnabled = config.privacy.analytics_enabled;\n }\n if (typeof config.privacy.advertising_enabled === 'boolean') {\n meta.advertisingEnabled = config.privacy.advertising_enabled;\n }\n if (config.privacy.killswitches) {\n const killswitches = new Set(config.privacy.killswitches);\n if (killswitches.has('analytics')) {\n meta.analyticsEnabled = false;\n }\n if (killswitches.has('advertising')) {\n meta.advertisingEnabled = false;\n }\n }\n }\n\n if (config.events) {\n if (Array.isArray(config.events.allowlist)) {\n meta.eventAllowlist = new Set(config.events.allowlist);\n }\n if (Array.isArray(config.events.denylist)) {\n meta.eventDenylist = new Set(config.events.denylist);\n }\n\n const samplingEntries: Record<string, number> = {};\n if (config.events.sampling) {\n for (const [eventName, value] of Object.entries(config.events.sampling)) {\n const numeric = Number(value);\n if (Number.isFinite(numeric)) {\n samplingEntries[eventName] = Math.max(0, Math.min(1, numeric));\n }\n }\n }\n if (typeof config.events.sampling_rate === 'number') {\n samplingEntries['*'] = Math.max(0, Math.min(1, config.events.sampling_rate));\n }\n if (Object.keys(samplingEntries).length > 0) {\n meta.samplingRates = samplingEntries;\n }\n\n const rateLimitConfig = config.events.rate_limit;\n if (rateLimitConfig) {\n const globalRule = this.normalizeRateLimitRule(rateLimitConfig);\n let perEventRules: Map<string, RateLimitRule> | undefined;\n if (rateLimitConfig.per_event) {\n const entries = Object.entries(rateLimitConfig.per_event);\n if (entries.length > 0) {\n perEventRules = new Map<string, RateLimitRule>();\n for (const [eventName, ruleConfig] of entries) {\n const rule = this.normalizeRateLimitRule(ruleConfig);\n if (rule) {\n perEventRules.set(eventName, rule);\n }\n }\n if (perEventRules.size === 0) {\n perEventRules = undefined;\n }\n }\n }\n const rateLimits: { global?: RateLimitRule; perEvent?: Map<string, RateLimitRule> } = {};\n if (globalRule) {\n rateLimits.global = globalRule;\n }\n if (perEventRules) {\n rateLimits.perEvent = perEventRules;\n }\n if (rateLimits.global || rateLimits.perEvent) {\n meta.rateLimits = rateLimits;\n }\n }\n }\n\n return meta;\n }\n\n private setupNetworkListener(): void {\n if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('online', () => {\n this.setOnlineState(true);\n });\n\n window.addEventListener('offline', () => {\n this.setOnlineState(false);\n });\n }\n }\n\n setOnlineState(isOnline: boolean): void {\n if (this.isOnline === isOnline) {\n return;\n }\n\n this.isOnline = isOnline;\n\n if (isOnline) {\n this.scheduleQueueFlush(true);\n }\n }\n\n private async hydrateQueue(): Promise<void> {\n if (!this.queueStorage) {\n return;\n }\n\n try {\n const snapshot = await this.queueStorage.load();\n if (!snapshot || !Array.isArray(snapshot.items) || snapshot.items.length === 0) {\n if (snapshot) {\n await this.queueStorage.clear();\n }\n return;\n }\n\n const nowTs = now();\n const maxAge = this.queueConfig.maxItemAgeMs;\n const hydrated: QueuedRequest[] = [];\n\n for (const item of snapshot.items) {\n if (item && typeof item.endpoint === 'string') {\n const queuedAt = typeof item.queuedAt === 'number' ? item.queuedAt : nowTs;\n if (nowTs - queuedAt <= maxAge) {\n hydrated.push({\n endpoint: item.endpoint,\n data: item.data,\n attempts: typeof item.attempts === 'number' ? item.attempts : 0,\n queuedAt,\n nextAttemptAt: typeof item.nextAttemptAt === 'number' ? item.nextAttemptAt : nowTs,\n requestId: typeof item.requestId === 'string' ? item.requestId : generateId('req'),\n retryable: item.retryable !== false\n });\n }\n }\n }\n\n if (hydrated.length === 0) {\n await this.queueStorage.clear();\n this.eventQueue = [];\n return;\n }\n\n const limited = hydrated.slice(0, this.queueConfig.maxQueueSize);\n const trimmed = limited.length !== hydrated.length;\n\n this.eventQueue = limited;\n\n if (trimmed || limited.length !== snapshot.items.length) {\n await this.persistQueue();\n }\n } catch (error) {\n if (this.config.enableDebug) {\n console.warn('Failed to hydrate queue', error);\n }\n }\n }\n\n private async persistQueue(): Promise<void> {\n if (!this.queueStorage) {\n return;\n }\n\n const snapshot: StoredQueueSnapshot = {\n version: 1,\n items: this.eventQueue.map((item) => ({\n endpoint: item.endpoint,\n data: item.data,\n attempts: item.attempts,\n queuedAt: item.queuedAt,\n nextAttemptAt: item.nextAttemptAt,\n requestId: item.requestId,\n retryable: item.retryable\n }))\n };\n\n try {\n if (snapshot.items.length === 0) {\n await this.queueStorage.clear();\n } else {\n await this.queueStorage.save(snapshot);\n }\n } catch (error) {\n if (this.config.enableDebug) {\n console.warn('Failed to persist queue', error);\n }\n }\n }\n\n async track(eventName: string, properties?: EventData): Promise<void> {\n if (!this.shouldProcessEvent(eventName)) {\n if (this.config.enableDebug) {\n console.log(`Event '${eventName}' dropped due to consent or config gating`);\n }\n return;\n }\n\n if (!this.passesSampling(eventName)) {\n if (this.config.enableDebug) {\n console.log(`Event '${eventName}' sampled out`);\n }\n return;\n }\n\n const baseEvent: BaseEvent = {\n event: eventName,\n timestamp: new Date().toISOString(),\n event_id: this.generateEventId(),\n app_id: this.config.appId,\n session_id: this.sessionId,\n environment: this.config.environment,\n platform: this.deviceInfo.platform!,\n os_version: this.deviceInfo.os_version!,\n app_version: this.deviceInfo.app_version!,\n device_model: this.deviceInfo.device_model!,\n locale: this.deviceInfo.locale!,\n ...this.deviceInfo,\n properties: properties || {},\n ...(this.resolveAppUserId() && { app_user_id: this.resolveAppUserId() })\n };\n\n const batchPayload: EventsBatchPayload = {\n events: [baseEvent as unknown as BaseEvent],\n batch_id: this.generateBatchId(),\n sent_at: new Date().toISOString()\n };\n\n await this.enqueue('/events', batchPayload);\n }\n\n private shouldProcessEvent(eventName: string): boolean {\n if (SYSTEM_EVENTS.has(eventName)) {\n return true;\n }\n\n if (!this.isAnalyticsEnabled()) {\n return false;\n }\n\n if (\n this.remoteConfigMeta.eventAllowlist &&\n !this.remoteConfigMeta.eventAllowlist.has(eventName)\n ) {\n return false;\n }\n\n if (this.remoteConfigMeta.eventDenylist && this.remoteConfigMeta.eventDenylist.has(eventName)) {\n return false;\n }\n\n if (!this.passesRateLimit(eventName)) {\n return false;\n }\n\n return true;\n }\n\n private passesSampling(eventName: string): boolean {\n const sampling = this.remoteConfigMeta.samplingRates;\n if (!sampling) {\n return true;\n }\n\n const rate = sampling[eventName] ?? sampling['*'];\n if (typeof rate !== 'number') {\n return true;\n }\n\n return Math.random() <= Math.max(0, Math.min(1, rate));\n }\n\n private resolveAppUserId(): string | undefined {\n return this.config.appUserId;\n }\n\n async screen(screenName: string, properties?: EventData): Promise<void> {\n await this.track('screen_view', {\n screen_name: screenName,\n ...properties\n });\n }\n\n async setUserProperties(properties: UserProperties): Promise<void> {\n if (!this.isAnalyticsEnabled()) {\n return;\n }\n\n const payload: UserPropertiesPayload = {\n app_id: this.config.appId,\n properties,\n timestamp: new Date().toISOString(),\n ...(this.resolveAppUserId() && { app_user_id: this.resolveAppUserId() })\n };\n\n await this.enqueue('/users/properties', payload);\n }\n\n isAnalyticsEnabled(): boolean {\n if (this.remoteConfigMeta.analyticsEnabled === false) {\n return false;\n }\n return this.consentState.analytics !== false;\n }\n\n isAdvertisingEnabled(): boolean {\n if (this.remoteConfigMeta.advertisingEnabled === false) {\n return false;\n }\n return this.consentState.advertising !== false;\n }\n\n async setConsent(consent: ConsentOptions): Promise<void> {\n this.consentState = {\n advertising:\n typeof consent.advertising === 'boolean'\n ? consent.advertising\n : this.consentState.advertising,\n analytics:\n typeof consent.analytics === 'boolean' ? consent.analytics : this.consentState.analytics\n };\n\n const payload: ConsentPayload = {\n app_id: this.config.appId,\n consent: { ...this.consentState },\n timestamp: new Date().toISOString(),\n ...(this.resolveAppUserId() && { app_user_id: this.resolveAppUserId() })\n };\n\n await this.enqueue('/consent', payload);\n }\n\n private async enqueue(\n endpoint: string,\n data: unknown,\n options?: { retryable?: boolean }\n ): Promise<void> {\n const retryable = options?.retryable !== false;\n\n if (this.eventQueue.length >= this.queueConfig.maxQueueSize) {\n this.eventQueue.shift();\n }\n\n this.eventQueue.push({\n endpoint,\n data,\n attempts: 0,\n queuedAt: now(),\n nextAttemptAt: now(),\n requestId: generateId('req'),\n retryable\n });\n\n if (this.isOnline) {\n this.scheduleQueueFlush(true);\n } else {\n this.scheduleQueueFlush();\n }\n\n void this.persistQueue();\n }\n\n private scheduleQueueFlush(immediate = false): void {\n if (this.queueTimer) {\n clearTimeout(this.queueTimer);\n this.queueTimer = null;\n }\n\n const delay = immediate ? 0 : this.queueConfig.flushIntervalMs;\n this.queueTimer = setTimeout(() => {\n this.queueTimer = null;\n void this.processQueue();\n }, delay);\n }\n\n private async processQueue(): Promise<void> {\n if (!this.isOnline || this.eventQueue.length === 0) {\n this.scheduleQueueFlush();\n return;\n }\n\n this.dropExpiredQueueItems();\n\n const pending: QueuedRequest[] = [];\n\n for (const item of this.eventQueue) {\n if (item.nextAttemptAt > now()) {\n pending.push(item);\n } else {\n let shouldRequeue = false;\n try {\n await this.makeRequest(\n item.endpoint,\n {\n method: 'POST',\n body: JSON.stringify(item.data)\n },\n item.requestId\n );\n } catch (err) {\n if (!item.retryable) {\n if (this.config.enableDebug) {\n console.warn('Dropping non-retryable item', { endpoint: item.endpoint, error: err });\n }\n } else {\n item.attempts += 1;\n if (item.attempts > this.queueConfig.maxRetries) {\n if (this.config.enableDebug) {\n console.warn('Dropping item after max retries', {\n endpoint: item.endpoint,\n error: err\n });\n }\n } else {\n item.nextAttemptAt = now() + this.getBackoffDelay(item.attempts);\n shouldRequeue = true;\n if (this.config.enableDebug) {\n console.warn('Retry scheduled', {\n endpoint: item.endpoint,\n nextAttemptAt: item.nextAttemptAt,\n error: err\n });\n }\n }\n }\n }\n\n if (shouldRequeue) {\n pending.push(item);\n }\n }\n }\n\n this.eventQueue = pending;\n await this.persistQueue();\n this.scheduleQueueFlush(this.eventQueue.length > 0);\n }\n\n private dropExpiredQueueItems(): void {\n const cutoff = now() - this.queueConfig.maxItemAgeMs;\n if (this.eventQueue.length === 0) {\n return;\n }\n\n const retained = this.eventQueue.filter((item) => item.queuedAt >= cutoff);\n if (this.config.enableDebug && retained.length !== this.eventQueue.length) {\n console.warn('Dropped stale queue items', {\n dropped: this.eventQueue.length - retained.length\n });\n }\n this.eventQueue = retained;\n void this.persistQueue();\n }\n\n private getBackoffDelay(attempt: number): number {\n const jitter = Math.random() * 250;\n const delay = this.queueConfig.baseRetryDelayMs * 2 ** (attempt - 1);\n return Math.min(delay + jitter, this.queueConfig.maxRetryDelayMs);\n }\n\n private resetRateLimitState(): void {\n this.rateLimitState = {\n global: {},\n perEvent: new Map<string, RateLimitCounter>()\n };\n }\n\n private getEventRateCounter(eventName: string): RateLimitCounter {\n let counter = this.rateLimitState.perEvent.get(eventName);\n if (!counter) {\n counter = {};\n this.rateLimitState.perEvent.set(eventName, counter);\n }\n return counter;\n }\n\n private normalizeRateLimitRule(\n input: { per_minute?: number; per_hour?: number } | undefined\n ): RateLimitRule | undefined {\n if (!input) {\n return undefined;\n }\n const rule: RateLimitRule = {};\n if (typeof input.per_minute === 'number' && input.per_minute > 0) {\n rule.perMinute = Math.floor(input.per_minute);\n }\n if (typeof input.per_hour === 'number' && input.per_hour > 0) {\n rule.perHour = Math.floor(input.per_hour);\n }\n return Object.keys(rule).length > 0 ? rule : undefined;\n }\n\n private passesRateLimit(eventName: string): boolean {\n if (SYSTEM_EVENTS.has(eventName)) {\n return true;\n }\n const { rateLimits } = this.remoteConfigMeta;\n if (!rateLimits) {\n return true;\n }\n const timestamp = now();\n const perEventRules = rateLimits.perEvent;\n const eventRule = perEventRules?.get(eventName) ?? perEventRules?.get('*');\n if (\n eventRule &&\n !this.canConsumeRateLimit(eventRule, this.getEventRateCounter(eventName), timestamp)\n ) {\n if (this.config.enableDebug) {\n console.warn('Rate limit reached for event', { event: eventName });\n }\n return false;\n }\n if (\n rateLimits.global &&\n !this.canConsumeRateLimit(rateLimits.global, this.rateLimitState.global, timestamp)\n ) {\n if (this.config.enableDebug) {\n console.warn('Global rate limit reached', { event: eventName });\n }\n return false;\n }\n if (eventRule) {\n this.recordRateLimit(eventRule, this.getEventRateCounter(eventName), timestamp);\n }\n if (rateLimits.global) {\n this.recordRateLimit(rateLimits.global, this.rateLimitState.global, timestamp);\n }\n return true;\n }\n\n private canConsumeRateLimit(\n rule: RateLimitRule,\n counter: RateLimitCounter,\n timestamp: number\n ): boolean {\n return (\n this.canConsumeWindow(rule.perMinute, counter, 'perMinute', 60_000, timestamp) &&\n this.canConsumeWindow(rule.perHour, counter, 'perHour', 3_600_000, timestamp)\n );\n }\n\n private canConsumeWindow(\n limit: number | undefined,\n counter: RateLimitCounter,\n key: 'perMinute' | 'perHour',\n windowMs: number,\n timestamp: number\n ): boolean {\n if (limit === undefined) {\n return true;\n }\n const { count } = this.getWindowInfo(counter, key, windowMs, timestamp);\n return count + 1 <= limit;\n }\n\n private recordRateLimit(rule: RateLimitRule, counter: RateLimitCounter, timestamp: number): void {\n this.incrementWindow(rule.perMinute, counter, 'perMinute', 60_000, timestamp);\n this.incrementWindow(rule.perHour, counter, 'perHour', 3_600_000, timestamp);\n }\n\n private incrementWindow(\n limit: number | undefined,\n counter: RateLimitCounter,\n key: 'perMinute' | 'perHour',\n windowMs: number,\n timestamp: number\n ): void {\n if (limit === undefined) {\n return;\n }\n const windowStart = Math.floor(timestamp / windowMs) * windowMs;\n const existing = counter[key];\n if (!existing || existing.windowStart !== windowStart) {\n counter[key] = { windowStart, count: 1 };\n } else {\n existing.count += 1;\n }\n }\n\n private getWindowInfo(\n counter: RateLimitCounter,\n key: 'perMinute' | 'perHour',\n windowMs: number,\n timestamp: number\n ): RateWindowCounter {\n const windowStart = Math.floor(timestamp / windowMs) * windowMs;\n const existing = counter[key];\n if (!existing || existing.windowStart !== windowStart) {\n return { windowStart, count: 0 };\n }\n return existing;\n }\n\n private async makeRequest<T = unknown>(\n endpoint: string,\n options: RequestInit,\n requestId: string = generateId('req')\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n const controller = typeof AbortController !== 'undefined' ? new AbortController() : undefined;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Api-Key': this.config.apiKey,\n 'X-App-Id': this.config.appId,\n 'X-Environment': this.config.environment,\n 'X-SDK-Version': SDK_VERSION,\n 'X-Request-Id': requestId,\n ...(options.headers as Record<string, string> | undefined)\n };\n\n if (this.sessionId) {\n headers['X-Session-Id'] = this.sessionId;\n }\n\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n if (controller) {\n options = { ...options, signal: controller.signal };\n timeoutHandle = setTimeout(() => {\n controller.abort();\n }, this.queueConfig.requestTimeoutMs);\n }\n\n try {\n const response = await fetch(url, {\n ...options,\n headers\n });\n\n if (!response.ok) {\n if (!this.isRetryableStatus(response.status)) {\n throw Object.assign(new Error(`HTTP ${response.status}: ${response.statusText}`), {\n status: response.status\n });\n }\n throw Object.assign(new Error(`Retryable HTTP ${response.status}`), {\n status: response.status\n });\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n return JSON.parse(text) as T;\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n private isRetryableStatus(status: number): boolean {\n if (status === 429 || (status >= 500 && status < 600)) {\n return true;\n }\n return false;\n }\n\n private generateEventId(): string {\n return generateId('evt');\n }\n\n private generateBatchId(): string {\n return generateId('batch');\n }\n\n getRemoteConfig(): RemoteConfig | null {\n return this.remoteConfig;\n }\n\n getRemoteConfigVersion(): string | undefined {\n return this.remoteConfigMeta.version;\n }\n\n getConsentState(): Required<ConsentOptions> {\n return { ...this.consentState };\n }\n\n setAppUserId(appUserId: string | undefined): void {\n this.config.appUserId = appUserId;\n }\n\n /** @deprecated Use setAppUserId instead */\n setUserId(userId: string): void {\n this.setAppUserId(userId);\n }\n\n getConfig(): LayersConfig {\n return { ...this.config };\n }\n\n getAppUserId(): string | undefined {\n return this.resolveAppUserId();\n }\n\n /** @deprecated Use getAppUserId instead */\n getUserId(): string | undefined {\n return this.resolveAppUserId();\n }\n\n getSessionId(): string {\n return this.sessionId;\n }\n\n async flush(): Promise<void> {\n await this.processQueue();\n }\n\n setDeviceInfo(deviceInfo: Partial<BaseEvent>): void {\n this.deviceInfo = {\n ...this.deviceInfo,\n ...Object.fromEntries(\n Object.entries(deviceInfo).filter(([, value]) => value !== undefined && value !== null)\n )\n };\n }\n\n startNewSession(): void {\n this.sessionId = this.generateSessionId();\n }\n}\n\nfunction createDefaultQueueStorage(appId: string): QueueStorage | null {\n if (typeof window === 'undefined') {\n return null;\n }\n\n try {\n const storage = window.localStorage;\n if (!storage) {\n return null;\n }\n } catch {\n return null;\n }\n\n const storageKey = `layers_queue_${appId}`;\n return createLocalStorageQueueStorage(storageKey);\n}\n\nfunction createLocalStorageQueueStorage(storageKey: string): QueueStorage {\n return {\n async load() {\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n return parsed as StoredQueueSnapshot;\n } catch (error) {\n console.warn('Failed to load queue from localStorage', error);\n return null;\n }\n },\n async save(snapshot: StoredQueueSnapshot) {\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(snapshot));\n } catch (error) {\n console.warn('Failed to persist queue to localStorage', error);\n }\n },\n async clear() {\n try {\n window.localStorage.removeItem(storageKey);\n } catch (error) {\n console.warn('Failed to clear queue storage', error);\n }\n }\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["DEFAULT_CONSENT: Required<ConsentOptions>","DEFAULT_QUEUE_CONFIG: QueueConfig","meta: RemoteConfigMeta","samplingEntries: Record<string, number>","perEventRules: Map<string, RateLimitRule> | undefined","rateLimits: { global?: RateLimitRule; perEvent?: Map<string, RateLimitRule> }","hydrated: QueuedRequest[]","snapshot: StoredQueueSnapshot","batchPayload: EventsBatchPayload","payload: UserPropertiesPayload","payload: ConsentPayload","pending: QueuedRequest[]","rule: RateLimitRule","headers: Record<string, string>","timeoutHandle: ReturnType<typeof setTimeout> | undefined","error"],"sources":["../src/index.ts"],"sourcesContent":["import type {\n BaseEvent,\n ConsentPayload,\n EventsBatchPayload,\n RemoteConfigResponse,\n UserPropertiesPayload\n} from './api-types.js';\n\nexport interface QueueOptions {\n flushIntervalMs?: number;\n maxQueueSize?: number;\n maxItemAgeMs?: number;\n requestTimeoutMs?: number;\n maxRetries?: number;\n baseRetryDelayMs?: number;\n maxRetryDelayMs?: number;\n}\n\nexport interface LayersConfig {\n apiKey: string;\n appId: string;\n environment: 'development' | 'staging' | 'production';\n appUserId?: string | undefined;\n enableDebug?: boolean;\n baseUrl?: string;\n queueOptions?: QueueOptions;\n queueStorage?: QueueStorage | null;\n}\n\nexport interface EventData {\n [key: string]: unknown;\n}\n\nexport interface UserProperties {\n [key: string]: unknown;\n}\n\nexport interface ConsentOptions {\n advertising?: boolean;\n analytics?: boolean;\n}\n\nexport type RemoteConfig = RemoteConfigResponse['config'];\n\nexport * from './api-types.js';\n\n// TODO: read this from package json, no need to manage version in the code\nconst SDK_VERSION = '0.0.0';\nconst DEFAULT_BASE_URL = 'https://in.layers.com';\nconst SYSTEM_EVENTS = new Set(['consent_updated', 'att_status_changed']);\nconst DEFAULT_CONSENT: Required<ConsentOptions> = {\n advertising: true,\n analytics: true\n};\n\ninterface QueueConfig {\n flushIntervalMs: number;\n maxQueueSize: number;\n maxItemAgeMs: number;\n requestTimeoutMs: number;\n maxRetries: number;\n baseRetryDelayMs: number;\n maxRetryDelayMs: number;\n}\n\ninterface QueuedRequest {\n endpoint: string;\n data: unknown;\n attempts: number;\n queuedAt: number;\n nextAttemptAt: number;\n requestId: string;\n retryable: boolean;\n}\n\nexport interface StoredQueuedRequest extends QueuedRequest {}\n\nexport interface StoredQueueSnapshot {\n version: number;\n items: StoredQueuedRequest[];\n}\n\nexport interface QueueStorage {\n load(): Promise<StoredQueueSnapshot | null>;\n save(snapshot: StoredQueueSnapshot): Promise<void>;\n clear(): Promise<void>;\n}\n\ntype RemoteConfigEnvelope = RemoteConfigResponse;\n\ninterface RateLimitRule {\n perMinute?: number;\n perHour?: number;\n}\n\ninterface RateWindowCounter {\n windowStart: number;\n count: number;\n}\n\ninterface RateLimitCounter {\n perMinute?: RateWindowCounter;\n perHour?: RateWindowCounter;\n}\n\ninterface RemoteConfigMeta {\n version?: string;\n etag?: string;\n expiresAt?: number;\n analyticsEnabled?: boolean;\n advertisingEnabled?: boolean;\n eventAllowlist?: Set<string>;\n eventDenylist?: Set<string>;\n samplingRates?: Record<string, number>;\n rateLimits?: {\n global?: RateLimitRule;\n perEvent?: Map<string, RateLimitRule>;\n };\n}\n\nconst DEFAULT_QUEUE_CONFIG: QueueConfig = {\n flushIntervalMs: 10_000,\n maxQueueSize: 200,\n maxItemAgeMs: 5 * 60_000,\n requestTimeoutMs: 10_000,\n maxRetries: 5,\n baseRetryDelayMs: 1_000,\n maxRetryDelayMs: 30_000\n};\n\nfunction now(): number {\n return Date.now();\n}\n\nfunction generateId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}_${now()}`;\n}\n\nexport class LayersClient {\n private config: LayersConfig;\n private remoteConfig: RemoteConfig | null = null;\n private remoteConfigMeta: RemoteConfigMeta = {};\n private eventQueue: QueuedRequest[] = [];\n private isOnline = true;\n private consentState: Required<ConsentOptions> = { ...DEFAULT_CONSENT };\n private sessionId: string;\n private deviceInfo: Partial<BaseEvent> = {};\n private queueTimer: ReturnType<typeof setTimeout> | null = null;\n private queueConfig: QueueConfig;\n private queueStorage: QueueStorage | null;\n private rateLimitState: {\n global: RateLimitCounter;\n perEvent: Map<string, RateLimitCounter>;\n } = {\n global: {},\n perEvent: new Map<string, RateLimitCounter>()\n };\n\n private logLevel(): string {\n // Check environment variable first\n if (typeof process !== 'undefined' && process.env?.LOG_LEVEL) {\n return process.env.LOG_LEVEL.toLowerCase();\n }\n // Fall back to config flag\n if (this.config.enableDebug) {\n return 'debug';\n }\n // Default to info\n return 'info';\n }\n\n private shouldLog(level: 'error' | 'warn' | 'info' | 'debug' | 'trace'): boolean {\n const currentLevel = this.logLevel();\n const levels = ['error', 'warn', 'info', 'debug', 'trace'];\n const currentIndex = levels.indexOf(currentLevel);\n const targetIndex = levels.indexOf(level);\n return currentIndex >= targetIndex;\n }\n\n constructor(config: LayersConfig) {\n this.queueConfig = { ...DEFAULT_QUEUE_CONFIG, ...(config.queueOptions || {}) };\n this.queueStorage = config.queueStorage ?? createDefaultQueueStorage(config.appId);\n\n const resolvedAppUserId = config.appUserId;\n\n this.config = {\n ...config,\n baseUrl: (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, ''),\n appUserId: resolvedAppUserId\n };\n this.sessionId = this.generateSessionId();\n this.resetRateLimitState();\n this.initializeDeviceInfo();\n }\n\n private generateSessionId(): string {\n return generateId('sess');\n }\n\n private initializeDeviceInfo(): void {\n this.deviceInfo = {\n platform: 'react-native' as const,\n os_version: 'unknown',\n app_version: 'unknown',\n locale: 'en-US',\n device_model: 'unknown'\n };\n }\n\n async init(): Promise<void> {\n await this.hydrateQueue();\n await this.fetchRemoteConfig();\n this.setupNetworkListener();\n this.scheduleQueueFlush(this.eventQueue.length > 0);\n }\n\n private async fetchRemoteConfig(force = false): Promise<void> {\n const expired = !this.remoteConfigMeta.expiresAt || this.remoteConfigMeta.expiresAt < now();\n if (!force && this.remoteConfig && !expired) {\n return;\n }\n\n try {\n const response = await this.makeRequest<RemoteConfigEnvelope>('/config', {\n method: 'GET'\n });\n\n if (!response?.config) {\n return;\n }\n\n this.remoteConfig = response.config;\n const ttlMs = (response.cache_ttl ?? 300) * 1000;\n this.remoteConfigMeta = {\n version: response.version,\n expiresAt: now() + ttlMs,\n ...this.extractRemoteConfigSettings(response)\n };\n this.resetRateLimitState();\n } catch (error) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Failed to fetch remote config:', error);\n }\n }\n }\n\n private extractRemoteConfigSettings(envelope: RemoteConfigEnvelope): RemoteConfigMeta {\n const meta: RemoteConfigMeta = {};\n const config = envelope.config ?? {};\n\n if (config.privacy) {\n if (typeof config.privacy.analytics_enabled === 'boolean') {\n meta.analyticsEnabled = config.privacy.analytics_enabled;\n }\n if (typeof config.privacy.advertising_enabled === 'boolean') {\n meta.advertisingEnabled = config.privacy.advertising_enabled;\n }\n if (config.privacy.killswitches) {\n const killswitches = new Set(config.privacy.killswitches);\n if (killswitches.has('analytics')) {\n meta.analyticsEnabled = false;\n }\n if (killswitches.has('advertising')) {\n meta.advertisingEnabled = false;\n }\n }\n }\n\n if (config.events) {\n if (Array.isArray(config.events.allowlist)) {\n meta.eventAllowlist = new Set(config.events.allowlist);\n }\n if (Array.isArray(config.events.denylist)) {\n meta.eventDenylist = new Set(config.events.denylist);\n }\n\n const samplingEntries: Record<string, number> = {};\n if (config.events.sampling) {\n for (const [eventName, value] of Object.entries(config.events.sampling)) {\n const numeric = Number(value);\n if (Number.isFinite(numeric)) {\n samplingEntries[eventName] = Math.max(0, Math.min(1, numeric));\n }\n }\n }\n if (typeof config.events.sampling_rate === 'number') {\n samplingEntries['*'] = Math.max(0, Math.min(1, config.events.sampling_rate));\n }\n if (Object.keys(samplingEntries).length > 0) {\n meta.samplingRates = samplingEntries;\n }\n\n const rateLimitConfig = config.events.rate_limit;\n if (rateLimitConfig) {\n const globalRule = this.normalizeRateLimitRule(rateLimitConfig);\n let perEventRules: Map<string, RateLimitRule> | undefined;\n if (rateLimitConfig.per_event) {\n const entries = Object.entries(rateLimitConfig.per_event);\n if (entries.length > 0) {\n perEventRules = new Map<string, RateLimitRule>();\n for (const [eventName, ruleConfig] of entries) {\n const rule = this.normalizeRateLimitRule(ruleConfig);\n if (rule) {\n perEventRules.set(eventName, rule);\n }\n }\n if (perEventRules.size === 0) {\n perEventRules = undefined;\n }\n }\n }\n const rateLimits: { global?: RateLimitRule; perEvent?: Map<string, RateLimitRule> } = {};\n if (globalRule) {\n rateLimits.global = globalRule;\n }\n if (perEventRules) {\n rateLimits.perEvent = perEventRules;\n }\n if (rateLimits.global || rateLimits.perEvent) {\n meta.rateLimits = rateLimits;\n }\n }\n }\n\n return meta;\n }\n\n private setupNetworkListener(): void {\n if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('online', () => {\n this.setOnlineState(true);\n });\n\n window.addEventListener('offline', () => {\n this.setOnlineState(false);\n });\n }\n }\n\n setOnlineState(isOnline: boolean): void {\n if (this.isOnline === isOnline) {\n return;\n }\n\n this.isOnline = isOnline;\n\n if (isOnline) {\n this.scheduleQueueFlush(true);\n }\n }\n\n private async hydrateQueue(): Promise<void> {\n if (!this.queueStorage) {\n return;\n }\n\n try {\n const snapshot = await this.queueStorage.load();\n if (!snapshot || !Array.isArray(snapshot.items) || snapshot.items.length === 0) {\n if (snapshot) {\n await this.queueStorage.clear();\n }\n return;\n }\n\n const nowTs = now();\n const maxAge = this.queueConfig.maxItemAgeMs;\n const hydrated: QueuedRequest[] = [];\n\n for (const item of snapshot.items) {\n if (item && typeof item.endpoint === 'string') {\n const queuedAt = typeof item.queuedAt === 'number' ? item.queuedAt : nowTs;\n if (nowTs - queuedAt <= maxAge) {\n hydrated.push({\n endpoint: item.endpoint,\n data: item.data,\n attempts: typeof item.attempts === 'number' ? item.attempts : 0,\n queuedAt,\n nextAttemptAt: typeof item.nextAttemptAt === 'number' ? item.nextAttemptAt : nowTs,\n requestId: typeof item.requestId === 'string' ? item.requestId : generateId('req'),\n retryable: item.retryable !== false\n });\n }\n }\n }\n\n if (hydrated.length === 0) {\n await this.queueStorage.clear();\n this.eventQueue = [];\n return;\n }\n\n const limited = hydrated.slice(0, this.queueConfig.maxQueueSize);\n const trimmed = limited.length !== hydrated.length;\n\n this.eventQueue = limited;\n\n if (trimmed || limited.length !== snapshot.items.length) {\n await this.persistQueue();\n }\n } catch (error) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Failed to hydrate queue', error);\n }\n }\n }\n\n private async persistQueue(): Promise<void> {\n if (!this.queueStorage) {\n return;\n }\n\n const snapshot: StoredQueueSnapshot = {\n version: 1,\n items: this.eventQueue.map((item) => ({\n endpoint: item.endpoint,\n data: item.data,\n attempts: item.attempts,\n queuedAt: item.queuedAt,\n nextAttemptAt: item.nextAttemptAt,\n requestId: item.requestId,\n retryable: item.retryable\n }))\n };\n\n try {\n if (snapshot.items.length === 0) {\n await this.queueStorage.clear();\n } else {\n await this.queueStorage.save(snapshot);\n }\n } catch (error) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Failed to persist queue', error);\n }\n }\n }\n\n async track(eventName: string, properties?: EventData): Promise<void> {\n if (!this.shouldProcessEvent(eventName)) {\n if (this.shouldLog('debug')) {\n console.log(`[Layers] Event '${eventName}' dropped due to consent or config gating`);\n }\n return;\n }\n\n if (!this.passesSampling(eventName)) {\n if (this.shouldLog('debug')) {\n console.log(`[Layers] Event '${eventName}' sampled out`);\n }\n return;\n }\n\n const baseEvent: BaseEvent = {\n event: eventName,\n timestamp: new Date().toISOString(),\n event_id: this.generateEventId(),\n app_id: this.config.appId,\n session_id: this.sessionId,\n environment: this.config.environment,\n platform: this.deviceInfo.platform!,\n os_version: this.deviceInfo.os_version!,\n app_version: this.deviceInfo.app_version!,\n device_model: this.deviceInfo.device_model!,\n locale: this.deviceInfo.locale!,\n ...this.deviceInfo,\n properties: properties || {},\n ...(this.resolveAppUserId() && { app_user_id: this.resolveAppUserId() })\n };\n\n const batchPayload: EventsBatchPayload = {\n events: [baseEvent as unknown as BaseEvent],\n batch_id: this.generateBatchId(),\n sent_at: new Date().toISOString()\n };\n\n const appUserId = this.resolveAppUserId();\n console.log(\n `[Layers] Tracking event: ${eventName}${appUserId ? ` (user: ${appUserId})` : ' (no user)'}`\n );\n\n await this.enqueue('/events', batchPayload);\n }\n\n private shouldProcessEvent(eventName: string): boolean {\n if (SYSTEM_EVENTS.has(eventName)) {\n return true;\n }\n\n if (!this.isAnalyticsEnabled()) {\n return false;\n }\n\n if (\n this.remoteConfigMeta.eventAllowlist &&\n !this.remoteConfigMeta.eventAllowlist.has(eventName)\n ) {\n return false;\n }\n\n if (this.remoteConfigMeta.eventDenylist && this.remoteConfigMeta.eventDenylist.has(eventName)) {\n return false;\n }\n\n if (!this.passesRateLimit(eventName)) {\n return false;\n }\n\n return true;\n }\n\n private passesSampling(eventName: string): boolean {\n const sampling = this.remoteConfigMeta.samplingRates;\n if (!sampling) {\n return true;\n }\n\n const rate = sampling[eventName] ?? sampling['*'];\n if (typeof rate !== 'number') {\n return true;\n }\n\n return Math.random() <= Math.max(0, Math.min(1, rate));\n }\n\n private resolveAppUserId(): string | undefined {\n return this.config.appUserId;\n }\n\n async screen(screenName: string, properties?: EventData): Promise<void> {\n await this.track('screen_view', {\n screen_name: screenName,\n ...properties\n });\n }\n\n async setUserProperties(properties: UserProperties): Promise<void> {\n if (!this.isAnalyticsEnabled()) {\n return;\n }\n\n const payload: UserPropertiesPayload = {\n app_id: this.config.appId,\n properties,\n timestamp: new Date().toISOString(),\n ...(this.resolveAppUserId() && { app_user_id: this.resolveAppUserId() })\n };\n\n await this.enqueue('/users/properties', payload);\n }\n\n isAnalyticsEnabled(): boolean {\n if (this.remoteConfigMeta.analyticsEnabled === false) {\n return false;\n }\n return this.consentState.analytics !== false;\n }\n\n isAdvertisingEnabled(): boolean {\n if (this.remoteConfigMeta.advertisingEnabled === false) {\n return false;\n }\n return this.consentState.advertising !== false;\n }\n\n async setConsent(consent: ConsentOptions): Promise<void> {\n this.consentState = {\n advertising:\n typeof consent.advertising === 'boolean'\n ? consent.advertising\n : this.consentState.advertising,\n analytics:\n typeof consent.analytics === 'boolean' ? consent.analytics : this.consentState.analytics\n };\n\n const payload: ConsentPayload = {\n app_id: this.config.appId,\n consent: { ...this.consentState },\n timestamp: new Date().toISOString(),\n ...(this.resolveAppUserId() && { app_user_id: this.resolveAppUserId() })\n };\n\n await this.enqueue('/consent', payload);\n }\n\n private async enqueue(\n endpoint: string,\n data: unknown,\n options?: { retryable?: boolean }\n ): Promise<void> {\n const retryable = options?.retryable !== false;\n\n if (this.eventQueue.length >= this.queueConfig.maxQueueSize) {\n this.eventQueue.shift();\n }\n\n this.eventQueue.push({\n endpoint,\n data,\n attempts: 0,\n queuedAt: now(),\n nextAttemptAt: now(),\n requestId: generateId('req'),\n retryable\n });\n\n if (this.isOnline) {\n this.scheduleQueueFlush(true);\n } else {\n this.scheduleQueueFlush();\n }\n\n void this.persistQueue();\n }\n\n private scheduleQueueFlush(immediate = false): void {\n if (this.queueTimer) {\n clearTimeout(this.queueTimer);\n this.queueTimer = null;\n }\n\n const delay = immediate ? 0 : this.queueConfig.flushIntervalMs;\n this.queueTimer = setTimeout(() => {\n this.queueTimer = null;\n void this.processQueue();\n }, delay);\n }\n\n private async processQueue(): Promise<void> {\n if (!this.isOnline || this.eventQueue.length === 0) {\n this.scheduleQueueFlush();\n return;\n }\n\n this.dropExpiredQueueItems();\n\n const pending: QueuedRequest[] = [];\n\n for (const item of this.eventQueue) {\n if (item.nextAttemptAt > now()) {\n pending.push(item);\n } else {\n let shouldRequeue = false;\n try {\n await this.makeRequest(\n item.endpoint,\n {\n method: 'POST',\n body: JSON.stringify(item.data)\n },\n item.requestId\n );\n } catch (err) {\n if (!item.retryable) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Dropping non-retryable item', {\n endpoint: item.endpoint,\n error: err\n });\n }\n } else {\n item.attempts += 1;\n if (item.attempts > this.queueConfig.maxRetries) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Dropping item after max retries', {\n endpoint: item.endpoint,\n error: err\n });\n }\n } else {\n item.nextAttemptAt = now() + this.getBackoffDelay(item.attempts);\n shouldRequeue = true;\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Retry scheduled', {\n endpoint: item.endpoint,\n nextAttemptAt: item.nextAttemptAt,\n error: err\n });\n }\n }\n }\n }\n\n if (shouldRequeue) {\n pending.push(item);\n }\n }\n }\n\n this.eventQueue = pending;\n await this.persistQueue();\n this.scheduleQueueFlush(this.eventQueue.length > 0);\n }\n\n private dropExpiredQueueItems(): void {\n const cutoff = now() - this.queueConfig.maxItemAgeMs;\n if (this.eventQueue.length === 0) {\n return;\n }\n\n const retained = this.eventQueue.filter((item) => item.queuedAt >= cutoff);\n if (this.shouldLog('debug') && retained.length !== this.eventQueue.length) {\n console.warn('[Layers] Dropped stale queue items', {\n dropped: this.eventQueue.length - retained.length\n });\n }\n this.eventQueue = retained;\n void this.persistQueue();\n }\n\n private getBackoffDelay(attempt: number): number {\n const jitter = Math.random() * 250;\n const delay = this.queueConfig.baseRetryDelayMs * 2 ** (attempt - 1);\n return Math.min(delay + jitter, this.queueConfig.maxRetryDelayMs);\n }\n\n private resetRateLimitState(): void {\n this.rateLimitState = {\n global: {},\n perEvent: new Map<string, RateLimitCounter>()\n };\n }\n\n private getEventRateCounter(eventName: string): RateLimitCounter {\n let counter = this.rateLimitState.perEvent.get(eventName);\n if (!counter) {\n counter = {};\n this.rateLimitState.perEvent.set(eventName, counter);\n }\n return counter;\n }\n\n private normalizeRateLimitRule(\n input: { per_minute?: number; per_hour?: number } | undefined\n ): RateLimitRule | undefined {\n if (!input) {\n return undefined;\n }\n const rule: RateLimitRule = {};\n if (typeof input.per_minute === 'number' && input.per_minute > 0) {\n rule.perMinute = Math.floor(input.per_minute);\n }\n if (typeof input.per_hour === 'number' && input.per_hour > 0) {\n rule.perHour = Math.floor(input.per_hour);\n }\n return Object.keys(rule).length > 0 ? rule : undefined;\n }\n\n private passesRateLimit(eventName: string): boolean {\n if (SYSTEM_EVENTS.has(eventName)) {\n return true;\n }\n const { rateLimits } = this.remoteConfigMeta;\n if (!rateLimits) {\n return true;\n }\n const timestamp = now();\n const perEventRules = rateLimits.perEvent;\n const eventRule = perEventRules?.get(eventName) ?? perEventRules?.get('*');\n if (\n eventRule &&\n !this.canConsumeRateLimit(eventRule, this.getEventRateCounter(eventName), timestamp)\n ) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Rate limit reached for event', { event: eventName });\n }\n return false;\n }\n if (\n rateLimits.global &&\n !this.canConsumeRateLimit(rateLimits.global, this.rateLimitState.global, timestamp)\n ) {\n if (this.shouldLog('debug')) {\n console.warn('[Layers] Global rate limit reached', { event: eventName });\n }\n return false;\n }\n if (eventRule) {\n this.recordRateLimit(eventRule, this.getEventRateCounter(eventName), timestamp);\n }\n if (rateLimits.global) {\n this.recordRateLimit(rateLimits.global, this.rateLimitState.global, timestamp);\n }\n return true;\n }\n\n private canConsumeRateLimit(\n rule: RateLimitRule,\n counter: RateLimitCounter,\n timestamp: number\n ): boolean {\n return (\n this.canConsumeWindow(rule.perMinute, counter, 'perMinute', 60_000, timestamp) &&\n this.canConsumeWindow(rule.perHour, counter, 'perHour', 3_600_000, timestamp)\n );\n }\n\n private canConsumeWindow(\n limit: number | undefined,\n counter: RateLimitCounter,\n key: 'perMinute' | 'perHour',\n windowMs: number,\n timestamp: number\n ): boolean {\n if (limit === undefined) {\n return true;\n }\n const { count } = this.getWindowInfo(counter, key, windowMs, timestamp);\n return count + 1 <= limit;\n }\n\n private recordRateLimit(rule: RateLimitRule, counter: RateLimitCounter, timestamp: number): void {\n this.incrementWindow(rule.perMinute, counter, 'perMinute', 60_000, timestamp);\n this.incrementWindow(rule.perHour, counter, 'perHour', 3_600_000, timestamp);\n }\n\n private incrementWindow(\n limit: number | undefined,\n counter: RateLimitCounter,\n key: 'perMinute' | 'perHour',\n windowMs: number,\n timestamp: number\n ): void {\n if (limit === undefined) {\n return;\n }\n const windowStart = Math.floor(timestamp / windowMs) * windowMs;\n const existing = counter[key];\n if (!existing || existing.windowStart !== windowStart) {\n counter[key] = { windowStart, count: 1 };\n } else {\n existing.count += 1;\n }\n }\n\n private getWindowInfo(\n counter: RateLimitCounter,\n key: 'perMinute' | 'perHour',\n windowMs: number,\n timestamp: number\n ): RateWindowCounter {\n const windowStart = Math.floor(timestamp / windowMs) * windowMs;\n const existing = counter[key];\n if (!existing || existing.windowStart !== windowStart) {\n return { windowStart, count: 0 };\n }\n return existing;\n }\n\n private async makeRequest<T = unknown>(\n endpoint: string,\n options: RequestInit,\n requestId: string = generateId('req')\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n const controller = typeof AbortController !== 'undefined' ? new AbortController() : undefined;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Api-Key': this.config.apiKey,\n 'X-App-Id': this.config.appId,\n 'X-Environment': this.config.environment,\n 'X-SDK-Version': SDK_VERSION,\n 'X-Request-Id': requestId,\n ...(options.headers as Record<string, string> | undefined)\n };\n\n if (this.sessionId) {\n headers['X-Session-Id'] = this.sessionId;\n }\n\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n if (controller) {\n options = { ...options, signal: controller.signal };\n timeoutHandle = setTimeout(() => {\n controller.abort();\n }, this.queueConfig.requestTimeoutMs);\n }\n\n try {\n if (this.shouldLog('trace')) {\n console.log(`[Layers] → ${options.method || 'GET'} ${url}`);\n if (options.method === 'POST' && options.body) {\n console.log(`[Layers] Request body:`, JSON.parse(options.body as string));\n }\n }\n\n const response = await fetch(url, {\n ...options,\n headers\n });\n\n if (this.shouldLog('trace')) {\n console.log(`[Layers] ← ${response.status} ${response.statusText}`);\n }\n\n if (!response.ok) {\n if (!this.isRetryableStatus(response.status)) {\n const error = Object.assign(\n new Error(`HTTP ${response.status}: ${response.statusText}`),\n {\n status: response.status\n }\n );\n if (this.shouldLog('debug')) {\n console.warn(`[Layers] Non-retryable error for ${url}:`, error);\n }\n throw error;\n }\n const error = Object.assign(new Error(`Retryable HTTP ${response.status}`), {\n status: response.status\n });\n if (this.shouldLog('debug')) {\n console.warn(`[Layers] Retryable error for ${url}:`, error);\n }\n throw error;\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n const parsed = JSON.parse(text) as T;\n if (this.shouldLog('trace')) {\n console.log(`[Layers] Response:`, parsed);\n }\n return parsed;\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n private isRetryableStatus(status: number): boolean {\n if (status === 429 || (status >= 500 && status < 600)) {\n return true;\n }\n return false;\n }\n\n private generateEventId(): string {\n return generateId('evt');\n }\n\n private generateBatchId(): string {\n return generateId('batch');\n }\n\n getRemoteConfig(): RemoteConfig | null {\n return this.remoteConfig;\n }\n\n getRemoteConfigVersion(): string | undefined {\n return this.remoteConfigMeta.version;\n }\n\n getConsentState(): Required<ConsentOptions> {\n return { ...this.consentState };\n }\n\n setAppUserId(appUserId: string | undefined): void {\n this.config.appUserId = appUserId;\n if (this.shouldLog('info')) {\n console.log(`[Layers] App user ID set: ${appUserId || '(cleared)'}`);\n }\n }\n\n /** @deprecated Use setAppUserId instead */\n setUserId(userId: string): void {\n this.setAppUserId(userId);\n }\n\n getConfig(): LayersConfig {\n return { ...this.config };\n }\n\n getAppUserId(): string | undefined {\n return this.resolveAppUserId();\n }\n\n /** @deprecated Use getAppUserId instead */\n getUserId(): string | undefined {\n return this.resolveAppUserId();\n }\n\n getSessionId(): string {\n return this.sessionId;\n }\n\n async flush(): Promise<void> {\n await this.processQueue();\n }\n\n setDeviceInfo(deviceInfo: Partial<BaseEvent>): void {\n this.deviceInfo = {\n ...this.deviceInfo,\n ...Object.fromEntries(\n Object.entries(deviceInfo).filter(([, value]) => value !== undefined && value !== null)\n )\n };\n }\n\n startNewSession(): void {\n this.sessionId = this.generateSessionId();\n }\n}\n\nfunction createDefaultQueueStorage(appId: string): QueueStorage | null {\n if (typeof window === 'undefined') {\n return null;\n }\n\n try {\n const storage = window.localStorage;\n if (!storage) {\n return null;\n }\n } catch {\n return null;\n }\n\n const storageKey = `layers_queue_${appId}`;\n return createLocalStorageQueueStorage(storageKey);\n}\n\nfunction createLocalStorageQueueStorage(storageKey: string): QueueStorage {\n return {\n async load() {\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== 'object') {\n return null;\n }\n return parsed as StoredQueueSnapshot;\n } catch (error) {\n console.warn('Failed to load queue from localStorage', error);\n return null;\n }\n },\n async save(snapshot: StoredQueueSnapshot) {\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(snapshot));\n } catch (error) {\n console.warn('Failed to persist queue to localStorage', error);\n }\n },\n async clear() {\n try {\n window.localStorage.removeItem(storageKey);\n } catch (error) {\n console.warn('Failed to clear queue storage', error);\n }\n }\n };\n}\n"],"mappings":";AA+CA,MAAM,cAAc;AACpB,MAAM,mBAAmB;AACzB,MAAM,gBAAgB,IAAI,IAAI,CAAC,mBAAmB,qBAAqB,CAAC;AACxE,MAAMA,kBAA4C;CAChD,aAAa;CACb,WAAW;CACZ;AAmED,MAAMC,uBAAoC;CACxC,iBAAiB;CACjB,cAAc;CACd,cAAc,IAAI;CAClB,kBAAkB;CAClB,YAAY;CACZ,kBAAkB;CAClB,iBAAiB;CAClB;AAED,SAAS,MAAc;AACrB,QAAO,KAAK,KAAK;;AAGnB,SAAS,WAAW,QAAwB;AAC1C,QAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK;;AAGlE,IAAa,eAAb,MAA0B;CACxB,AAAQ;CACR,AAAQ,eAAoC;CAC5C,AAAQ,mBAAqC,EAAE;CAC/C,AAAQ,aAA8B,EAAE;CACxC,AAAQ,WAAW;CACnB,AAAQ,eAAyC,EAAE,GAAG,iBAAiB;CACvE,AAAQ;CACR,AAAQ,aAAiC,EAAE;CAC3C,AAAQ,aAAmD;CAC3D,AAAQ;CACR,AAAQ;CACR,AAAQ,iBAGJ;EACF,QAAQ,EAAE;EACV,0BAAU,IAAI,KAA+B;EAC9C;CAED,AAAQ,WAAmB;AAEzB,MAAI,OAAO,YAAY,eAAe,QAAQ,KAAK,UACjD,QAAO,QAAQ,IAAI,UAAU,aAAa;AAG5C,MAAI,KAAK,OAAO,YACd,QAAO;AAGT,SAAO;;CAGT,AAAQ,UAAU,OAA+D;EAC/E,MAAM,eAAe,KAAK,UAAU;EACpC,MAAM,SAAS;GAAC;GAAS;GAAQ;GAAQ;GAAS;GAAQ;AAG1D,SAFqB,OAAO,QAAQ,aAAa,IAC7B,OAAO,QAAQ,MAAM;;CAI3C,YAAY,QAAsB;AAChC,OAAK,cAAc;GAAE,GAAG;GAAsB,GAAI,OAAO,gBAAgB,EAAE;GAAG;AAC9E,OAAK,eAAe,OAAO,gBAAgB,0BAA0B,OAAO,MAAM;EAElF,MAAM,oBAAoB,OAAO;AAEjC,OAAK,SAAS;GACZ,GAAG;GACH,UAAU,OAAO,WAAW,kBAAkB,QAAQ,OAAO,GAAG;GAChE,WAAW;GACZ;AACD,OAAK,YAAY,KAAK,mBAAmB;AACzC,OAAK,qBAAqB;AAC1B,OAAK,sBAAsB;;CAG7B,AAAQ,oBAA4B;AAClC,SAAO,WAAW,OAAO;;CAG3B,AAAQ,uBAA6B;AACnC,OAAK,aAAa;GAChB,UAAU;GACV,YAAY;GACZ,aAAa;GACb,QAAQ;GACR,cAAc;GACf;;CAGH,MAAM,OAAsB;AAC1B,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,mBAAmB;AAC9B,OAAK,sBAAsB;AAC3B,OAAK,mBAAmB,KAAK,WAAW,SAAS,EAAE;;CAGrD,MAAc,kBAAkB,QAAQ,OAAsB;EAC5D,MAAM,UAAU,CAAC,KAAK,iBAAiB,aAAa,KAAK,iBAAiB,YAAY,KAAK;AAC3F,MAAI,CAAC,SAAS,KAAK,gBAAgB,CAAC,QAClC;AAGF,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,YAAkC,WAAW,EACvE,QAAQ,OACT,CAAC;AAEF,OAAI,CAAC,UAAU,OACb;AAGF,QAAK,eAAe,SAAS;GAC7B,MAAM,SAAS,SAAS,aAAa,OAAO;AAC5C,QAAK,mBAAmB;IACtB,SAAS,SAAS;IAClB,WAAW,KAAK,GAAG;IACnB,GAAG,KAAK,4BAA4B,SAAS;IAC9C;AACD,QAAK,qBAAqB;WACnB,OAAO;AACd,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,2CAA2C,MAAM;;;CAKpE,AAAQ,4BAA4B,UAAkD;EACpF,MAAMC,OAAyB,EAAE;EACjC,MAAM,SAAS,SAAS,UAAU,EAAE;AAEpC,MAAI,OAAO,SAAS;AAClB,OAAI,OAAO,OAAO,QAAQ,sBAAsB,UAC9C,MAAK,mBAAmB,OAAO,QAAQ;AAEzC,OAAI,OAAO,OAAO,QAAQ,wBAAwB,UAChD,MAAK,qBAAqB,OAAO,QAAQ;AAE3C,OAAI,OAAO,QAAQ,cAAc;IAC/B,MAAM,eAAe,IAAI,IAAI,OAAO,QAAQ,aAAa;AACzD,QAAI,aAAa,IAAI,YAAY,CAC/B,MAAK,mBAAmB;AAE1B,QAAI,aAAa,IAAI,cAAc,CACjC,MAAK,qBAAqB;;;AAKhC,MAAI,OAAO,QAAQ;AACjB,OAAI,MAAM,QAAQ,OAAO,OAAO,UAAU,CACxC,MAAK,iBAAiB,IAAI,IAAI,OAAO,OAAO,UAAU;AAExD,OAAI,MAAM,QAAQ,OAAO,OAAO,SAAS,CACvC,MAAK,gBAAgB,IAAI,IAAI,OAAO,OAAO,SAAS;GAGtD,MAAMC,kBAA0C,EAAE;AAClD,OAAI,OAAO,OAAO,SAChB,MAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,OAAO,OAAO,SAAS,EAAE;IACvE,MAAM,UAAU,OAAO,MAAM;AAC7B,QAAI,OAAO,SAAS,QAAQ,CAC1B,iBAAgB,aAAa,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC;;AAIpE,OAAI,OAAO,OAAO,OAAO,kBAAkB,SACzC,iBAAgB,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,OAAO,cAAc,CAAC;AAE9E,OAAI,OAAO,KAAK,gBAAgB,CAAC,SAAS,EACxC,MAAK,gBAAgB;GAGvB,MAAM,kBAAkB,OAAO,OAAO;AACtC,OAAI,iBAAiB;IACnB,MAAM,aAAa,KAAK,uBAAuB,gBAAgB;IAC/D,IAAIC;AACJ,QAAI,gBAAgB,WAAW;KAC7B,MAAM,UAAU,OAAO,QAAQ,gBAAgB,UAAU;AACzD,SAAI,QAAQ,SAAS,GAAG;AACtB,sCAAgB,IAAI,KAA4B;AAChD,WAAK,MAAM,CAAC,WAAW,eAAe,SAAS;OAC7C,MAAM,OAAO,KAAK,uBAAuB,WAAW;AACpD,WAAI,KACF,eAAc,IAAI,WAAW,KAAK;;AAGtC,UAAI,cAAc,SAAS,EACzB,iBAAgB;;;IAItB,MAAMC,aAAgF,EAAE;AACxF,QAAI,WACF,YAAW,SAAS;AAEtB,QAAI,cACF,YAAW,WAAW;AAExB,QAAI,WAAW,UAAU,WAAW,SAClC,MAAK,aAAa;;;AAKxB,SAAO;;CAGT,AAAQ,uBAA6B;AACnC,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,qBAAqB,YAAY;AAClF,UAAO,iBAAiB,gBAAgB;AACtC,SAAK,eAAe,KAAK;KACzB;AAEF,UAAO,iBAAiB,iBAAiB;AACvC,SAAK,eAAe,MAAM;KAC1B;;;CAIN,eAAe,UAAyB;AACtC,MAAI,KAAK,aAAa,SACpB;AAGF,OAAK,WAAW;AAEhB,MAAI,SACF,MAAK,mBAAmB,KAAK;;CAIjC,MAAc,eAA8B;AAC1C,MAAI,CAAC,KAAK,aACR;AAGF,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,aAAa,MAAM;AAC/C,OAAI,CAAC,YAAY,CAAC,MAAM,QAAQ,SAAS,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG;AAC9E,QAAI,SACF,OAAM,KAAK,aAAa,OAAO;AAEjC;;GAGF,MAAM,QAAQ,KAAK;GACnB,MAAM,SAAS,KAAK,YAAY;GAChC,MAAMC,WAA4B,EAAE;AAEpC,QAAK,MAAM,QAAQ,SAAS,MAC1B,KAAI,QAAQ,OAAO,KAAK,aAAa,UAAU;IAC7C,MAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAI,QAAQ,YAAY,OACtB,UAAS,KAAK;KACZ,UAAU,KAAK;KACf,MAAM,KAAK;KACX,UAAU,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;KAC9D;KACA,eAAe,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;KAC7E,WAAW,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY,WAAW,MAAM;KAClF,WAAW,KAAK,cAAc;KAC/B,CAAC;;AAKR,OAAI,SAAS,WAAW,GAAG;AACzB,UAAM,KAAK,aAAa,OAAO;AAC/B,SAAK,aAAa,EAAE;AACpB;;GAGF,MAAM,UAAU,SAAS,MAAM,GAAG,KAAK,YAAY,aAAa;GAChE,MAAM,UAAU,QAAQ,WAAW,SAAS;AAE5C,QAAK,aAAa;AAElB,OAAI,WAAW,QAAQ,WAAW,SAAS,MAAM,OAC/C,OAAM,KAAK,cAAc;WAEpB,OAAO;AACd,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,oCAAoC,MAAM;;;CAK7D,MAAc,eAA8B;AAC1C,MAAI,CAAC,KAAK,aACR;EAGF,MAAMC,WAAgC;GACpC,SAAS;GACT,OAAO,KAAK,WAAW,KAAK,UAAU;IACpC,UAAU,KAAK;IACf,MAAM,KAAK;IACX,UAAU,KAAK;IACf,UAAU,KAAK;IACf,eAAe,KAAK;IACpB,WAAW,KAAK;IAChB,WAAW,KAAK;IACjB,EAAE;GACJ;AAED,MAAI;AACF,OAAI,SAAS,MAAM,WAAW,EAC5B,OAAM,KAAK,aAAa,OAAO;OAE/B,OAAM,KAAK,aAAa,KAAK,SAAS;WAEjC,OAAO;AACd,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,oCAAoC,MAAM;;;CAK7D,MAAM,MAAM,WAAmB,YAAuC;AACpE,MAAI,CAAC,KAAK,mBAAmB,UAAU,EAAE;AACvC,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,IAAI,mBAAmB,UAAU,2CAA2C;AAEtF;;AAGF,MAAI,CAAC,KAAK,eAAe,UAAU,EAAE;AACnC,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,IAAI,mBAAmB,UAAU,eAAe;AAE1D;;EAoBF,MAAMC,eAAmC;GACvC,QAAQ,CAlBmB;IAC3B,OAAO;IACP,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,UAAU,KAAK,iBAAiB;IAChC,QAAQ,KAAK,OAAO;IACpB,YAAY,KAAK;IACjB,aAAa,KAAK,OAAO;IACzB,UAAU,KAAK,WAAW;IAC1B,YAAY,KAAK,WAAW;IAC5B,aAAa,KAAK,WAAW;IAC7B,cAAc,KAAK,WAAW;IAC9B,QAAQ,KAAK,WAAW;IACxB,GAAG,KAAK;IACR,YAAY,cAAc,EAAE;IAC5B,GAAI,KAAK,kBAAkB,IAAI,EAAE,aAAa,KAAK,kBAAkB,EAAE;IACxE,CAG4C;GAC3C,UAAU,KAAK,iBAAiB;GAChC,0BAAS,IAAI,MAAM,EAAC,aAAa;GAClC;EAED,MAAM,YAAY,KAAK,kBAAkB;AACzC,UAAQ,IACN,4BAA4B,YAAY,YAAY,WAAW,UAAU,KAAK,eAC/E;AAED,QAAM,KAAK,QAAQ,WAAW,aAAa;;CAG7C,AAAQ,mBAAmB,WAA4B;AACrD,MAAI,cAAc,IAAI,UAAU,CAC9B,QAAO;AAGT,MAAI,CAAC,KAAK,oBAAoB,CAC5B,QAAO;AAGT,MACE,KAAK,iBAAiB,kBACtB,CAAC,KAAK,iBAAiB,eAAe,IAAI,UAAU,CAEpD,QAAO;AAGT,MAAI,KAAK,iBAAiB,iBAAiB,KAAK,iBAAiB,cAAc,IAAI,UAAU,CAC3F,QAAO;AAGT,MAAI,CAAC,KAAK,gBAAgB,UAAU,CAClC,QAAO;AAGT,SAAO;;CAGT,AAAQ,eAAe,WAA4B;EACjD,MAAM,WAAW,KAAK,iBAAiB;AACvC,MAAI,CAAC,SACH,QAAO;EAGT,MAAM,OAAO,SAAS,cAAc,SAAS;AAC7C,MAAI,OAAO,SAAS,SAClB,QAAO;AAGT,SAAO,KAAK,QAAQ,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;;CAGxD,AAAQ,mBAAuC;AAC7C,SAAO,KAAK,OAAO;;CAGrB,MAAM,OAAO,YAAoB,YAAuC;AACtE,QAAM,KAAK,MAAM,eAAe;GAC9B,aAAa;GACb,GAAG;GACJ,CAAC;;CAGJ,MAAM,kBAAkB,YAA2C;AACjE,MAAI,CAAC,KAAK,oBAAoB,CAC5B;EAGF,MAAMC,UAAiC;GACrC,QAAQ,KAAK,OAAO;GACpB;GACA,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,GAAI,KAAK,kBAAkB,IAAI,EAAE,aAAa,KAAK,kBAAkB,EAAE;GACxE;AAED,QAAM,KAAK,QAAQ,qBAAqB,QAAQ;;CAGlD,qBAA8B;AAC5B,MAAI,KAAK,iBAAiB,qBAAqB,MAC7C,QAAO;AAET,SAAO,KAAK,aAAa,cAAc;;CAGzC,uBAAgC;AAC9B,MAAI,KAAK,iBAAiB,uBAAuB,MAC/C,QAAO;AAET,SAAO,KAAK,aAAa,gBAAgB;;CAG3C,MAAM,WAAW,SAAwC;AACvD,OAAK,eAAe;GAClB,aACE,OAAO,QAAQ,gBAAgB,YAC3B,QAAQ,cACR,KAAK,aAAa;GACxB,WACE,OAAO,QAAQ,cAAc,YAAY,QAAQ,YAAY,KAAK,aAAa;GAClF;EAED,MAAMC,UAA0B;GAC9B,QAAQ,KAAK,OAAO;GACpB,SAAS,EAAE,GAAG,KAAK,cAAc;GACjC,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,GAAI,KAAK,kBAAkB,IAAI,EAAE,aAAa,KAAK,kBAAkB,EAAE;GACxE;AAED,QAAM,KAAK,QAAQ,YAAY,QAAQ;;CAGzC,MAAc,QACZ,UACA,MACA,SACe;EACf,MAAM,YAAY,SAAS,cAAc;AAEzC,MAAI,KAAK,WAAW,UAAU,KAAK,YAAY,aAC7C,MAAK,WAAW,OAAO;AAGzB,OAAK,WAAW,KAAK;GACnB;GACA;GACA,UAAU;GACV,UAAU,KAAK;GACf,eAAe,KAAK;GACpB,WAAW,WAAW,MAAM;GAC5B;GACD,CAAC;AAEF,MAAI,KAAK,SACP,MAAK,mBAAmB,KAAK;MAE7B,MAAK,oBAAoB;AAG3B,EAAK,KAAK,cAAc;;CAG1B,AAAQ,mBAAmB,YAAY,OAAa;AAClD,MAAI,KAAK,YAAY;AACnB,gBAAa,KAAK,WAAW;AAC7B,QAAK,aAAa;;EAGpB,MAAM,QAAQ,YAAY,IAAI,KAAK,YAAY;AAC/C,OAAK,aAAa,iBAAiB;AACjC,QAAK,aAAa;AAClB,GAAK,KAAK,cAAc;KACvB,MAAM;;CAGX,MAAc,eAA8B;AAC1C,MAAI,CAAC,KAAK,YAAY,KAAK,WAAW,WAAW,GAAG;AAClD,QAAK,oBAAoB;AACzB;;AAGF,OAAK,uBAAuB;EAE5B,MAAMC,UAA2B,EAAE;AAEnC,OAAK,MAAM,QAAQ,KAAK,WACtB,KAAI,KAAK,gBAAgB,KAAK,CAC5B,SAAQ,KAAK,KAAK;OACb;GACL,IAAI,gBAAgB;AACpB,OAAI;AACF,UAAM,KAAK,YACT,KAAK,UACL;KACE,QAAQ;KACR,MAAM,KAAK,UAAU,KAAK,KAAK;KAChC,EACD,KAAK,UACN;YACM,KAAK;AACZ,QAAI,CAAC,KAAK,WACR;SAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,wCAAwC;MACnD,UAAU,KAAK;MACf,OAAO;MACR,CAAC;WAEC;AACL,UAAK,YAAY;AACjB,SAAI,KAAK,WAAW,KAAK,YAAY,YACnC;UAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,4CAA4C;OACvD,UAAU,KAAK;OACf,OAAO;OACR,CAAC;YAEC;AACL,WAAK,gBAAgB,KAAK,GAAG,KAAK,gBAAgB,KAAK,SAAS;AAChE,sBAAgB;AAChB,UAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,4BAA4B;OACvC,UAAU,KAAK;OACf,eAAe,KAAK;OACpB,OAAO;OACR,CAAC;;;;AAMV,OAAI,cACF,SAAQ,KAAK,KAAK;;AAKxB,OAAK,aAAa;AAClB,QAAM,KAAK,cAAc;AACzB,OAAK,mBAAmB,KAAK,WAAW,SAAS,EAAE;;CAGrD,AAAQ,wBAA8B;EACpC,MAAM,SAAS,KAAK,GAAG,KAAK,YAAY;AACxC,MAAI,KAAK,WAAW,WAAW,EAC7B;EAGF,MAAM,WAAW,KAAK,WAAW,QAAQ,SAAS,KAAK,YAAY,OAAO;AAC1E,MAAI,KAAK,UAAU,QAAQ,IAAI,SAAS,WAAW,KAAK,WAAW,OACjE,SAAQ,KAAK,sCAAsC,EACjD,SAAS,KAAK,WAAW,SAAS,SAAS,QAC5C,CAAC;AAEJ,OAAK,aAAa;AAClB,EAAK,KAAK,cAAc;;CAG1B,AAAQ,gBAAgB,SAAyB;EAC/C,MAAM,SAAS,KAAK,QAAQ,GAAG;EAC/B,MAAM,QAAQ,KAAK,YAAY,mBAAmB,MAAM,UAAU;AAClE,SAAO,KAAK,IAAI,QAAQ,QAAQ,KAAK,YAAY,gBAAgB;;CAGnE,AAAQ,sBAA4B;AAClC,OAAK,iBAAiB;GACpB,QAAQ,EAAE;GACV,0BAAU,IAAI,KAA+B;GAC9C;;CAGH,AAAQ,oBAAoB,WAAqC;EAC/D,IAAI,UAAU,KAAK,eAAe,SAAS,IAAI,UAAU;AACzD,MAAI,CAAC,SAAS;AACZ,aAAU,EAAE;AACZ,QAAK,eAAe,SAAS,IAAI,WAAW,QAAQ;;AAEtD,SAAO;;CAGT,AAAQ,uBACN,OAC2B;AAC3B,MAAI,CAAC,MACH;EAEF,MAAMC,OAAsB,EAAE;AAC9B,MAAI,OAAO,MAAM,eAAe,YAAY,MAAM,aAAa,EAC7D,MAAK,YAAY,KAAK,MAAM,MAAM,WAAW;AAE/C,MAAI,OAAO,MAAM,aAAa,YAAY,MAAM,WAAW,EACzD,MAAK,UAAU,KAAK,MAAM,MAAM,SAAS;AAE3C,SAAO,OAAO,KAAK,KAAK,CAAC,SAAS,IAAI,OAAO;;CAG/C,AAAQ,gBAAgB,WAA4B;AAClD,MAAI,cAAc,IAAI,UAAU,CAC9B,QAAO;EAET,MAAM,EAAE,eAAe,KAAK;AAC5B,MAAI,CAAC,WACH,QAAO;EAET,MAAM,YAAY,KAAK;EACvB,MAAM,gBAAgB,WAAW;EACjC,MAAM,YAAY,eAAe,IAAI,UAAU,IAAI,eAAe,IAAI,IAAI;AAC1E,MACE,aACA,CAAC,KAAK,oBAAoB,WAAW,KAAK,oBAAoB,UAAU,EAAE,UAAU,EACpF;AACA,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,yCAAyC,EAAE,OAAO,WAAW,CAAC;AAE7E,UAAO;;AAET,MACE,WAAW,UACX,CAAC,KAAK,oBAAoB,WAAW,QAAQ,KAAK,eAAe,QAAQ,UAAU,EACnF;AACA,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,sCAAsC,EAAE,OAAO,WAAW,CAAC;AAE1E,UAAO;;AAET,MAAI,UACF,MAAK,gBAAgB,WAAW,KAAK,oBAAoB,UAAU,EAAE,UAAU;AAEjF,MAAI,WAAW,OACb,MAAK,gBAAgB,WAAW,QAAQ,KAAK,eAAe,QAAQ,UAAU;AAEhF,SAAO;;CAGT,AAAQ,oBACN,MACA,SACA,WACS;AACT,SACE,KAAK,iBAAiB,KAAK,WAAW,SAAS,aAAa,KAAQ,UAAU,IAC9E,KAAK,iBAAiB,KAAK,SAAS,SAAS,WAAW,MAAW,UAAU;;CAIjF,AAAQ,iBACN,OACA,SACA,KACA,UACA,WACS;AACT,MAAI,UAAU,OACZ,QAAO;EAET,MAAM,EAAE,UAAU,KAAK,cAAc,SAAS,KAAK,UAAU,UAAU;AACvE,SAAO,QAAQ,KAAK;;CAGtB,AAAQ,gBAAgB,MAAqB,SAA2B,WAAyB;AAC/F,OAAK,gBAAgB,KAAK,WAAW,SAAS,aAAa,KAAQ,UAAU;AAC7E,OAAK,gBAAgB,KAAK,SAAS,SAAS,WAAW,MAAW,UAAU;;CAG9E,AAAQ,gBACN,OACA,SACA,KACA,UACA,WACM;AACN,MAAI,UAAU,OACZ;EAEF,MAAM,cAAc,KAAK,MAAM,YAAY,SAAS,GAAG;EACvD,MAAM,WAAW,QAAQ;AACzB,MAAI,CAAC,YAAY,SAAS,gBAAgB,YACxC,SAAQ,OAAO;GAAE;GAAa,OAAO;GAAG;MAExC,UAAS,SAAS;;CAItB,AAAQ,cACN,SACA,KACA,UACA,WACmB;EACnB,MAAM,cAAc,KAAK,MAAM,YAAY,SAAS,GAAG;EACvD,MAAM,WAAW,QAAQ;AACzB,MAAI,CAAC,YAAY,SAAS,gBAAgB,YACxC,QAAO;GAAE;GAAa,OAAO;GAAG;AAElC,SAAO;;CAGT,MAAc,YACZ,UACA,SACA,YAAoB,WAAW,MAAM,EACzB;EACZ,MAAM,MAAM,GAAG,KAAK,OAAO,UAAU;EACrC,MAAM,aAAa,OAAO,oBAAoB,cAAc,IAAI,iBAAiB,GAAG;EAEpF,MAAMC,UAAkC;GACtC,gBAAgB;GAChB,aAAa,KAAK,OAAO;GACzB,YAAY,KAAK,OAAO;GACxB,iBAAiB,KAAK,OAAO;GAC7B,iBAAiB;GACjB,gBAAgB;GAChB,GAAI,QAAQ;GACb;AAED,MAAI,KAAK,UACP,SAAQ,kBAAkB,KAAK;EAGjC,IAAIC;AACJ,MAAI,YAAY;AACd,aAAU;IAAE,GAAG;IAAS,QAAQ,WAAW;IAAQ;AACnD,mBAAgB,iBAAiB;AAC/B,eAAW,OAAO;MACjB,KAAK,YAAY,iBAAiB;;AAGvC,MAAI;AACF,OAAI,KAAK,UAAU,QAAQ,EAAE;AAC3B,YAAQ,IAAI,cAAc,QAAQ,UAAU,MAAM,GAAG,MAAM;AAC3D,QAAI,QAAQ,WAAW,UAAU,QAAQ,KACvC,SAAQ,IAAI,0BAA0B,KAAK,MAAM,QAAQ,KAAe,CAAC;;GAI7E,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,GAAG;IACH;IACD,CAAC;AAEF,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,IAAI,cAAc,SAAS,OAAO,GAAG,SAAS,aAAa;AAGrE,OAAI,CAAC,SAAS,IAAI;AAChB,QAAI,CAAC,KAAK,kBAAkB,SAAS,OAAO,EAAE;KAC5C,MAAMC,UAAQ,OAAO,uBACnB,IAAI,MAAM,QAAQ,SAAS,OAAO,IAAI,SAAS,aAAa,EAC5D,EACE,QAAQ,SAAS,QAClB,CACF;AACD,SAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,oCAAoC,IAAI,IAAIA,QAAM;AAEjE,WAAMA;;IAER,MAAM,QAAQ,OAAO,uBAAO,IAAI,MAAM,kBAAkB,SAAS,SAAS,EAAE,EAC1E,QAAQ,SAAS,QAClB,CAAC;AACF,QAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,KAAK,gCAAgC,IAAI,IAAI,MAAM;AAE7D,UAAM;;AAGR,OAAI,SAAS,WAAW,IACtB;GAGF,MAAM,OAAO,MAAM,SAAS,MAAM;AAClC,OAAI,CAAC,KACH;GAEF,MAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,OAAI,KAAK,UAAU,QAAQ,CACzB,SAAQ,IAAI,sBAAsB,OAAO;AAE3C,UAAO;YACC;AACR,OAAI,cACF,cAAa,cAAc;;;CAKjC,AAAQ,kBAAkB,QAAyB;AACjD,MAAI,WAAW,OAAQ,UAAU,OAAO,SAAS,IAC/C,QAAO;AAET,SAAO;;CAGT,AAAQ,kBAA0B;AAChC,SAAO,WAAW,MAAM;;CAG1B,AAAQ,kBAA0B;AAChC,SAAO,WAAW,QAAQ;;CAG5B,kBAAuC;AACrC,SAAO,KAAK;;CAGd,yBAA6C;AAC3C,SAAO,KAAK,iBAAiB;;CAG/B,kBAA4C;AAC1C,SAAO,EAAE,GAAG,KAAK,cAAc;;CAGjC,aAAa,WAAqC;AAChD,OAAK,OAAO,YAAY;AACxB,MAAI,KAAK,UAAU,OAAO,CACxB,SAAQ,IAAI,6BAA6B,aAAa,cAAc;;;CAKxE,UAAU,QAAsB;AAC9B,OAAK,aAAa,OAAO;;CAG3B,YAA0B;AACxB,SAAO,EAAE,GAAG,KAAK,QAAQ;;CAG3B,eAAmC;AACjC,SAAO,KAAK,kBAAkB;;;CAIhC,YAAgC;AAC9B,SAAO,KAAK,kBAAkB;;CAGhC,eAAuB;AACrB,SAAO,KAAK;;CAGd,MAAM,QAAuB;AAC3B,QAAM,KAAK,cAAc;;CAG3B,cAAc,YAAsC;AAClD,OAAK,aAAa;GAChB,GAAG,KAAK;GACR,GAAG,OAAO,YACR,OAAO,QAAQ,WAAW,CAAC,QAAQ,GAAG,WAAW,UAAU,UAAa,UAAU,KAAK,CACxF;GACF;;CAGH,kBAAwB;AACtB,OAAK,YAAY,KAAK,mBAAmB;;;AAI7C,SAAS,0BAA0B,OAAoC;AACrE,KAAI,OAAO,WAAW,YACpB,QAAO;AAGT,KAAI;AAEF,MAAI,CADY,OAAO,aAErB,QAAO;SAEH;AACN,SAAO;;AAIT,QAAO,+BADY,gBAAgB,QACc;;AAGnD,SAAS,+BAA+B,YAAkC;AACxE,QAAO;EACL,MAAM,OAAO;AACX,OAAI;IACF,MAAM,MAAM,OAAO,aAAa,QAAQ,WAAW;AACnD,QAAI,CAAC,IACH,QAAO;IAET,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QAAI,CAAC,UAAU,OAAO,WAAW,SAC/B,QAAO;AAET,WAAO;YACA,OAAO;AACd,YAAQ,KAAK,0CAA0C,MAAM;AAC7D,WAAO;;;EAGX,MAAM,KAAK,UAA+B;AACxC,OAAI;AACF,WAAO,aAAa,QAAQ,YAAY,KAAK,UAAU,SAAS,CAAC;YAC1D,OAAO;AACd,YAAQ,KAAK,2CAA2C,MAAM;;;EAGlE,MAAM,QAAQ;AACZ,OAAI;AACF,WAAO,aAAa,WAAW,WAAW;YACnC,OAAO;AACd,YAAQ,KAAK,iCAAiC,MAAM;;;EAGzD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layers/client",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.1-alpha.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/api-types.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}