@vielzeug/sourcerer 1.0.6 → 2.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 (152) hide show
  1. package/README.md +19 -74
  2. package/dist/_dev.cjs +2 -0
  3. package/dist/_dev.cjs.map +1 -0
  4. package/dist/_dev.d.ts +2 -0
  5. package/dist/_dev.d.ts.map +1 -0
  6. package/dist/_dev.js +6 -0
  7. package/dist/_dev.js.map +1 -0
  8. package/dist/asyncSource.cjs +1 -1
  9. package/dist/asyncSource.cjs.map +1 -1
  10. package/dist/asyncSource.d.ts +14 -58
  11. package/dist/asyncSource.d.ts.map +1 -1
  12. package/dist/asyncSource.js +28 -27
  13. package/dist/asyncSource.js.map +1 -1
  14. package/dist/cursorSource.cjs +1 -1
  15. package/dist/cursorSource.cjs.map +1 -1
  16. package/dist/cursorSource.d.ts +3 -3
  17. package/dist/cursorSource.d.ts.map +1 -1
  18. package/dist/cursorSource.js +77 -110
  19. package/dist/cursorSource.js.map +1 -1
  20. package/dist/devtools.cjs +2 -0
  21. package/dist/devtools.cjs.map +1 -0
  22. package/dist/devtools.d.ts +6 -0
  23. package/dist/devtools.d.ts.map +1 -0
  24. package/dist/devtools.js +8 -0
  25. package/dist/devtools.js.map +1 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.d.ts +2 -12
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +5 -14
  30. package/dist/infiniteSource.cjs +1 -1
  31. package/dist/infiniteSource.cjs.map +1 -1
  32. package/dist/infiniteSource.d.ts +3 -3
  33. package/dist/infiniteSource.d.ts.map +1 -1
  34. package/dist/infiniteSource.js +72 -107
  35. package/dist/infiniteSource.js.map +1 -1
  36. package/dist/localSource.cjs +1 -1
  37. package/dist/localSource.cjs.map +1 -1
  38. package/dist/localSource.d.ts +2 -22
  39. package/dist/localSource.d.ts.map +1 -1
  40. package/dist/localSource.js +58 -114
  41. package/dist/localSource.js.map +1 -1
  42. package/dist/pageSource.cjs +2 -0
  43. package/dist/pageSource.cjs.map +1 -0
  44. package/dist/pageSource.d.ts +4 -0
  45. package/dist/pageSource.d.ts.map +1 -0
  46. package/dist/pageSource.js +96 -0
  47. package/dist/pageSource.js.map +1 -0
  48. package/dist/pagination.cjs +1 -1
  49. package/dist/pagination.cjs.map +1 -1
  50. package/dist/pagination.d.ts +5 -30
  51. package/dist/pagination.d.ts.map +1 -1
  52. package/dist/pagination.js +21 -27
  53. package/dist/pagination.js.map +1 -1
  54. package/dist/requestController.cjs +2 -0
  55. package/dist/requestController.cjs.map +1 -0
  56. package/dist/requestController.d.ts +13 -0
  57. package/dist/requestController.d.ts.map +1 -0
  58. package/dist/requestController.js +29 -0
  59. package/dist/requestController.js.map +1 -0
  60. package/dist/sourceStore.cjs +2 -0
  61. package/dist/sourceStore.cjs.map +1 -0
  62. package/dist/sourceStore.d.ts +10 -0
  63. package/dist/sourceStore.d.ts.map +1 -0
  64. package/dist/sourceStore.js +38 -0
  65. package/dist/sourceStore.js.map +1 -0
  66. package/dist/sourcerer.cjs +1 -1
  67. package/dist/sourcerer.cjs.map +1 -1
  68. package/dist/sourcerer.iife.js +1 -1
  69. package/dist/sourcerer.iife.js.map +1 -1
  70. package/dist/sourcerer.js +1 -1
  71. package/dist/sourcerer.js.map +1 -1
  72. package/dist/types.d.ts +128 -345
  73. package/dist/types.d.ts.map +1 -1
  74. package/package.json +10 -7
  75. package/dist/_utils.cjs +0 -2
  76. package/dist/_utils.cjs.map +0 -1
  77. package/dist/_utils.d.ts +0 -8
  78. package/dist/_utils.d.ts.map +0 -1
  79. package/dist/_utils.js +0 -7
  80. package/dist/_utils.js.map +0 -1
  81. package/dist/applyQuery.cjs +0 -2
  82. package/dist/applyQuery.cjs.map +0 -1
  83. package/dist/applyQuery.d.ts +0 -20
  84. package/dist/applyQuery.d.ts.map +0 -1
  85. package/dist/applyQuery.js +0 -8
  86. package/dist/applyQuery.js.map +0 -1
  87. package/dist/asyncSearch.cjs +0 -2
  88. package/dist/asyncSearch.cjs.map +0 -1
  89. package/dist/asyncSearch.d.ts +0 -13
  90. package/dist/asyncSearch.d.ts.map +0 -1
  91. package/dist/asyncSearch.js +0 -28
  92. package/dist/asyncSearch.js.map +0 -1
  93. package/dist/codecs.cjs +0 -2
  94. package/dist/codecs.cjs.map +0 -1
  95. package/dist/codecs.d.ts +0 -30
  96. package/dist/codecs.d.ts.map +0 -1
  97. package/dist/codecs.js +0 -36
  98. package/dist/codecs.js.map +0 -1
  99. package/dist/core.cjs +0 -2
  100. package/dist/core.cjs.map +0 -1
  101. package/dist/core.d.ts +0 -47
  102. package/dist/core.d.ts.map +0 -1
  103. package/dist/core.js +0 -59
  104. package/dist/core.js.map +0 -1
  105. package/dist/derive.cjs +0 -2
  106. package/dist/derive.cjs.map +0 -1
  107. package/dist/derive.d.ts +0 -28
  108. package/dist/derive.d.ts.map +0 -1
  109. package/dist/derive.js +0 -40
  110. package/dist/derive.js.map +0 -1
  111. package/dist/errors.cjs +0 -2
  112. package/dist/errors.cjs.map +0 -1
  113. package/dist/errors.d.ts +0 -62
  114. package/dist/errors.d.ts.map +0 -1
  115. package/dist/errors.js +0 -29
  116. package/dist/errors.js.map +0 -1
  117. package/dist/fetchManager.cjs +0 -2
  118. package/dist/fetchManager.cjs.map +0 -1
  119. package/dist/fetchManager.d.ts +0 -27
  120. package/dist/fetchManager.d.ts.map +0 -1
  121. package/dist/fetchManager.js +0 -41
  122. package/dist/fetchManager.js.map +0 -1
  123. package/dist/merge.cjs +0 -2
  124. package/dist/merge.cjs.map +0 -1
  125. package/dist/merge.d.ts +0 -30
  126. package/dist/merge.d.ts.map +0 -1
  127. package/dist/merge.js +0 -34
  128. package/dist/merge.js.map +0 -1
  129. package/dist/prefetch.cjs +0 -2
  130. package/dist/prefetch.cjs.map +0 -1
  131. package/dist/prefetch.d.ts +0 -32
  132. package/dist/prefetch.d.ts.map +0 -1
  133. package/dist/prefetch.js +0 -38
  134. package/dist/prefetch.js.map +0 -1
  135. package/dist/presets.cjs +0 -2
  136. package/dist/presets.cjs.map +0 -1
  137. package/dist/presets.d.ts +0 -17
  138. package/dist/presets.d.ts.map +0 -1
  139. package/dist/presets.js +0 -43
  140. package/dist/presets.js.map +0 -1
  141. package/dist/remoteSource.cjs +0 -2
  142. package/dist/remoteSource.cjs.map +0 -1
  143. package/dist/remoteSource.d.ts +0 -4
  144. package/dist/remoteSource.d.ts.map +0 -1
  145. package/dist/remoteSource.js +0 -165
  146. package/dist/remoteSource.js.map +0 -1
  147. package/dist/state.cjs +0 -2
  148. package/dist/state.cjs.map +0 -1
  149. package/dist/state.d.ts +0 -23
  150. package/dist/state.d.ts.map +0 -1
  151. package/dist/state.js +0 -14
  152. package/dist/state.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"remoteSource.js","names":[],"sources":["../src/remoteSource.ts"],"sourcesContent":["import type { RemoteConfig, RemoteSource, RemoteSourceQuery, SearchOptions } from './types';\n\nimport { defaultKeyOf, extractError, retry } from './_utils';\nimport { createAsyncSearchCoordinator } from './asyncSearch';\nimport { createAsyncSource } from './asyncSource';\nimport { SourcererError } from './errors';\nimport { clampPage, createMeta, pageCount } from './pagination';\n\n/** Creates a remote page-based source that fetches data from a network endpoint. */\nexport function createRemoteSource<T, TFilter = unknown, TSort = unknown>(\n cfg: RemoteConfig<T, TFilter, TSort>,\n): RemoteSource<T, TFilter, TSort> {\n const keyOf = cfg.queryKey ?? defaultKeyOf;\n\n // ── Config defaults ─────────────────────────────────────────────────────────\n const staleTimeMs = cfg.staleTime ?? 0;\n\n // ── Mutable state ───────────────────────────────────────────────────────────\n let limit = Math.max(1, Math.trunc(cfg.limit ?? 20));\n let page = 1;\n let search = '';\n let filter: TFilter | undefined = cfg.filter;\n let sort: TSort | undefined = cfg.sort;\n let items: readonly T[] = [];\n let total = 0;\n let error: SourcererError | null = null;\n let lastFetchTime = 0;\n let lastFetchKey = '';\n\n // Optimistic update state.\n let optimistic: { active: boolean; prevItems: readonly T[]; prevTotal: number } | null = null;\n\n // ── Snapshot pre-population ─────────────────────────────────────────────────\n if (cfg.snapshot) {\n items = cfg.snapshot.items;\n total = cfg.snapshot.total;\n\n if (cfg.snapshot.page !== undefined) page = cfg.snapshot.page;\n\n if (cfg.snapshot.search) search = cfg.snapshot.search;\n\n lastFetchTime = Date.now();\n }\n\n // ── Cached accessors ────────────────────────────────────────────────────────\n let cachedCurrent: readonly T[] = [];\n let cachedMeta = createMeta({\n error: null,\n isLoading: false,\n isSearchPending: false,\n pageNumber: 1,\n pageSize: limit,\n totalItems: 0,\n });\n\n const refreshMeta = () => {\n const pages = pageCount(total, limit);\n const safePage = clampPage(page, pages);\n\n // items is already the current page from the server — no local slicing needed.\n cachedCurrent = items;\n cachedMeta = createMeta({\n error,\n isLoading: base.pendingCount() > 0,\n isSearchPending: base.core.isScheduled,\n pageNumber: safePage,\n pageSize: limit,\n totalItems: total,\n });\n };\n\n // onBeforeNotify ensures refreshMeta() runs before any subscriber observes the new state,\n // eliminating the need for a parallel listeners Set.\n const base = createAsyncSource<RemoteSourceQuery<TFilter, TSort>>(cfg, keyOf, refreshMeta);\n const { autoFetch, debounceMs, retryAttempts, retryDelay } = base;\n\n // Initialise cache before first fetch.\n refreshMeta();\n\n const notifyListeners = () => {\n if (base.disposed) return;\n\n base.core.notify();\n };\n const searchCoordinator = createAsyncSearchCoordinator(base.core, notifyListeners);\n\n // ── Assign result ───────────────────────────────────────────────────────────\n const assign = (result: Readonly<{ items: readonly T[]; total: number }>) => {\n if (optimistic?.active) {\n optimistic.active = false;\n optimistic = null;\n }\n\n items = result.items;\n total = result.total;\n page = clampPage(page, pageCount(total, limit));\n };\n\n // ── Core fetch ──────────────────────────────────────────────────────────────\n const toRemoteQuery = (): RemoteSourceQuery<TFilter, TSort> => ({\n ...(filter !== undefined && { filter }),\n ...(sort !== undefined && { sort }),\n ...(search && { search }),\n limit,\n page,\n });\n\n const fetchQuery = (q: RemoteSourceQuery<TFilter, TSort>): Promise<void> => {\n const key = keyOf(q);\n\n if (\n staleTimeMs > 0 &&\n key === lastFetchKey &&\n total > 0 &&\n Date.now() - lastFetchTime < staleTimeMs &&\n !optimistic?.active\n ) {\n return Promise.resolve();\n }\n\n error = null;\n\n return base.fetch(\n q,\n async (q: RemoteSourceQuery<TFilter, TSort>, signal, isLatest) => {\n const startTime = Date.now();\n\n try {\n const result = await retry((sig) => cfg.fetch(q, sig!), {\n delay: retryDelay,\n signal,\n times: retryAttempts + 1,\n });\n\n if (isLatest()) {\n assign(result);\n error = null;\n lastFetchKey = key;\n lastFetchTime = Date.now();\n cfg.onFetch?.({ durationMs: Date.now() - startTime, query: q, status: 'success' });\n }\n } catch (reason: unknown) {\n if (signal.aborted) return;\n\n if (isLatest()) {\n if (optimistic?.active) {\n optimistic.active = false;\n items = optimistic.prevItems;\n total = optimistic.prevTotal;\n optimistic = null;\n } else {\n items = [];\n total = 0;\n }\n\n error = new SourcererError(extractError(reason), {\n cause: reason,\n context: { kind: 'remote', limit: q.limit, page: q.page, ...(q.search && { search: q.search }) },\n });\n cfg.onFetch?.({ durationMs: Date.now() - startTime, error, query: q, status: 'error' });\n }\n }\n },\n () => {\n notifyListeners();\n\n searchCoordinator.settleIfIdle(base.pendingCount());\n },\n );\n };\n\n const doUpdate = () => fetchQuery(toRemoteQuery());\n\n // ── Auto-fetch + refresh interval ───────────────────────────────────────────\n if (autoFetch) void doUpdate();\n\n base.startRefreshInterval(() => void doUpdate());\n\n // ── Public API ──────────────────────────────────────────────────────────────\n return {\n get current() {\n return cachedCurrent;\n },\n\n get disposalSignal() {\n return base.disposalSignal;\n },\n\n dispose: () => {\n searchCoordinator.cancel();\n searchCoordinator.dispose();\n base.dispose();\n },\n\n get disposed() {\n return base.disposed;\n },\n\n goTo(target) {\n const clamped = total > 0 ? clampPage(target, pageCount(total, limit)) : Math.max(1, Math.trunc(target));\n\n if (clamped === page) return Promise.resolve();\n\n page = clamped;\n\n return doUpdate();\n },\n\n goToLast() {\n const last = pageCount(total, limit);\n\n if (page === last) return Promise.resolve();\n\n page = last;\n\n return doUpdate();\n },\n\n get meta() {\n return cachedMeta;\n },\n\n next() {\n const pages = pageCount(total, limit);\n\n if (page >= pages) return Promise.resolve();\n\n page++;\n\n return doUpdate();\n },\n\n optimisticUpdate(mutator, options) {\n if (optimistic?.active) {\n throw new SourcererError(\n 'An optimistic update is already active. Rollback the previous update before starting another.',\n );\n }\n\n const prevItems = items;\n const prevTotal = total;\n\n optimistic = { active: true, prevItems, prevTotal };\n\n try {\n items = mutator(items);\n } catch (e: unknown) {\n optimistic = null;\n throw e;\n }\n\n total = options?.total ?? total;\n notifyListeners();\n\n return () => {\n if (optimistic?.active) {\n optimistic.active = false;\n items = prevItems;\n total = prevTotal;\n optimistic = null;\n notifyListeners();\n }\n };\n },\n\n patch(changes) {\n let changed = false;\n\n if (changes.limit !== undefined) {\n const next = Math.max(1, Math.trunc(changes.limit));\n\n if (next !== limit) {\n limit = next;\n changed = true;\n }\n }\n\n if ('filter' in changes) {\n filter = changes.filter;\n changed = true;\n }\n\n if ('sort' in changes) {\n sort = changes.sort;\n changed = true;\n }\n\n // `|| base.core.isScheduled` also catches patching in the same search text as an already-pending\n // debounced search() call — that still needs flushing, not silently dropping as a no-op.\n if ('search' in changes && (changes.search !== search || base.core.isScheduled)) {\n search = changes.search ?? '';\n changed = true;\n }\n\n if (changes.page !== undefined) {\n const next =\n total > 0 ? clampPage(changes.page, pageCount(total, limit)) : Math.max(1, Math.trunc(changes.page));\n\n if (next !== page) {\n page = next;\n changed = true;\n }\n }\n\n if (!changed) return Promise.resolve();\n\n // patch() is documented as a single atomic fetch — cancel any debounced search()\n // still pending so it doesn't fire a second, redundant fetch afterwards.\n searchCoordinator.cancel();\n\n // Reset to page 1 when non-page query fields changed without explicit page\n if (\n (changes.limit !== undefined || 'filter' in changes || 'sort' in changes || 'search' in changes) &&\n changes.page === undefined\n ) {\n page = 1;\n }\n\n return doUpdate();\n },\n\n prev() {\n if (page <= 1) return Promise.resolve();\n\n page--;\n\n return doUpdate();\n },\n\n get query() {\n return {\n ...(filter !== undefined && { filter }),\n ...(sort !== undefined && { sort }),\n ...(search && { search }),\n limit,\n page,\n };\n },\n\n ready(timeout) {\n return base.ready(timeout);\n },\n\n refresh() {\n return doUpdate();\n },\n\n reset() {\n searchCoordinator.cancel();\n search = '';\n page = 1;\n filter = cfg.filter;\n sort = cfg.sort;\n\n return doUpdate();\n },\n\n search(q, opts?: SearchOptions): Promise<void> {\n if (opts?.immediate) {\n // A pending debounced search for this same text still needs flushing —\n // `q === search` alone doesn't mean the fetch already happened.\n if (q === search && !base.core.isScheduled) return Promise.resolve();\n\n searchCoordinator.cancel();\n search = q;\n page = 1;\n\n return doUpdate();\n }\n\n if (q === search) return Promise.resolve();\n\n search = q;\n page = 1;\n\n return searchCoordinator.schedule(() => void doUpdate(), debounceMs);\n },\n\n subscribe: (listener) => base.core.subscribe(listener),\n\n [Symbol.dispose]: () => {\n searchCoordinator.cancel();\n searchCoordinator.dispose();\n base.dispose();\n },\n };\n}\n"],"mappings":"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"}
