@lorikeetai/react-native-sdk 2.0.0-alpha.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  import { StyleProp, TextStyle } from "react-native";
2
2
  import { WebView, WebViewMessageEvent, WebViewProps } from "react-native-webview";
3
- //#region src/conversation-metadata.d.ts
4
3
  type ConversationMetadata = Record<string, unknown>;
5
- //#endregion
6
- //#region src/customisations.d.ts
7
4
  /**
8
5
  * What the chat page accepts as `customisations`, as the SDK's own types.
9
6
  *
@@ -13,13 +10,21 @@ type ConversationMetadata = Record<string, unknown>;
13
10
  * have: `Customisations` then degraded to `any` and typed nothing.
14
11
  * `ConversationMetadata` is duplicated here for the same reason.
15
12
  *
16
- * `src/customisations.web-sdk-parity.ts` fails the build if the two drift.
13
+ * `src/customisations.web-sdk-parity.ts` fails `typecheck` if the two drift. Not
14
+ * the build: that file is unreachable from `index.ts`, so the declaration build
15
+ * never sees it.
17
16
  *
18
- * Fields that only mean something on a web page, the viewport sizes and the
19
- * launcher button, are kept so the page's behaviour is unchanged and so a host
20
- * sharing one configuration object with its web widget still type-checks.
17
+ * Fields that only mean something on a web page are kept so the page's behaviour
18
+ * is unchanged and so a host sharing one configuration object with its web
19
+ * widget still type-checks. The viewport sizes, the launcher button and `mode`
20
+ * are all read by the web SDK rather than by the page, so none of them reaches
21
+ * anything this SDK renders.
22
+ */
23
+ /**
24
+ * Sizing for one viewport. Mostly desktop: the page is full-screen on mobile, so
25
+ * `height`, `width` and `borderRadius` are read for `desktop` alone, while
26
+ * `topClearance` and `default_open` are read for whichever viewport applies.
21
27
  */
