@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/README.md +117 -21
- package/dist/index.cjs +96 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -66
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +123 -66
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -86
- package/dist/index.js.map +1 -1
- package/package.json +7 -8
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { WebView, WebViewMessageEvent, WebViewProps } from "react-native-webview";
|
|
2
2
|
import { StyleProp, TextStyle } from "react-native";
|
|
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
|
|
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
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
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.
|
|
107
|
-
* `/css` or `/css2`, and
|
|
108
|
-
*
|
|
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
|
|
134
|
-
* surfaces
|
|
135
|
-
*
|
|
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
|
|
139
|
-
* being rewritten, and an event is
|
|
140
|
-
*
|
|
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
|
|
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
|
|
174
|
-
* `new_chat`,
|
|
175
|
-
* rest of the handshake.
|
|
176
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
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
|
-
*
|
|
343
|
-
* reported
|
|
344
|
-
* customer has been logged out. It does not
|
|
345
|
-
*
|
|
346
|
-
* what the widget is on and what its own
|
|
347
|
-
* its `reason` are how you hear that it
|
|
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
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
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.
|
|
381
|
-
*
|
|
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 `
|
|
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 `
|
|
451
|
-
*
|
|
452
|
-
*
|
|
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
|
-
*
|
|
505
|
-
* Mirrored here because the page publishes
|
|
506
|
-
* otherwise be matching on strings it discovered
|
|
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.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","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":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","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"}
|