@qontinui/ui-bridge-native 0.6.15 → 0.7.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.
Files changed (43) hide show
  1. package/README.md +17 -0
  2. package/dist/control/index.js.map +1 -1
  3. package/dist/control/index.mjs.map +1 -1
  4. package/dist/core/index.js +42 -0
  5. package/dist/core/index.js.map +1 -1
  6. package/dist/core/index.mjs +42 -0
  7. package/dist/core/index.mjs.map +1 -1
  8. package/dist/core/registry.d.ts +23 -1
  9. package/dist/core/registry.d.ts.map +1 -1
  10. package/dist/core/types.d.ts +66 -2
  11. package/dist/core/types.d.ts.map +1 -1
  12. package/dist/index.d.ts +3 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +425 -24
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +421 -25
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/observation/index.d.ts +12 -0
  19. package/dist/observation/index.d.ts.map +1 -0
  20. package/dist/observation/observation.d.ts +233 -0
  21. package/dist/observation/observation.d.ts.map +1 -0
  22. package/dist/react/index.d.ts +4 -0
  23. package/dist/react/index.d.ts.map +1 -1
  24. package/dist/react/index.js +425 -24
  25. package/dist/react/index.js.map +1 -1
  26. package/dist/react/index.mjs +421 -25
  27. package/dist/react/index.mjs.map +1 -1
  28. package/dist/react/routePattern.d.ts +145 -0
  29. package/dist/react/routePattern.d.ts.map +1 -0
  30. package/dist/react/useRouteAwareness.d.ts +106 -0
  31. package/dist/react/useRouteAwareness.d.ts.map +1 -0
  32. package/dist/server/handlers.d.ts.map +1 -1
  33. package/dist/server/index.d.ts +2 -0
  34. package/dist/server/index.d.ts.map +1 -1
  35. package/dist/server/index.js +314 -21
  36. package/dist/server/index.js.map +1 -1
  37. package/dist/server/index.mjs +308 -22
  38. package/dist/server/index.mjs.map +1 -1
  39. package/dist/server/page-health.d.ts +50 -7
  40. package/dist/server/page-health.d.ts.map +1 -1
  41. package/dist/server/types.d.ts +5 -3
  42. package/dist/server/types.d.ts.map +1 -1
  43. package/package.json +1 -1
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Route-pattern helpers for React Native routers — derive a route TEMPLATE
3
+ * from the router's own route identifiers, failing closed.
4
+ *
5
+ * Why this exists: `useRouteAwareness({ pattern })` is consumed as a route
6
+ * TEMPLATE (the runner's journey ledger stores it as `pathnameTemplate`, which
7
+ * must never carry user input). The web SDK derives its pattern by VALUE
8
+ * substitution (`routePatternFromParams` in `@qontinui/ui-bridge`), because
9
+ * Next.js exposes only a concrete pathname. Native routers need no
10
+ * substitution: both already expose template identifiers directly.
11
+ *
12
+ * - **Expo Router** — `useSegments()` returns file-route names
13
+ * (`['profile', '[user]']`, `['(tabs)', 'runs']`), never the concrete path.
14
+ * A not-found render reads `['+not-found']` in its segments. The concrete
15
+ * not-found path is never a segment: it is always in `pathname` (which the
16
+ * helpers never take), and on the NESTED not-found branch it is also in
17
+ * `params['not-found']`; on the top-level branch `params` is `{}`
18
+ * (expo-router 6.0.23 `build/global-state/routeInfo.js:22-30, 96-99`).
19
+ * - **React Navigation** — the navigation state carries each route's `name`,
20
+ * a static identifier declared in code (`<Stack.Screen name="Profile">`).
21
+ * User values live only in `route.params`, which these helpers never read.
22
+ *
23
+ * So the helpers only VALIDATE shape. GUARANTEE, and its precondition: a
24
+ * non-null result is built solely from the segments / route names the caller
25
+ * passed, each of which is a non-empty string containing no `/`, `?` or `#`.
26
+ * It carries no user input ONLY when those inputs are the router's own
27
+ * route-identifier output — `useSegments()` or the navigation state — and
28
+ * never `usePathname()`, a URL, or a param value. One residual: when Expo's
29
+ * navigation state is incomplete it pushes `route.params.screen` strings into
30
+ * the segments (`routeInfo.js:59-83`). Those are navigator screen names, not
31
+ * user values, so the guarantee holds as long as an app never navigates with a
32
+ * user-controlled `screen` param; the shape test bounds what such a value
33
+ * could carry.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * import { useSegments } from 'expo-router';
38
+ * import {
39
+ * expoRouterPattern,
40
+ * expoRouterRouteStack,
41
+ * isExpoRouterUnmatched,
42
+ * } from '@qontinui/ui-bridge-native';
43
+ *
44
+ * function useExpoRoute() {
45
+ * const segments = useSegments();
46
+ * return {
47
+ * pattern: expoRouterPattern(segments),
48
+ * routeStack: expoRouterRouteStack(segments),
49
+ * unmatched: isExpoRouterUnmatched(segments),
50
+ * };
51
+ * }
52
+ * ```
53
+ */
54
+ /**
55
+ * Structural subset of a React Navigation state object — the ROOT state, as
56
+ * `navigationRef.getRootState()` (from `useNavigationContainerRef()`) or the
57
+ * `NavigationContainer` `onStateChange` callback returns it. Do NOT use
58
+ * `useNavigationState((s) => s)`: outside a navigator it throws, and inside a
59
+ * screen it returns only that navigator's state, truncating the chain.
60
+ * Declared structurally so this package takes no dependency on
61
+ * `@react-navigation/*`. `params` is deliberately absent: the helper never
62
+ * reads it.
63
+ */
64
+ export interface NavigationStateLike {
65
+ /**
66
+ * Index of the focused route in `routes`. When absent (a partial state),
67
+ * React Navigation's own rule applies: the LAST route for a stack (or a
68
+ * state with no `type`), the FIRST route for any other navigator type.
69
+ */
70
+ index?: number;
71
+ /** Navigator type (`'stack'`, `'tab'`, `'drawer'`, …), when known. */
72
+ type?: string;
73
+ routes: ReadonlyArray<{
74
+ name: string;
75
+ /** The nested navigator's state, when this route hosts one. */
76
+ state?: NavigationStateLike;
77
+ }>;
78
+ }
79
+ /** Options for {@link reactNavigationPattern}. */
80
+ export interface ReactNavigationPatternOptions {
81
+ /**
82
+ * Route names that render the app's not-found screen (the `linking`
83
+ * config's catch-all screen). When the focused LEAF route has one of these
84
+ * names the helper returns `null`.
85
+ */
86
+ notFoundRouteNames?: readonly string[];
87
+ }
88
+ /**
89
+ * True when Expo Router's segments name a system route — any segment starting
90
+ * with `+` (`+not-found`; `+html` / `+api` never render). Expo reserves the
91
+ * `+` prefix, so no `+` segment names a user screen. Pass the result as
92
+ * `useRouteAwareness(info, { unmatched })`.
93
+ */
94
+ export declare function isExpoRouterUnmatched(segments: readonly string[]): boolean;
95
+ /**
96
+ * Derive a route template from Expo Router's `useSegments()`:
97
+ * `'/' + segments.join('/')`, with layout groups such as `(tabs)` KEPT.
98
+ *
99
+ * - `[]` → `'/'` (Expo already pops a trailing `index`);
100
+ * - `['profile', '[user]']` → `'/profile/[user]'`;
101
+ * - `['(tabs)', 'runs']` → `'/(tabs)/runs'`.
102
+ *
103
+ * Groups are kept because they are developer-declared names, never user
104
+ * input, and because two screens in different groups can share a URL — the
105
+ * group is what keeps them distinct. A consumer that wants the URL shape can
106
+ * strip `(…)` segments; a stripped pattern cannot be un-stripped.
107
+ *
108
+ * Returns `null` when any segment starts with `+` (a system route, see
109
+ * {@link isExpoRouterUnmatched}) or fails the route-identifier shape test
110
+ * (empty, not a string, or containing `/`, `?` or `#`).
111
+ */
112
+ export declare function expoRouterPattern(segments: readonly string[]): string | null;
113
+ /**
114
+ * Derive the cumulative route stack from Expo Router's `useSegments()`, with
115
+ * the same meaning as the web `RouteInfo.routeStack` (`["/", "/tasks",
116
+ * "/tasks/:id"]`): one template per depth, root first.
117
+ *
118
+ * - `[]` → `['/']`;
119
+ * - `['(tabs)', 'runs']` → `['/', '/(tabs)', '/(tabs)/runs']`.
120
+ *
121
+ * Fails closed by the same rules as {@link expoRouterPattern}: returns
122
+ * `undefined` (no stack reported) when any segment is a `+` system route or
123
+ * fails the route-identifier shape test.
124
+ */
125
+ export declare function expoRouterRouteStack(segments: readonly string[]): string[] | undefined;
126
+ /**
127
+ * Derive a route template from a React Navigation state: the focused
128
+ * route-NAME chain, root to leaf, joined with `/` — e.g. `/HomeTabs/Profile`.
129
+ *
130
+ * The whole chain rather than the leaf keeps same-named screens in different
131
+ * navigators (`Settings` under two tabs) distinct. Route `params` are never
132
+ * read, so no param shape can leak into the result. Pass the ROOT state
133
+ * (see {@link NavigationStateLike}); a level with no `index` focuses its last
134
+ * route for a stack (or an untyped state) and its first for any other type.
135
+ *
136
+ * Returns `null` on an empty `routes`, an out-of-range or non-integer
137
+ * `index`, a route name that fails the route-identifier shape test, or a
138
+ * focused leaf whose name is in `options.notFoundRouteNames`.
139
+ *
140
+ * Expo Router apps should use {@link expoRouterPattern} instead: Expo Router
141
+ * is React Navigation underneath, and a raw walk of its state yields Expo's
142
+ * internal route names rather than the file routes.
143
+ */
144
+ export declare function reactNavigationPattern(state: NavigationStateLike | null | undefined, options?: ReactNavigationPatternOptions): string | null;
145
+ //# sourceMappingURL=routePattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routePattern.d.ts","sourceRoot":"","sources":["../../src/react/routePattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,+DAA+D;QAC/D,KAAK,CAAC,EAAE,mBAAmB,CAAC;KAC7B,CAAC,CAAC;CACJ;AAED,kDAAkD;AAClD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AA2BD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAO5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAOtF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAC7C,OAAO,GAAE,6BAAkC,GAC1C,MAAM,GAAG,IAAI,CAiBf"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * useRouteAwareness — report the router's current route TEMPLATE to the
3
+ * native bridge, emitted on every snapshot as `page.route`.
4
+ *
5
+ * `pattern` is a route TEMPLATE, never the concrete pathname: a concrete path
6
+ * (`/search/<what the user typed>`) reported as a pattern leaks user input into
7
+ * anything that stores templates — the runner's journey ledger reads
8
+ * `snapshot.page.route.pattern` and keeps it only under
9
+ * `patternSource: 'router'`. Derive the pattern with `expoRouterPattern`
10
+ * (Expo Router `useSegments()`) or `reactNavigationPattern` (React Navigation
11
+ * state), which return `null` rather than leak, and say where it came from
12
+ * with `patternSource: 'router'`. NEVER pass `usePathname()`, a URL, or a
13
+ * param value as the pattern.
14
+ *
15
+ * The not-found signal is a plain boolean, `{ unmatched }`. The web SDK needs
16
+ * a provider-owned context signal and a layout effect because a Next.js layout
17
+ * renders before its `not-found.tsx` exists, so it cannot know at render time
18
+ * that the render is a 404. Neither native router has that gap: Expo Router's
19
+ * `useSegments()` already reads `['+not-found']` in the same render
20
+ * (`isExpoRouterUnmatched`), and a React Navigation not-found screen is an
21
+ * ordinary named route in the state the caller already reads. So there is no
22
+ * signal to wire. While `unmatched` is true the reported `pattern` is `null`
23
+ * AND `params` is dropped: on a NESTED `+not-found` route expo-router also
24
+ * carries the concrete not-found path in `params['not-found']` (on the
25
+ * top-level branch `params` is `{}`; the path is always in `pathname`, which
26
+ * the hook never takes), so a caller passing the router's search params as
27
+ * `params` would otherwise ship user input.
28
+ *
29
+ * Note: native's `unmatched?: boolean` shares its option KEY with the web
30
+ * hook's `unmatched?: RouteUnmatchedSignal | null`, but not its type.
31
+ *
32
+ * The reported info is cleared when the component unmounts. Outside a
33
+ * `UIBridgeNativeProvider` the hook is a no-op.
34
+ *
35
+ * Usage with Expo Router (in the root layout):
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * import { useSegments } from 'expo-router';
40
+ * import {
41
+ * expoRouterPattern,
42
+ * expoRouterRouteStack,
43
+ * isExpoRouterUnmatched,
44
+ * useRouteAwareness,
45
+ * } from '@qontinui/ui-bridge-native';
46
+ *
47
+ * function RouteAwareness() {
48
+ * const segments = useSegments();
49
+ * useRouteAwareness(
50
+ * {
51
+ * pattern: expoRouterPattern(segments),
52
+ * patternSource: 'router',
53
+ * routeStack: expoRouterRouteStack(segments),
54
+ * },
55
+ * { unmatched: isExpoRouterUnmatched(segments) }
56
+ * );
57
+ * return null;
58
+ * }
59
+ * ```
60
+ *
61
+ * Usage with React Navigation: read the ROOT state from the container, not
62
+ * with `useNavigationState` (which throws outside a navigator and, inside a
63
+ * screen, sees only that navigator's state). The component must render inside
64
+ * `UIBridgeNativeProvider`:
65
+ *
66
+ * @example
67
+ * ```tsx
68
+ * import { useState } from 'react';
69
+ * import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
70
+ * import {
71
+ * reactNavigationPattern,
72
+ * useRouteAwareness,
73
+ * type NavigationStateLike,
74
+ * } from '@qontinui/ui-bridge-native';
75
+ *
76
+ * function Navigation({ children }: { children: React.ReactNode }) {
77
+ * const navigationRef = useNavigationContainerRef();
78
+ * const [rootState, setRootState] = useState<NavigationStateLike | undefined>();
79
+ * const syncRootState = () => setRootState(navigationRef.getRootState());
80
+ *
81
+ * const pattern = reactNavigationPattern(rootState, { notFoundRouteNames: ['NotFound'] });
82
+ * useRouteAwareness({ pattern, patternSource: 'router' }, { unmatched: pattern === null });
83
+ *
84
+ * return (
85
+ * <NavigationContainer ref={navigationRef} onReady={syncRootState} onStateChange={syncRootState}>
86
+ * {children}
87
+ * </NavigationContainer>
88
+ * );
89
+ * }
90
+ * ```
91
+ */
92
+ import type { RouteInfo } from '../core/types';
93
+ export interface UseRouteAwarenessOptions {
94
+ /**
95
+ * True while the current route is a not-found screen. The reported
96
+ * `pattern` is then `null` and `params` is dropped, whatever `info` says.
97
+ */
98
+ unmatched?: boolean;
99
+ }
100
+ /**
101
+ * Report router information to the native bridge's `page.route`.
102
+ *
103
+ * The info is cleared when the component unmounts.
104
+ */
105
+ export declare function useRouteAwareness(info: RouteInfo, options?: UseRouteAwarenessOptions): void;
106
+ //# sourceMappingURL=useRouteAwareness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRouteAwareness.d.ts","sourceRoot":"","sources":["../../src/react/useRouteAwareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,GAAE,wBAA6B,GAAG,IAAI,CAwB/F"}
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,EACL,KAAK,sBAAsB,EAK5B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA4VhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,GACA,oBAAoB,CA4/BtB"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/server/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,EACL,KAAK,sBAAsB,EAK5B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAwB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAQV,oBAAoB,EAKrB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AA4VhF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,CAAC,EAAE;IACP,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,MAAM;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,GACA,oBAAoB,CAmhCtB"}
@@ -15,4 +15,6 @@ export { WebSocketEventBridge } from './ws-event-bridge';
15
15
  export { ConsoleErrorBuffer, NetworkRequestBuffer } from './observability';
16
16
  export { bindWithRetry, isAddrInUseError } from './bind-retry';
17
17
  export type { BindWithRetryOptions } from './bind-retry';
18
+ export { diagnosePageHealth, pageHealthUnknown, NATIVE_PAGE_HEALTH_PRODUCER_ID, type PageHealthValue, type PageHealthObservation, type PageHealthInput, type PageHealthOptions, type PageHealthElement, type PageHealthFinding, type PageHealthSeverity, } from './page-health';
19
+ export { Observation, ObservationError, UNKNOWN_CODES, isUnknownCode, type UnknownCode, type ObservationStatus, type ObservationProducer, type ObservationCoverage, type UnmeasuredDimension, type ObservationCache, type ObservationProvenance, type ObservationUnknown, type MeasuredObservation, type AbsentObservation, type UnknownObservation, } from '../observation';
18
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIzD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,8BAA8B,EAC9B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC"}