stellar-drive 1.0.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 (246) hide show
  1. package/README.md +607 -0
  2. package/dist/actions/remoteChange.d.ts +204 -0
  3. package/dist/actions/remoteChange.d.ts.map +1 -0
  4. package/dist/actions/remoteChange.js +424 -0
  5. package/dist/actions/remoteChange.js.map +1 -0
  6. package/dist/actions/truncateTooltip.d.ts +56 -0
  7. package/dist/actions/truncateTooltip.d.ts.map +1 -0
  8. package/dist/actions/truncateTooltip.js +312 -0
  9. package/dist/actions/truncateTooltip.js.map +1 -0
  10. package/dist/auth/crypto.d.ts +41 -0
  11. package/dist/auth/crypto.d.ts.map +1 -0
  12. package/dist/auth/crypto.js +50 -0
  13. package/dist/auth/crypto.js.map +1 -0
  14. package/dist/auth/deviceVerification.d.ts +283 -0
  15. package/dist/auth/deviceVerification.d.ts.map +1 -0
  16. package/dist/auth/deviceVerification.js +575 -0
  17. package/dist/auth/deviceVerification.js.map +1 -0
  18. package/dist/auth/displayUtils.d.ts +98 -0
  19. package/dist/auth/displayUtils.d.ts.map +1 -0
  20. package/dist/auth/displayUtils.js +145 -0
  21. package/dist/auth/displayUtils.js.map +1 -0
  22. package/dist/auth/loginGuard.d.ts +134 -0
  23. package/dist/auth/loginGuard.d.ts.map +1 -0
  24. package/dist/auth/loginGuard.js +276 -0
  25. package/dist/auth/loginGuard.js.map +1 -0
  26. package/dist/auth/offlineCredentials.d.ts +105 -0
  27. package/dist/auth/offlineCredentials.d.ts.map +1 -0
  28. package/dist/auth/offlineCredentials.js +176 -0
  29. package/dist/auth/offlineCredentials.js.map +1 -0
  30. package/dist/auth/offlineSession.d.ts +96 -0
  31. package/dist/auth/offlineSession.d.ts.map +1 -0
  32. package/dist/auth/offlineSession.js +145 -0
  33. package/dist/auth/offlineSession.js.map +1 -0
  34. package/dist/auth/resolveAuthState.d.ts +85 -0
  35. package/dist/auth/resolveAuthState.d.ts.map +1 -0
  36. package/dist/auth/resolveAuthState.js +249 -0
  37. package/dist/auth/resolveAuthState.js.map +1 -0
  38. package/dist/auth/singleUser.d.ts +498 -0
  39. package/dist/auth/singleUser.d.ts.map +1 -0
  40. package/dist/auth/singleUser.js +1282 -0
  41. package/dist/auth/singleUser.js.map +1 -0
  42. package/dist/bin/commands.d.ts +14 -0
  43. package/dist/bin/commands.d.ts.map +1 -0
  44. package/dist/bin/commands.js +68 -0
  45. package/dist/bin/commands.js.map +1 -0
  46. package/dist/bin/install-pwa.d.ts +41 -0
  47. package/dist/bin/install-pwa.d.ts.map +1 -0
  48. package/dist/bin/install-pwa.js +4594 -0
  49. package/dist/bin/install-pwa.js.map +1 -0
  50. package/dist/config.d.ts +249 -0
  51. package/dist/config.d.ts.map +1 -0
  52. package/dist/config.js +395 -0
  53. package/dist/config.js.map +1 -0
  54. package/dist/conflicts.d.ts +306 -0
  55. package/dist/conflicts.d.ts.map +1 -0
  56. package/dist/conflicts.js +807 -0
  57. package/dist/conflicts.js.map +1 -0
  58. package/dist/crdt/awareness.d.ts +128 -0
  59. package/dist/crdt/awareness.d.ts.map +1 -0
  60. package/dist/crdt/awareness.js +284 -0
  61. package/dist/crdt/awareness.js.map +1 -0
  62. package/dist/crdt/channel.d.ts +165 -0
  63. package/dist/crdt/channel.d.ts.map +1 -0
  64. package/dist/crdt/channel.js +522 -0
  65. package/dist/crdt/channel.js.map +1 -0
  66. package/dist/crdt/config.d.ts +58 -0
  67. package/dist/crdt/config.d.ts.map +1 -0
  68. package/dist/crdt/config.js +123 -0
  69. package/dist/crdt/config.js.map +1 -0
  70. package/dist/crdt/helpers.d.ts +104 -0
  71. package/dist/crdt/helpers.d.ts.map +1 -0
  72. package/dist/crdt/helpers.js +116 -0
  73. package/dist/crdt/helpers.js.map +1 -0
  74. package/dist/crdt/offline.d.ts +58 -0
  75. package/dist/crdt/offline.d.ts.map +1 -0
  76. package/dist/crdt/offline.js +130 -0
  77. package/dist/crdt/offline.js.map +1 -0
  78. package/dist/crdt/persistence.d.ts +65 -0
  79. package/dist/crdt/persistence.d.ts.map +1 -0
  80. package/dist/crdt/persistence.js +171 -0
  81. package/dist/crdt/persistence.js.map +1 -0
  82. package/dist/crdt/provider.d.ts +109 -0
  83. package/dist/crdt/provider.d.ts.map +1 -0
  84. package/dist/crdt/provider.js +543 -0
  85. package/dist/crdt/provider.js.map +1 -0
  86. package/dist/crdt/store.d.ts +111 -0
  87. package/dist/crdt/store.d.ts.map +1 -0
  88. package/dist/crdt/store.js +158 -0
  89. package/dist/crdt/store.js.map +1 -0
  90. package/dist/crdt/types.d.ts +281 -0
  91. package/dist/crdt/types.d.ts.map +1 -0
  92. package/dist/crdt/types.js +26 -0
  93. package/dist/crdt/types.js.map +1 -0
  94. package/dist/data.d.ts +502 -0
  95. package/dist/data.d.ts.map +1 -0
  96. package/dist/data.js +862 -0
  97. package/dist/data.js.map +1 -0
  98. package/dist/database.d.ts +153 -0
  99. package/dist/database.d.ts.map +1 -0
  100. package/dist/database.js +325 -0
  101. package/dist/database.js.map +1 -0
  102. package/dist/debug.d.ts +87 -0
  103. package/dist/debug.d.ts.map +1 -0
  104. package/dist/debug.js +135 -0
  105. package/dist/debug.js.map +1 -0
  106. package/dist/demo.d.ts +131 -0
  107. package/dist/demo.d.ts.map +1 -0
  108. package/dist/demo.js +168 -0
  109. package/dist/demo.js.map +1 -0
  110. package/dist/deviceId.d.ts +47 -0
  111. package/dist/deviceId.d.ts.map +1 -0
  112. package/dist/deviceId.js +106 -0
  113. package/dist/deviceId.js.map +1 -0
  114. package/dist/diagnostics.d.ts +292 -0
  115. package/dist/diagnostics.d.ts.map +1 -0
  116. package/dist/diagnostics.js +378 -0
  117. package/dist/diagnostics.js.map +1 -0
  118. package/dist/engine.d.ts +230 -0
  119. package/dist/engine.d.ts.map +1 -0
  120. package/dist/engine.js +2636 -0
  121. package/dist/engine.js.map +1 -0
  122. package/dist/entries/actions.d.ts +16 -0
  123. package/dist/entries/actions.d.ts.map +1 -0
  124. package/dist/entries/actions.js +29 -0
  125. package/dist/entries/actions.js.map +1 -0
  126. package/dist/entries/auth.d.ts +19 -0
  127. package/dist/entries/auth.d.ts.map +1 -0
  128. package/dist/entries/auth.js +50 -0
  129. package/dist/entries/auth.js.map +1 -0
  130. package/dist/entries/config.d.ts +15 -0
  131. package/dist/entries/config.d.ts.map +1 -0
  132. package/dist/entries/config.js +20 -0
  133. package/dist/entries/config.js.map +1 -0
  134. package/dist/entries/crdt.d.ts +32 -0
  135. package/dist/entries/crdt.d.ts.map +1 -0
  136. package/dist/entries/crdt.js +52 -0
  137. package/dist/entries/crdt.js.map +1 -0
  138. package/dist/entries/kit.d.ts +22 -0
  139. package/dist/entries/kit.d.ts.map +1 -0
  140. package/dist/entries/kit.js +58 -0
  141. package/dist/entries/kit.js.map +1 -0
  142. package/dist/entries/stores.d.ts +22 -0
  143. package/dist/entries/stores.d.ts.map +1 -0
  144. package/dist/entries/stores.js +57 -0
  145. package/dist/entries/stores.js.map +1 -0
  146. package/dist/entries/types.d.ts +23 -0
  147. package/dist/entries/types.d.ts.map +1 -0
  148. package/dist/entries/types.js +12 -0
  149. package/dist/entries/types.js.map +1 -0
  150. package/dist/entries/utils.d.ts +12 -0
  151. package/dist/entries/utils.d.ts.map +1 -0
  152. package/dist/entries/utils.js +42 -0
  153. package/dist/entries/utils.js.map +1 -0
  154. package/dist/entries/vite.d.ts +20 -0
  155. package/dist/entries/vite.d.ts.map +1 -0
  156. package/dist/entries/vite.js +26 -0
  157. package/dist/entries/vite.js.map +1 -0
  158. package/dist/index.d.ts +77 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +234 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/kit/auth.d.ts +80 -0
  163. package/dist/kit/auth.d.ts.map +1 -0
  164. package/dist/kit/auth.js +75 -0
  165. package/dist/kit/auth.js.map +1 -0
  166. package/dist/kit/confirm.d.ts +111 -0
  167. package/dist/kit/confirm.d.ts.map +1 -0
  168. package/dist/kit/confirm.js +169 -0
  169. package/dist/kit/confirm.js.map +1 -0
  170. package/dist/kit/loads.d.ts +187 -0
  171. package/dist/kit/loads.d.ts.map +1 -0
  172. package/dist/kit/loads.js +208 -0
  173. package/dist/kit/loads.js.map +1 -0
  174. package/dist/kit/server.d.ts +175 -0
  175. package/dist/kit/server.d.ts.map +1 -0
  176. package/dist/kit/server.js +297 -0
  177. package/dist/kit/server.js.map +1 -0
  178. package/dist/kit/sw.d.ts +176 -0
  179. package/dist/kit/sw.d.ts.map +1 -0
  180. package/dist/kit/sw.js +320 -0
  181. package/dist/kit/sw.js.map +1 -0
  182. package/dist/queue.d.ts +306 -0
  183. package/dist/queue.d.ts.map +1 -0
  184. package/dist/queue.js +925 -0
  185. package/dist/queue.js.map +1 -0
  186. package/dist/realtime.d.ts +280 -0
  187. package/dist/realtime.d.ts.map +1 -0
  188. package/dist/realtime.js +1031 -0
  189. package/dist/realtime.js.map +1 -0
  190. package/dist/runtime/runtimeConfig.d.ts +110 -0
  191. package/dist/runtime/runtimeConfig.d.ts.map +1 -0
  192. package/dist/runtime/runtimeConfig.js +260 -0
  193. package/dist/runtime/runtimeConfig.js.map +1 -0
  194. package/dist/schema.d.ts +150 -0
  195. package/dist/schema.d.ts.map +1 -0
  196. package/dist/schema.js +891 -0
  197. package/dist/schema.js.map +1 -0
  198. package/dist/stores/authState.d.ts +204 -0
  199. package/dist/stores/authState.d.ts.map +1 -0
  200. package/dist/stores/authState.js +336 -0
  201. package/dist/stores/authState.js.map +1 -0
  202. package/dist/stores/factories.d.ts +140 -0
  203. package/dist/stores/factories.d.ts.map +1 -0
  204. package/dist/stores/factories.js +157 -0
  205. package/dist/stores/factories.js.map +1 -0
  206. package/dist/stores/network.d.ts +48 -0
  207. package/dist/stores/network.d.ts.map +1 -0
  208. package/dist/stores/network.js +261 -0
  209. package/dist/stores/network.js.map +1 -0
  210. package/dist/stores/remoteChanges.d.ts +417 -0
  211. package/dist/stores/remoteChanges.d.ts.map +1 -0
  212. package/dist/stores/remoteChanges.js +626 -0
  213. package/dist/stores/remoteChanges.js.map +1 -0
  214. package/dist/stores/sync.d.ts +165 -0
  215. package/dist/stores/sync.d.ts.map +1 -0
  216. package/dist/stores/sync.js +275 -0
  217. package/dist/stores/sync.js.map +1 -0
  218. package/dist/supabase/auth.d.ts +219 -0
  219. package/dist/supabase/auth.d.ts.map +1 -0
  220. package/dist/supabase/auth.js +459 -0
  221. package/dist/supabase/auth.js.map +1 -0
  222. package/dist/supabase/client.d.ts +88 -0
  223. package/dist/supabase/client.d.ts.map +1 -0
  224. package/dist/supabase/client.js +313 -0
  225. package/dist/supabase/client.js.map +1 -0
  226. package/dist/supabase/validate.d.ts +118 -0
  227. package/dist/supabase/validate.d.ts.map +1 -0
  228. package/dist/supabase/validate.js +208 -0
  229. package/dist/supabase/validate.js.map +1 -0
  230. package/dist/sw/build/vite-plugin.d.ts +149 -0
  231. package/dist/sw/build/vite-plugin.d.ts.map +1 -0
  232. package/dist/sw/build/vite-plugin.js +517 -0
  233. package/dist/sw/build/vite-plugin.js.map +1 -0
  234. package/dist/sw/sw.js +664 -0
  235. package/dist/types.d.ts +363 -0
  236. package/dist/types.d.ts.map +1 -0
  237. package/dist/types.js +18 -0
  238. package/dist/types.js.map +1 -0
  239. package/dist/utils.d.ts +85 -0
  240. package/dist/utils.d.ts.map +1 -0
  241. package/dist/utils.js +156 -0
  242. package/dist/utils.js.map +1 -0
  243. package/package.json +117 -0
  244. package/src/components/DeferredChangesBanner.svelte +477 -0
  245. package/src/components/DemoBanner.svelte +110 -0
  246. package/src/components/SyncStatus.svelte +1732 -0
