@tapthrough/expo 0.0.0-stage → 0.1.1

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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -2
  3. package/app.plugin.d.ts +37 -0
  4. package/app.plugin.js +79 -0
  5. package/dist/Annotator.d.ts +14 -0
  6. package/dist/Annotator.d.ts.map +1 -0
  7. package/dist/Annotator.js +160 -0
  8. package/dist/Annotator.js.map +1 -0
  9. package/dist/Bubble.d.ts +27 -0
  10. package/dist/Bubble.d.ts.map +1 -0
  11. package/dist/Bubble.js +234 -0
  12. package/dist/Bubble.js.map +1 -0
  13. package/dist/Feedback.d.ts +14 -0
  14. package/dist/Feedback.d.ts.map +1 -0
  15. package/dist/Feedback.js +977 -0
  16. package/dist/Feedback.js.map +1 -0
  17. package/dist/Overlay.d.ts +13 -0
  18. package/dist/Overlay.d.ts.map +1 -0
  19. package/dist/Overlay.js +44 -0
  20. package/dist/Overlay.js.map +1 -0
  21. package/dist/Popover.d.ts +98 -0
  22. package/dist/Popover.d.ts.map +1 -0
  23. package/dist/Popover.js +531 -0
  24. package/dist/Popover.js.map +1 -0
  25. package/dist/Tapthrough.d.ts +27 -0
  26. package/dist/Tapthrough.d.ts.map +1 -0
  27. package/dist/Tapthrough.js +111 -0
  28. package/dist/Tapthrough.js.map +1 -0
  29. package/dist/core/annotations.d.ts +63 -0
  30. package/dist/core/annotations.d.ts.map +1 -0
  31. package/dist/core/annotations.js +76 -0
  32. package/dist/core/annotations.js.map +1 -0
  33. package/dist/core/bubble.d.ts +21 -0
  34. package/dist/core/bubble.d.ts.map +1 -0
  35. package/dist/core/bubble.js +25 -0
  36. package/dist/core/bubble.js.map +1 -0
  37. package/dist/core/controller.d.ts +46 -0
  38. package/dist/core/controller.d.ts.map +1 -0
  39. package/dist/core/controller.js +103 -0
  40. package/dist/core/controller.js.map +1 -0
  41. package/dist/core/diagnostics.d.ts +47 -0
  42. package/dist/core/diagnostics.d.ts.map +1 -0
  43. package/dist/core/diagnostics.js +101 -0
  44. package/dist/core/diagnostics.js.map +1 -0
  45. package/dist/core/feedback.d.ts +302 -0
  46. package/dist/core/feedback.d.ts.map +1 -0
  47. package/dist/core/feedback.js +345 -0
  48. package/dist/core/feedback.js.map +1 -0
  49. package/dist/core/flags.d.ts +13 -0
  50. package/dist/core/flags.d.ts.map +1 -0
  51. package/dist/core/flags.js +25 -0
  52. package/dist/core/flags.js.map +1 -0
  53. package/dist/core/ideas.d.ts +166 -0
  54. package/dist/core/ideas.d.ts.map +1 -0
  55. package/dist/core/ideas.js +159 -0
  56. package/dist/core/ideas.js.map +1 -0
  57. package/dist/core/launch.d.ts +43 -0
  58. package/dist/core/launch.d.ts.map +1 -0
  59. package/dist/core/launch.js +81 -0
  60. package/dist/core/launch.js.map +1 -0
  61. package/dist/core/reset.d.ts +17 -0
  62. package/dist/core/reset.d.ts.map +1 -0
  63. package/dist/core/reset.js +19 -0
  64. package/dist/core/reset.js.map +1 -0
  65. package/dist/core/review.d.ts +49 -0
  66. package/dist/core/review.d.ts.map +1 -0
  67. package/dist/core/review.js +92 -0
  68. package/dist/core/review.js.map +1 -0
  69. package/dist/core/url.d.ts +9 -0
  70. package/dist/core/url.d.ts.map +1 -0
  71. package/dist/core/url.js +23 -0
  72. package/dist/core/url.js.map +1 -0
  73. package/dist/hooks.d.ts +6 -0
  74. package/dist/hooks.d.ts.map +1 -0
  75. package/dist/hooks.js +13 -0
  76. package/dist/hooks.js.map +1 -0
  77. package/dist/index.d.ts +9 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +7 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/native-intent.d.ts +18 -0
  82. package/dist/native-intent.d.ts.map +1 -0
  83. package/dist/native-intent.js +32 -0
  84. package/dist/native-intent.js.map +1 -0
  85. package/dist/runtime.d.ts +24 -0
  86. package/dist/runtime.d.ts.map +1 -0
  87. package/dist/runtime.js +17 -0
  88. package/dist/runtime.js.map +1 -0
  89. package/dist/screenshot.d.ts +7 -0
  90. package/dist/screenshot.d.ts.map +1 -0
  91. package/dist/screenshot.js +48 -0
  92. package/dist/screenshot.js.map +1 -0
  93. package/dist/supabase.d.ts +20 -0
  94. package/dist/supabase.d.ts.map +1 -0
  95. package/dist/supabase.js +18 -0
  96. package/dist/supabase.js.map +1 -0
  97. package/dist/ui/native.d.ts +34 -0
  98. package/dist/ui/native.d.ts.map +1 -0
  99. package/dist/ui/native.js +76 -0
  100. package/dist/ui/native.js.map +1 -0
  101. package/dist/ui/parts.d.ts +62 -0
  102. package/dist/ui/parts.d.ts.map +1 -0
  103. package/dist/ui/parts.js +110 -0
  104. package/dist/ui/parts.js.map +1 -0
  105. package/dist/ui/theme.d.ts +90 -0
  106. package/dist/ui/theme.d.ts.map +1 -0
  107. package/dist/ui/theme.js +61 -0
  108. package/dist/ui/theme.js.map +1 -0
  109. package/package.json +82 -3
  110. package/src/Annotator.tsx +279 -0
  111. package/src/Bubble.tsx +331 -0
  112. package/src/Feedback.tsx +1739 -0
  113. package/src/Overlay.tsx +61 -0
  114. package/src/Popover.tsx +1393 -0
  115. package/src/Tapthrough.tsx +171 -0
  116. package/src/core/annotations.ts +116 -0
  117. package/src/core/bubble.ts +45 -0
  118. package/src/core/controller.ts +119 -0
  119. package/src/core/diagnostics.ts +128 -0
  120. package/src/core/feedback.ts +589 -0
  121. package/src/core/flags.ts +31 -0
  122. package/src/core/ideas.ts +337 -0
  123. package/src/core/launch.ts +119 -0
  124. package/src/core/reset.ts +28 -0
  125. package/src/core/review.ts +148 -0
  126. package/src/core/url.ts +21 -0
  127. package/src/hooks.ts +15 -0
  128. package/src/index.ts +8 -0
  129. package/src/native-intent.ts +36 -0
  130. package/src/runtime.ts +30 -0
  131. package/src/screenshot.ts +64 -0
  132. package/src/supabase.ts +27 -0
  133. package/src/ui/native.ts +116 -0
  134. package/src/ui/parts.tsx +249 -0
  135. package/src/ui/theme.ts +75 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Hands launch links to Tapthrough and keeps Expo Router from trying to open