package/dist/state.cjs DELETED
@@ -1,2 +0,0 @@
1
- function e(e){return e.meta.isLoading||e.meta.isSearchPending?{status:`loading`}:e.meta.error?{error:e.meta.error,status:`error`}:{items:e.current,status:`success`}}exports.sourceState=e;
2
- //# sourceMappingURL=state.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.cjs","names":[],"sources":["../src/state.ts"],"sourcesContent":["import type { SourcererError, SourceState } from './types';\n\n/**\n * Derives a `SourceState<T>` discriminated union from a reactive source.\n * Works with any object that exposes `current`, `meta.isLoading`, `meta.error`, and optionally `meta.isSearchPending`.\n * Returns `'loading'` when `isLoading` or `isSearchPending` is true, so callers see a spinner during debounce windows.\n *\n * @example\n * ```ts\n * const state = sourceState(source);\n * if (state.status === 'loading') return <Spinner />;\n * if (state.status === 'error') return <p>{state.error.message}</p>;\n * return <List items={state.items} />;\n * ```\n */\nexport function sourceState<T>(source: {\n readonly current: readonly T[];\n readonly meta: {\n readonly error: SourcererError | null;\n readonly isLoading: boolean;\n readonly isSearchPending?: boolean;\n };\n}): SourceState<T> {\n if (source.meta.isLoading || source.meta.isSearchPending) return { status: 'loading' };\n\n if (source.meta.error) return { error: source.meta.error, status: 'error' };\n\n return { items: source.current, status: 'success' };\n}\n"],"mappings":"AAeA,SAAgB,EAAe,EAOZ,CAKjB,OAJI,EAAO,KAAK,WAAa,EAAO,KAAK,gBAAwB,CAAE,OAAQ,SAAU,EAEjF,EAAO,KAAK,MAAc,CAAE,MAAO,EAAO,KAAK,MAAO,OAAQ,OAAQ,EAEnE,CAAE,MAAO,EAAO,QAAS,OAAQ,SAAU,CACpD"}
package/dist/state.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import type { SourcererError, SourceState } from './types';
2
- /**
3
- * Derives a `SourceState<T>` discriminated union from a reactive source.
4
- * Works with any object that exposes `current`, `meta.isLoading`, `meta.error`, and optionally `meta.isSearchPending`.
5
- * Returns `'loading'` when `isLoading` or `isSearchPending` is true, so callers see a spinner during debounce windows.
6
- *
7
- * @example
8
- * ```ts
9
- * const state = sourceState(source);
10
- * if (state.status === 'loading') return <Spinner />;
11
- * if (state.status === 'error') return <p>{state.error.message}</p>;
12
- * return <List items={state.items} />;
13
- * ```
14
- */
15
- export declare function sourceState<T>(source: {
16
- readonly current: readonly T[];
17
- readonly meta: {
18
- readonly error: SourcererError | null;
19
- readonly isLoading: boolean;
20
- readonly isSearchPending?: boolean;
21
- };
22
- }): SourceState<T>;
23
- //# sourceMappingURL=state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;QACtC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;KACpC,CAAC;CACH,GAAG,WAAW,CAAC,CAAC,CAAC,CAMjB"}
package/dist/state.js DELETED
@@ -1,14 +0,0 @@
1
- //#region src/state.ts
2
- function e(e) {
3
- return e.meta.isLoading || e.meta.isSearchPending ? { status: "loading" } : e.meta.error ? {
4
- error: e.meta.error,
5
- status: "error"
6
- } : {
7
- items: e.current,
8
- status: "success"
9
- };
10
- }
11
- //#endregion
12
- export { e as sourceState };
13
-
14
- //# sourceMappingURL=state.js.map
package/dist/state.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.js","names":[],"sources":["../src/state.ts"],"sourcesContent":["import type { SourcererError, SourceState } from './types';\n\n/**\n * Derives a `SourceState<T>` discriminated union from a reactive source.\n * Works with any object that exposes `current`, `meta.isLoading`, `meta.error`, and optionally `meta.isSearchPending`.\n * Returns `'loading'` when `isLoading` or `isSearchPending` is true, so callers see a spinner during debounce windows.\n *\n * @example\n * ```ts\n * const state = sourceState(source);\n * if (state.status === 'loading') return <Spinner />;\n * if (state.status === 'error') return <p>{state.error.message}</p>;\n * return <List items={state.items} />;\n * ```\n */\nexport function sourceState<T>(source: {\n readonly current: readonly T[];\n readonly meta: {\n readonly error: SourcererError | null;\n readonly isLoading: boolean;\n readonly isSearchPending?: boolean;\n };\n}): SourceState<T> {\n if (source.meta.isLoading || source.meta.isSearchPending) return { status: 'loading' };\n\n if (source.meta.error) return { error: source.meta.error, status: 'error' };\n\n return { items: source.current, status: 'success' };\n}\n"],"mappings":";AAeA,SAAgB,EAAe,GAOZ;CAKjB,OAJI,EAAO,KAAK,aAAa,EAAO,KAAK,kBAAwB,EAAE,QAAQ,UAAU,IAEjF,EAAO,KAAK,QAAc;EAAE,OAAO,EAAO,KAAK;EAAO,QAAQ;CAAQ,IAEnE;EAAE,OAAO,EAAO;EAAS,QAAQ;CAAU;AACpD"}