22
- /** Sizing for one viewport. Desktop only: the page is full-screen on mobile. */
23
28
  interface ViewportCustomisations {
24
29
  /** Clamped to a 2rem maximum. */
25
30
  borderRadius?: string;
@@ -37,7 +42,10 @@ interface Customisations {
37
42
  desktop?: ViewportCustomisations;
38
43
  /**
39
44
  * Which header the customer gets, not whether there is one. `true` hides the
40
- * page's own; `false` keeps it, and it carries Close and End chat.
45
+ * page's own; `false` keeps it, and with it the page's way out of a
46
+ * conversation. Ending and minimising are what that header is for, and which
47
+ * controls it offers depends on the subscriber's configuration, so hiding it
48
+ * leaves the customer no way to end or minimise unless the host supplies one.
41
49
  *
42
50
  * What replaces a hidden one is the host's business, so there is no one
43
51
  * default to quote. `LorikeetWidgetView` substitutes its own header, a title
@@ -53,12 +61,17 @@ interface Customisations {
53
61
  messages?: {
54
62
  /** Shown when the widget is in an unexpectedly failed state. */
55
63
  failOver?: string;
56
- /** Shown when live chat has been switched off deliberately. */
64
+ /**
65
+ * Shown when live chat has been switched off deliberately. Reachable only
66
+ * where the live agent bridge is on for the subscriber; without it the widget
67
+ * has no unavailable state for this to label.
68
+ */
57
69
  unavailable?: string;
58
70
  /**
59
71
  * Replaces the line under "Someone is taking a look", for a conversation
60
72
  * handed to a person. Say where the reply will come from when the default
61
- * should not promise it.
73
+ * should not promise it. Shown only where the live chat experience is on,
74
+ * which is what puts the notice on screen in the first place.
62
75
  */
63
76
  escalated?: string;
64
77
  };
@@ -103,9 +116,10 @@ interface CustomisationTheme {
103
116
  /**
104
117
  * Google Fonts CSS URL declaring the `@font-face` rules for `fontFamily`.
105
118
  * The page ships Inter only, so a brand font the device lacks falls back
106
- * unless its files are loaded. Host must be `fonts.googleapis.com`, path
107
- * `/css` or `/css2`, and only `family` and `display` params; anything else is
108
- * ignored.
119
+ * unless its files are loaded. Must be https, host `fonts.googleapis.com`,
120
+ * path `/css` or `/css2`, and carry `family` plus at most a standard
121
+ * `display`. A URL failing any of that is dropped whole rather than trimmed,
122
+ * so one stray query param means no font loads at all.
109
123
  */
110
124
  fontUrl?: string;
111
125
  /**
@@ -122,22 +136,21 @@ interface CustomisationTheme {
122
136
  subtleBrandColor?: string;
123
137
  textColor?: string;
124
138
  }
125
- //#endregion
126
- //#region src/events.d.ts
127
139
  /**
128
140
  * What the page reports, as events rather than as raw bridge messages.
129
141
  *
130
142
  * Names follow the web SDK's (`LorikeetEvent` in `@lorikeetai/web-sdk/types`)
131
143
  * wherever it has one, because a host that integrates both should not have to
132
144
  * learn two vocabularies. The rest cover what the page tells a host that owns
133
- * its own layout and storage, which on web the SDK handles internally and never
134
- * surfaces: the close handshake, the persistence messages, the logout
135
- * confirmation, and error codes. `logout_failed` is the one the SDK reports
136
- * itself, for a page that said nothing when it had to.
145
+ * its own layout and storage, which the web SDK largely handles for itself: it
146
+ * surfaces a close without its reason, a created ticket without the stored pair
147
+ * behind it, and `EXPIRED_TOKEN` alone of the error codes. `logout_failed` is
148
+ * the one the SDK reports itself, for a page that said nothing when it had to.
137
149
  *
138
- * `token_expiry` is deliberately absent. The credential model it belongs to is
139
- * being rewritten, and an event is the hardest thing to take back. Nothing
140
- * carrying a credential is translated at all, for the same reason.
150
+ * `token_expiry` is deliberately absent, and the anonymous session token with
151
+ * it. The credential model they belong to is being rewritten, and an event is
152
+ * the hardest thing to take back. `persist_session` is translated despite
153
+ * carrying a credential, because a resume cannot be rebuilt without it.
141
154
  */
142
155
  type LorikeetWidgetEvent =
143
156
  /** The page is up and the conversation is usable. */
@@ -146,7 +159,8 @@ type LorikeetWidgetEvent =
146
159
  } |
147
160
  /**
148
161
  * A ticket that did not exist before this page loaded. Once per ticket, and
149
- * never for a resume, matching the web SDK.
162
+ * never for a resume. The web SDK suppresses a resume too, but counts once
163
+ * per session rather than per ticket, so this is the stricter of the two.
150
164
  */
151
165
  {
152
166
  type: 'ticket_created';
@@ -170,12 +184,18 @@ type LorikeetWidgetEvent =
170
184
  markUnread?: boolean;
171
185
  } |
172
186
  /**
173
- * The page closed itself, and why. `ended_by_customer` is followed by a
174
- * `new_chat`, seconds later, so a host that tears down here never sees the
175
- * rest of the handshake. `minimised` has nothing behind it: the conversation
176
- * is intact and hiding it is enough.
187
+ * The page closed itself, and why. `ended_by_customer` is usually followed by
188
+ * a `new_chat`, once the end and any CSAT have settled, so a host that tears
189
+ * down here never sees the rest of the handshake. Usually rather than always:
190
+ * a CSAT rating that fails holds the replacement back, and nothing but another
191
+ * close releases it. `minimised` has nothing behind it: the conversation is
192
+ * intact and hiding it is enough.
177
193
  *
178
- * `reason` is absent from a page older than the release that added it.
194
+ * `reason` is absent from a page older than the release that added it, from one
195
+ * whose host lifecycle events are switched off, and from the closes the page
196
+ * makes on its own behalf, its error boundary among them. An absent reason
197
+ * reads as an end, so a minimise is only distinguishable when the page names
198
+ * it.
179
199
  */
180
200
  {
181
201
  type: 'close';
@@ -186,6 +206,9 @@ type LorikeetWidgetEvent =
186
206
  * or it timed out. Nothing follows, and nothing is asking the host to hide
187
207
  * anything. Left unhandled, this is the customer stranded on a conversation
188
208
  * that can no longer be used.
209
+ *
210
+ * Reported only by a page whose host lifecycle events are on, so it is not
211
+ * the only way an ended conversation can reach a host.
189
212
  */
190
213
  {
191
214
  type: 'conversation_ended';
@@ -199,13 +222,16 @@ type LorikeetWidgetEvent =
199
222
  } |
200
223
  /**
201
224
  * Store this against the customer, alongside the session. A resume needs both:
202
- * the ticket alone fails with `CUSTOMER_ID_MISSING`.
225
+ * the ticket alone is refused, usually as `CUSTOMER_ID_MISSING`.
203
226
  */
204
227
  {
205
228
  type: 'persist_ticket_id';
206
229
  ticketId: string;
207
230
  } |
208
- /** The other half of the stored pair. Arrives separately and in no order. */
231
+ /**
232
+ * The other half of the stored pair, as its own message. The SDK does not rely
233
+ * on which half arrives first, and neither should a host.
234
+ */
209
235
  {
210
236
  type: 'persist_session';
211
237
  session: string;
@@ -260,8 +286,6 @@ type LorikeetWidgetEvent =
260
286
  };
261
287
  /** The names, spelled out rather than derived, so callers import a real type. */
262
288
  type LorikeetWidgetEventType = 'agent_message' | 'close' | 'conversation_ended' | 'customer_message' | 'error' | 'logged_out' | 'logout_failed' | 'new_chat' | 'persist_session' | 'persist_ticket_id' | 'preload_complete' | 'ready' | 'ticket_created';
263
- //#endregion
264
- //#region src/types.d.ts
265
289
  interface LorikeetInitOptions {
266
290
  /**
267
291
  * The base URL of the Lorikeet API for the widget to interact with.
@@ -297,10 +321,16 @@ type LorikeetWidgetWebViewProps = {
297
321
  /**
298
322
  * What the page reported, as typed events rather than raw bridge messages.
299
323
  *
300
- * This component reports; it does not act. A host composing it owns its own
301
- * URL, layout and storage, so hiding on a close, rebuilding a resume URL or
302
- * recovering from process loss are all theirs to do. `LorikeetWidgetView`
303
- * consumes this same path and acts on top of it, because it owns the URL.
324
+ * This component acts on navigation alone; about the conversation it does
325
+ * nothing. A top-level navigation leaving the widget's origin goes to the OS,
326
+ * unless your own `webviewProps.onShouldStartLoadWithRequest` returns `false`
327
+ * for it, which is taken as a decision and not second-guessed. A navigation
328
+ * the WebView reports as a subframe stays in the page, since a frame the page
329
+ * embedded is not a link the customer followed. A host
330
+ * composing it owns its own URL, layout and storage, so hiding on a close,
331
+ * rebuilding a resume URL or recovering from process loss are all theirs to
332
+ * do. `LorikeetWidgetView` consumes this same path and acts on top of it,
333
+ * because it owns the URL.
304
334
  */
305
335
  onEvent?: (event: LorikeetWidgetEvent) => void;
306
336
  };
@@ -339,17 +369,27 @@ type LorikeetWidgetHandle = {
339
369
  * host holding what it passed at mount can be holding a conversation that no
340
370
  * longer exists.
341
371
  *
342
- * `null` means exactly that the widget has nothing to resume: no conversation
343
- * reported yet, only half of one, the credentials have moved on, or the
344
- * customer has been logged out. It does not mean the conversation is over. A
345
- * conversation the customer ended is still reported, because that is still
346
- * what the widget is on and what its own recovery would resume; `close` and
347
- * its `reason` are how you hear that it ended.
372
+ * The ticket is the half that decides. `null` means no ticket has been
373
+ * reported for these credentials: none yet, a session on its own, the
374
+ * credentials have moved on, or the customer has been logged out. It does not
375
+ * mean the conversation is over. A conversation the customer ended is still
376
+ * reported, because that is still what the widget is on and what its own
377
+ * recovery would resume; `close` and its `reason` are how you hear that it
378
+ * ended.
348
379
  *
349
- * Reports what is on screen, so inside an `onEvent` handler it is still what
350
- * was on screen before that event: read `reason` on the `close` rather than
351
- * calling this from the handler. Read it again after a change rather than
352
- * caching what it said.
380
+ * A reported ticket with no `session` yet is not `null`, and is also not
381
+ * resumable on its own: the ticket route needs both. Treat `session` as
382
+ * outstanding rather than absent until it arrives.
383
+ *
384
+ * Reads live, so inside an `onEvent` handler for `persist_ticket_id` or
385
+ * `persist_session` it has already taken that event into account. What it will
386
+ * not do is answer before a ticket exists, and the page normally sends the
387
+ * session first, so the `persist_session` handler sees `null`. Store each half
388
+ * from its own event rather than asking here.
389
+ *
390
+ * `minimised` moves with a render instead, so inside a `close` handler it
391
+ * describes what was on screen before: read `reason` on the `close` rather
392
+ * than this. Read it again after a change rather than caching what it said.
353
393
  */
354
394
  getConversation: () => {
355
395
  minimised: boolean;
@@ -377,8 +417,17 @@ type LorikeetWidgetHandle = {
377
417
  * `logout_failed` outlives this component, and the obligation with it. The
378
418
  * SDK stores nothing, so a widget unmounted before the clear confirmed, by a
379
419
  * screen change or an app restart, comes back with no memory of it and will
380
- * open a chat normally. Record the failure where you record the conversation,
381
- * and call `logout()` again before you mount a chat for anyone else.
420
+ * open a chat normally. So persist the `baseUrl`, `publicKey` and cookie-store
421
+ * `webviewProps` being cleared before calling this, and delete that record
422
+ * only on `logged_out`: unmounting cancels the `logout_failed` timer, so an
423
+ * app that dies inside the budget reports nothing to record.
424
+ *
425
+ * Recovering does not need the customer who left. Navigate a WebView to
426
+ * `LorikeetClient.getLogoutUrl()`, which needs no `authToken`. It does need
427
+ * that same recorded target, because clearing another origin or another cookie
428
+ * store reports `logged_out` just the same. Calling this instead would clear
429
+ * for whoever is in props by then and lock that customer out rather than the
430
+ * last one.
382
431
  *
383
432
  * Clear your own stored `ticketId` and `session` as well.
384
433
  */
@@ -442,14 +491,15 @@ type LorikeetWidgetViewProps = {
442
491
  * Resume this conversation instead of starting a new one. Without it the
443
492
  * widget boots `/widget`, which mints a fresh ticket on every mount.
444
493
  *
445
- * Take it from the `persistLorikeetTicketId` message and store it yourself;
446
- * the SDK has no storage of its own.
494
+ * Take it from the `persist_ticket_id` event, or from `getConversation()`, and
495
+ * store it yourself; the SDK has no storage of its own.
447
496
  */
448
497
  ticketId?: string;
449
498
  /**
450
- * The session token last reported by `persistLorikeetSession`, stored
451
- * alongside `ticketId`. The ticket route needs it to authorise a WebView that
452
- * has no cookie yet, so a resume without it fails with CUSTOMER_ID_MISSING.
499
+ * The session token last reported by `persist_session`, stored alongside
500
+ * `ticketId`. The ticket route needs it to authorise a WebView that has no
501
+ * cookie yet, so a resume without it is refused, usually as
502
+ * CUSTOMER_ID_MISSING.
453
503
  */
454
504
  session?: string;
455
505
  /**
@@ -465,14 +515,21 @@ type LorikeetWidgetViewProps = {
465
515
  * the SDK reads the bridge first and then calls yours.
466
516
  */
467
517
  webviewProps?: WebViewProps;
518
+ /**
519
+ * Pads the widget by the keyboard's height while it is open, so the composer
520
+ * stays above it. Defaults to `true`.
521
+ *
522
+ * Android apps drawn edge to edge, the default for current Expo and React
523
+ * Native apps, no longer resize their window for the keyboard, so without
524
+ * this the keyboard covers the composer. Pass `false` if your screen already
525
+ * makes room for the keyboard, for example with its own
526
+ * `KeyboardAvoidingView` around the widget, or the widget is padded twice.
527
+ */
528
+ avoidKeyboard?: boolean;
468
529
  };
469
- //#endregion
470
- //#region src/widget.d.ts
471
530
  declare const LorikeetWidgetWebView: import("react").ForwardRefExoticComponent<LorikeetWidgetWebViewProps & import("react").RefAttributes<WebView<{}>>>;
472
531
  declare const LorikeetWidgetHeader: ({ title, style, icon, onIconPress }: LorikeetWidgetHeaderProps) => import("react").JSX.Element;
473
532
  declare const LorikeetWidgetView: import("react").ForwardRefExoticComponent<LorikeetWidgetViewProps & import("react").RefAttributes<LorikeetWidgetHandle>>;
474
- //#endregion
475
- //#region src/client.d.ts
476
533
  declare class LorikeetClient {
477
534
  baseUrl: string;
478
535
  customisations: Customisations | null;
@@ -498,20 +555,21 @@ declare class LorikeetClient {
498
555
  */
499
556
  getLogoutUrl: () => string;
500
557
  }
501
- //#endregion
502
- //#region src/errors.d.ts
503
558
  /**
504
- * Codes the chat page posts to the host as `{ type: 'error', error: CODE }`.
505
- * Mirrored here because the page publishes them nowhere else, so a host would
506
- * otherwise be matching on strings it discovered by observation.
559
+ * The chat page's error vocabulary, as it reaches a host in
560
+ * `{ type: 'error', error: CODE }`. Mirrored here because the page publishes it
561
+ * nowhere else, so a host would otherwise be matching on strings it discovered
562
+ * by observation.
563
+ *
564
+ * The page's own list rather than a list of codes seen in the wild:
565
+ * `MISSING_PUBLIC_KEY` has no producer today, and is kept because narrowing this
566
+ * would be a breaking change.
507
567
  */
508
568
  declare const LORIKEET_ERROR_CODES: readonly ["MISSING_TOKEN", "CORRUPT_TOKEN_DATA", "DECRYPT_FAILED", "EXPIRED_TOKEN", "MALFORMED_TOKEN", "MISSING_PUBLIC_KEY", "UNKNOWN_PUBLIC_KEY", "CUSTOMER_ID_CONFLICT", "CUSTOMER_ID_MISSING", "FATAL_ERROR", "INVALID_SESSION", "DOMAIN_NOT_ALLOWED", "TICKET_NOT_FOUND"];
509
569
  type LorikeetErrorCode = (typeof LORIKEET_ERROR_CODES)[number];
510
570
  /** Whether an error code means the stored conversation cannot be reopened. */
511
571
  declare function isUnusableConversationCode(code: string): boolean;
512
572
  declare function isUnusableConversation(message: unknown): boolean;
513
- //#endregion
514
- //#region src/lifecycle.d.ts
515
573
  /**
516
574
  * How long `/logout` gets to confirm it cleared the frame before the host is
517
575
  * told it did not. Matches the web SDK's own budget, and like it, a logout that
@@ -524,6 +582,5 @@ declare function isUnusableConversation(message: unknown): boolean;
524
582
  * app calls a clear failed that the other never does.
525
583
  */
526
584
  declare const LOGOUT_CONFIRMATION_TIMEOUT_MS = 10000;
527
- //#endregion
528
585
  export { type CustomisationTheme, type Customisations, LOGOUT_CONFIRMATION_TIMEOUT_MS, LORIKEET_ERROR_CODES, LorikeetClient, type LorikeetErrorCode, type LorikeetInitOptions, type LorikeetWidgetEvent, type LorikeetWidgetEventType, type LorikeetWidgetHandle, LorikeetWidgetHeader, type LorikeetWidgetHeaderProps, LorikeetWidgetView, type LorikeetWidgetViewProps, LorikeetWidgetWebView, type LorikeetWidgetWebViewProps, isUnusableConversation, isUnusableConversationCode };
529
586
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/conversation-metadata.ts","../src/customisations.ts","../src/events.ts","../src/types.ts","../src/widget.tsx","../src/client.ts","../src/errors.ts","../src/lifecycle.ts"],"mappings":";;;KAEY,uBAAuB;;;;;;;;;;;;;;;;;;;UCezB;;EAER;EACA;;EAEA;;EAEA;EACA;;UAGe;;EAEf;EACA;EACA,UAAU;;;;;;;;;;;;EAYV;;EAEA;EACA;EACA;;IAEE;;IAEA;;;;;;IAMA;;EAEF,SAAS;EACT;;;;;;;EAOA;IACE;IACA;IACA;IACA;IACA;;IAEA;;;EAGF;EACA,QAAQ;EACR;;EAEA;;UAGe;;;;;;EAMf;EACA;;EAEA;EACA;;EAEA;EACA;;;;;;;;EAQA;;;;;EAKA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;KCxGU;;;EAEN;;;;;;;EAKA;EAAwB;;;;EAExB;;;;;;;;;;;;EAUA;EAAuB;;;;;;;;;;;EASvB;EAAe;;;;;;;;;EAOf;;;;;;;EAKA;;;;;;;EAKA;EAA2B;;;;EAE3B;EAAyB;;;;;;;;;;;;;;;;EAczB;;;;;;;;;;;;EAUA;;;;EAEA;EAAe;;;;;;;;;;;;;EAYf;EACA;EACA;;;KAIM;;;UCnGK;;;;EAIf;;;;EAIA,iBAAiB;;;;;EAKjB,WAAW;;;;EAIX;;KAGU;;;;EAIV;;;;EAIA;;;;EAIA,eAAe;;;;;;;;;EASf,WAAW,OAAO;;KAGR;;;;EAIV;;;;EAIA,QAAQ,UAAU;;;;EAIlB,OAAO,MAAM;;;;EAIb;;;;;;;KAQU;;;;;;;;;;;;;;;;;;;;;;;;EAwBV;IACE;IACA;IACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BF;;;;;;;;;;;;;EAaA;;KAGU;;;;EAIV;;;;EAIA;;;;EAIA;;;;;;;;;;;;;EAaA,oBAAoB,OAAO;;;;;EAK3B,WAAW,OAAO;;;;EAIlB,iBAAiB;;;;EAIjB;IACE,SAAS,UAAU;;;;;;;;;EASrB;;;;;;EAMA;;;;;;EAMA,WAAW;;;;;;;EAOX,eAAe;;;;cC3HJ,uCAAqB,0BAAA,6CAAA,cAAA;cA2HrB,yBAAwB,OAAA,OAAA,MAAA,eAKlC,8CAAyB,IAAA;cAYf,oCAAkB,0BAAA,0CAAA,cAAA;;;cCjOlB;EACX;EACA,gBAAgB;EAChB,UAAU;EACV;EAEY,cACV,gBACA,UACA,UACA,cACC;EAeH,kBAAiB,gBAAA,eAAA,OAAA,WAAA;IAOf;IACA;IACA;IACA;IACA;;;;;;;;;;;;EAmDF;;;;;;;;;cCxFW;KAgBD,4BAA4B;;iBAexB,2BAA2B;iBAK3B,uBAAuB;;;;;;;;;;;;;;cCjB1B"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/conversation-metadata.ts","../src/customisations.ts","../src/events.ts","../src/types.ts","../src/widget.tsx","../src/client.ts","../src/errors.ts","../src/lifecycle.ts"],"mappings":";;KAEY,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;UCuBzB;;EAER;EACA;;EAEA;;EAEA;EACA;;UAGe;;EAEf;EACA;EACA,UAAU;;;;;;;;;;;;;;;EAeV;;EAEA;EACA;EACA;;IAEE;;;;;;IAMA;;;;;;;IAOA;;EAEF,SAAS;EACT;;;;;;;EAOA;IACE;IACA;IACA;IACA;IACA;;IAEA;;;EAGF;EACA,QAAQ;EACR;;EAEA;;UAGe;;;;;;EAMf;EACA;;EAEA;EACA;;EAEA;EACA;;;;;;;;;EASA;;;;;EAKA;;EAEA;;EAEA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;KCxHU;;;EAEN;;;;;;;;EAMA;EAAwB;;;;EAExB;;;;;;;;;;;;EAUA;EAAuB;;;;;;;;;;;;;;;;;EAevB;EAAe;;;;;;;;;;;;EAUf;;;;;;;EAKA;;;;;;;EAKA;EAA2B;;;;;;;EAK3B;EAAyB;;;;;;;;;;;;;;;;EAczB;;;;;;;;;;;;EAUA;;;;EAEA;EAAe;;;;;;;;;;;;;EAYf;EACA;EACA;;;KAIM;UCjHK;;;;EAIf;;;;EAIA,iBAAiB;;;;;EAKjB,WAAW;;;;EAIX;;KAGU;;;;EAIV;;;;EAIA;;;;EAIA,eAAe;;;;;;;;;;;;;;;EAef,WAAW,OAAO;;KAGR;;;;EAIV;;;;EAIA,QAAQ,UAAU;;;;EAIlB,OAAO,MAAM;;;;EAIb;;;;;;;KAQU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCV;IACE;IACA;IACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCF;;;;;;;;;;;;;EAaA;;KAGU;;;;EAIV;;;;EAIA;;;;EAIA;;;;;;;;;;;;;EAaA,oBAAoB,OAAO;;;;;EAK3B,WAAW,OAAO;;;;EAIlB,iBAAiB;;;;EAIjB;IACE,SAAS,UAAU;;;;;;;;;EASrB;;;;;;;EAOA;;;;;;EAMA,WAAW;;;;;;;EAOX,eAAe;;;;;;;;;;;EAWf;;cC7JW,uCAAqB,0BAAA,6CAAA,cAAA;cA2HrB,yBAAwB,OAAA,OAAA,MAAA,eAKlC,8CAAyB,IAAA;cAYf,oCAAkB,0BAAA,0CAAA,cAAA;cCpOlB;EACX;EACA,gBAAgB;EAChB,UAAU;EACV;EAEY,cACV,gBACA,UACA,UACA,cACC;EAeH,kBAAiB,gBAAA,eAAA,OAAA,WAAA;IAOf;IACA;IACA;IACA;IACA;;;;;;;;;;;;EAmDF;;;;;;;;;;;;cCnFW;KAgBD,4BAA4B;;iBAexB,2BAA2B;iBAK3B,uBAAuB;;;;;;;;;;;;cCtB1B"}