3
+ * them as a screen. Use it as your `app/+native-intent.tsx`:
4
+ *
5
+ * ```ts
6
+ * export { redirectSystemPath } from '@tapthrough/expo'
7
+ * ```
8
+ *
9
+ * If you already have a `redirectSystemPath`, call `handleLaunchPath(path)`
10
+ * first and return early when it returns true.
11
+ */
12
+ export declare function redirectSystemPath({ path, initial, }: {
13
+ path: string;
14
+ initial: boolean;
15
+ }): string | null;
16
+ /** Queues the launch if `path` is a Tapthrough launch link. Returns whether it was one. */
17
+ export declare function handleLaunchPath(path: string): boolean;
18
+ //# sourceMappingURL=native-intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-intent.d.ts","sourceRoot":"","sources":["../src/native-intent.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,GACR,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,MAAM,GAAG,IAAI,CAIhB;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQtD"}
@@ -0,0 +1,32 @@
1
+ import { parseLaunchUrl } from './core/url.js';
2
+ import { controller } from './runtime.js';
3
+ /**
4
+ * Hands launch links to Tapthrough and keeps Expo Router from trying to open
5
+ * them as a screen. Use it as your `app/+native-intent.tsx`:
6
+ *
7
+ * ```ts
8
+ * export { redirectSystemPath } from '@tapthrough/expo'
9
+ * ```
10
+ *
11
+ * If you already have a `redirectSystemPath`, call `handleLaunchPath(path)`
12
+ * first and return early when it returns true.
13
+ */
14
+ export function redirectSystemPath({ path, initial, }) {
15
+ if (!handleLaunchPath(path))
16
+ return path;
17
+ // Stay put on a warm open; start at the root on a cold one. The SDK navigates once seeded.
18
+ return initial ? '/' : null;
19
+ }
20
+ /** Queues the launch if `path` is a Tapthrough launch link. Returns whether it was one. */
21
+ export function handleLaunchPath(path) {
22
+ try {
23
+ if (!parseLaunchUrl(path))
24
+ return false;
25
+ controller.offer(path);
26
+ return true;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ //# sourceMappingURL=native-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-intent.js","sourceRoot":"","sources":["../src/native-intent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,GAIR;IACC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACxC,2FAA2F;IAC3F,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;AAC7B,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QACvC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ /** One controller per app, shared by `<Tapthrough>` and `redirectSystemPath`. */
2
+ export declare const controller: {
3
+ offer(url: string | null | undefined, source?: import("./core/controller.js").LaunchSource): boolean;
4
+ configure(next: import("./core/controller.js").ControllerDeps | undefined): void;
5
+ setNavigator(next: ((path: string) => void | Promise<void>) | undefined): void;
6
+ dismiss(): void;
7
+ getState: () => import("./index.js").LaunchState;
8
+ lastScenarioId: () => string | undefined;
9
+ subscribe(listener: () => void): () => void;
10
+ };
11
+ export declare const DEFAULT_API_URL = "https://tapthrough-cloud.vercel.app";
12
+ export interface PluginConfig {
13
+ enabled: boolean;
14
+ seedHookUrl: string | undefined;
15
+ /** Tapthrough's base URL, where reports are sent. */
16
+ apiUrl: string;
17
+ /** Staging and TestFlight builds: a feedback button outside PR previews. */
18
+ staff: boolean;
19
+ /** The repo's app key, which proves staff builds belong to it. */
20
+ appKey: string | undefined;
21
+ }
22
+ /** What the config plugin wrote into `extra.tapthrough` at build time. */
23
+ export declare function pluginConfig(): PluginConfig;
24
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,eAAO,MAAM,UAAU;;;;;;;;CAA2B,CAAA;AAElD,eAAO,MAAM,eAAe,wCAAwC,CAAA;AAEpE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,KAAK,EAAE,OAAO,CAAA;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,IAAI,YAAY,CAS3C"}
@@ -0,0 +1,17 @@
1
+ import Constants from 'expo-constants';
2
+ import { createLaunchController } from './core/controller.js';
3
+ /** One controller per app, shared by `<Tapthrough>` and `redirectSystemPath`. */
4
+ export const controller = createLaunchController();
5
+ export const DEFAULT_API_URL = 'https://tapthrough-cloud.vercel.app';
6
+ /** What the config plugin wrote into `extra.tapthrough` at build time. */
7
+ export function pluginConfig() {
8
+ const extra = Constants.expoConfig?.extra?.tapthrough;
9
+ return {
10
+ enabled: extra?.enabled === true,
11
+ seedHookUrl: typeof extra?.seedHookUrl === 'string' ? extra.seedHookUrl : undefined,
12
+ apiUrl: typeof extra?.apiUrl === 'string' ? extra.apiUrl : DEFAULT_API_URL,
13
+ staff: extra?.staff === true && typeof extra.appKey === 'string',
14
+ appKey: typeof extra?.appKey === 'string' ? extra.appKey : undefined,
15
+ };
16
+ }
17
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,EAAE,CAAA;AAElD,MAAM,CAAC,MAAM,eAAe,GAAG,qCAAqC,CAAA;AAapE,0EAA0E;AAC1E,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,UAA+C,CAAA;IAC1F,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI;QAChC,WAAW,EAAE,OAAO,KAAK,EAAE,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACnF,MAAM,EAAE,OAAO,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe;QAC1E,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChE,MAAM,EAAE,OAAO,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;KACrE,CAAA;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface Screenshot {
2
+ contentType: 'image/jpeg';
3
+ base64: string;
4
+ }
5
+ /** A JPEG of the whole screen, scaled to at most 720px wide to keep uploads small. */
6
+ export declare function captureScreenshot(): Promise<Screenshot | null>;
7
+ //# sourceMappingURL=screenshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,YAAY,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,sFAAsF;AACtF,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA0BpE"}
@@ -0,0 +1,48 @@
1
+ import { Dimensions } from 'react-native';
2
+ let viewShot;
3
+ /** `react-native-view-shot` is optional: without it, reports go out without a screenshot. */
4
+ function loadViewShot() {
5
+ if (viewShot === undefined) {
6
+ try {
7
+ // Metro treats a require inside try/catch as an optional dependency.
8
+ viewShot = require('react-native-view-shot');
9
+ }
10
+ catch {
11
+ viewShot = null;
12
+ }
13
+ }
14
+ return viewShot;
15
+ }
16
+ /** A JPEG of the whole screen, scaled to at most 720px wide to keep uploads small. */
17
+ export async function captureScreenshot() {
18
+ const shot = loadViewShot();
19
+ if (!shot)
20
+ return null;
21
+ const { width, height } = Dimensions.get('window');
22
+ const targetWidth = Math.min(720, Math.round(width * 2));
23
+ let timer;
24
+ try {
25
+ const base64 = await Promise.race([
26
+ shot.captureScreen({
27
+ format: 'jpg',
28
+ quality: 0.7,
29
+ result: 'base64',
30
+ width: targetWidth,
31
+ height: Math.round((targetWidth * height) / width),
32
+ }),
33
+ // The native capture can stall on some screens; the report shouldn't wait on it.
34
+ new Promise((resolve) => {
35
+ timer = setTimeout(() => resolve(null), CAPTURE_TIMEOUT_MS);
36
+ }),
37
+ ]);
38
+ return base64 ? { contentType: 'image/jpeg', base64 } : null;
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ finally {
44
+ clearTimeout(timer);
45
+ }
46
+ }
47
+ const CAPTURE_TIMEOUT_MS = 2500;
48
+ //# sourceMappingURL=screenshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAczC,IAAI,QAAqC,CAAA;AAEzC,6FAA6F;AAC7F,SAAS,YAAY;IACnB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,qEAAqE;YACrE,QAAQ,GAAG,OAAO,CAAC,wBAAwB,CAAa,CAAA;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,IAAI,CAAA;QACjB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAOD,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,IAAI,GAAG,YAAY,EAAE,CAAA;IAC3B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;IACxD,IAAI,KAAgD,CAAA;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC;gBACjB,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,GAAG;gBACZ,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC;aACnD,CAAC;YACF,iFAAiF;YACjF,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC5B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAA;YAC7D,CAAC,CAAC;SACH,CAAC,CAAA;QACF,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;AACH,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { AuthAdapter } from './core/launch.js';
2
+ interface SupabaseAuthClient {
3
+ auth: {
4
+ setSession(session: {
5
+ access_token: string;
6
+ refresh_token: string;
7
+ }): Promise<{
8
+ error: {
9
+ message: string;
10
+ } | null;
11
+ }>;
12
+ };
13
+ }
14
+ /**
15
+ * Logs in with the `{ access_token, refresh_token }` session that
16
+ * `createTestUser` from `@tapthrough/seed/supabase` returns.
17
+ */
18
+ export declare function supabaseAuth(client: SupabaseAuthClient): AuthAdapter;
19
+ export {};
20
+ //# sourceMappingURL=supabase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../src/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,UAAU,kBAAkB;IAC1B,IAAI,EAAE;QACJ,UAAU,CAAC,OAAO,EAAE;YAClB,YAAY,EAAE,MAAM,CAAA;YACpB,aAAa,EAAE,MAAM,CAAA;SACtB,GAAG,OAAO,CAAC;YAAE,KAAK,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAA;aAAE,GAAG,IAAI,CAAA;SAAE,CAAC,CAAA;KACnD,CAAA;CACF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,WAAW,CAWpE"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Logs in with the `{ access_token, refresh_token }` session that
3
+ * `createTestUser` from `@tapthrough/seed/supabase` returns.
4
+ */
5
+ export function supabaseAuth(client) {
6
+ return {
7
+ async signIn(session) {
8
+ const { access_token, refresh_token } = session;
9
+ if (typeof access_token !== 'string' || typeof refresh_token !== 'string') {
10
+ throw new Error('Seed hook session is missing access_token or refresh_token');
11
+ }
12
+ const { error } = await client.auth.setSession({ access_token, refresh_token });
13
+ if (error)
14
+ throw new Error(error.message);
15
+ },
16
+ };
17
+ }
18
+ //# sourceMappingURL=supabase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../src/supabase.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,OAAO,CAAA;YAC/C,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC1E,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;YAC/E,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAA;YAC/E,IAAI,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC3C,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type ComponentType } from 'react';
2
+ import { type ColorValue, type ViewProps } from 'react-native';
3
+ export interface Glass {
4
+ GlassView: ComponentType<ViewProps & {
5
+ glassEffectStyle?: 'regular' | 'clear';
6
+ tintColor?: string;
7
+ isInteractive?: boolean;
8
+ }>;
9
+ isLiquidGlassAvailable(): boolean;
10
+ }
11
+ /** Liquid Glass on iOS 26 through `expo-glass-effect`, or null. */
12
+ export declare const loadGlass: () => Glass | null;
13
+ interface Symbols {
14
+ SymbolView: ComponentType<ViewProps & {
15
+ name: string;
16
+ size?: number;
17
+ tintColor?: ColorValue;
18
+ weight?: 'regular' | 'medium' | 'semibold' | 'bold';
19
+ type?: 'monochrome' | 'hierarchical';
20
+ }>;
21
+ }
22
+ /** SF Symbols through `expo-symbols`, on iOS only. */
23
+ export declare const loadSymbols: () => Symbols | null;
24
+ /** Haptics through `expo-haptics`; silent without it. Only for the reviewer's own actions. */
25
+ export declare const haptics: {
26
+ selection: () => void;
27
+ success: () => void;
28
+ warning: () => void;
29
+ light: () => void;
30
+ };
31
+ export declare const useReduceMotion: () => boolean;
32
+ export declare const useReduceTransparency: () => boolean;
33
+ export {};
34
+ //# sourceMappingURL=native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/ui/native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,OAAO,CAAA;AAC/D,OAAO,EAAqB,KAAK,UAAU,EAAY,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAiB3F,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,aAAa,CACtB,SAAS,GAAG;QACV,gBAAgB,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;QACtC,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,OAAO,CAAA;KACxB,CACF,CAAA;IACD,sBAAsB,IAAI,OAAO,CAAA;CAClC;AAED,mEAAmE;AACnE,eAAO,MAAM,SAAS,oBAOpB,CAAA;AAEF,UAAU,OAAO;IACf,UAAU,EAAE,aAAa,CACvB,SAAS,GAAG;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,UAAU,CAAA;QACtB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAA;QACnD,IAAI,CAAC,EAAE,YAAY,GAAG,cAAc,CAAA;KACrC,CACF,CAAA;CACF;AAED,sDAAsD;AACtD,eAAO,MAAM,WAAW,sBAOtB,CAAA;AAuBF,8FAA8F;AAC9F,eAAO,MAAM,OAAO;;;;;CAKnB,CAAA;AAyBD,eAAO,MAAM,eAAe,eAAmE,CAAA;AAC/F,eAAO,MAAM,qBAAqB,eACsC,CAAA"}
@@ -0,0 +1,76 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { AccessibilityInfo, Platform } from 'react-native';
3
+ /**
4
+ * Optional Expo modules. Metro only treats a `require` as optional when the
5
+ * call sits directly inside a `try` block, so each loader has its own; an app
6
+ * without the module still builds and the SDK falls back to something plainer.
7
+ */
8
+ function once(load) {
9
+ let value;
10
+ return () => {
11
+ if (value === undefined)
12
+ value = load();
13
+ return value;
14
+ };
15
+ }
16
+ /** Liquid Glass on iOS 26 through `expo-glass-effect`, or null. */
17
+ export const loadGlass = once(() => {
18
+ try {
19
+ const glass = require('expo-glass-effect');
20
+ return glass.isLiquidGlassAvailable() ? glass : null;
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ });
26
+ /** SF Symbols through `expo-symbols`, on iOS only. */
27
+ export const loadSymbols = once(() => {
28
+ if (Platform.OS !== 'ios')
29
+ return null;
30
+ try {
31
+ return require('expo-symbols');
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ });
37
+ const loadHaptics = once(() => {
38
+ try {
39
+ return require('expo-haptics');
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ });
45
+ function play(run) {
46
+ const haptics = loadHaptics();
47
+ if (haptics)
48
+ run(haptics).catch(() => { });
49
+ }
50
+ /** Haptics through `expo-haptics`; silent without it. Only for the reviewer's own actions. */
51
+ export const haptics = {
52
+ selection: () => play((h) => h.selectionAsync()),
53
+ success: () => play((h) => h.notificationAsync(h.NotificationFeedbackType.Success)),
54
+ warning: () => play((h) => h.notificationAsync(h.NotificationFeedbackType.Warning)),
55
+ light: () => play((h) => h.impactAsync(h.ImpactFeedbackStyle.Light)),
56
+ };
57
+ function useAccessibilitySetting(read, event) {
58
+ const [on, setOn] = useState(false);
59
+ useEffect(() => {
60
+ let live = true;
61
+ read()
62
+ .then((value) => live && setOn(value))
63
+ .catch(() => { });
64
+ const subscription = AccessibilityInfo.addEventListener(event, setOn);
65
+ return () => {
66
+ live = false;
67
+ subscription.remove();
68
+ };
69
+ }, [read, event]);
70
+ return on;
71
+ }
72
+ const readMotion = () => AccessibilityInfo.isReduceMotionEnabled();
73
+ const readTransparency = () => Platform.OS === 'ios' ? AccessibilityInfo.isReduceTransparencyEnabled() : Promise.resolve(false);
74
+ export const useReduceMotion = () => useAccessibilitySetting(readMotion, 'reduceMotionChanged');
75
+ export const useReduceTransparency = () => useAccessibilitySetting(readTransparency, 'reduceTransparencyChanged');
76
+ //# sourceMappingURL=native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../../src/ui/native.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type ColorValue, type StyleProp, type ViewProps, type ViewStyle } from 'react-native';
3
+ /** SF Symbol names used by the SDK, with a text fallback for apps without `expo-symbols`. */
4
+ declare const GLYPHS: {
5
+ readonly xmark: "✕";
6
+ readonly checkmark: "✓";
7
+ readonly 'chevron.left': "‹";
8
+ readonly 'chevron.right': "›";
9
+ readonly 'arrow.up.left.and.arrow.down.right': "⤢";
10
+ readonly 'arrow.down.right.and.arrow.up.left': "⤡";
11
+ readonly 'arrow.clockwise': "↻";
12
+ readonly 'arrow.down.circle.fill': "↓";
13
+ readonly 'arrow.right.circle': "→";
14
+ readonly 'person.fill': "●";
15
+ readonly 'tray.full.fill': "▤";
16
+ readonly 'flag.fill': "⚑";
17
+ readonly 'arrow.right': "→";
18
+ readonly 'arrow.up': "↑";
19
+ readonly lightbulb: "✦";
20
+ readonly 'arrow.triangle.branch': "⑂";
21
+ };
22
+ export type IconName = keyof typeof GLYPHS;
23
+ export declare function Icon({ name, size, color, weight, }: {
24
+ name: IconName;
25
+ size?: number;
26
+ color: ColorValue;
27
+ weight?: 'regular' | 'medium' | 'semibold' | 'bold';
28
+ }): import("react").JSX.Element;
29
+ /**
30
+ * A floating surface: Liquid Glass where the system has it, otherwise a solid
31
+ * grouped background with a soft shadow. Reduce Transparency always gets solid.
32
+ */
33
+ export declare function Surface({ radius, style, children, ...rest }: ViewProps & {
34
+ radius: number;
35
+ children: ReactNode;
36
+ }): import("react").JSX.Element;
37
+ /** A 44pt circle holding one symbol: back, close, expand, send. */
38
+ export declare function CircleButton({ icon, label, onPress, tint, disabled, busy, }: {
39
+ icon: IconName;
40
+ label: string;
41
+ onPress: () => void;
42
+ tint?: boolean;
43
+ disabled?: boolean;
44
+ busy?: boolean;
45
+ }): import("react").JSX.Element;
46
+ type CapsuleKind = 'prominent' | 'gray' | 'plain';
47
+ /** Every text button: prominent (tint fill), gray (secondary fill) or plain (tint text). */
48
+ export declare function Capsule({ title, onPress, kind, icon, iconColor, busy, disabled, accessibilityLabel, fillColor, style, }: {
49
+ title: string;
50
+ onPress: () => void;
51
+ kind?: CapsuleKind;
52
+ icon?: IconName;
53
+ iconColor?: ColorValue;
54
+ busy?: boolean;
55
+ disabled?: boolean;
56
+ accessibilityLabel?: string;
57
+ /** Fills the button with a result color, e.g. green once Pass is chosen. */
58
+ fillColor?: ColorValue;
59
+ style?: StyleProp<ViewStyle>;
60
+ }): import("react").JSX.Element;
61
+ export {};
62
+ //# sourceMappingURL=parts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/ui/parts.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAEL,KAAK,UAAU,EAEf,KAAK,SAAS,EAId,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AAIrB,6FAA6F;AAC7F,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;CAiBF,CAAA;AACV,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,MAAM,CAAA;AAE1C,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,IAAS,EACT,KAAK,EACL,MAAmB,GACpB,EAAE;IACD,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAA;CACpD,+BAsBA;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAuBrD;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,KAAK,EACL,OAAO,EACP,IAAY,EACZ,QAAgB,EAChB,IAAY,GACb,EAAE;IACD,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,+BAwBA;AAED,KAAK,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjD,4FAA4F;AAC5F,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,OAAO,EACP,IAAkB,EAClB,IAAI,EACJ,SAAS,EACT,IAAY,EACZ,QAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,KAAK,GACN,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAC7B,+BAyCA"}
@@ -0,0 +1,110 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { ActivityIndicator, Pressable, StyleSheet, Text, View, } from 'react-native';
3
+ import { loadGlass, loadSymbols, useReduceTransparency } from './native.js';
4
+ import { text, useColors } from './theme.js';
5
+ /** SF Symbol names used by the SDK, with a text fallback for apps without `expo-symbols`. */
6
+ const GLYPHS = {
7
+ xmark: '✕',
8
+ checkmark: '✓',
9
+ 'chevron.left': '‹',
10
+ 'chevron.right': '›',
11
+ 'arrow.up.left.and.arrow.down.right': '⤢',
12
+ 'arrow.down.right.and.arrow.up.left': '⤡',
13
+ 'arrow.clockwise': '↻',
14
+ 'arrow.down.circle.fill': '↓',
15
+ 'arrow.right.circle': '→',
16
+ 'person.fill': '●',
17
+ 'tray.full.fill': '▤',
18
+ 'flag.fill': '⚑',
19
+ 'arrow.right': '→',
20
+ 'arrow.up': '↑',
21
+ lightbulb: '✦',
22
+ 'arrow.triangle.branch': '⑂',
23
+ };
24
+ export function Icon({ name, size = 17, color, weight = 'semibold', }) {
25
+ const symbols = loadSymbols();
26
+ if (symbols) {
27
+ return (_jsx(symbols.SymbolView, { name: name, size: size, tintColor: color, weight: weight, style: { width: size, height: size }, pointerEvents: "none" }));
28
+ }
29
+ return (_jsx(Text, { style: { color, fontSize: size, lineHeight: size * 1.15, fontWeight: '600' }, allowFontScaling: false, children: GLYPHS[name] }));
30
+ }
31
+ /**
32
+ * A floating surface: Liquid Glass where the system has it, otherwise a solid
33
+ * grouped background with a soft shadow. Reduce Transparency always gets solid.
34
+ */
35
+ export function Surface({ radius, style, children, ...rest }) {
36
+ const colors = useColors();
37
+ const solid = useReduceTransparency();
38
+ const glass = solid ? null : loadGlass();
39
+ return (_jsxs(View, { ...rest, style: [
40
+ { borderRadius: radius },
41
+ glass ? styles.glassShadow : [styles.solid, { backgroundColor: colors.surface }],
42
+ style,
43
+ ], children: [glass ? (_jsx(glass.GlassView, { style: [StyleSheet.absoluteFill, { borderRadius: radius }], glassEffectStyle: "regular", pointerEvents: "none" })) : null, children] }));
44
+ }
45
+ /** A 44pt circle holding one symbol: back, close, expand, send. */
46
+ export function CircleButton({ icon, label, onPress, tint = false, disabled = false, busy = false, }) {
47
+ const colors = useColors();
48
+ const fg = tint ? '#FFFFFF' : colors.label;
49
+ return (_jsx(Pressable, { onPress: onPress, disabled: disabled || busy, accessibilityRole: "button", accessibilityLabel: label, accessibilityState: { disabled: disabled || busy, busy }, style: ({ pressed }) => [
50
+ styles.circle,
51
+ { backgroundColor: tint ? colors.tint : colors.fill },
52
+ disabled && styles.disabled,
53
+ pressed && styles.pressed,
54
+ ], children: busy ? (_jsx(ActivityIndicator, { color: fg })) : (_jsx(Icon, { name: icon, size: 15, color: fg, weight: tint ? 'bold' : 'semibold' })) }));
55
+ }
56
+ /** Every text button: prominent (tint fill), gray (secondary fill) or plain (tint text). */
57
+ export function Capsule({ title, onPress, kind = 'prominent', icon, iconColor, busy = false, disabled = false, accessibilityLabel, fillColor, style, }) {
58
+ const colors = useColors();
59
+ const fg = fillColor || kind === 'prominent' ? '#FFFFFF' : kind === 'gray' ? colors.label : colors.tint;
60
+ return (_jsx(Pressable, { onPress: onPress, disabled: disabled || busy, accessibilityRole: "button", accessibilityLabel: accessibilityLabel ?? title, accessibilityState: { disabled: disabled || busy, busy }, style: ({ pressed }) => [
61
+ styles.capsule,
62
+ kind === 'prominent' && { backgroundColor: colors.tint },
63
+ kind === 'gray' && { backgroundColor: colors.fill },
64
+ kind === 'plain' && styles.plain,
65
+ fillColor ? { backgroundColor: fillColor } : null,
66
+ (disabled || busy) && styles.disabled,
67
+ pressed && styles.pressed,
68
+ style,
69
+ ], children: busy ? (_jsx(ActivityIndicator, { color: fg })) : (_jsxs(_Fragment, { children: [icon ? _jsx(Icon, { name: icon, size: 14, color: fillColor ? fg : (iconColor ?? fg) }) : null, _jsx(Text, { style: [
70
+ kind === 'plain' ? text.subhead : text.headline,
71
+ { color: fg },
72
+ kind === 'gray' && styles.grayText,
73
+ ], numberOfLines: 1, children: title })] })) }));
74
+ }
75
+ const styles = StyleSheet.create({
76
+ solid: {
77
+ shadowColor: '#000000',
78
+ shadowOpacity: 0.16,
79
+ shadowRadius: 24,
80
+ shadowOffset: { width: 0, height: 8 },
81
+ elevation: 12,
82
+ },
83
+ glassShadow: {
84
+ shadowColor: '#000000',
85
+ shadowOpacity: 0.12,
86
+ shadowRadius: 20,
87
+ shadowOffset: { width: 0, height: 6 },
88
+ },
89
+ circle: {
90
+ width: 44,
91
+ height: 44,
92
+ borderRadius: 22,
93
+ alignItems: 'center',
94
+ justifyContent: 'center',
95
+ },
96
+ capsule: {
97
+ minHeight: 50,
98
+ borderRadius: 25,
99
+ paddingHorizontal: 18,
100
+ flexDirection: 'row',
101
+ gap: 6,
102
+ alignItems: 'center',
103
+ justifyContent: 'center',
104
+ },
105
+ plain: { minHeight: 44 },
106
+ grayText: { fontSize: 15 },
107
+ disabled: { opacity: 0.4 },
108
+ pressed: { opacity: 0.7, transform: [{ scale: 0.96 }] },
109
+ });
110
+ //# sourceMappingURL=parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts.js","sourceRoot":"","sources":["../../src/ui/parts.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import { type ColorValue } from 'react-native';
2
+ /** Light and dark values; on iOS they back the system colors' names below. */
3
+ declare const TABLE: {
4
+ surface: {
5
+ light: string;
6
+ dark: string;
7
+ };
8
+ label: {
9
+ light: string;
10
+ dark: string;
11
+ };
12
+ secondary: {
13
+ light: string;
14
+ dark: string;
15
+ };
16
+ tertiary: {
17
+ light: string;
18
+ dark: string;
19
+ };
20
+ separator: {
21
+ light: string;
22
+ dark: string;
23
+ };
24
+ fill: {
25
+ light: string;
26
+ dark: string;
27
+ };
28
+ tint: {
29
+ light: string;
30
+ dark: string;
31
+ };
32
+ pass: {
33
+ light: string;
34
+ dark: string;
35
+ };
36
+ fail: {
37
+ light: string;
38
+ dark: string;
39
+ };
40
+ tintFill: {
41
+ light: string;
42
+ dark: string;
43
+ };
44
+ /** The selected segment of a segmented control. */
45
+ segment: {
46
+ light: string;
47
+ dark: string;
48
+ };
49
+ };
50
+ type Name = keyof typeof TABLE;
51
+ export type Colors = Record<Name, ColorValue>;
52
+ /** The SDK's colors: iOS system colors, or a light/dark table elsewhere. */
53
+ export declare function useColors(): Colors;
54
+ /** Apple's text styles at the default Dynamic Type size. */
55
+ export declare const text: {
56
+ title2: {
57
+ fontSize: number;
58
+ lineHeight: number;
59
+ fontWeight: "700";
60
+ };
61
+ headline: {
62
+ fontSize: number;
63
+ lineHeight: number;
64
+ fontWeight: "600";
65
+ };
66
+ body: {
67
+ fontSize: number;
68
+ lineHeight: number;
69
+ };
70
+ subhead: {
71
+ fontSize: number;
72
+ lineHeight: number;
73
+ };
74
+ footnote: {
75
+ fontSize: number;
76
+ lineHeight: number;
77
+ };
78
+ caption: {
79
+ fontSize: number;
80
+ lineHeight: number;
81
+ };
82
+ };
83
+ /** The iOS curve for things that enter or leave, as a spring. */
84
+ export declare const SPRING: {
85
+ stiffness: number;
86
+ damping: number;
87
+ mass: number;
88
+ };
89
+ export {};
90
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAMhB,MAAM,cAAc,CAAA;AAErB,8EAA8E;AAC9E,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAWT,mDAAmD;;;;;CAEpD,CAAA;AAED,KAAK,IAAI,GAAG,MAAM,OAAO,KAAK,CAAA;AAC9B,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;AA2B7C,4EAA4E;AAC5E,wBAAgB,SAAS,IAAI,MAAM,CAOlC;AAED,4DAA4D;AAC5D,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOoB,CAAA;AAErC,iEAAiE;AACjE,eAAO,MAAM,MAAM;;;;CAA2C,CAAA"}