package/dist/debug.js ADDED
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @fileoverview Debug Logging Utilities
3
+ *
4
+ * Provides opt-in debug logging gated by a localStorage flag. When debug
5
+ * mode is enabled (`localStorage.<prefix>_debug_mode === 'true'`), all
6
+ * debug calls forward to the browser console. When disabled, they are
7
+ * silently dropped — zero runtime cost.
8
+ *
9
+ * The prefix is configurable via {@link _setDebugPrefix} (set by
10
+ * {@link config.ts#initEngine}) so multiple engine instances on the same
11
+ * origin don't collide.
12
+ *
13
+ * @example
14
+ * // Enable debug mode from the browser console:
15
+ * localStorage.setItem('myapp_debug_mode', 'true');
16
+ *
17
+ * // Or programmatically:
18
+ * import { setDebugMode } from 'stellar-drive';
19
+ * setDebugMode(true);
20
+ */
21
+ // =============================================================================
22
+ // Internal State
23
+ // =============================================================================
24
+ /** Cached result of the localStorage check (avoids repeated reads). */
25
+ let debugEnabled = null;
26
+ /** Configurable prefix for the localStorage key (default: `'stellar'`). */
27
+ let debugPrefix = 'stellar';
28
+ // =============================================================================
29
+ // Internal Helpers
30
+ // =============================================================================
31
+ /**
32
+ * Set the prefix used for the localStorage debug flag key.
33
+ *
34
+ * Called internally by {@link config.ts#initEngine} — not part of the
35
+ * public API.
36
+ *
37
+ * @param prefix - Application-specific prefix (e.g., `'myapp'`).
38
+ * @internal
39
+ */
40
+ export function _setDebugPrefix(prefix) {
41
+ debugPrefix = prefix;
42
+ }
43
+ // =============================================================================
44
+ // Public API
45
+ // =============================================================================
46
+ /**
47
+ * Check whether debug mode is currently enabled.
48
+ *
49
+ * Reads `localStorage.<prefix>_debug_mode` on the first call and caches
50
+ * the result for subsequent calls. Returns `false` in SSR environments
51
+ * where `localStorage` is unavailable.
52
+ *
53
+ * @returns `true` if debug logging is active.
54
+ */
55
+ export function isDebugMode() {
56
+ if (debugEnabled !== null)
57
+ return debugEnabled;
58
+ debugEnabled =
59
+ typeof localStorage !== 'undefined' &&
60
+ localStorage.getItem(`${debugPrefix}_debug_mode`) === 'true';
61
+ return debugEnabled;
62
+ }
63
+ /**
64
+ * Enable or disable debug mode at runtime.
65
+ *
66
+ * Persists the setting to localStorage so it survives page reloads.
67
+ *
68
+ * @param enabled - `true` to enable debug logging, `false` to disable.
69
+ */
70
+ export function setDebugMode(enabled) {
71
+ debugEnabled = enabled;
72
+ localStorage.setItem(`${debugPrefix}_debug_mode`, enabled ? 'true' : 'false');
73
+ }
74
+ /**
75
+ * Log a debug message at the `console.log` level.
76
+ *
77
+ * No-op when debug mode is disabled.
78
+ *
79
+ * @param args - Arguments forwarded to `console.log`.
80
+ */
81
+ export function debugLog(...args) {
82
+ if (isDebugMode())
83
+ console.log(...args);
84
+ }
85
+ /**
86
+ * Log a debug message at the `console.warn` level.
87
+ *
88
+ * No-op when debug mode is disabled.
89
+ *
90
+ * @param args - Arguments forwarded to `console.warn`.
91
+ */
92
+ export function debugWarn(...args) {
93
+ if (isDebugMode())
94
+ console.warn(...args);
95
+ }
96
+ /**
97
+ * Log a debug message at the `console.error` level.
98
+ *
99
+ * No-op when debug mode is disabled.
100
+ *
101
+ * @param args - Arguments forwarded to `console.error`.
102
+ */
103
+ export function debugError(...args) {
104
+ if (isDebugMode())
105
+ console.error(...args);
106
+ }
107
+ /**
108
+ * Unified debug logging function with configurable severity level.
109
+ *
110
+ * Replaces the individual `debugLog` / `debugWarn` / `debugError` calls
111
+ * when a single import is preferred.
112
+ *
113
+ * @param level - Console severity: `'log'`, `'warn'`, or `'error'`.
114
+ * @param args - Arguments forwarded to the corresponding `console` method.
115
+ *
116
+ * @example
117
+ * debug('log', '[SYNC] Starting push...');
118
+ * debug('error', '[SYNC] Push failed:', error);
119
+ */
120
+ export function debug(level, ...args) {
121
+ if (!isDebugMode())
122
+ return;
123
+ switch (level) {
124
+ case 'log':
125
+ console.log(...args);
126
+ break;
127
+ case 'warn':
128
+ console.warn(...args);
129
+ break;
130
+ case 'error':
131
+ console.error(...args);
132
+ break;
133
+ }
134
+ }
135
+ //# sourceMappingURL=debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF,uEAAuE;AACvE,IAAI,YAAY,GAAmB,IAAI,CAAC;AAExC,2EAA2E;AAC3E,IAAI,WAAW,GAAG,SAAS,CAAC;AAE5B,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,WAAW,GAAG,MAAM,CAAC;AACvB,CAAC;AAED,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IAC/C,YAAY;QACV,OAAO,YAAY,KAAK,WAAW;YACnC,YAAY,CAAC,OAAO,CAAC,GAAG,WAAW,aAAa,CAAC,KAAK,MAAM,CAAC;IAC/D,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,YAAY,GAAG,OAAO,CAAC;IACvB,YAAY,CAAC,OAAO,CAAC,GAAG,WAAW,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,IAAe;IACzC,IAAI,WAAW,EAAE;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAG,IAAe;IAC1C,IAAI,WAAW,EAAE;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,GAAG,IAAe;IAC3C,IAAI,WAAW,EAAE;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,KAAK,CAAC,KAA+B,EAAE,GAAG,IAAe;IACvE,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO;IAC3B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,KAAK;YACR,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YACrB,MAAM;QACR,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACtB,MAAM;QACR,KAAK,OAAO;YACV,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YACvB,MAAM;IACV,CAAC;AACH,CAAC"}
package/dist/demo.d.ts ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @fileoverview Demo Mode State Module
3
+ *
4
+ * Provides a completely isolated sandbox for consumer PWA apps. When demo mode
5
+ * is active, the app uses a separate Dexie database (`${name}_demo`), makes
6
+ * zero Supabase connections, and skips all sync/auth/email/device-verification
7
+ * flows. Writes go to the sandboxed DB and are dropped on page refresh (mock
8
+ * data is re-seeded).
9
+ *
10
+ * **Security model:**
11
+ * Demo mode does NOT "bypass" auth — it replaces the entire data layer.
12
+ * The real database is never opened. No Supabase client is created. If someone
13
+ * manually sets the localStorage flag on a real instance, they see an empty or
14
+ * seeded demo DB — there is no path to real user data.
15
+ *
16
+ * Callers of `setDemoMode()` must trigger a **full page reload**
17
+ * (`window.location.href`) to ensure complete engine teardown and
18
+ * reinitialization with the correct database.
19
+ *
20
+ * @module demo
21
+ * @see {@link config.ts} for demo DB name switching in `initEngine()`
22
+ * @see {@link engine.ts} for sync guards that check `isDemoMode()`
23
+ */
24
+ import Dexie from 'dexie';
25
+ /**
26
+ * Configuration for demo mode, provided by the consumer app.
27
+ *
28
+ * Contains a callback to seed mock data and a mock user profile for the
29
+ * demo session. Registered via `initEngine({ demo: demoConfig })`.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const demoConfig: DemoConfig = {
34
+ * seedData: async (db) => {
35
+ * await db.table('items').bulkPut([
36
+ * { id: '1', name: 'Sample Item', ... },
37
+ * ]);
38
+ * },
39
+ * mockProfile: {
40
+ * email: 'demo@example.com',
41
+ * firstName: 'Demo',
42
+ * lastName: 'User',
43
+ * },
44
+ * };
45
+ * ```
46
+ */
47
+ export interface DemoConfig {
48
+ /** Consumer callback that populates the demo Dexie DB with mock data. */
49
+ seedData: (db: Dexie) => Promise<void>;
50
+ /** Mock user profile for the demo session. */
51
+ mockProfile: {
52
+ email: string;
53
+ firstName: string;
54
+ lastName: string;
55
+ [key: string]: unknown;
56
+ };
57
+ }
58
+ /**
59
+ * Check whether demo mode is currently active.
60
+ *
61
+ * SSR-safe: returns `false` on the server (no `localStorage` access).
62
+ *
63
+ * @returns `true` if the demo mode localStorage flag is set.
64
+ */
65
+ export declare function isDemoMode(): boolean;
66
+ /**
67
+ * Activate or deactivate demo mode.
68
+ *
69
+ * Sets a localStorage flag that is read during engine initialization.
70
+ * **The caller must trigger a full page reload** after calling this
71
+ * to ensure the engine reinitializes with the correct (demo or real) database.
72
+ *
73
+ * @param enabled - `true` to enter demo mode, `false` to exit.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * setDemoMode(true);
78
+ * window.location.href = '/';
79
+ * ```
80
+ */
81
+ export declare function setDemoMode(enabled: boolean): void;
82
+ /**
83
+ * Register the demo configuration.
84
+ *
85
+ * Called by `initEngine()` when the consumer provides a `demo` config.
86
+ *
87
+ * @param config - The demo configuration from the consumer app.
88
+ * @internal
89
+ */
90
+ export declare function registerDemoConfig(config: DemoConfig): void;
91
+ /**
92
+ * Get the currently registered demo configuration.
93
+ *
94
+ * @returns The demo config, or `null` if none is registered.
95
+ */
96
+ export declare function getDemoConfig(): DemoConfig | null;
97
+ /**
98
+ * Set the prefix used for the demo mode localStorage key.
99
+ *
100
+ * Called by `initEngine()` to propagate the app prefix.
101
+ *
102
+ * @param prefix - The application prefix (e.g. `'myapp'`).
103
+ * @internal
104
+ */
105
+ export declare function _setDemoPrefix(prefix: string): void;
106
+ /**
107
+ * Seed the demo database with mock data.
108
+ *
109
+ * Idempotent per page load: no-ops if data has already been seeded
110
+ * (prevents re-seeding on SvelteKit client-side navigations).
111
+ *
112
+ * Steps:
113
+ * 1. Check `_demoSeeded` flag — return if already seeded.
114
+ * 2. Clear all app tables (using engine config's table definitions).
115
+ * 3. Clear system tables (`syncQueue`, `conflictHistory`).
116
+ * 4. Call the consumer's `seedData(db)` callback.
117
+ * 5. Set `_demoSeeded = true`.
118
+ *
119
+ * @throws {Error} If no demo config is registered.
120
+ */
121
+ export declare function seedDemoData(): Promise<void>;
122
+ /**
123
+ * Delete the demo Dexie database entirely.
124
+ *
125
+ * Called when deactivating demo mode to clean up the sandboxed database.
126
+ * The caller should trigger a full page reload after this.
127
+ *
128
+ * @param dbName - The name of the demo database to delete (e.g. `'myapp-db_demo'`).
129
+ */
130
+ export declare function cleanupDemoDatabase(dbName: string): Promise<void>;
131
+ //# sourceMappingURL=demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,QAAQ,EAAE,CAAC,EAAE,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,8CAA8C;IAC9C,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAmBD;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAGpC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOlD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAgClD;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE"}
package/dist/demo.js ADDED
@@ -0,0 +1,168 @@
1
+ /**
2
+ * @fileoverview Demo Mode State Module
3
+ *
4
+ * Provides a completely isolated sandbox for consumer PWA apps. When demo mode
5
+ * is active, the app uses a separate Dexie database (`${name}_demo`), makes
6
+ * zero Supabase connections, and skips all sync/auth/email/device-verification
7
+ * flows. Writes go to the sandboxed DB and are dropped on page refresh (mock
8
+ * data is re-seeded).
9
+ *
10
+ * **Security model:**
11
+ * Demo mode does NOT "bypass" auth — it replaces the entire data layer.
12
+ * The real database is never opened. No Supabase client is created. If someone
13
+ * manually sets the localStorage flag on a real instance, they see an empty or
14
+ * seeded demo DB — there is no path to real user data.
15
+ *
16
+ * Callers of `setDemoMode()` must trigger a **full page reload**
17
+ * (`window.location.href`) to ensure complete engine teardown and
18
+ * reinitialization with the correct database.
19
+ *
20
+ * @module demo
21
+ * @see {@link config.ts} for demo DB name switching in `initEngine()`
22
+ * @see {@link engine.ts} for sync guards that check `isDemoMode()`
23
+ */
24
+ import Dexie from 'dexie';
25
+ import { getDb } from './database';
26
+ import { getEngineConfig, getDexieTableFor } from './config';
27
+ // =============================================================================
28
+ // Module State
29
+ // =============================================================================
30
+ /** The registered demo configuration (set via `registerDemoConfig`). */
31
+ let _demoConfig = null;
32
+ /** Whether demo data has been seeded in this page load (prevents re-seeding). */
33
+ let _demoSeeded = false;
34
+ /** The app prefix, used to namespace the localStorage demo flag. */
35
+ let _demoPrefix = '';
36
+ // =============================================================================
37
+ // Public API
38
+ // =============================================================================
39
+ /**
40
+ * Check whether demo mode is currently active.
41
+ *
42
+ * SSR-safe: returns `false` on the server (no `localStorage` access).
43
+ *
44
+ * @returns `true` if the demo mode localStorage flag is set.
45
+ */
46
+ export function isDemoMode() {
47
+ if (typeof localStorage === 'undefined')
48
+ return false;
49
+ return localStorage.getItem(`${_demoPrefix}_demo_mode`) === 'true';
50
+ }
51
+ /**
52
+ * Activate or deactivate demo mode.
53
+ *
54
+ * Sets a localStorage flag that is read during engine initialization.
55
+ * **The caller must trigger a full page reload** after calling this
56
+ * to ensure the engine reinitializes with the correct (demo or real) database.
57
+ *
58
+ * @param enabled - `true` to enter demo mode, `false` to exit.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * setDemoMode(true);
63
+ * window.location.href = '/';
64
+ * ```
65
+ */
66
+ export function setDemoMode(enabled) {
67
+ if (typeof localStorage === 'undefined')
68
+ return;
69
+ if (enabled) {
70
+ localStorage.setItem(`${_demoPrefix}_demo_mode`, 'true');
71
+ }
72
+ else {
73
+ localStorage.removeItem(`${_demoPrefix}_demo_mode`);
74
+ }
75
+ }
76
+ /**
77
+ * Register the demo configuration.
78
+ *
79
+ * Called by `initEngine()` when the consumer provides a `demo` config.
80
+ *
81
+ * @param config - The demo configuration from the consumer app.
82
+ * @internal
83
+ */
84
+ export function registerDemoConfig(config) {
85
+ _demoConfig = config;
86
+ }
87
+ /**
88
+ * Get the currently registered demo configuration.
89
+ *
90
+ * @returns The demo config, or `null` if none is registered.
91
+ */
92
+ export function getDemoConfig() {
93
+ return _demoConfig;
94
+ }
95
+ /**
96
+ * Set the prefix used for the demo mode localStorage key.
97
+ *
98
+ * Called by `initEngine()` to propagate the app prefix.
99
+ *
100
+ * @param prefix - The application prefix (e.g. `'myapp'`).
101
+ * @internal
102
+ */
103
+ export function _setDemoPrefix(prefix) {
104
+ _demoPrefix = prefix;
105
+ }
106
+ /**
107
+ * Seed the demo database with mock data.
108
+ *
109
+ * Idempotent per page load: no-ops if data has already been seeded
110
+ * (prevents re-seeding on SvelteKit client-side navigations).
111
+ *
112
+ * Steps:
113
+ * 1. Check `_demoSeeded` flag — return if already seeded.
114
+ * 2. Clear all app tables (using engine config's table definitions).
115
+ * 3. Clear system tables (`syncQueue`, `conflictHistory`).
116
+ * 4. Call the consumer's `seedData(db)` callback.
117
+ * 5. Set `_demoSeeded = true`.
118
+ *
119
+ * @throws {Error} If no demo config is registered.
120
+ */
121
+ export async function seedDemoData() {
122
+ if (_demoSeeded)
123
+ return;
124
+ if (!_demoConfig) {
125
+ throw new Error('No demo config registered. Pass `demo` to initEngine().');
126
+ }
127
+ const db = getDb();
128
+ const config = getEngineConfig();
129
+ /* Clear all app tables */
130
+ for (const table of config.tables) {
131
+ const dexieName = getDexieTableFor(table);
132
+ try {
133
+ await db.table(dexieName).clear();
134
+ }
135
+ catch {
136
+ /* Table may not exist in the demo DB — safe to ignore. */
137
+ }
138
+ }
139
+ /* Clear system tables */
140
+ for (const systemTable of ['syncQueue', 'conflictHistory']) {
141
+ try {
142
+ await db.table(systemTable).clear();
143
+ }
144
+ catch {
145
+ /* Safe to ignore if table doesn't exist. */
146
+ }
147
+ }
148
+ /* Call consumer's seed function */
149
+ await _demoConfig.seedData(db);
150
+ _demoSeeded = true;
151
+ }
152
+ /**
153
+ * Delete the demo Dexie database entirely.
154
+ *
155
+ * Called when deactivating demo mode to clean up the sandboxed database.
156
+ * The caller should trigger a full page reload after this.
157
+ *
158
+ * @param dbName - The name of the demo database to delete (e.g. `'myapp-db_demo'`).
159
+ */
160
+ export async function cleanupDemoDatabase(dbName) {
161
+ try {
162
+ await Dexie.delete(dbName);
163
+ }
164
+ catch {
165
+ /* Ignore deletion errors — the DB may not exist. */
166
+ }
167
+ }
168
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAyC7D,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF,wEAAwE;AACxE,IAAI,WAAW,GAAsB,IAAI,CAAC;AAE1C,iFAAiF;AACjF,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,oEAAoE;AACpE,IAAI,WAAW,GAAG,EAAE,CAAC;AAErB,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,OAAO,YAAY,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACtD,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,WAAW,YAAY,CAAC,KAAK,MAAM,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,IAAI,OAAO,YAAY,KAAK,WAAW;QAAE,OAAO;IAChD,IAAI,OAAO,EAAE,CAAC;QACZ,YAAY,CAAC,OAAO,CAAC,GAAG,WAAW,YAAY,EAAE,MAAM,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,YAAY,CAAC,UAAU,CAAC,GAAG,WAAW,YAAY,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAkB;IACnD,WAAW,GAAG,MAAM,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,WAAW,GAAG,MAAM,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,WAAW;QAAE,OAAO;IACxB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IAEjC,0BAA0B;IAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,0DAA0D;QAC5D,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,KAAK,MAAM,WAAW,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,MAAM,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAE/B,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAc;IACtD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;AACH,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @fileoverview Stable Device Identifier Management
3
+ *
4
+ * Generates and persists a unique device identifier in localStorage. The ID
5
+ * survives page reloads and browser restarts, providing a stable "fingerprint"
6
+ * for the current browser profile.
7
+ *
8
+ * The device ID serves two critical roles in the sync engine:
9
+ * 1. **Echo suppression** — Realtime subscription payloads include `device_id`,
10
+ * allowing the engine to skip changes that originated from this device.
11
+ * 2. **Deterministic conflict tiebreaker** — When two operations have identical
12
+ * timestamps, the lexicographically lower `device_id` wins. This ensures
13
+ * all devices resolve the same conflict the same way.
14
+ *
15
+ * The localStorage key is prefixed (e.g., `myapp_device_id`) so multiple engine
16
+ * instances on the same origin don't collide.
17
+ *
18
+ * @see {@link conflicts.ts#resolveByTimestamp} for the tiebreaker logic
19
+ * @see {@link realtime.ts#isOwnDeviceChange} for echo suppression
20
+ */
21
+ /**
22
+ * Set the prefix used for the localStorage device ID key.
23
+ *
24
+ * Called internally by {@link config.ts#initEngine} — not part of the
25
+ * public API.
26
+ *
27
+ * @param prefix - Application-specific prefix (e.g., `'myapp'`).
28
+ * @internal
29
+ */
30
+ export declare function _setDeviceIdPrefix(prefix: string): void;
31
+ /**
32
+ * Get or create a stable device identifier for this browser/device.
33
+ *
34
+ * On the first call, generates a random UUID v4 and persists it to
35
+ * localStorage. Subsequent calls return the cached value.
36
+ *
37
+ * Returns `'ssr-placeholder'` in SSR contexts (no localStorage) — the
38
+ * placeholder is never used for real sync operations since the engine
39
+ * only runs client-side.
40
+ *
41
+ * @returns A UUID v4 string identifying this device.
42
+ *
43
+ * @example
44
+ * const id = getDeviceId(); // e.g., "a3f2b1c4-..."
45
+ */
46
+ export declare function getDeviceId(): string;
47
+ //# sourceMappingURL=deviceId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceId.d.ts","sourceRoot":"","sources":["../src/deviceId.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAaH;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,QAEhD;AAeD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAcpC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @fileoverview Stable Device Identifier Management
3
+ *
4
+ * Generates and persists a unique device identifier in localStorage. The ID
5
+ * survives page reloads and browser restarts, providing a stable "fingerprint"
6
+ * for the current browser profile.
7
+ *
8
+ * The device ID serves two critical roles in the sync engine:
9
+ * 1. **Echo suppression** — Realtime subscription payloads include `device_id`,
10
+ * allowing the engine to skip changes that originated from this device.
11
+ * 2. **Deterministic conflict tiebreaker** — When two operations have identical
12
+ * timestamps, the lexicographically lower `device_id` wins. This ensures
13
+ * all devices resolve the same conflict the same way.
14
+ *
15
+ * The localStorage key is prefixed (e.g., `myapp_device_id`) so multiple engine
16
+ * instances on the same origin don't collide.
17
+ *
18
+ * @see {@link conflicts.ts#resolveByTimestamp} for the tiebreaker logic
19
+ * @see {@link realtime.ts#isOwnDeviceChange} for echo suppression
20
+ */
21
+ // =============================================================================
22
+ // Internal State
23
+ // =============================================================================
24
+ /** Configurable prefix for the localStorage key (default: `'stellar'`). */
25
+ let _deviceIdPrefix = 'stellar';
26
+ // =============================================================================
27
+ // Internal Helpers
28
+ // =============================================================================
29
+ /**
30
+ * Set the prefix used for the localStorage device ID key.
31
+ *
32
+ * Called internally by {@link config.ts#initEngine} — not part of the
33
+ * public API.
34
+ *
35
+ * @param prefix - Application-specific prefix (e.g., `'myapp'`).
36
+ * @internal
37
+ */
38
+ export function _setDeviceIdPrefix(prefix) {
39
+ _deviceIdPrefix = prefix;
40
+ }
41
+ /**
42
+ * Build the full localStorage key for the device ID.
43
+ *
44
+ * @returns The prefixed key string (e.g., `'myapp_device_id'`).
45
+ */
46
+ function getDeviceIdKey() {
47
+ return `${_deviceIdPrefix}_device_id`;
48
+ }
49
+ // =============================================================================
50
+ // Public API
51
+ // =============================================================================
52
+ /**
53
+ * Get or create a stable device identifier for this browser/device.
54
+ *
55
+ * On the first call, generates a random UUID v4 and persists it to
56
+ * localStorage. Subsequent calls return the cached value.
57
+ *
58
+ * Returns `'ssr-placeholder'` in SSR contexts (no localStorage) — the
59
+ * placeholder is never used for real sync operations since the engine
60
+ * only runs client-side.
61
+ *
62
+ * @returns A UUID v4 string identifying this device.
63
+ *
64
+ * @example
65
+ * const id = getDeviceId(); // e.g., "a3f2b1c4-..."
66
+ */
67
+ export function getDeviceId() {
68
+ if (typeof localStorage === 'undefined') {
69
+ /* SSR context — return a placeholder that won't be used for sync. */
70
+ return 'ssr-placeholder';
71
+ }
72
+ let deviceId = localStorage.getItem(getDeviceIdKey());
73
+ if (!deviceId) {
74
+ deviceId = generateUUID();
75
+ localStorage.setItem(getDeviceIdKey(), deviceId);
76
+ }
77
+ return deviceId;
78
+ }
79
+ // =============================================================================
80
+ // UUID Generation
81
+ // =============================================================================
82
+ /**
83
+ * Generate a UUID v4 (random UUID).
84
+ *
85
+ * Prefers the native `crypto.randomUUID()` API (available in modern browsers
86
+ * and Node 19+). Falls back to a manual implementation using `Math.random()`
87
+ * for older environments.
88
+ *
89
+ * @returns A lowercase UUID v4 string (e.g., `"550e8400-e29b-41d4-a716-446655440000"`).
90
+ */
91
+ function generateUUID() {
92
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
93
+ return crypto.randomUUID();
94
+ }
95
+ /*
96
+ * Fallback for older browsers that lack crypto.randomUUID().
97
+ * Replaces 'x' with a random hex digit and 'y' with a digit
98
+ * constrained to the UUID v4 variant bits (8, 9, a, or b).
99
+ */
100
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
101
+ const r = (Math.random() * 16) | 0;
102
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
103
+ return v.toString(16);
104
+ });
105
+ }
106
+ //# sourceMappingURL=deviceId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceId.js","sourceRoot":"","sources":["../src/deviceId.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF,2EAA2E;AAC3E,IAAI,eAAe,GAAG,SAAS,CAAC;AAEhC,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,eAAe,GAAG,MAAM,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc;IACrB,OAAO,GAAG,eAAe,YAAY,CAAC;AACxC,CAAC;AAED,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE,CAAC;QACxC,qEAAqE;QACrE,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,IAAI,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAEtD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,YAAY,EAAE,CAAC;QAC1B,YAAY,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,SAAS,YAAY;IACnB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC"}