gemi 0.52.0 → 0.54.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 (244) hide show
  1. package/dist/app/index.js +2 -2
  2. package/dist/app/index.js.map +1 -1
  3. package/dist/bin/gemi.js +1456 -5
  4. package/dist/bin/gemi.js.map +9 -5
  5. package/dist/broadcasting/index.js +1 -1
  6. package/dist/bun/plugin.js +2 -2
  7. package/dist/bun/plugin.js.map +1 -1
  8. package/dist/bun/preload.js +2 -2
  9. package/dist/bun/preload.js.map +1 -1
  10. package/dist/{chunk-msz8rngs.js → chunk-004bcmsa.js} +2 -2
  11. package/dist/chunk-004bcmsa.js.map +10 -0
  12. package/dist/chunk-07t0dmdg.js +4 -0
  13. package/dist/{chunk-faa987e4.js.map → chunk-07t0dmdg.js.map} +2 -2
  14. package/dist/{chunk-4t6a82fh.js → chunk-0weeq0ke.js} +2 -2
  15. package/dist/{chunk-4t6a82fh.js.map → chunk-0weeq0ke.js.map} +1 -1
  16. package/dist/chunk-113khwbw.js +5 -0
  17. package/dist/{chunk-2qn472j4.js.map → chunk-113khwbw.js.map} +1 -1
  18. package/dist/{chunk-tmk4zfz9.js → chunk-1sh6kqjn.js} +3 -3
  19. package/dist/{chunk-tmk4zfz9.js.map → chunk-1sh6kqjn.js.map} +1 -1
  20. package/dist/{chunk-2gw6cyyj.js → chunk-1snh7yc4.js} +2 -2
  21. package/dist/{chunk-2gw6cyyj.js.map → chunk-1snh7yc4.js.map} +1 -1
  22. package/dist/chunk-26r8dcxd.js +6 -0
  23. package/dist/{chunk-hbycemy5.js.map → chunk-26r8dcxd.js.map} +2 -2
  24. package/dist/{chunk-ebcgdv00.js → chunk-2pt6kyn9.js} +3 -3
  25. package/dist/{chunk-ebcgdv00.js.map → chunk-2pt6kyn9.js.map} +1 -1
  26. package/dist/{chunk-jdfe4dmh.js → chunk-2zmz3pjk.js} +3 -3
  27. package/dist/{chunk-jdfe4dmh.js.map → chunk-2zmz3pjk.js.map} +1 -1
  28. package/dist/{chunk-zhsaz9cr.js → chunk-3bw1jk21.js} +1 -1
  29. package/dist/chunk-4qkzdyj7.js +4 -0
  30. package/dist/{chunk-4e61qbp4.js.map → chunk-4qkzdyj7.js.map} +1 -1
  31. package/dist/{chunk-d1ahbza9.js → chunk-50vm7x98.js} +3 -3
  32. package/dist/{chunk-d1ahbza9.js.map → chunk-50vm7x98.js.map} +1 -1
  33. package/dist/{chunk-qyaqg07q.js → chunk-6j1z2cqt.js} +2 -2
  34. package/dist/{chunk-qyaqg07q.js.map → chunk-6j1z2cqt.js.map} +1 -1
  35. package/dist/chunk-6rhebm18.js +5 -0
  36. package/dist/chunk-6rhebm18.js.map +10 -0
  37. package/dist/{chunk-rq770c71.js → chunk-71m47kad.js} +2 -2
  38. package/dist/{chunk-rq770c71.js.map → chunk-71m47kad.js.map} +1 -1
  39. package/dist/{chunk-0h3jr9d9.js → chunk-7f5ad759.js} +2 -2
  40. package/dist/{chunk-8p6rqegw.js.map → chunk-7f5ad759.js.map} +1 -1
  41. package/dist/{chunk-qj4mmner.js → chunk-85av4ncy.js} +2 -2
  42. package/dist/{chunk-qj4mmner.js.map → chunk-85av4ncy.js.map} +1 -1
  43. package/dist/{chunk-23g7qdpg.js → chunk-9taz1h3t.js} +3 -3
  44. package/dist/{chunk-23g7qdpg.js.map → chunk-9taz1h3t.js.map} +1 -1
  45. package/dist/{chunk-ppt296ye.js → chunk-agabw2w1.js} +2 -2
  46. package/dist/{chunk-ppt296ye.js.map → chunk-agabw2w1.js.map} +1 -1
  47. package/dist/{chunk-092pj2j2.js → chunk-bb3zvxsf.js} +3 -3
  48. package/dist/{chunk-092pj2j2.js.map → chunk-bb3zvxsf.js.map} +1 -1
  49. package/dist/{chunk-h7jv3ame.js → chunk-br8ten26.js} +2 -2
  50. package/dist/{chunk-h7jv3ame.js.map → chunk-br8ten26.js.map} +1 -1
  51. package/dist/{chunk-4e61qbp4.js → chunk-bzhtymvv.js} +2 -2
  52. package/dist/{chunk-0h3jr9d9.js.map → chunk-bzhtymvv.js.map} +1 -1
  53. package/dist/{chunk-68w225rv.js → chunk-c0wcsmpj.js} +2 -2
  54. package/dist/{chunk-68w225rv.js.map → chunk-c0wcsmpj.js.map} +1 -1
  55. package/dist/{chunk-xsmt86n3.js → chunk-c22vcxty.js} +2 -2
  56. package/dist/{chunk-xsmt86n3.js.map → chunk-c22vcxty.js.map} +1 -1
  57. package/dist/{chunk-a0sy9f9x.js → chunk-c2pv3ah8.js} +2 -2
  58. package/dist/{chunk-a0sy9f9x.js.map → chunk-c2pv3ah8.js.map} +2 -2
  59. package/dist/{chunk-q09mmr05.js → chunk-cz3szqhq.js} +2 -2
  60. package/dist/{chunk-q09mmr05.js.map → chunk-cz3szqhq.js.map} +1 -1
  61. package/dist/{chunk-69w4egkg.js → chunk-dwx2y7br.js} +4 -4
  62. package/dist/{chunk-69w4egkg.js.map → chunk-dwx2y7br.js.map} +1 -1
  63. package/dist/{chunk-2sfz64xh.js → chunk-dxw8k6f1.js} +2 -2
  64. package/dist/{chunk-2sfz64xh.js.map → chunk-dxw8k6f1.js.map} +1 -1
  65. package/dist/chunk-e3mggavt.js +5 -0
  66. package/dist/chunk-e3mggavt.js.map +11 -0
  67. package/dist/{chunk-j1knf8gv.js → chunk-efsk1wy0.js} +3 -3
  68. package/dist/{chunk-j1knf8gv.js.map → chunk-efsk1wy0.js.map} +1 -1
  69. package/dist/{chunk-t4n25km9.js → chunk-f13f68c0.js} +2 -2
  70. package/dist/{chunk-t4n25km9.js.map → chunk-f13f68c0.js.map} +1 -1
  71. package/dist/{chunk-vv72kw74.js → chunk-f418jh9k.js} +2 -2
  72. package/dist/{chunk-vv72kw74.js.map → chunk-f418jh9k.js.map} +1 -1
  73. package/dist/chunk-f4e7fh95.js +17 -0
  74. package/dist/chunk-f4e7fh95.js.map +14 -0
  75. package/dist/{chunk-ewgv1j8q.js → chunk-fcqc3e3r.js} +2 -2
  76. package/dist/{chunk-ewgv1j8q.js.map → chunk-fcqc3e3r.js.map} +1 -1
  77. package/dist/{chunk-3y9nf09k.js → chunk-g5tj10p8.js} +2 -2
  78. package/dist/{chunk-3y9nf09k.js.map → chunk-g5tj10p8.js.map} +1 -1
  79. package/dist/chunk-gn9zjgep.js +5 -0
  80. package/dist/chunk-gn9zjgep.js.map +10 -0
  81. package/dist/{chunk-5s45prj5.js → chunk-h7mcwfg5.js} +4 -4
  82. package/dist/{chunk-5s45prj5.js.map → chunk-h7mcwfg5.js.map} +1 -1
  83. package/dist/chunk-hk067634.js +4 -0
  84. package/dist/{chunk-vnjvd82s.js.map → chunk-hk067634.js.map} +2 -2
  85. package/dist/{chunk-qx6sahe0.js → chunk-hrrmxreg.js} +2 -2
  86. package/dist/{chunk-qx6sahe0.js.map → chunk-hrrmxreg.js.map} +1 -1
  87. package/dist/{chunk-p22rkf1g.js → chunk-jb022m7n.js} +2 -2
  88. package/dist/{chunk-p22rkf1g.js.map → chunk-jb022m7n.js.map} +1 -1
  89. package/dist/chunk-jb2nst6v.js +4 -0
  90. package/dist/{chunk-6scjrbw7.js.map → chunk-jb2nst6v.js.map} +2 -2
  91. package/dist/{chunk-kxzwem3g.js → chunk-jdgvdddd.js} +2 -2
  92. package/dist/{chunk-kxzwem3g.js.map → chunk-jdgvdddd.js.map} +1 -1
  93. package/dist/{chunk-2yth3kk2.js → chunk-jp4pf3yt.js} +4 -4
  94. package/dist/{chunk-2yth3kk2.js.map → chunk-jp4pf3yt.js.map} +1 -1
  95. package/dist/{chunk-0tbwn6er.js → chunk-k14dmqwh.js} +3 -3
  96. package/dist/{chunk-0tbwn6er.js.map → chunk-k14dmqwh.js.map} +1 -1
  97. package/dist/{chunk-1ce7veh9.js → chunk-k8endm5j.js} +3 -3
  98. package/dist/{chunk-1ce7veh9.js.map → chunk-k8endm5j.js.map} +1 -1
  99. package/dist/chunk-kkkqyvwv.js +81 -0
  100. package/dist/{chunk-km6x37ws.js.map → chunk-kkkqyvwv.js.map} +5 -5
  101. package/dist/{chunk-cmq5t8p9.js → chunk-kv2ep453.js} +3 -3
  102. package/dist/{chunk-cmq5t8p9.js.map → chunk-kv2ep453.js.map} +1 -1
  103. package/dist/{chunk-z4q1ty6w.js → chunk-kz39hphm.js} +3 -3
  104. package/dist/{chunk-z4q1ty6w.js.map → chunk-kz39hphm.js.map} +1 -1
  105. package/dist/{chunk-kaxvw75w.js → chunk-ms8qd7da.js} +3 -3
  106. package/dist/{chunk-kaxvw75w.js.map → chunk-ms8qd7da.js.map} +1 -1
  107. package/dist/{chunk-ttzkn1qd.js → chunk-n1tkn8gv.js} +2 -2
  108. package/dist/{chunk-ttzkn1qd.js.map → chunk-n1tkn8gv.js.map} +1 -1
  109. package/dist/chunk-nncwsdzz.js +5 -0
  110. package/dist/chunk-nncwsdzz.js.map +10 -0
  111. package/dist/{chunk-et0j6jx8.js → chunk-pgjk5ft3.js} +3 -3
  112. package/dist/{chunk-et0j6jx8.js.map → chunk-pgjk5ft3.js.map} +1 -1
  113. package/dist/{chunk-tztqkat2.js → chunk-r06rxn19.js} +2 -2
  114. package/dist/{chunk-tztqkat2.js.map → chunk-r06rxn19.js.map} +1 -1
  115. package/dist/chunk-r9z5rrk0.js +4 -0
  116. package/dist/{chunk-1ab1ptq5.js.map → chunk-r9z5rrk0.js.map} +2 -2
  117. package/dist/{chunk-h5g05qwb.js → chunk-s6e7cvek.js} +2 -2
  118. package/dist/{chunk-h5g05qwb.js.map → chunk-s6e7cvek.js.map} +1 -1
  119. package/dist/{chunk-53e48ce8.js → chunk-sqp7kn7h.js} +3 -3
  120. package/dist/{chunk-53e48ce8.js.map → chunk-sqp7kn7h.js.map} +1 -1
  121. package/dist/{chunk-mt2755rs.js → chunk-w6gb9gc5.js} +3 -3
  122. package/dist/{chunk-mt2755rs.js.map → chunk-w6gb9gc5.js.map} +1 -1
  123. package/dist/{chunk-ha7n1c94.js → chunk-xxw0gz4q.js} +2 -2
  124. package/dist/{chunk-ha7n1c94.js.map → chunk-xxw0gz4q.js.map} +1 -1
  125. package/dist/chunk-ywr2vd5r.js +5 -0
  126. package/dist/{chunk-f29vd5mc.js.map → chunk-ywr2vd5r.js.map} +2 -2
  127. package/dist/{chunk-38ma6gg3.js → chunk-zckj6bs6.js} +3 -3
  128. package/dist/{chunk-38ma6gg3.js.map → chunk-zckj6bs6.js.map} +1 -1
  129. package/dist/chunks/ThemeProvider-Bk1eZymb.js +2901 -0
  130. package/dist/chunks/ThemeProvider-Bk1eZymb.js.map +1 -0
  131. package/dist/client/ComponentContext.d.ts.map +1 -1
  132. package/dist/client/DictionarySinkContext.d.ts +10 -0
  133. package/dist/client/DictionarySinkContext.d.ts.map +1 -0
  134. package/dist/client/Mutation.d.ts +1 -1
  135. package/dist/client/Mutation.d.ts.map +1 -1
  136. package/dist/client/ThemeProvider.d.ts +7 -0
  137. package/dist/client/ThemeProvider.d.ts.map +1 -1
  138. package/dist/client/createRoot.d.ts.map +1 -1
  139. package/dist/client/index.d.ts +2 -0
  140. package/dist/client/index.d.ts.map +1 -1
  141. package/dist/client/index.js +242 -2629
  142. package/dist/client/index.js.map +1 -1
  143. package/dist/client/useDictionary.d.ts +34 -0
  144. package/dist/client/useDictionary.d.ts.map +1 -0
  145. package/dist/client/useDictionary.test-d.d.ts +2 -0
  146. package/dist/client/useDictionary.test-d.d.ts.map +1 -0
  147. package/dist/client/useIsNavigationPending.d.ts.map +1 -1
  148. package/dist/client/useMutate.d.ts.map +1 -1
  149. package/dist/client/useTranslator.d.ts +8 -0
  150. package/dist/client/useTranslator.d.ts.map +1 -1
  151. package/dist/config/index.js +1 -1
  152. package/dist/console/run.js +2 -2
  153. package/dist/console/run.js.map +1 -1
  154. package/dist/container/index.js +2 -2
  155. package/dist/container/index.js.map +1 -1
  156. package/dist/database/index.js +2 -2
  157. package/dist/database/index.js.map +1 -1
  158. package/dist/email/index.js +2 -2
  159. package/dist/email/index.js.map +1 -1
  160. package/dist/facades/Lang.d.ts.map +1 -1
  161. package/dist/facades/index.js +2 -2
  162. package/dist/facades/index.js.map +1 -1
  163. package/dist/foundation/index.js +2 -2
  164. package/dist/foundation/index.js.map +1 -1
  165. package/dist/http/index.js +2 -2
  166. package/dist/http/index.js.map +1 -1
  167. package/dist/i18n/Dictionary.d.ts +7 -0
  168. package/dist/i18n/Dictionary.d.ts.map +1 -1
  169. package/dist/i18n/Translator.d.ts +12 -0
  170. package/dist/i18n/Translator.d.ts.map +1 -1
  171. package/dist/i18n/config.d.ts +6 -0
  172. package/dist/i18n/config.d.ts.map +1 -1
  173. package/dist/i18n/defineDictionary.d.ts +65 -0
  174. package/dist/i18n/defineDictionary.d.ts.map +1 -0
  175. package/dist/i18n/dictionaryRegistry.d.ts +85 -0
  176. package/dist/i18n/dictionaryRegistry.d.ts.map +1 -0
  177. package/dist/i18n/dictionaryRuntime.d.ts +16 -0
  178. package/dist/i18n/dictionaryRuntime.d.ts.map +1 -0
  179. package/dist/i18n/dictionaryRuntime.js +4 -0
  180. package/dist/i18n/dictionaryRuntime.js.map +9 -0
  181. package/dist/i18n/dictionaryShape.d.ts +66 -0
  182. package/dist/i18n/dictionaryShape.d.ts.map +1 -0
  183. package/dist/i18n/dictionarySink.d.ts +31 -0
  184. package/dist/i18n/dictionarySink.d.ts.map +1 -0
  185. package/dist/i18n/index.d.ts +3 -0
  186. package/dist/i18n/index.d.ts.map +1 -1
  187. package/dist/i18n/index.js +2 -2
  188. package/dist/i18n/index.js.map +5 -4
  189. package/dist/i18n/translate.d.ts +21 -0
  190. package/dist/i18n/translate.d.ts.map +1 -0
  191. package/dist/internal/gemiExternals.d.ts +1 -1
  192. package/dist/internal/gemiExternals.d.ts.map +1 -1
  193. package/dist/kernel/index.js +2 -2
  194. package/dist/kernel/index.js.map +2 -2
  195. package/dist/orm/index.js +2 -2
  196. package/dist/orm/index.js.map +2 -2
  197. package/dist/server/index.js +2 -2
  198. package/dist/server/index.js.map +1 -1
  199. package/dist/services/index.js +4 -4
  200. package/dist/services/index.js.map +2 -2
  201. package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
  202. package/dist/services/router/streamQueryInjection.d.ts +9 -1
  203. package/dist/services/router/streamQueryInjection.d.ts.map +1 -1
  204. package/dist/support/index.js +2 -2
  205. package/dist/support/index.js.map +1 -1
  206. package/dist/testing/Page.d.ts +166 -0
  207. package/dist/testing/Page.d.ts.map +1 -0
  208. package/dist/testing/index.d.ts +3 -0
  209. package/dist/testing/index.d.ts.map +1 -0
  210. package/dist/testing/index.js +352 -0
  211. package/dist/testing/index.js.map +1 -0
  212. package/dist/utils/Subject.d.ts.map +1 -1
  213. package/dist/utils/variantKey.d.ts +19 -0
  214. package/dist/utils/variantKey.d.ts.map +1 -0
  215. package/dist/vite/__vite-browser-external-S5EYS4bz.mjs +7 -0
  216. package/dist/vite/api_vite-DSBC5Nzy.mjs +5 -0
  217. package/dist/vite/browser-DFEUWTkA.mjs +6086 -0
  218. package/dist/vite/build-C0lmnz6d.mjs +5326 -0
  219. package/dist/vite/index.mjs +1349 -1
  220. package/dist/vite/lib-TT6NqN6b.mjs +363 -0
  221. package/dist/vite/lib-U4DF62jt.mjs +48846 -0
  222. package/dist/vite/main-Drp2rSLR.mjs +2123 -0
  223. package/dist/vite/node-BgyIm-M7.mjs +17799 -0
  224. package/dist/vite/node-yGkKTK1d.mjs +789 -0
  225. package/dist/vite/postcss-hCXrlC4m.mjs +3515 -0
  226. package/dist/vite/postcss-import-rYEe0OKc.mjs +448 -0
  227. package/dist/vite/prompt--dNycKSZ-BmZ8jzP_.mjs +889 -0
  228. package/dist/vite/rolldown-runtime-B4lejLz5.mjs +37 -0
  229. package/package.json +4 -1
  230. package/dist/chunk-1ab1ptq5.js +0 -4
  231. package/dist/chunk-2qn472j4.js +0 -5
  232. package/dist/chunk-6scjrbw7.js +0 -4
  233. package/dist/chunk-88pq4gmf.js +0 -5
  234. package/dist/chunk-88pq4gmf.js.map +0 -10
  235. package/dist/chunk-8p6rqegw.js +0 -4
  236. package/dist/chunk-f29vd5mc.js +0 -5
  237. package/dist/chunk-faa987e4.js +0 -4
  238. package/dist/chunk-hbycemy5.js +0 -6
  239. package/dist/chunk-km6x37ws.js +0 -81
  240. package/dist/chunk-msz8rngs.js.map +0 -10
  241. package/dist/chunk-vnjvd82s.js +0 -4
  242. package/dist/chunk-xw44bwnh.js +0 -5
  243. package/dist/chunk-xw44bwnh.js.map +0 -11
  244. /package/dist/{chunk-zhsaz9cr.js.map → chunk-3bw1jk21.js.map} +0 -0
@@ -0,0 +1,2901 @@
1
+ import { Component, createContext, createElement, lazy, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { createPortal } from "react-dom";
4
+ //#region utils/Subject.ts
5
+ var Subject = class {
6
+ subscribers = /* @__PURE__ */ new Set();
7
+ value;
8
+ constructor(initialValue) {
9
+ this.value = initialValue;
10
+ this.subscribe = this.subscribe.bind(this);
11
+ this.next = this.next.bind(this);
12
+ this.getValue = this.getValue.bind(this);
13
+ }
14
+ subscribe(subscriber) {
15
+ this.subscribers.add(subscriber);
16
+ return () => {
17
+ this.subscribers.delete(subscriber);
18
+ };
19
+ }
20
+ next(value) {
21
+ this.value = value;
22
+ this.subscribers.forEach((subscriber) => subscriber(value));
23
+ }
24
+ getValue() {
25
+ return this.value;
26
+ }
27
+ };
28
+ //#endregion
29
+ //#region client/QueryError.ts
30
+ /**
31
+ * An HTTP failure from a query endpoint, in a shape an error boundary can
32
+ * work with. `resolveVariant` used to store the parsed response body as the
33
+ * error; boundaries expect an `Error`, so the body moves to a field.
34
+ */
35
+ var QueryError = class extends Error {
36
+ path;
37
+ variantKey;
38
+ status;
39
+ body;
40
+ constructor(path, variantKey, status, body) {
41
+ super(typeof body?.message === "string" ? body.message : `Request to /api${path} failed with status ${status}`);
42
+ this.path = path;
43
+ this.variantKey = variantKey;
44
+ this.status = status;
45
+ this.body = body;
46
+ this.name = "QueryError";
47
+ }
48
+ };
49
+ //#endregion
50
+ //#region client/QueryResource.ts
51
+ var DEFAULT_STALE_TIME = 5e3;
52
+ var QueryResource = class {
53
+ store;
54
+ staleVariants = /* @__PURE__ */ new Set();
55
+ lastFetchRecord = /* @__PURE__ */ new Map();
56
+ key;
57
+ /**
58
+ * Variants with a request on the wire. React discards and retries a
59
+ * suspended render, so `read` runs many times for one commit — this is what
60
+ * collapses those attempts onto a single fetch. The `loading` flag can't do
61
+ * it: render-initiated fetches are silent and never write to the store.
62
+ */
63
+ inflight = /* @__PURE__ */ new Set();
64
+ /**
65
+ * One promise per suspended variant, handed to `use()`. Settled by whatever
66
+ * write lands first — the variant's own fetch or a `hydrate` from a route
67
+ * payload — so a prefetch that arrives mid-suspension wakes the reader
68
+ * without waiting on the wire.
69
+ */
70
+ pending = /* @__PURE__ */ new Map();
71
+ constructor(key, initialState) {
72
+ this.key = key;
73
+ this.store = new Subject(/* @__PURE__ */ new Map());
74
+ this.hydrate(initialState);
75
+ }
76
+ /**
77
+ * Adopt server-prefetched data into the cache.
78
+ *
79
+ * Called once from the constructor for the SSR payload, and again on every
80
+ * client-side navigation with the `prefetchedData` the server just produced —
81
+ * otherwise the resource cache (which is keyed by path for the lifetime of
82
+ * the app) would keep serving the first payload and revalidate it over `/api`.
83
+ */
84
+ hydrate(initialState) {
85
+ const store = this.store.getValue();
86
+ const now = Date.now();
87
+ let changed = false;
88
+ for (const [variantKey, data] of Object.entries(initialState ?? {})) {
89
+ if (data === void 0) continue;
90
+ const current = store.get(variantKey);
91
+ if (current?.loading) continue;
92
+ if (current?.hasData && current.data === data) continue;
93
+ store.set(variantKey, {
94
+ loading: false,
95
+ data,
96
+ hasData: true,
97
+ error: null,
98
+ version: now
99
+ });
100
+ this.staleVariants.delete(variantKey);
101
+ this.lastFetchRecord.set(variantKey, now);
102
+ this.settle(variantKey);
103
+ changed = true;
104
+ }
105
+ if (changed) this.store.next(store);
106
+ }
107
+ pendingFor(variantKey) {
108
+ let deferred = this.pending.get(variantKey);
109
+ if (!deferred) {
110
+ let resolve;
111
+ deferred = {
112
+ promise: new Promise((r) => {
113
+ resolve = r;
114
+ }),
115
+ resolve
116
+ };
117
+ this.pending.set(variantKey, deferred);
118
+ }
119
+ return deferred;
120
+ }
121
+ settle(variantKey) {
122
+ const deferred = this.pending.get(variantKey);
123
+ if (deferred) {
124
+ this.pending.delete(variantKey);
125
+ deferred.resolve();
126
+ }
127
+ }
128
+ isStale(variantKey, staleTime) {
129
+ if (this.staleVariants.has(variantKey)) return true;
130
+ const now = Date.now();
131
+ return now - (this.lastFetchRecord.get(variantKey) ?? now) >= staleTime;
132
+ }
133
+ /**
134
+ * The cached state for a variant, or `undefined` — a plain read that never
135
+ * fetches and never revalidates.
136
+ *
137
+ * `getVariant` is the read that keeps the cache honest, and it starts a
138
+ * request when it has to. That makes it the wrong thing to call while
139
+ * rendering: React throws away a render whose subtree suspends and retries
140
+ * it, so every discarded attempt would leak a request. Renders read with
141
+ * this; effects, which only run for a render that committed, use
142
+ * `getVariant`.
143
+ */
144
+ peek(variantKey) {
145
+ return this.store.getValue().get(variantKey);
146
+ }
147
+ /**
148
+ * The read a render performs. Never suspends when data is in hand (stale
149
+ * data revalidates in the background instead), dedupes across the render
150
+ * attempts React throws away, and hands back a promise that resolves off
151
+ * any write to the variant — its own fetch or a `hydrate`.
152
+ *
153
+ * Safe during render: it never writes to the store synchronously, so the
154
+ * snapshot `useSyncExternalStore` read stays valid for the whole attempt.
155
+ */
156
+ read(variantKey, staleTime = DEFAULT_STALE_TIME) {
157
+ const state = this.peek(variantKey);
158
+ if (state?.hasData) {
159
+ if (!this.inflight.has(variantKey) && this.isStale(variantKey, staleTime)) {
160
+ this.lastFetchRecord.set(variantKey, Date.now());
161
+ this.resolveVariant(variantKey, true);
162
+ }
163
+ return { state };
164
+ }
165
+ if (state?.error) return { state };
166
+ if (typeof window === "undefined") return { state };
167
+ const deferred = this.pendingFor(variantKey);
168
+ if (!this.inflight.has(variantKey)) this.resolveVariant(variantKey, true);
169
+ return {
170
+ state,
171
+ promise: deferred.promise
172
+ };
173
+ }
174
+ getVariant(variantKey, staleTime = DEFAULT_STALE_TIME) {
175
+ const store = this.store.getValue();
176
+ if (!store.has(variantKey)) {
177
+ if (!this.inflight.has(variantKey)) this.resolveVariant(variantKey);
178
+ } else {
179
+ const variant = store.get(variantKey);
180
+ if (!variant.loading && !this.inflight.has(variantKey)) {
181
+ if (!variant.hasData) {
182
+ this.resolveVariant(variantKey);
183
+ return store.get(variantKey);
184
+ }
185
+ if (this.isStale(variantKey, staleTime)) {
186
+ this.lastFetchRecord.set(variantKey, Date.now());
187
+ this.resolveVariant(variantKey, true);
188
+ return store.get(variantKey);
189
+ }
190
+ }
191
+ }
192
+ return store.get(variantKey);
193
+ }
194
+ /**
195
+ * Drop the error for one variant (or every variant when omitted), so an
196
+ * error boundary reset re-renders into a clean read instead of instantly
197
+ * re-throwing the stored failure.
198
+ */
199
+ clearError(variantKey) {
200
+ const store = this.store.getValue();
201
+ let changed = false;
202
+ for (const [key, state] of store) {
203
+ if (variantKey !== void 0 && key !== variantKey) continue;
204
+ if (state.error) {
205
+ store.set(key, {
206
+ ...state,
207
+ error: null
208
+ });
209
+ changed = true;
210
+ }
211
+ }
212
+ if (changed) this.store.next(store);
213
+ }
214
+ mutate(variantKey, fn = (data) => data) {
215
+ const cacheKey = [
216
+ typeof window !== "undefined" && window.location?.origin ? window.location.origin : "",
217
+ this.key,
218
+ variantKey
219
+ ].filter((s) => s.length > 0).join("?");
220
+ try {
221
+ if (caches) caches?.delete(cacheKey);
222
+ } catch (err) {}
223
+ const store = this.store.getValue();
224
+ const state = store.get(variantKey);
225
+ if (!state || !state.hasData) {
226
+ this.resolveVariant(variantKey, false, false);
227
+ return;
228
+ }
229
+ const data = fn(state.data);
230
+ this.staleVariants.add(variantKey);
231
+ this.store.next(store.set(variantKey, {
232
+ loading: false,
233
+ data,
234
+ hasData: true,
235
+ error: null,
236
+ version: state.version
237
+ }));
238
+ this.resolveVariant(variantKey, false, false);
239
+ }
240
+ refetch(variantKey) {
241
+ this.resolveVariant(variantKey, false, false);
242
+ }
243
+ async resolveVariant(variantKey, silent = false, cache = true) {
244
+ if (typeof window === "undefined") return;
245
+ this.inflight.add(variantKey);
246
+ try {
247
+ const store = this.store.getValue();
248
+ const previousState = store.get(variantKey);
249
+ if (!silent) store.set(variantKey, {
250
+ loading: true,
251
+ data: previousState?.data,
252
+ hasData: previousState?.hasData ?? false,
253
+ error: previousState?.error,
254
+ version: previousState?.version
255
+ });
256
+ let data = null;
257
+ let response = null;
258
+ const fullUrl = [this.key, variantKey].filter((s) => s.length).join("?");
259
+ try {
260
+ response = await fetch(`/api${fullUrl}`, { cache: cache ? "default" : "reload" });
261
+ data = await response.json();
262
+ } catch (error) {
263
+ console.error(`Error fetching url /api${fullUrl}`, error);
264
+ this.store.next(store.set(variantKey, {
265
+ loading: false,
266
+ data: previousState?.data,
267
+ hasData: previousState?.hasData ?? false,
268
+ error,
269
+ version: previousState?.version
270
+ }));
271
+ return;
272
+ }
273
+ if (response.ok) {
274
+ this.store.next(store.set(variantKey, {
275
+ loading: false,
276
+ data,
277
+ hasData: true,
278
+ error: null,
279
+ version: Date.now()
280
+ }));
281
+ this.staleVariants.delete(variantKey);
282
+ this.lastFetchRecord.set(variantKey, Date.now());
283
+ } else this.store.next(store.set(variantKey, {
284
+ loading: false,
285
+ data: previousState?.data,
286
+ hasData: previousState?.hasData ?? false,
287
+ error: new QueryError(this.key, variantKey, response.status, data),
288
+ version: previousState?.version
289
+ }));
290
+ } finally {
291
+ this.inflight.delete(variantKey);
292
+ this.settle(variantKey);
293
+ }
294
+ }
295
+ };
296
+ //#endregion
297
+ //#region client/QueryManagerContext.tsx
298
+ var QueryConfigContext = createContext(null);
299
+ /**
300
+ * The runtime mirror of the `QueryConfig` type: TS excess-property checking
301
+ * only fires on fresh object literals, so a dynamically built (or plain-JS)
302
+ * config could smuggle call-site-only keys (`lazy`, `fallbackData`,
303
+ * `refetchUntil`) into every query. The provider picks these keys — and only
304
+ * these — before the value enters the context. Keys whose value is
305
+ * `undefined` are dropped too, so an absent value (e.g. an unset env-derived
306
+ * `staleTime`) falls through to the framework default instead of shadowing it.
307
+ */
308
+ var APP_WIDE_QUERY_CONFIG_KEYS = [
309
+ "suspense",
310
+ "staleTime",
311
+ "keepPreviousData",
312
+ "retryIntervalOnError",
313
+ "refreshInterval"
314
+ ];
315
+ function pickAppWideQueryConfig(queryConfig) {
316
+ if (!queryConfig) return null;
317
+ const picked = {};
318
+ for (const key of APP_WIDE_QUERY_CONFIG_KEYS) if (queryConfig[key] !== void 0) picked[key] = queryConfig[key];
319
+ return picked;
320
+ }
321
+ var QueryManagerContext = createContext({
322
+ getResource: (key, initialState = {}) => {
323
+ return new QueryResource(key, initialState);
324
+ },
325
+ hydrate: () => {},
326
+ clearErrors: () => {}
327
+ });
328
+ var QueryManagerProvider = ({ children, queryConfig = null }) => {
329
+ const resourcesRef = useRef(/* @__PURE__ */ new Map());
330
+ const appQueryConfig = useMemo(() => pickAppWideQueryConfig(queryConfig), [queryConfig]);
331
+ const getResource = useCallback((key, initialState) => {
332
+ let resource = resourcesRef.current.get(key);
333
+ if (!resource) {
334
+ resource = new QueryResource(key, initialState ?? {});
335
+ resourcesRef.current.set(key, resource);
336
+ }
337
+ return resource;
338
+ }, []);
339
+ const hydrate = useCallback((prefetchedData) => {
340
+ if (!prefetchedData) return;
341
+ for (const [key, initialState] of Object.entries(prefetchedData)) {
342
+ if (!initialState || typeof initialState !== "object") continue;
343
+ const resource = resourcesRef.current.get(key);
344
+ if (resource) resource.hydrate(initialState);
345
+ else resourcesRef.current.set(key, new QueryResource(key, initialState));
346
+ }
347
+ }, []);
348
+ const clearErrors = useCallback(() => {
349
+ for (const resource of resourcesRef.current.values()) resource.clearError();
350
+ }, []);
351
+ const drainedStreamRef = useRef(false);
352
+ if (typeof window !== "undefined" && !drainedStreamRef.current) {
353
+ drainedStreamRef.current = true;
354
+ const w = window;
355
+ const adopt = ([path, variantKey, data]) => {
356
+ hydrate({ [path]: { [variantKey]: data } });
357
+ };
358
+ const buffered = Array.isArray(w.__GEMI_STREAM__) ? w.__GEMI_STREAM__ : [];
359
+ w.__GEMI_STREAM__ = { push: adopt };
360
+ for (const payload of buffered) adopt(payload);
361
+ }
362
+ const value = useMemo(() => ({
363
+ getResource,
364
+ hydrate,
365
+ clearErrors
366
+ }), [
367
+ getResource,
368
+ hydrate,
369
+ clearErrors
370
+ ]);
371
+ return /* @__PURE__ */ jsx(QueryManagerContext.Provider, {
372
+ value,
373
+ children: /* @__PURE__ */ jsx(QueryConfigContext.Provider, {
374
+ value: appQueryConfig,
375
+ children
376
+ })
377
+ });
378
+ };
379
+ //#endregion
380
+ //#region utils/applyParams.ts
381
+ function applyParams(url, params) {
382
+ return url.replace(/:([^/]+[*?]?)/g, (_, key) => {
383
+ const hasSuffix = key.endsWith("?") || key.endsWith("*");
384
+ const paramName = hasSuffix ? key.slice(0, -1) : key;
385
+ const value = params[paramName];
386
+ if (value === void 0) {
387
+ if (hasSuffix) return "";
388
+ console.error(`Missing parameter: ${paramName} in URL: ${url}`);
389
+ }
390
+ return String(value);
391
+ }).replace(/\/\//g, "/").replace(/\/$/, "");
392
+ }
393
+ //#endregion
394
+ //#region utils/omitNullishValues.ts
395
+ function omitNullishValues(input) {
396
+ return Object.fromEntries(Object.entries(input).filter(([, value]) => {
397
+ return value !== null && value !== void 0;
398
+ }));
399
+ }
400
+ //#endregion
401
+ //#region utils/variantKey.ts
402
+ /**
403
+ * The key one search-param combination is cached under, inside a query's
404
+ * resource: the params sorted and serialized, empty when there are none.
405
+ *
406
+ * Sorted because `?b=2&a=1` and `?a=1&b=2` are the same request, and a cache
407
+ * that keyed them separately would fetch twice and hydrate one of them from a
408
+ * payload the server produced for the other. Nullish values are dropped for
409
+ * the same reason: an optional filter left `undefined` is absent, not the
410
+ * string `"undefined"`.
411
+ *
412
+ * Every site that reads or writes the cache derives its key from here —
413
+ * `useQuery` (the read), `useMutate` (the write), and `gemi/testing`'s `<Page>`
414
+ * (the seed). They used to hold a copy each, which is the kind of duplication
415
+ * that fails quietly: a seed built by an old copy simply misses, and the test
416
+ * that should have read it fetches over the network and asserts an empty state
417
+ * with nothing pointing at the mismatch.
418
+ */
419
+ function toVariantKey(search) {
420
+ const searchParams = new URLSearchParams(typeof search === "string" ? search : omitNullishValues(search ?? {}));
421
+ searchParams.sort();
422
+ return searchParams.toString();
423
+ }
424
+ //#endregion
425
+ //#region client/RouteStateContext.tsx
426
+ var RouteStateContext = createContext({});
427
+ var RouteStateProvider = (props) => {
428
+ return /* @__PURE__ */ jsx(RouteStateContext.Provider, {
429
+ value: props.state,
430
+ children: props.children
431
+ });
432
+ };
433
+ //#endregion
434
+ //#region client/useParams.ts
435
+ function useParams() {
436
+ const { params = {} } = useContext(RouteStateContext);
437
+ return params;
438
+ }
439
+ //#endregion
440
+ //#region ../../node_modules/.bun/@babel+runtime@7.29.2/node_modules/@babel/runtime/helpers/esm/extends.js
441
+ function _extends() {
442
+ return _extends = Object.assign ? Object.assign.bind() : function(n) {
443
+ for (var e = 1; e < arguments.length; e++) {
444
+ var t = arguments[e];
445
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
446
+ }
447
+ return n;
448
+ }, _extends.apply(null, arguments);
449
+ }
450
+ //#endregion
451
+ //#region ../../node_modules/.bun/history@5.3.0/node_modules/history/index.js
452
+ /**
453
+ * Actions represent the type of change to a location value.
454
+ *
455
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#action
456
+ */
457
+ var Action;
458
+ (function(Action) {
459
+ /**
460
+ * A POP indicates a change to an arbitrary index in the history stack, such
461
+ * as a back or forward navigation. It does not describe the direction of the
462
+ * navigation, only that the current index changed.
463
+ *
464
+ * Note: This is the default action for newly created history objects.
465
+ */
466
+ Action["Pop"] = "POP";
467
+ /**
468
+ * A PUSH indicates a new entry being added to the history stack, such as when
469
+ * a link is clicked and a new page loads. When this happens, all subsequent
470
+ * entries in the stack are lost.
471
+ */
472
+ Action["Push"] = "PUSH";
473
+ /**
474
+ * A REPLACE indicates the entry at the current index in the history stack
475
+ * being replaced by a new one.
476
+ */
477
+ Action["Replace"] = "REPLACE";
478
+ })(Action || (Action = {}));
479
+ var readOnly = process.env.NODE_ENV !== "production" ? function(obj) {
480
+ return Object.freeze(obj);
481
+ } : function(obj) {
482
+ return obj;
483
+ };
484
+ function warning(cond, message) {
485
+ if (!cond) {
486
+ if (typeof console !== "undefined") console.warn(message);
487
+ try {
488
+ throw new Error(message);
489
+ } catch (e) {}
490
+ }
491
+ }
492
+ var BeforeUnloadEventType = "beforeunload";
493
+ var PopStateEventType = "popstate";
494
+ /**
495
+ * Browser history stores the location in regular URLs. This is the standard for
496
+ * most web apps, but it requires some configuration on the server to ensure you
497
+ * serve the same app at multiple URLs.
498
+ *
499
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory
500
+ */
501
+ function createBrowserHistory(options) {
502
+ if (options === void 0) options = {};
503
+ var _options$window = options.window, window = _options$window === void 0 ? document.defaultView : _options$window;
504
+ var globalHistory = window.history;
505
+ function getIndexAndLocation() {
506
+ var _window$location = window.location, pathname = _window$location.pathname, search = _window$location.search, hash = _window$location.hash;
507
+ var state = globalHistory.state || {};
508
+ return [state.idx, readOnly({
509
+ pathname,
510
+ search,
511
+ hash,
512
+ state: state.usr || null,
513
+ key: state.key || "default"
514
+ })];
515
+ }
516
+ var blockedPopTx = null;
517
+ function handlePop() {
518
+ if (blockedPopTx) {
519
+ blockers.call(blockedPopTx);
520
+ blockedPopTx = null;
521
+ } else {
522
+ var nextAction = Action.Pop;
523
+ var _getIndexAndLocation = getIndexAndLocation(), nextIndex = _getIndexAndLocation[0], nextLocation = _getIndexAndLocation[1];
524
+ if (blockers.length) if (nextIndex != null) {
525
+ var delta = index - nextIndex;
526
+ if (delta) {
527
+ blockedPopTx = {
528
+ action: nextAction,
529
+ location: nextLocation,
530
+ retry: function retry() {
531
+ go(delta * -1);
532
+ }
533
+ };
534
+ go(delta);
535
+ }
536
+ } else process.env.NODE_ENV !== "production" && warning(false, "You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation.");
537
+ else applyTx(nextAction);
538
+ }
539
+ }
540
+ window.addEventListener(PopStateEventType, handlePop);
541
+ var action = Action.Pop;
542
+ var _getIndexAndLocation2 = getIndexAndLocation(), index = _getIndexAndLocation2[0], location = _getIndexAndLocation2[1];
543
+ var listeners = createEvents();
544
+ var blockers = createEvents();
545
+ if (index == null) {
546
+ index = 0;
547
+ globalHistory.replaceState(_extends({}, globalHistory.state, { idx: index }), "");
548
+ }
549
+ function createHref(to) {
550
+ return typeof to === "string" ? to : createPath(to);
551
+ }
552
+ function getNextLocation(to, state) {
553
+ if (state === void 0) state = null;
554
+ return readOnly(_extends({
555
+ pathname: location.pathname,
556
+ hash: "",
557
+ search: ""
558
+ }, typeof to === "string" ? parsePath(to) : to, {
559
+ state,
560
+ key: createKey()
561
+ }));
562
+ }
563
+ function getHistoryStateAndUrl(nextLocation, index) {
564
+ return [{
565
+ usr: nextLocation.state,
566
+ key: nextLocation.key,
567
+ idx: index
568
+ }, createHref(nextLocation)];
569
+ }
570
+ function allowTx(action, location, retry) {
571
+ return !blockers.length || (blockers.call({
572
+ action,
573
+ location,
574
+ retry
575
+ }), false);
576
+ }
577
+ function applyTx(nextAction) {
578
+ action = nextAction;
579
+ var _getIndexAndLocation3 = getIndexAndLocation();
580
+ index = _getIndexAndLocation3[0];
581
+ location = _getIndexAndLocation3[1];
582
+ listeners.call({
583
+ action,
584
+ location
585
+ });
586
+ }
587
+ function push(to, state) {
588
+ var nextAction = Action.Push;
589
+ var nextLocation = getNextLocation(to, state);
590
+ function retry() {
591
+ push(to, state);
592
+ }
593
+ if (allowTx(nextAction, nextLocation, retry)) {
594
+ var _getHistoryStateAndUr = getHistoryStateAndUrl(nextLocation, index + 1), historyState = _getHistoryStateAndUr[0], url = _getHistoryStateAndUr[1];
595
+ try {
596
+ globalHistory.pushState(historyState, "", url);
597
+ } catch (error) {
598
+ window.location.assign(url);
599
+ }
600
+ applyTx(nextAction);
601
+ }
602
+ }
603
+ function replace(to, state) {
604
+ var nextAction = Action.Replace;
605
+ var nextLocation = getNextLocation(to, state);
606
+ function retry() {
607
+ replace(to, state);
608
+ }
609
+ if (allowTx(nextAction, nextLocation, retry)) {
610
+ var _getHistoryStateAndUr2 = getHistoryStateAndUrl(nextLocation, index), historyState = _getHistoryStateAndUr2[0], url = _getHistoryStateAndUr2[1];
611
+ globalHistory.replaceState(historyState, "", url);
612
+ applyTx(nextAction);
613
+ }
614
+ }
615
+ function go(delta) {
616
+ globalHistory.go(delta);
617
+ }
618
+ return {
619
+ get action() {
620
+ return action;
621
+ },
622
+ get location() {
623
+ return location;
624
+ },
625
+ createHref,
626
+ push,
627
+ replace,
628
+ go,
629
+ back: function back() {
630
+ go(-1);
631
+ },
632
+ forward: function forward() {
633
+ go(1);
634
+ },
635
+ listen: function listen(listener) {
636
+ return listeners.push(listener);
637
+ },
638
+ block: function block(blocker) {
639
+ var unblock = blockers.push(blocker);
640
+ if (blockers.length === 1) window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
641
+ return function() {
642
+ unblock();
643
+ if (!blockers.length) window.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
644
+ };
645
+ }
646
+ };
647
+ }
648
+ /**
649
+ * Memory history stores the current location in memory. It is designed for use
650
+ * in stateful non-browser environments like tests and React Native.
651
+ *
652
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#creatememoryhistory
653
+ */
654
+ function createMemoryHistory(options) {
655
+ if (options === void 0) options = {};
656
+ var _options3 = options, _options3$initialEntr = _options3.initialEntries, initialEntries = _options3$initialEntr === void 0 ? ["/"] : _options3$initialEntr, initialIndex = _options3.initialIndex;
657
+ var entries = initialEntries.map(function(entry) {
658
+ var location = readOnly(_extends({
659
+ pathname: "/",
660
+ search: "",
661
+ hash: "",
662
+ state: null,
663
+ key: createKey()
664
+ }, typeof entry === "string" ? parsePath(entry) : entry));
665
+ process.env.NODE_ENV !== "production" && warning(location.pathname.charAt(0) === "/", "Relative pathnames are not supported in createMemoryHistory({ initialEntries }) (invalid entry: " + JSON.stringify(entry) + ")");
666
+ return location;
667
+ });
668
+ var index = clamp(initialIndex == null ? entries.length - 1 : initialIndex, 0, entries.length - 1);
669
+ var action = Action.Pop;
670
+ var location = entries[index];
671
+ var listeners = createEvents();
672
+ var blockers = createEvents();
673
+ function createHref(to) {
674
+ return typeof to === "string" ? to : createPath(to);
675
+ }
676
+ function getNextLocation(to, state) {
677
+ if (state === void 0) state = null;
678
+ return readOnly(_extends({
679
+ pathname: location.pathname,
680
+ search: "",
681
+ hash: ""
682
+ }, typeof to === "string" ? parsePath(to) : to, {
683
+ state,
684
+ key: createKey()
685
+ }));
686
+ }
687
+ function allowTx(action, location, retry) {
688
+ return !blockers.length || (blockers.call({
689
+ action,
690
+ location,
691
+ retry
692
+ }), false);
693
+ }
694
+ function applyTx(nextAction, nextLocation) {
695
+ action = nextAction;
696
+ location = nextLocation;
697
+ listeners.call({
698
+ action,
699
+ location
700
+ });
701
+ }
702
+ function push(to, state) {
703
+ var nextAction = Action.Push;
704
+ var nextLocation = getNextLocation(to, state);
705
+ function retry() {
706
+ push(to, state);
707
+ }
708
+ process.env.NODE_ENV !== "production" && warning(location.pathname.charAt(0) === "/", "Relative pathnames are not supported in memory history.push(" + JSON.stringify(to) + ")");
709
+ if (allowTx(nextAction, nextLocation, retry)) {
710
+ index += 1;
711
+ entries.splice(index, entries.length, nextLocation);
712
+ applyTx(nextAction, nextLocation);
713
+ }
714
+ }
715
+ function replace(to, state) {
716
+ var nextAction = Action.Replace;
717
+ var nextLocation = getNextLocation(to, state);
718
+ function retry() {
719
+ replace(to, state);
720
+ }
721
+ process.env.NODE_ENV !== "production" && warning(location.pathname.charAt(0) === "/", "Relative pathnames are not supported in memory history.replace(" + JSON.stringify(to) + ")");
722
+ if (allowTx(nextAction, nextLocation, retry)) {
723
+ entries[index] = nextLocation;
724
+ applyTx(nextAction, nextLocation);
725
+ }
726
+ }
727
+ function go(delta) {
728
+ var nextIndex = clamp(index + delta, 0, entries.length - 1);
729
+ var nextAction = Action.Pop;
730
+ var nextLocation = entries[nextIndex];
731
+ function retry() {
732
+ go(delta);
733
+ }
734
+ if (allowTx(nextAction, nextLocation, retry)) {
735
+ index = nextIndex;
736
+ applyTx(nextAction, nextLocation);
737
+ }
738
+ }
739
+ return {
740
+ get index() {
741
+ return index;
742
+ },
743
+ get action() {
744
+ return action;
745
+ },
746
+ get location() {
747
+ return location;
748
+ },
749
+ createHref,
750
+ push,
751
+ replace,
752
+ go,
753
+ back: function back() {
754
+ go(-1);
755
+ },
756
+ forward: function forward() {
757
+ go(1);
758
+ },
759
+ listen: function listen(listener) {
760
+ return listeners.push(listener);
761
+ },
762
+ block: function block(blocker) {
763
+ return blockers.push(blocker);
764
+ }
765
+ };
766
+ }
767
+ function clamp(n, lowerBound, upperBound) {
768
+ return Math.min(Math.max(n, lowerBound), upperBound);
769
+ }
770
+ function promptBeforeUnload(event) {
771
+ event.preventDefault();
772
+ event.returnValue = "";
773
+ }
774
+ function createEvents() {
775
+ var handlers = [];
776
+ return {
777
+ get length() {
778
+ return handlers.length;
779
+ },
780
+ push: function push(fn) {
781
+ handlers.push(fn);
782
+ return function() {
783
+ handlers = handlers.filter(function(handler) {
784
+ return handler !== fn;
785
+ });
786
+ };
787
+ },
788
+ call: function call(arg) {
789
+ handlers.forEach(function(fn) {
790
+ return fn && fn(arg);
791
+ });
792
+ }
793
+ };
794
+ }
795
+ function createKey() {
796
+ return Math.random().toString(36).substr(2, 8);
797
+ }
798
+ /**
799
+ * Creates a string URL path from the given pathname, search, and hash components.
800
+ *
801
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createpath
802
+ */
803
+ function createPath(_ref) {
804
+ var _ref$pathname = _ref.pathname, pathname = _ref$pathname === void 0 ? "/" : _ref$pathname, _ref$search = _ref.search, search = _ref$search === void 0 ? "" : _ref$search, _ref$hash = _ref.hash, hash = _ref$hash === void 0 ? "" : _ref$hash;
805
+ if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
806
+ if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
807
+ return pathname;
808
+ }
809
+ /**
810
+ * Parses a string URL path into its separate pathname, search, and hash components.
811
+ *
812
+ * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#parsepath
813
+ */
814
+ function parsePath(path) {
815
+ var parsedPath = {};
816
+ if (path) {
817
+ var hashIndex = path.indexOf("#");
818
+ if (hashIndex >= 0) {
819
+ parsedPath.hash = path.substr(hashIndex);
820
+ path = path.substr(0, hashIndex);
821
+ }
822
+ var searchIndex = path.indexOf("?");
823
+ if (searchIndex >= 0) {
824
+ parsedPath.search = path.substr(searchIndex);
825
+ path = path.substr(0, searchIndex);
826
+ }
827
+ if (path) parsedPath.pathname = path;
828
+ }
829
+ return parsedPath;
830
+ }
831
+ //#endregion
832
+ //#region ../../node_modules/.bun/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.js
833
+ var Pe = Object.defineProperty;
834
+ var a = (e, t) => Pe(e, "name", {
835
+ value: t,
836
+ configurable: !0
837
+ });
838
+ var P = class {
839
+ type = 3;
840
+ name = "";
841
+ prefix = "";
842
+ value = "";
843
+ suffix = "";
844
+ modifier = 3;
845
+ constructor(t, r, n, c, l, f) {
846
+ this.type = t, this.name = r, this.prefix = n, this.value = c, this.suffix = l, this.modifier = f;
847
+ }
848
+ hasCustomName() {
849
+ return this.name !== "" && typeof this.name != "number";
850
+ }
851
+ };
852
+ a(P, "Part");
853
+ var Re = /[$_\p{ID_Start}]/u;
854
+ var Ee = /[$_\u200C\u200D\p{ID_Continue}]/u;
855
+ var v = ".*";
856
+ function Oe(e, t) {
857
+ return (t ? /^[\x00-\xFF]*$/ : /^[\x00-\x7F]*$/).test(e);
858
+ }
859
+ a(Oe, "isASCII");
860
+ function D(e, t = !1) {
861
+ let r = [], n = 0;
862
+ for (; n < e.length;) {
863
+ let c = e[n], l = a(function(f) {
864
+ if (!t) throw new TypeError(f);
865
+ r.push({
866
+ type: "INVALID_CHAR",
867
+ index: n,
868
+ value: e[n++]
869
+ });
870
+ }, "ErrorOrInvalid");
871
+ if (c === "*") {
872
+ r.push({
873
+ type: "ASTERISK",
874
+ index: n,
875
+ value: e[n++]
876
+ });
877
+ continue;
878
+ }
879
+ if (c === "+" || c === "?") {
880
+ r.push({
881
+ type: "OTHER_MODIFIER",
882
+ index: n,
883
+ value: e[n++]
884
+ });
885
+ continue;
886
+ }
887
+ if (c === "\\") {
888
+ r.push({
889
+ type: "ESCAPED_CHAR",
890
+ index: n++,
891
+ value: e[n++]
892
+ });
893
+ continue;
894
+ }
895
+ if (c === "{") {
896
+ r.push({
897
+ type: "OPEN",
898
+ index: n,
899
+ value: e[n++]
900
+ });
901
+ continue;
902
+ }
903
+ if (c === "}") {
904
+ r.push({
905
+ type: "CLOSE",
906
+ index: n,
907
+ value: e[n++]
908
+ });
909
+ continue;
910
+ }
911
+ if (c === ":") {
912
+ let f = "", s = n + 1;
913
+ for (; s < e.length;) {
914
+ let i = e.substr(s, 1);
915
+ if (s === n + 1 && Re.test(i) || s !== n + 1 && Ee.test(i)) {
916
+ f += e[s++];
917
+ continue;
918
+ }
919
+ break;
920
+ }
921
+ if (!f) {
922
+ l(`Missing parameter name at ${n}`);
923
+ continue;
924
+ }
925
+ r.push({
926
+ type: "NAME",
927
+ index: n,
928
+ value: f
929
+ }), n = s;
930
+ continue;
931
+ }
932
+ if (c === "(") {
933
+ let f = 1, s = "", i = n + 1, o = !1;
934
+ if (e[i] === "?") {
935
+ l(`Pattern cannot start with "?" at ${i}`);
936
+ continue;
937
+ }
938
+ for (; i < e.length;) {
939
+ if (!Oe(e[i], !1)) {
940
+ l(`Invalid character '${e[i]}' at ${i}.`), o = !0;
941
+ break;
942
+ }
943
+ if (e[i] === "\\") {
944
+ s += e[i++] + e[i++];
945
+ continue;
946
+ }
947
+ if (e[i] === ")") {
948
+ if (f--, f === 0) {
949
+ i++;
950
+ break;
951
+ }
952
+ } else if (e[i] === "(" && (f++, e[i + 1] !== "?")) {
953
+ l(`Capturing groups are not allowed at ${i}`), o = !0;
954
+ break;
955
+ }
956
+ s += e[i++];
957
+ }
958
+ if (o) continue;
959
+ if (f) {
960
+ l(`Unbalanced pattern at ${n}`);
961
+ continue;
962
+ }
963
+ if (!s) {
964
+ l(`Missing pattern at ${n}`);
965
+ continue;
966
+ }
967
+ r.push({
968
+ type: "REGEX",
969
+ index: n,
970
+ value: s
971
+ }), n = i;
972
+ continue;
973
+ }
974
+ r.push({
975
+ type: "CHAR",
976
+ index: n,
977
+ value: e[n++]
978
+ });
979
+ }
980
+ return r.push({
981
+ type: "END",
982
+ index: n,
983
+ value: ""
984
+ }), r;
985
+ }
986
+ a(D, "lexer");
987
+ function F(e, t = {}) {
988
+ let r = D(e);
989
+ t.delimiter ??= "/#?", t.prefixes ??= "./";
990
+ let n = `[^${x(t.delimiter)}]+?`, c = [], l = 0, f = 0, i = /* @__PURE__ */ new Set(), o = a((u) => {
991
+ if (f < r.length && r[f].type === u) return r[f++].value;
992
+ }, "tryConsume"), h = a(() => o("OTHER_MODIFIER") ?? o("ASTERISK"), "tryConsumeModifier"), p = a((u) => {
993
+ let d = o(u);
994
+ if (d !== void 0) return d;
995
+ let { type: g, index: y } = r[f];
996
+ throw new TypeError(`Unexpected ${g} at ${y}, expected ${u}`);
997
+ }, "mustConsume"), A = a(() => {
998
+ let u = "", d;
999
+ for (; d = o("CHAR") ?? o("ESCAPED_CHAR");) u += d;
1000
+ return u;
1001
+ }, "consumeText"), xe = a((u) => u, "DefaultEncodePart"), N = t.encodePart || xe, H = "", $ = a((u) => {
1002
+ H += u;
1003
+ }, "appendToPendingFixedValue"), M = a(() => {
1004
+ H.length && (c.push(new P(3, "", "", N(H), "", 3)), H = "");
1005
+ }, "maybeAddPartFromPendingFixedValue"), X = a((u, d, g, y, Z) => {
1006
+ let m = 3;
1007
+ switch (Z) {
1008
+ case "?":
1009
+ m = 1;
1010
+ break;
1011
+ case "*":
1012
+ m = 0;
1013
+ break;
1014
+ case "+":
1015
+ m = 2;
1016
+ break;
1017
+ }
1018
+ if (!d && !g && m === 3) {
1019
+ $(u);
1020
+ return;
1021
+ }
1022
+ if (M(), !d && !g) {
1023
+ if (!u) return;
1024
+ c.push(new P(3, "", "", N(u), "", m));
1025
+ return;
1026
+ }
1027
+ let S;
1028
+ g ? g === "*" ? S = v : S = g : S = n;
1029
+ let k = 2;
1030
+ S === n ? (k = 1, S = "") : S === v && (k = 0, S = "");
1031
+ let E;
1032
+ if (d ? E = d : g && (E = l++), i.has(E)) throw new TypeError(`Duplicate name '${E}'.`);
1033
+ i.add(E), c.push(new P(k, E, N(u), S, N(y), m));
1034
+ }, "addPart");
1035
+ for (; f < r.length;) {
1036
+ let u = o("CHAR"), d = o("NAME"), g = o("REGEX");
1037
+ if (!d && !g && (g = o("ASTERISK")), d || g) {
1038
+ let m = u ?? "";
1039
+ t.prefixes.indexOf(m) === -1 && ($(m), m = ""), M();
1040
+ let S = h();
1041
+ X(m, d, g, "", S);
1042
+ continue;
1043
+ }
1044
+ let y = u ?? o("ESCAPED_CHAR");
1045
+ if (y) {
1046
+ $(y);
1047
+ continue;
1048
+ }
1049
+ if (o("OPEN")) {
1050
+ let m = A(), S = o("NAME"), k = o("REGEX");
1051
+ !S && !k && (k = o("ASTERISK"));
1052
+ let E = A();
1053
+ p("CLOSE");
1054
+ let be = h();
1055
+ X(m, S, k, E, be);
1056
+ continue;
1057
+ }
1058
+ M(), p("END");
1059
+ }
1060
+ return c;
1061
+ }
1062
+ a(F, "parse");
1063
+ function x(e) {
1064
+ return e.replace(/([.+*?^${}()[\]|/\\])/g, "\\$1");
1065
+ }
1066
+ a(x, "escapeString");
1067
+ function B(e) {
1068
+ return e && e.ignoreCase ? "ui" : "u";
1069
+ }
1070
+ a(B, "flags");
1071
+ function q(e, t, r) {
1072
+ return W(F(e, r), t, r);
1073
+ }
1074
+ a(q, "stringToRegexp");
1075
+ function T(e) {
1076
+ switch (e) {
1077
+ case 0: return "*";
1078
+ case 1: return "?";
1079
+ case 2: return "+";
1080
+ case 3: return "";
1081
+ }
1082
+ }
1083
+ a(T, "modifierToString");
1084
+ function W(e, t, r = {}) {
1085
+ r.delimiter ??= "/#?", r.prefixes ??= "./", r.sensitive ??= !1, r.strict ??= !1, r.end ??= !0, r.start ??= !0, r.endsWith = "";
1086
+ let n = r.start ? "^" : "";
1087
+ for (let s of e) {
1088
+ if (s.type === 3) {
1089
+ s.modifier === 3 ? n += x(s.value) : n += `(?:${x(s.value)})${T(s.modifier)}`;
1090
+ continue;
1091
+ }
1092
+ t && t.push(s.name);
1093
+ let i = `[^${x(r.delimiter)}]+?`, o = s.value;
1094
+ if (s.type === 1 ? o = i : s.type === 0 && (o = v), !s.prefix.length && !s.suffix.length) {
1095
+ s.modifier === 3 || s.modifier === 1 ? n += `(${o})${T(s.modifier)}` : n += `((?:${o})${T(s.modifier)})`;
1096
+ continue;
1097
+ }
1098
+ if (s.modifier === 3 || s.modifier === 1) {
1099
+ n += `(?:${x(s.prefix)}(${o})${x(s.suffix)})`, n += T(s.modifier);
1100
+ continue;
1101
+ }
1102
+ n += `(?:${x(s.prefix)}`, n += `((?:${o})(?:`, n += x(s.suffix), n += x(s.prefix), n += `(?:${o}))*)${x(s.suffix)})`, s.modifier === 0 && (n += "?");
1103
+ }
1104
+ let c = `[${x(r.endsWith)}]|$`, l = `[${x(r.delimiter)}]`;
1105
+ if (r.end) return r.strict || (n += `${l}?`), r.endsWith.length ? n += `(?=${c})` : n += "$", new RegExp(n, B(r));
1106
+ r.strict || (n += `(?:${l}(?=${c}))?`);
1107
+ let f = !1;
1108
+ if (e.length) {
1109
+ let s = e[e.length - 1];
1110
+ s.type === 3 && s.modifier === 3 && (f = r.delimiter.indexOf(s) > -1);
1111
+ }
1112
+ return f || (n += `(?=${l}|${c})`), new RegExp(n, B(r));
1113
+ }
1114
+ a(W, "partsToRegexp");
1115
+ var b = {
1116
+ delimiter: "",
1117
+ prefixes: "",
1118
+ sensitive: !0,
1119
+ strict: !0
1120
+ };
1121
+ var J = {
1122
+ delimiter: ".",
1123
+ prefixes: "",
1124
+ sensitive: !0,
1125
+ strict: !0
1126
+ };
1127
+ var Q = {
1128
+ delimiter: "/",
1129
+ prefixes: "/",
1130
+ sensitive: !0,
1131
+ strict: !0
1132
+ };
1133
+ function ee(e, t) {
1134
+ return e.length ? e[0] === "/" ? !0 : !t || e.length < 2 ? !1 : (e[0] == "\\" || e[0] == "{") && e[1] == "/" : !1;
1135
+ }
1136
+ a(ee, "isAbsolutePathname");
1137
+ function te(e, t) {
1138
+ return e.startsWith(t) ? e.substring(t.length, e.length) : e;
1139
+ }
1140
+ a(te, "maybeStripPrefix");
1141
+ function ke(e, t) {
1142
+ return e.endsWith(t) ? e.substr(0, e.length - t.length) : e;
1143
+ }
1144
+ a(ke, "maybeStripSuffix");
1145
+ function _(e) {
1146
+ return !e || e.length < 2 ? !1 : e[0] === "[" || (e[0] === "\\" || e[0] === "{") && e[1] === "[";
1147
+ }
1148
+ a(_, "treatAsIPv6Hostname");
1149
+ var re = [
1150
+ "ftp",
1151
+ "file",
1152
+ "http",
1153
+ "https",
1154
+ "ws",
1155
+ "wss"
1156
+ ];
1157
+ function U(e) {
1158
+ if (!e) return !0;
1159
+ for (let t of re) if (e.test(t)) return !0;
1160
+ return !1;
1161
+ }
1162
+ a(U, "isSpecialScheme");
1163
+ function ne(e, t) {
1164
+ if (e = te(e, "#"), t || e === "") return e;
1165
+ let r = new URL("https://example.com");
1166
+ return r.hash = e, r.hash ? r.hash.substring(1, r.hash.length) : "";
1167
+ }
1168
+ a(ne, "canonicalizeHash");
1169
+ function se(e, t) {
1170
+ if (e = te(e, "?"), t || e === "") return e;
1171
+ let r = new URL("https://example.com");
1172
+ return r.search = e, r.search ? r.search.substring(1, r.search.length) : "";
1173
+ }
1174
+ a(se, "canonicalizeSearch");
1175
+ function ie(e, t) {
1176
+ return t || e === "" ? e : _(e) ? K(e) : j(e);
1177
+ }
1178
+ a(ie, "canonicalizeHostname");
1179
+ function ae(e, t) {
1180
+ if (t || e === "") return e;
1181
+ let r = new URL("https://example.com");
1182
+ return r.password = e, r.password;
1183
+ }
1184
+ a(ae, "canonicalizePassword");
1185
+ function oe(e, t) {
1186
+ if (t || e === "") return e;
1187
+ let r = new URL("https://example.com");
1188
+ return r.username = e, r.username;
1189
+ }
1190
+ a(oe, "canonicalizeUsername");
1191
+ function ce(e, t, r) {
1192
+ if (r || e === "") return e;
1193
+ if (t && !re.includes(t)) return new URL(`${t}:${e}`).pathname;
1194
+ let n = e[0] == "/";
1195
+ return e = new URL(n ? e : "/-" + e, "https://example.com").pathname, n || (e = e.substring(2, e.length)), e;
1196
+ }
1197
+ a(ce, "canonicalizePathname");
1198
+ function le(e, t, r) {
1199
+ return z(t) === e && (e = ""), r || e === "" ? e : G(e);
1200
+ }
1201
+ a(le, "canonicalizePort");
1202
+ function fe(e, t) {
1203
+ return e = ke(e, ":"), t || e === "" ? e : w(e);
1204
+ }
1205
+ a(fe, "canonicalizeProtocol");
1206
+ function z(e) {
1207
+ switch (e) {
1208
+ case "ws":
1209
+ case "http": return "80";
1210
+ case "wws":
1211
+ case "https": return "443";
1212
+ case "ftp": return "21";
1213
+ default: return "";
1214
+ }
1215
+ }
1216
+ a(z, "defaultPortForProtocol");
1217
+ function w(e) {
1218
+ if (e === "") return e;
1219
+ if (/^[-+.A-Za-z0-9]*$/.test(e)) return e.toLowerCase();
1220
+ throw new TypeError(`Invalid protocol '${e}'.`);
1221
+ }
1222
+ a(w, "protocolEncodeCallback");
1223
+ function he(e) {
1224
+ if (e === "") return e;
1225
+ let t = new URL("https://example.com");
1226
+ return t.username = e, t.username;
1227
+ }
1228
+ a(he, "usernameEncodeCallback");
1229
+ function ue(e) {
1230
+ if (e === "") return e;
1231
+ let t = new URL("https://example.com");
1232
+ return t.password = e, t.password;
1233
+ }
1234
+ a(ue, "passwordEncodeCallback");
1235
+ function j(e) {
1236
+ if (e === "") return e;
1237
+ if (/[\t\n\r #%/:<>?@[\]^\\|]/g.test(e)) throw new TypeError(`Invalid hostname '${e}'`);
1238
+ let t = new URL("https://example.com");
1239
+ return t.hostname = e, t.hostname;
1240
+ }
1241
+ a(j, "hostnameEncodeCallback");
1242
+ function K(e) {
1243
+ if (e === "") return e;
1244
+ if (/[^0-9a-fA-F[\]:]/g.test(e)) throw new TypeError(`Invalid IPv6 hostname '${e}'`);
1245
+ return e.toLowerCase();
1246
+ }
1247
+ a(K, "ipv6HostnameEncodeCallback");
1248
+ function G(e) {
1249
+ if (e === "" || /^[0-9]*$/.test(e) && parseInt(e) <= 65535) return e;
1250
+ throw new TypeError(`Invalid port '${e}'.`);
1251
+ }
1252
+ a(G, "portEncodeCallback");
1253
+ function de(e) {
1254
+ if (e === "") return e;
1255
+ let t = new URL("https://example.com");
1256
+ return t.pathname = e[0] !== "/" ? "/-" + e : e, e[0] !== "/" ? t.pathname.substring(2, t.pathname.length) : t.pathname;
1257
+ }
1258
+ a(de, "standardURLPathnameEncodeCallback");
1259
+ function pe(e) {
1260
+ return e === "" ? e : new URL(`data:${e}`).pathname;
1261
+ }
1262
+ a(pe, "pathURLPathnameEncodeCallback");
1263
+ function ge(e) {
1264
+ if (e === "") return e;
1265
+ let t = new URL("https://example.com");
1266
+ return t.search = e, t.search.substring(1, t.search.length);
1267
+ }
1268
+ a(ge, "searchEncodeCallback");
1269
+ function me(e) {
1270
+ if (e === "") return e;
1271
+ let t = new URL("https://example.com");
1272
+ return t.hash = e, t.hash.substring(1, t.hash.length);
1273
+ }
1274
+ a(me, "hashEncodeCallback");
1275
+ var C$1 = class {
1276
+ #i;
1277
+ #n = [];
1278
+ #t = {};
1279
+ #e = 0;
1280
+ #s = 1;
1281
+ #l = 0;
1282
+ #o = 0;
1283
+ #d = 0;
1284
+ #p = 0;
1285
+ #g = !1;
1286
+ constructor(t) {
1287
+ this.#i = t;
1288
+ }
1289
+ get result() {
1290
+ return this.#t;
1291
+ }
1292
+ parse() {
1293
+ for (this.#n = D(this.#i, !0); this.#e < this.#n.length; this.#e += this.#s) {
1294
+ if (this.#s = 1, this.#n[this.#e].type === "END") {
1295
+ if (this.#o === 0) {
1296
+ this.#b(), this.#f() ? this.#r(9, 1) : this.#h() ? this.#r(8, 1) : this.#r(7, 0);
1297
+ continue;
1298
+ } else if (this.#o === 2) {
1299
+ this.#u(5);
1300
+ continue;
1301
+ }
1302
+ this.#r(10, 0);
1303
+ break;
1304
+ }
1305
+ if (this.#d > 0) if (this.#A()) this.#d -= 1;
1306
+ else continue;
1307
+ if (this.#T()) {
1308
+ this.#d += 1;
1309
+ continue;
1310
+ }
1311
+ switch (this.#o) {
1312
+ case 0:
1313
+ this.#P() && this.#u(1);
1314
+ break;
1315
+ case 1:
1316
+ if (this.#P()) {
1317
+ this.#C();
1318
+ let t = 7, r = 1;
1319
+ this.#E() ? (t = 2, r = 3) : this.#g && (t = 2), this.#r(t, r);
1320
+ }
1321
+ break;
1322
+ case 2:
1323
+ this.#S() ? this.#u(3) : (this.#x() || this.#h() || this.#f()) && this.#u(5);
1324
+ break;
1325
+ case 3:
1326
+ this.#O() ? this.#r(4, 1) : this.#S() && this.#r(5, 1);
1327
+ break;
1328
+ case 4:
1329
+ this.#S() && this.#r(5, 1);
1330
+ break;
1331
+ case 5:
1332
+ this.#y() ? this.#p += 1 : this.#w() && (this.#p -= 1), this.#k() && !this.#p ? this.#r(6, 1) : this.#x() ? this.#r(7, 0) : this.#h() ? this.#r(8, 1) : this.#f() && this.#r(9, 1);
1333
+ break;
1334
+ case 6:
1335
+ this.#x() ? this.#r(7, 0) : this.#h() ? this.#r(8, 1) : this.#f() && this.#r(9, 1);
1336
+ break;
1337
+ case 7:
1338
+ this.#h() ? this.#r(8, 1) : this.#f() && this.#r(9, 1);
1339
+ break;
1340
+ case 8:
1341
+ this.#f() && this.#r(9, 1);
1342
+ break;
1343
+ case 9: break;
1344
+ case 10: break;
1345
+ }
1346
+ }
1347
+ this.#t.hostname !== void 0 && this.#t.port === void 0 && (this.#t.port = "");
1348
+ }
1349
+ #r(t, r) {
1350
+ switch (this.#o) {
1351
+ case 0: break;
1352
+ case 1:
1353
+ this.#t.protocol = this.#c();
1354
+ break;
1355
+ case 2: break;
1356
+ case 3:
1357
+ this.#t.username = this.#c();
1358
+ break;
1359
+ case 4:
1360
+ this.#t.password = this.#c();
1361
+ break;
1362
+ case 5:
1363
+ this.#t.hostname = this.#c();
1364
+ break;
1365
+ case 6:
1366
+ this.#t.port = this.#c();
1367
+ break;
1368
+ case 7:
1369
+ this.#t.pathname = this.#c();
1370
+ break;
1371
+ case 8:
1372
+ this.#t.search = this.#c();
1373
+ break;
1374
+ case 9:
1375
+ this.#t.hash = this.#c();
1376
+ break;
1377
+ case 10: break;
1378
+ }
1379
+ this.#o !== 0 && t !== 10 && ([
1380
+ 1,
1381
+ 2,
1382
+ 3,
1383
+ 4
1384
+ ].includes(this.#o) && [
1385
+ 6,
1386
+ 7,
1387
+ 8,
1388
+ 9
1389
+ ].includes(t) && (this.#t.hostname ??= ""), [
1390
+ 1,
1391
+ 2,
1392
+ 3,
1393
+ 4,
1394
+ 5,
1395
+ 6
1396
+ ].includes(this.#o) && [8, 9].includes(t) && (this.#t.pathname ??= this.#g ? "/" : ""), [
1397
+ 1,
1398
+ 2,
1399
+ 3,
1400
+ 4,
1401
+ 5,
1402
+ 6,
1403
+ 7
1404
+ ].includes(this.#o) && t === 9 && (this.#t.search ??= "")), this.#R(t, r);
1405
+ }
1406
+ #R(t, r) {
1407
+ this.#o = t, this.#l = this.#e + r, this.#e += r, this.#s = 0;
1408
+ }
1409
+ #b() {
1410
+ this.#e = this.#l, this.#s = 0;
1411
+ }
1412
+ #u(t) {
1413
+ this.#b(), this.#o = t;
1414
+ }
1415
+ #m(t) {
1416
+ return t < 0 && (t = this.#n.length - t), t < this.#n.length ? this.#n[t] : this.#n[this.#n.length - 1];
1417
+ }
1418
+ #a(t, r) {
1419
+ let n = this.#m(t);
1420
+ return n.value === r && (n.type === "CHAR" || n.type === "ESCAPED_CHAR" || n.type === "INVALID_CHAR");
1421
+ }
1422
+ #P() {
1423
+ return this.#a(this.#e, ":");
1424
+ }
1425
+ #E() {
1426
+ return this.#a(this.#e + 1, "/") && this.#a(this.#e + 2, "/");
1427
+ }
1428
+ #S() {
1429
+ return this.#a(this.#e, "@");
1430
+ }
1431
+ #O() {
1432
+ return this.#a(this.#e, ":");
1433
+ }
1434
+ #k() {
1435
+ return this.#a(this.#e, ":");
1436
+ }
1437
+ #x() {
1438
+ return this.#a(this.#e, "/");
1439
+ }
1440
+ #h() {
1441
+ if (this.#a(this.#e, "?")) return !0;
1442
+ if (this.#n[this.#e].value !== "?") return !1;
1443
+ let t = this.#m(this.#e - 1);
1444
+ return t.type !== "NAME" && t.type !== "REGEX" && t.type !== "CLOSE" && t.type !== "ASTERISK";
1445
+ }
1446
+ #f() {
1447
+ return this.#a(this.#e, "#");
1448
+ }
1449
+ #T() {
1450
+ return this.#n[this.#e].type == "OPEN";
1451
+ }
1452
+ #A() {
1453
+ return this.#n[this.#e].type == "CLOSE";
1454
+ }
1455
+ #y() {
1456
+ return this.#a(this.#e, "[");
1457
+ }
1458
+ #w() {
1459
+ return this.#a(this.#e, "]");
1460
+ }
1461
+ #c() {
1462
+ let t = this.#n[this.#e], r = this.#m(this.#l).index;
1463
+ return this.#i.substring(r, t.index);
1464
+ }
1465
+ #C() {
1466
+ let t = {};
1467
+ Object.assign(t, b), t.encodePart = w;
1468
+ let r = q(this.#c(), void 0, t);
1469
+ this.#g = U(r);
1470
+ }
1471
+ };
1472
+ a(C$1, "Parser");
1473
+ var V = [
1474
+ "protocol",
1475
+ "username",
1476
+ "password",
1477
+ "hostname",
1478
+ "port",
1479
+ "pathname",
1480
+ "search",
1481
+ "hash"
1482
+ ];
1483
+ var O = "*";
1484
+ function Se(e, t) {
1485
+ if (typeof e != "string") throw new TypeError("parameter 1 is not of type 'string'.");
1486
+ let r = new URL(e, t);
1487
+ return {
1488
+ protocol: r.protocol.substring(0, r.protocol.length - 1),
1489
+ username: r.username,
1490
+ password: r.password,
1491
+ hostname: r.hostname,
1492
+ port: r.port,
1493
+ pathname: r.pathname,
1494
+ search: r.search !== "" ? r.search.substring(1, r.search.length) : void 0,
1495
+ hash: r.hash !== "" ? r.hash.substring(1, r.hash.length) : void 0
1496
+ };
1497
+ }
1498
+ a(Se, "extractValues");
1499
+ function R(e, t) {
1500
+ return t ? I(e) : e;
1501
+ }
1502
+ a(R, "processBaseURLString");
1503
+ function L(e, t, r) {
1504
+ let n;
1505
+ if (typeof t.baseURL == "string") try {
1506
+ n = new URL(t.baseURL), t.protocol === void 0 && (e.protocol = R(n.protocol.substring(0, n.protocol.length - 1), r)), !r && t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.username === void 0 && (e.username = R(n.username, r)), !r && t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.username === void 0 && t.password === void 0 && (e.password = R(n.password, r)), t.protocol === void 0 && t.hostname === void 0 && (e.hostname = R(n.hostname, r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && (e.port = R(n.port, r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.pathname === void 0 && (e.pathname = R(n.pathname, r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.pathname === void 0 && t.search === void 0 && (e.search = R(n.search.substring(1, n.search.length), r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.pathname === void 0 && t.search === void 0 && t.hash === void 0 && (e.hash = R(n.hash.substring(1, n.hash.length), r));
1507
+ } catch {
1508
+ throw new TypeError(`invalid baseURL '${t.baseURL}'.`);
1509
+ }
1510
+ if (typeof t.protocol == "string" && (e.protocol = fe(t.protocol, r)), typeof t.username == "string" && (e.username = oe(t.username, r)), typeof t.password == "string" && (e.password = ae(t.password, r)), typeof t.hostname == "string" && (e.hostname = ie(t.hostname, r)), typeof t.port == "string" && (e.port = le(t.port, e.protocol, r)), typeof t.pathname == "string") {
1511
+ if (e.pathname = t.pathname, n && !ee(e.pathname, r)) {
1512
+ let c = n.pathname.lastIndexOf("/");
1513
+ c >= 0 && (e.pathname = R(n.pathname.substring(0, c + 1), r) + e.pathname);
1514
+ }
1515
+ e.pathname = ce(e.pathname, e.protocol, r);
1516
+ }
1517
+ return typeof t.search == "string" && (e.search = se(t.search, r)), typeof t.hash == "string" && (e.hash = ne(t.hash, r)), e;
1518
+ }
1519
+ a(L, "applyInit");
1520
+ function I(e) {
1521
+ return e.replace(/([+*?:{}()\\])/g, "\\$1");
1522
+ }
1523
+ a(I, "escapePatternString");
1524
+ function Te(e) {
1525
+ return e.replace(/([.+*?^${}()[\]|/\\])/g, "\\$1");
1526
+ }
1527
+ a(Te, "escapeRegexpString");
1528
+ function Ae(e, t) {
1529
+ t.delimiter ??= "/#?", t.prefixes ??= "./", t.sensitive ??= !1, t.strict ??= !1, t.end ??= !0, t.start ??= !0, t.endsWith = "";
1530
+ let r = ".*", n = `[^${Te(t.delimiter)}]+?`, c = /[$_\u200C\u200D\p{ID_Continue}]/u, l = "";
1531
+ for (let f = 0; f < e.length; ++f) {
1532
+ let s = e[f];
1533
+ if (s.type === 3) {
1534
+ if (s.modifier === 3) {
1535
+ l += I(s.value);
1536
+ continue;
1537
+ }
1538
+ l += `{${I(s.value)}}${T(s.modifier)}`;
1539
+ continue;
1540
+ }
1541
+ let i = s.hasCustomName(), o = !!s.suffix.length || !!s.prefix.length && (s.prefix.length !== 1 || !t.prefixes.includes(s.prefix)), h = f > 0 ? e[f - 1] : null, p = f < e.length - 1 ? e[f + 1] : null;
1542
+ if (!o && i && s.type === 1 && s.modifier === 3 && p && !p.prefix.length && !p.suffix.length) if (p.type === 3) {
1543
+ let A = p.value.length > 0 ? p.value[0] : "";
1544
+ o = c.test(A);
1545
+ } else o = !p.hasCustomName();
1546
+ if (!o && !s.prefix.length && h && h.type === 3) {
1547
+ let A = h.value[h.value.length - 1];
1548
+ o = t.prefixes.includes(A);
1549
+ }
1550
+ o && (l += "{"), l += I(s.prefix), i && (l += `:${s.name}`), s.type === 2 ? l += `(${s.value})` : s.type === 1 ? i || (l += `(${n})`) : s.type === 0 && (!i && (!h || h.type === 3 || h.modifier !== 3 || o || s.prefix !== "") ? l += "*" : l += `(${r})`), s.type === 1 && i && s.suffix.length && c.test(s.suffix[0]) && (l += "\\"), l += I(s.suffix), o && (l += "}"), s.modifier !== 3 && (l += T(s.modifier));
1551
+ }
1552
+ return l;
1553
+ }
1554
+ a(Ae, "partsToPattern");
1555
+ var Y = class {
1556
+ #i;
1557
+ #n = {};
1558
+ #t = {};
1559
+ #e = {};
1560
+ #s = {};
1561
+ #l = !1;
1562
+ constructor(t = {}, r, n) {
1563
+ try {
1564
+ let c;
1565
+ if (typeof r == "string" ? c = r : n = r, typeof t == "string") {
1566
+ let i = new C$1(t);
1567
+ if (i.parse(), t = i.result, c === void 0 && typeof t.protocol != "string") throw new TypeError("A base URL must be provided for a relative constructor string.");
1568
+ t.baseURL = c;
1569
+ } else {
1570
+ if (!t || typeof t != "object") throw new TypeError("parameter 1 is not of type 'string' and cannot convert to dictionary.");
1571
+ if (c) throw new TypeError("parameter 1 is not of type 'string'.");
1572
+ }
1573
+ typeof n > "u" && (n = { ignoreCase: !1 });
1574
+ let l = { ignoreCase: n.ignoreCase === !0 }, f = {
1575
+ pathname: O,
1576
+ protocol: O,
1577
+ username: O,
1578
+ password: O,
1579
+ hostname: O,
1580
+ port: O,
1581
+ search: O,
1582
+ hash: O
1583
+ };
1584
+ this.#i = L(f, t, !0), z(this.#i.protocol) === this.#i.port && (this.#i.port = "");
1585
+ let s;
1586
+ for (s of V) {
1587
+ if (!(s in this.#i)) continue;
1588
+ let i = {}, o = this.#i[s];
1589
+ switch (this.#t[s] = [], s) {
1590
+ case "protocol":
1591
+ Object.assign(i, b), i.encodePart = w;
1592
+ break;
1593
+ case "username":
1594
+ Object.assign(i, b), i.encodePart = he;
1595
+ break;
1596
+ case "password":
1597
+ Object.assign(i, b), i.encodePart = ue;
1598
+ break;
1599
+ case "hostname":
1600
+ Object.assign(i, J), _(o) ? i.encodePart = K : i.encodePart = j;
1601
+ break;
1602
+ case "port":
1603
+ Object.assign(i, b), i.encodePart = G;
1604
+ break;
1605
+ case "pathname":
1606
+ U(this.#n.protocol) ? (Object.assign(i, Q, l), i.encodePart = de) : (Object.assign(i, b, l), i.encodePart = pe);
1607
+ break;
1608
+ case "search":
1609
+ Object.assign(i, b, l), i.encodePart = ge;
1610
+ break;
1611
+ case "hash":
1612
+ Object.assign(i, b, l), i.encodePart = me;
1613
+ break;
1614
+ }
1615
+ try {
1616
+ this.#s[s] = F(o, i), this.#n[s] = W(this.#s[s], this.#t[s], i), this.#e[s] = Ae(this.#s[s], i), this.#l = this.#l || this.#s[s].some((h) => h.type === 2);
1617
+ } catch {
1618
+ throw new TypeError(`invalid ${s} pattern '${this.#i[s]}'.`);
1619
+ }
1620
+ }
1621
+ } catch (c) {
1622
+ throw new TypeError(`Failed to construct 'URLPattern': ${c.message}`);
1623
+ }
1624
+ }
1625
+ get [Symbol.toStringTag]() {
1626
+ return "URLPattern";
1627
+ }
1628
+ test(t = {}, r) {
1629
+ let n = {
1630
+ pathname: "",
1631
+ protocol: "",
1632
+ username: "",
1633
+ password: "",
1634
+ hostname: "",
1635
+ port: "",
1636
+ search: "",
1637
+ hash: ""
1638
+ };
1639
+ if (typeof t != "string" && r) throw new TypeError("parameter 1 is not of type 'string'.");
1640
+ if (typeof t > "u") return !1;
1641
+ try {
1642
+ typeof t == "object" ? n = L(n, t, !1) : n = L(n, Se(t, r), !1);
1643
+ } catch {
1644
+ return !1;
1645
+ }
1646
+ let c;
1647
+ for (c of V) if (!this.#n[c].exec(n[c])) return !1;
1648
+ return !0;
1649
+ }
1650
+ exec(t = {}, r) {
1651
+ let n = {
1652
+ pathname: "",
1653
+ protocol: "",
1654
+ username: "",
1655
+ password: "",
1656
+ hostname: "",
1657
+ port: "",
1658
+ search: "",
1659
+ hash: ""
1660
+ };
1661
+ if (typeof t != "string" && r) throw new TypeError("parameter 1 is not of type 'string'.");
1662
+ if (typeof t > "u") return;
1663
+ try {
1664
+ typeof t == "object" ? n = L(n, t, !1) : n = L(n, Se(t, r), !1);
1665
+ } catch {
1666
+ return null;
1667
+ }
1668
+ let c = {};
1669
+ r ? c.inputs = [t, r] : c.inputs = [t];
1670
+ let l;
1671
+ for (l of V) {
1672
+ let f = this.#n[l].exec(n[l]);
1673
+ if (!f) return null;
1674
+ let s = {};
1675
+ for (let [i, o] of this.#t[l].entries()) if (typeof o == "string" || typeof o == "number") s[o] = f[i + 1];
1676
+ c[l] = {
1677
+ input: n[l] ?? "",
1678
+ groups: s
1679
+ };
1680
+ }
1681
+ return c;
1682
+ }
1683
+ static compareComponent(t, r, n) {
1684
+ let c = a((i, o) => {
1685
+ for (let h of [
1686
+ "type",
1687
+ "modifier",
1688
+ "prefix",
1689
+ "value",
1690
+ "suffix"
1691
+ ]) {
1692
+ if (i[h] < o[h]) return -1;
1693
+ if (i[h] === o[h]) continue;
1694
+ return 1;
1695
+ }
1696
+ return 0;
1697
+ }, "comparePart"), l = new P(3, "", "", "", "", 3), f = new P(0, "", "", "", "", 3), s = a((i, o) => {
1698
+ let h = 0;
1699
+ for (; h < Math.min(i.length, o.length); ++h) {
1700
+ let p = c(i[h], o[h]);
1701
+ if (p) return p;
1702
+ }
1703
+ return i.length === o.length ? 0 : c(i[h] ?? l, o[h] ?? l);
1704
+ }, "comparePartList");
1705
+ return !r.#e[t] && !n.#e[t] ? 0 : r.#e[t] && !n.#e[t] ? s(r.#s[t], [f]) : !r.#e[t] && n.#e[t] ? s([f], n.#s[t]) : s(r.#s[t], n.#s[t]);
1706
+ }
1707
+ get protocol() {
1708
+ return this.#e.protocol;
1709
+ }
1710
+ get username() {
1711
+ return this.#e.username;
1712
+ }
1713
+ get password() {
1714
+ return this.#e.password;
1715
+ }
1716
+ get hostname() {
1717
+ return this.#e.hostname;
1718
+ }
1719
+ get port() {
1720
+ return this.#e.port;
1721
+ }
1722
+ get pathname() {
1723
+ return this.#e.pathname;
1724
+ }
1725
+ get search() {
1726
+ return this.#e.search;
1727
+ }
1728
+ get hash() {
1729
+ return this.#e.hash;
1730
+ }
1731
+ get hasRegExpGroups() {
1732
+ return this.#l;
1733
+ }
1734
+ };
1735
+ a(Y, "URLPattern");
1736
+ //#endregion
1737
+ //#region ../../node_modules/.bun/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.js
1738
+ if (!globalThis.URLPattern) globalThis.URLPattern = Y;
1739
+ //#endregion
1740
+ //#region utils/sleep.ts
1741
+ function sleep(time) {
1742
+ return new Promise((resolve) => setTimeout(resolve, time));
1743
+ }
1744
+ //#endregion
1745
+ //#region client/ProgressManager.ts
1746
+ var ProgressManager = class {
1747
+ state = new Subject(100);
1748
+ unsubscribe;
1749
+ timer;
1750
+ tick = 0;
1751
+ isTicking = false;
1752
+ constructor(subject) {
1753
+ this.unsubscribe = subject.subscribe((state) => {
1754
+ if (state) this.start();
1755
+ else this.end();
1756
+ });
1757
+ }
1758
+ getNextIncrement() {
1759
+ const current = this.state.getValue();
1760
+ if (current === 100) return Math.ceil(Math.random() * 10);
1761
+ if (current <= 20) {
1762
+ if (Math.ceil(Math.random() * 100) > 80) return current;
1763
+ return current + Math.ceil(Math.random() * 5) + 1;
1764
+ }
1765
+ if (current <= 50) {
1766
+ if (Math.ceil(Math.random() * 100) > 50) return current;
1767
+ return Math.min(current + Math.ceil(Math.random() * 10), 70);
1768
+ }
1769
+ if (current <= 70) {
1770
+ if (Math.ceil(Math.random() * 100) > 60) return current;
1771
+ return Math.min(current + Math.ceil(Math.random() * 3), 80);
1772
+ }
1773
+ if (current <= 80) return Math.min(current + Math.ceil(Math.random() * 1), 90);
1774
+ if (current <= 90) {
1775
+ const x = Math.ceil(Math.random() * 100) > 50 ? 0 : 1;
1776
+ return Math.min(current + x, 94);
1777
+ }
1778
+ if (current <= 94) {
1779
+ const x = Math.ceil(Math.random() * 100) > 20 ? 0 : 1;
1780
+ return Math.min(current + x, 99);
1781
+ }
1782
+ }
1783
+ getNextInterval() {
1784
+ if (this.tick === 0) {
1785
+ this.tick = 1;
1786
+ return 200;
1787
+ }
1788
+ const current = this.state.getValue();
1789
+ if (current >= 88) return 400;
1790
+ if (current >= 94) return 1e3;
1791
+ if (current >= 98) return 2e3;
1792
+ return 100;
1793
+ }
1794
+ async nextTick() {
1795
+ if (!this.isTicking) return;
1796
+ await sleep(this.getNextInterval());
1797
+ if (!this.isTicking) return;
1798
+ const increment = this.getNextIncrement();
1799
+ this.state.next(Math.min(increment, 96));
1800
+ await this.nextTick();
1801
+ }
1802
+ start() {
1803
+ this.isTicking = true;
1804
+ this.nextTick();
1805
+ }
1806
+ end() {
1807
+ this.state.next(99);
1808
+ this.isTicking = false;
1809
+ this.tick = 0;
1810
+ setTimeout(() => {
1811
+ this.state.next(100);
1812
+ }, 200);
1813
+ }
1814
+ destroy() {
1815
+ this.end();
1816
+ this.unsubscribe();
1817
+ }
1818
+ };
1819
+ //#endregion
1820
+ //#region client/useLocation.ts
1821
+ function useLocation() {
1822
+ const ctx = useContext(RouteStateContext);
1823
+ if (!ctx) throw new Error("Router context not found");
1824
+ const { hash, pathname, search, state, locale } = ctx;
1825
+ return {
1826
+ hash,
1827
+ key: pathname,
1828
+ pathname,
1829
+ search,
1830
+ state,
1831
+ locale
1832
+ };
1833
+ }
1834
+ //#endregion
1835
+ //#region client/ServerDataProvider.tsx
1836
+ var ServerDataContext = createContext({});
1837
+ var ServerDataProvider = (props) => {
1838
+ let _value = props.value;
1839
+ if (props.value) _value = props.value;
1840
+ else _value = window.__GEMI_DATA__;
1841
+ return /* @__PURE__ */ jsx(ServerDataContext.Provider, {
1842
+ value: _value,
1843
+ children: props.children
1844
+ });
1845
+ };
1846
+ //#endregion
1847
+ //#region client/I18nContext.tsx
1848
+ var I18nContext = createContext({});
1849
+ var I18nProvider = (props) => {
1850
+ const { i18n } = useContext(ServerDataContext);
1851
+ const [currentLocale, setCurrentLocale] = useState(i18n.currentLocale);
1852
+ const dictionary = useRef((() => {
1853
+ const dictionary = /* @__PURE__ */ new Map();
1854
+ for (const [locale, value] of Object.entries(i18n?.dictionary ?? {})) {
1855
+ const components = /* @__PURE__ */ new Map();
1856
+ for (const [component, translations] of Object.entries(value)) components.set(component, translations);
1857
+ dictionary.set(locale, components);
1858
+ }
1859
+ return dictionary;
1860
+ })());
1861
+ function updateDictionary(translations = {}, locale) {
1862
+ for (const [locale, value] of Object.entries(translations)) {
1863
+ if (!dictionary.current.has(locale)) dictionary.current.set(locale, /* @__PURE__ */ new Map());
1864
+ const scopes = dictionary.current.get(locale);
1865
+ for (const [scope, translations] of Object.entries(value)) {
1866
+ if (!scopes.has(scope)) scopes.set(scope, {});
1867
+ scopes.set(scope, translations);
1868
+ }
1869
+ }
1870
+ changeLocale(locale);
1871
+ }
1872
+ const changeLocale = (locale) => {
1873
+ if (dictionary.current.has(locale)) setCurrentLocale(locale);
1874
+ };
1875
+ const getTranslations = (locale) => {
1876
+ return (component) => {
1877
+ return dictionary.current.get(locale).get(component);
1878
+ };
1879
+ };
1880
+ const fetchTranslations = async (pathname, locale, signal) => {
1881
+ if (Object.keys(i18n).length === 0) return;
1882
+ updateDictionary(await (await fetch(`/api/__gemi__/services/i18n/translations/${locale || currentLocale}${pathname === "/" ? "" : pathname}`, { signal })).json());
1883
+ };
1884
+ return /* @__PURE__ */ jsx(I18nContext.Provider, {
1885
+ value: {
1886
+ getComponentTranslations: getTranslations(currentLocale),
1887
+ locale: currentLocale,
1888
+ changeLocale,
1889
+ updateDictionary,
1890
+ fetchTranslations,
1891
+ supportedLocales: i18n.supportedLocales,
1892
+ defaultLocale: i18n.defaultLocale
1893
+ },
1894
+ children: props.children
1895
+ });
1896
+ };
1897
+ //#endregion
1898
+ //#region client/useNavigate.ts
1899
+ function useNavigate() {
1900
+ const { history, setNavigationAbortController } = useContext(ClientRouterContext);
1901
+ const { defaultLocale } = useContext(I18nContext);
1902
+ const location = useLocation();
1903
+ function action(pushOrReplace) {
1904
+ return async (path, ...args) => {
1905
+ const navigationAbortController = new AbortController();
1906
+ if (setNavigationAbortController) setNavigationAbortController(navigationAbortController);
1907
+ const [options = {}] = args;
1908
+ const { search = {}, params = {}, shallow, locale, hash } = {
1909
+ params: {},
1910
+ shallow: false,
1911
+ locale: null,
1912
+ hash: "",
1913
+ ...options
1914
+ };
1915
+ const urlSearchParams = new URLSearchParams(search);
1916
+ let localeSegment = location.locale;
1917
+ if (locale) localeSegment = locale;
1918
+ if (localeSegment === defaultLocale) localeSegment = "";
1919
+ const routePath = applyParams(path, params);
1920
+ const finalPath = [[`${localeSegment ? `/${localeSegment}` : ""}${routePath === "/" ? "" : routePath}`, urlSearchParams.toString()].filter((s) => s.length > 0).join("?"), hash].filter(Boolean).join("");
1921
+ if (shallow) {
1922
+ history?.[pushOrReplace](finalPath, { shallow });
1923
+ return;
1924
+ }
1925
+ history?.[pushOrReplace](finalPath === "" ? "/" : finalPath);
1926
+ };
1927
+ }
1928
+ return {
1929
+ push: action("push"),
1930
+ replace: action("replace")
1931
+ };
1932
+ }
1933
+ //#endregion
1934
+ //#region client/useSearchParams.ts
1935
+ var SearchParams = class {
1936
+ searchParams;
1937
+ callback;
1938
+ constructor(searchParams, callback) {
1939
+ this.searchParams = searchParams;
1940
+ this.callback = callback;
1941
+ }
1942
+ get(key) {
1943
+ return this.searchParams.get(key);
1944
+ }
1945
+ set(key, value) {
1946
+ let entries = {};
1947
+ if (typeof key === "string") {
1948
+ let _value = value;
1949
+ if (typeof value === "function") _value = value(this.get(key) ?? "");
1950
+ entries[key] = _value;
1951
+ } else entries = key ?? {};
1952
+ for (const [key, value] of Object.entries(entries)) {
1953
+ let _value = value;
1954
+ if (typeof value === "function") _value = value(this.get(key) ?? "");
1955
+ this.searchParams.set(key, _value);
1956
+ }
1957
+ return this;
1958
+ }
1959
+ append(key, value) {
1960
+ this.searchParams.append(key, value);
1961
+ return this;
1962
+ }
1963
+ sort() {
1964
+ this.searchParams.sort();
1965
+ return this;
1966
+ }
1967
+ clear() {
1968
+ this.searchParams = new URLSearchParams();
1969
+ return this;
1970
+ }
1971
+ delete(key) {
1972
+ const keys = Array.isArray(key) ? key : [key];
1973
+ for (const key of keys) this.searchParams.delete(key);
1974
+ return this;
1975
+ }
1976
+ toJSON() {
1977
+ const map = /* @__PURE__ */ new Map();
1978
+ for (const [key, value] of this.searchParams) if (map.has(key)) {
1979
+ const currentValue = map.get(key);
1980
+ if (Array.isArray(currentValue)) {
1981
+ currentValue.push(value);
1982
+ map.set(key, currentValue);
1983
+ } else map.set(key, [currentValue, value]);
1984
+ } else map.set(key, value);
1985
+ return Object.fromEntries(map.entries());
1986
+ }
1987
+ toString() {
1988
+ return this.searchParams.toString();
1989
+ }
1990
+ push(mode = "soft") {
1991
+ this.callback(this.toJSON(), mode === "soft");
1992
+ }
1993
+ };
1994
+ function useSearchParams() {
1995
+ const { push } = useNavigate();
1996
+ const { search, pathname } = useContext(RouteStateContext);
1997
+ const params = useParams();
1998
+ const callback = (search, shallow) => {
1999
+ push(pathname, {
2000
+ params,
2001
+ search,
2002
+ shallow
2003
+ });
2004
+ };
2005
+ return new SearchParams(new URLSearchParams(search), callback);
2006
+ }
2007
+ //#endregion
2008
+ //#region client/useRoute.ts
2009
+ function useRoute() {
2010
+ const { pathname: _pathname } = useContext(RouteStateContext);
2011
+ return {
2012
+ pathname: _pathname,
2013
+ startsWith: (pathname) => {
2014
+ return _pathname.startsWith(pathname);
2015
+ }
2016
+ };
2017
+ }
2018
+ //#endregion
2019
+ //#region client/HttpReload.tsx
2020
+ var HttpReload = () => {
2021
+ const { replace } = useNavigate();
2022
+ useSearchParams();
2023
+ const { pathname } = useRoute();
2024
+ useParams();
2025
+ const [reloading, setReloading] = useState(false);
2026
+ const handleReload = () => {
2027
+ if (typeof document !== "undefined") document.querySelectorAll("vite-error-overlay").forEach((el) => {
2028
+ if (typeof el.close === "function") el.close();
2029
+ else el.remove();
2030
+ });
2031
+ setReloading(true);
2032
+ };
2033
+ useEffect(() => {
2034
+ if (import.meta.hot) import.meta.hot.on("http-reload", handleReload);
2035
+ return () => {
2036
+ if (import.meta.hot) import.meta.hot.off("http-reload", handleReload);
2037
+ };
2038
+ }, [handleReload]);
2039
+ if (!reloading || typeof document === "undefined") return null;
2040
+ return createPortal(/* @__PURE__ */ jsx("div", {
2041
+ className: "fixed z-[1000] bottom-0 right-0 p-2",
2042
+ children: /* @__PURE__ */ jsx("div", {
2043
+ className: "p-2 bg-white text-black rounded-md shadow-md",
2044
+ children: "..."
2045
+ })
2046
+ }), document.body);
2047
+ };
2048
+ //#endregion
2049
+ //#region client/PrefetchCache.ts
2050
+ /**
2051
+ * How long a prefetched payload stays usable. Long enough to cover the gap
2052
+ * between hovering a link and clicking it, short enough that a navigation is
2053
+ * not served a snapshot the visitor would notice as out of date.
2054
+ *
2055
+ * A payload cached here is committed wholesale on navigation — including into
2056
+ * the query cache via `hydrate` — so anything that invalidates page data has to
2057
+ * `clear()` this too. `useMutation` does exactly that on every successful
2058
+ * write; locale needs no such call, since the locale segment is part of the key.
2059
+ */
2060
+ var PREFETCH_TTL = 1e4;
2061
+ /**
2062
+ * Payloads fetched ahead of a navigation, keyed by the `.json` URL that
2063
+ * navigation would request. Entries are handed over once — a navigation that
2064
+ * consumes one becomes the live route data, so keeping a copy around would only
2065
+ * let a later visit render from a stale snapshot.
2066
+ */
2067
+ var PrefetchCache = class {
2068
+ entries = /* @__PURE__ */ new Map();
2069
+ isFresh(entry) {
2070
+ return Date.now() - entry.createdAt < PREFETCH_TTL;
2071
+ }
2072
+ /** Drops what has expired, then the oldest of whatever is still over budget. */
2073
+ evict() {
2074
+ for (const [url, entry] of this.entries) if (!this.isFresh(entry)) this.entries.delete(url);
2075
+ while (this.entries.size >= 12) {
2076
+ const oldest = this.entries.keys().next().value;
2077
+ if (oldest === void 0) return;
2078
+ this.entries.delete(oldest);
2079
+ }
2080
+ }
2081
+ /**
2082
+ * Runs `load` unless the same URL is already in flight or freshly cached, so
2083
+ * a link hovered repeatedly — or a screenful of eagerly prefetched links
2084
+ * pointing at one route — costs a single request.
2085
+ */
2086
+ prime(url, load) {
2087
+ const existing = this.entries.get(url);
2088
+ if (existing && this.isFresh(existing)) return existing.promise;
2089
+ this.evict();
2090
+ const entry = {
2091
+ createdAt: Date.now(),
2092
+ promise: null
2093
+ };
2094
+ entry.promise = load().catch(() => null).then((payload) => {
2095
+ if (payload == null && this.entries.get(url) === entry) this.entries.delete(url);
2096
+ return payload;
2097
+ });
2098
+ this.entries.set(url, entry);
2099
+ return entry.promise;
2100
+ }
2101
+ /**
2102
+ * Hands the payload for `url` to a navigation, if one was prefetched and is
2103
+ * still fresh. Resolves to `null` when the prefetch failed, which callers
2104
+ * must treat as a miss.
2105
+ */
2106
+ take(url) {
2107
+ const entry = this.entries.get(url);
2108
+ if (!entry) return null;
2109
+ this.entries.delete(url);
2110
+ return this.isFresh(entry) ? entry.promise : null;
2111
+ }
2112
+ /**
2113
+ * Drops everything, for when the data behind these payloads may have moved
2114
+ * on. In-flight loads still settle; their entries are simply gone by then.
2115
+ */
2116
+ clear() {
2117
+ this.entries.clear();
2118
+ }
2119
+ /** Retained entries, fresh or not. Exposed for tests. */
2120
+ get size() {
2121
+ return this.entries.size;
2122
+ }
2123
+ };
2124
+ //#endregion
2125
+ //#region client/helpers/routeDataUrl.ts
2126
+ /**
2127
+ * The `.json` URL a route's page data is served from.
2128
+ *
2129
+ * Prefetching and navigation have to agree on this string exactly — the
2130
+ * prefetch cache is keyed by it, and any disagreement silently turns every
2131
+ * prefetch into a wasted request plus a full fetch on click.
2132
+ */
2133
+ function routeDataUrl(options) {
2134
+ const { pathname, search = "", localeSegment = "" } = options;
2135
+ return `${localeSegment}${localeSegment.length > 0 && pathname === "/" ? "" : pathname}.json${search}`;
2136
+ }
2137
+ //#endregion
2138
+ //#region client/helpers/readRoutePayload.ts
2139
+ /**
2140
+ * Reads a navigation payload response (#290).
2141
+ *
2142
+ * The body is NDJSON: the first line is the envelope (route data, meta,
2143
+ * partial info, already-resolved `prefetchedData`), later lines are
2144
+ * `[path, variantKey, data]` query results streamed as they settle
2145
+ * server-side. The returned promise resolves with the envelope as soon as
2146
+ * its line arrives — the caller commits the navigation immediately — while
2147
+ * the remaining lines keep draining in the background into `onQueryPayload`,
2148
+ * whose `hydrate()` settles any segment that suspended on that variant.
2149
+ *
2150
+ * Tolerates two other body shapes so every producer keeps working: a plain
2151
+ * single-JSON body with no trailing newline (error-path responses, buffering
2152
+ * proxies) parses as the envelope at end-of-stream, and a `Response` without
2153
+ * a readable `body` (test doubles) falls back to `.json()`.
2154
+ */
2155
+ async function readRoutePayload(response, onQueryPayload) {
2156
+ const reader = response.body?.getReader?.();
2157
+ if (!reader) try {
2158
+ return await response.json();
2159
+ } catch {
2160
+ return null;
2161
+ }
2162
+ const decoder = new TextDecoder();
2163
+ let buffer = "";
2164
+ return await new Promise((resolve) => {
2165
+ let envelopeResolved = false;
2166
+ const emitEnvelope = (value) => {
2167
+ if (envelopeResolved) return;
2168
+ envelopeResolved = true;
2169
+ resolve(value);
2170
+ };
2171
+ const handleLine = (line) => {
2172
+ if (line.trim().length === 0) return;
2173
+ let value;
2174
+ try {
2175
+ value = JSON.parse(line);
2176
+ } catch (error) {
2177
+ console.error("[gemi] Unparseable route payload line", error);
2178
+ emitEnvelope(null);
2179
+ return;
2180
+ }
2181
+ if (!envelopeResolved) {
2182
+ emitEnvelope(value);
2183
+ return;
2184
+ }
2185
+ if (Array.isArray(value) && value.length === 3) onQueryPayload?.(value);
2186
+ };
2187
+ (async () => {
2188
+ try {
2189
+ while (true) {
2190
+ const { done, value } = await reader.read();
2191
+ if (done) break;
2192
+ buffer += decoder.decode(value, { stream: true });
2193
+ let newline = buffer.indexOf("\n");
2194
+ while (newline !== -1) {
2195
+ const line = buffer.slice(0, newline);
2196
+ buffer = buffer.slice(newline + 1);
2197
+ handleLine(line);
2198
+ newline = buffer.indexOf("\n");
2199
+ }
2200
+ }
2201
+ buffer += decoder.decode();
2202
+ handleLine(buffer);
2203
+ emitEnvelope(null);
2204
+ } catch (error) {
2205
+ console.error("[gemi] Route payload stream failed", error);
2206
+ emitEnvelope(null);
2207
+ }
2208
+ })();
2209
+ });
2210
+ }
2211
+ /**
2212
+ * Reads the response to the very end and returns the envelope with every
2213
+ * streamed query result merged into its `prefetchedData` — the settled
2214
+ * aggregate a `<Link prefetch>` warms ahead of a click, equivalent to what
2215
+ * the old blocking payload contained. Buffering is the point here: a hover
2216
+ * prefetch has time, and the cache stores one complete payload.
2217
+ */
2218
+ async function readSettledRoutePayload(response) {
2219
+ if (typeof response.text !== "function") try {
2220
+ return await response.json();
2221
+ } catch {
2222
+ return null;
2223
+ }
2224
+ let text;
2225
+ try {
2226
+ text = await response.text();
2227
+ } catch {
2228
+ return null;
2229
+ }
2230
+ const lines = text.split("\n").filter((line) => line.trim().length > 0);
2231
+ if (lines.length === 0) return null;
2232
+ let envelope;
2233
+ try {
2234
+ envelope = JSON.parse(lines[0]);
2235
+ } catch {
2236
+ return null;
2237
+ }
2238
+ for (const line of lines.slice(1)) {
2239
+ let value;
2240
+ try {
2241
+ value = JSON.parse(line);
2242
+ } catch {
2243
+ continue;
2244
+ }
2245
+ if (Array.isArray(value) && value.length === 3) {
2246
+ const [path, variantKey, data] = value;
2247
+ envelope.prefetchedData ??= {};
2248
+ envelope.prefetchedData[path] ??= {};
2249
+ envelope.prefetchedData[path][variantKey] = data;
2250
+ }
2251
+ }
2252
+ return envelope;
2253
+ }
2254
+ //#endregion
2255
+ //#region i18n/dictionaryRegistry.ts
2256
+ /**
2257
+ * Parked on `globalThis` rather than in module scope, because this module gets
2258
+ * bundled more than once and the copies have to agree.
2259
+ *
2260
+ * gemi ships `gemi/client` from one Vite lib build and `gemi/dictionary` from a
2261
+ * separate Bun build, an SSR view graph externalizes some gemi subpaths and
2262
+ * bundles others, and a dictionary imported by both a view and a controller is
2263
+ * evaluated on both sides. Every one of those splits would otherwise produce a
2264
+ * second registry: views would register into one Map while the view router
2265
+ * preloaded and snapshotted from another, and the hydration payload would come
2266
+ * out empty. Module identity is not something this can depend on; a global key
2267
+ * is.
2268
+ */
2269
+ var GLOBAL_KEY = "__GEMI_DICTIONARY_REGISTRY__";
2270
+ var state = globalThis[GLOBAL_KEY] ??= {
2271
+ registry: /* @__PURE__ */ new Map(),
2272
+ resolved: /* @__PURE__ */ new Map(),
2273
+ inFlight: /* @__PURE__ */ new Map(),
2274
+ degraded: /* @__PURE__ */ new Map(),
2275
+ order: [],
2276
+ warmed: /* @__PURE__ */ new Map(),
2277
+ activeLocale: null
2278
+ };
2279
+ var { registry, resolved, inFlight, degraded, order, warmed } = state;
2280
+ function cacheKey(id, locale) {
2281
+ return `${id}\0${locale}`;
2282
+ }
2283
+ function registerDictionary(entry) {
2284
+ if (registry.has(entry.id)) return;
2285
+ registry.set(entry.id, entry);
2286
+ order.push(entry.id);
2287
+ }
2288
+ /** A marker for "everything registered so far", for `preloadDictionaries`. */
2289
+ function dictionaryRegistrationMark() {
2290
+ return order.length;
2291
+ }
2292
+ function getResolved(id, locale) {
2293
+ return resolved.get(id)?.get(locale);
2294
+ }
2295
+ function putResolved(id, locale, strings) {
2296
+ let byLocale = resolved.get(id);
2297
+ if (!byLocale) {
2298
+ byLocale = /* @__PURE__ */ new Map();
2299
+ resolved.set(id, byLocale);
2300
+ }
2301
+ byLocale.set(locale, strings);
2302
+ }
2303
+ /**
2304
+ * Load one dictionary's locale, de-duplicating concurrent callers. Returns the
2305
+ * strings directly (not a promise) when they are already resolved, so the hook
2306
+ * can take a synchronous path without a microtask hop.
2307
+ */
2308
+ function loadDictionary(id, locale) {
2309
+ const already = getResolved(id, locale);
2310
+ if (already) return already;
2311
+ const key = cacheKey(id, locale);
2312
+ const pending = inFlight.get(key);
2313
+ if (pending) return pending;
2314
+ const entry = registry.get(id);
2315
+ if (!entry) throw new Error(`Unknown dictionary "${id}". A dictionary must be created with defineDictionary() and its module must have been evaluated before it is read.`);
2316
+ const result = entry.load(locale);
2317
+ if (!(result instanceof Promise)) {
2318
+ putResolved(id, locale, result);
2319
+ return result;
2320
+ }
2321
+ const promise = result.then((strings) => {
2322
+ putResolved(id, locale, strings);
2323
+ inFlight.delete(key);
2324
+ return strings;
2325
+ }, (err) => {
2326
+ inFlight.delete(key);
2327
+ throw err;
2328
+ });
2329
+ inFlight.set(key, promise);
2330
+ return promise;
2331
+ }
2332
+ /**
2333
+ * The same load, but as something safe to hand React's `use()`.
2334
+ *
2335
+ * A rejecting promise passed to `use()` rethrows during render, which unmounts
2336
+ * the whole route into its error boundary — or, before the shell is ready,
2337
+ * fails the server render outright. A missing locale chunk is a routine event
2338
+ * (a browser holding stale HTML after a rolling deploy requests a hashed
2339
+ * filename that no longer exists), and the deprecated `useTranslator` degraded
2340
+ * every i18n failure to rendering the raw key. This keeps that behaviour: the
2341
+ * returned promise resolves to no strings, and the per-key lookup in
2342
+ * `useDictionary` then logs and falls back to the key.
2343
+ *
2344
+ * The degraded promise is cached because `use()` requires a stable reference —
2345
+ * a fresh `.then()` per render would suspend forever. It is only consulted
2346
+ * after `getResolved` misses, so a later successful load supersedes it without
2347
+ * needing to be evicted.
2348
+ */
2349
+ function loadDictionaryForRender(id, locale) {
2350
+ const already = getResolved(id, locale);
2351
+ if (already) return already;
2352
+ const key = cacheKey(id, locale);
2353
+ const cached = degraded.get(key);
2354
+ if (cached) return cached;
2355
+ const result = loadDictionary(id, locale);
2356
+ if (!(result instanceof Promise)) return result;
2357
+ const safe = result.then((strings) => strings, (err) => {
2358
+ console.error(`Failed to load dictionary ${id} for locale ${locale}; rendering keys instead.`, err);
2359
+ return EMPTY_STRINGS;
2360
+ });
2361
+ degraded.set(key, safe);
2362
+ return safe;
2363
+ }
2364
+ var EMPTY_STRINGS = {};
2365
+ /**
2366
+ * Warm dictionaries for `locale`, so a subsequent render reads them
2367
+ * synchronously instead of suspending.
2368
+ *
2369
+ * With a `mark` — the value taken *before* importing a view module — only that
2370
+ * view's newly announced dictionaries are loaded. That is the client's use: it
2371
+ * knows exactly which chunk just arrived.
2372
+ *
2373
+ * Without one, it resumes from where this locale last got to. The server calls
2374
+ * it per request and has no mark to give (view modules were imported long
2375
+ * before the request arrived), so a plain scan from zero would walk every
2376
+ * dictionary in the app on every request — re-deriving the per-request cost this
2377
+ * whole change exists to remove, just with a smaller constant.
2378
+ *
2379
+ * An empty `locale` means the app configured none, and each dictionary is warmed
2380
+ * under its own source language — the same key `useDictionary` will ask for, so
2381
+ * the warmed entry is the one the render actually reads.
2382
+ *
2383
+ * Failures are swallowed: a dictionary that cannot load should surface at the
2384
+ * component that actually reads it, where the error names the key, rather than
2385
+ * take down an unrelated navigation.
2386
+ */
2387
+ async function preloadDictionaries(locale, mark) {
2388
+ const from = mark ?? warmed.get(locale) ?? 0;
2389
+ const ids = order.slice(from);
2390
+ if (ids.length === 0) return;
2391
+ const settled = await Promise.all(ids.map(async (id) => {
2392
+ try {
2393
+ await loadDictionary(id, localeFor(id, locale));
2394
+ return true;
2395
+ } catch {
2396
+ return false;
2397
+ }
2398
+ }));
2399
+ if (mark === void 0) {
2400
+ const firstFailure = settled.indexOf(false);
2401
+ const reached = firstFailure === -1 ? ids.length : firstFailure;
2402
+ warmed.set(locale, Math.max(warmed.get(locale) ?? 0, from + reached));
2403
+ }
2404
+ }
2405
+ /**
2406
+ * Which locale a given dictionary should be warmed under.
2407
+ *
2408
+ * `useDictionary` falls back to the dictionary's own source language when the
2409
+ * app has no locale configured, so the preload has to make the same choice or
2410
+ * it caches under a key no render ever reads — warming `""`, then suspending on
2411
+ * `"en-US"` a moment later.
2412
+ */
2413
+ function localeFor(id, locale) {
2414
+ if (locale) return locale;
2415
+ return registry.get(id)?.locales[0] ?? locale;
2416
+ }
2417
+ function setActiveLocale(locale) {
2418
+ if (locale) state.activeLocale = locale;
2419
+ }
2420
+ function getActiveLocale() {
2421
+ return state.activeLocale;
2422
+ }
2423
+ if (typeof window !== "undefined") {
2424
+ const w = window;
2425
+ const adopt = ([id, locale, strings]) => {
2426
+ putResolved(id, locale, strings);
2427
+ };
2428
+ const buffered = Array.isArray(w.__GEMI_DICT__) ? w.__GEMI_DICT__ : [];
2429
+ w.__GEMI_DICT__ = { push: adopt };
2430
+ for (const entry of buffered) adopt(entry);
2431
+ }
2432
+ //#endregion
2433
+ //#region client/helpers/flattenComponentTree.ts
2434
+ function flattenComponentTree(componentTree) {
2435
+ let out = [];
2436
+ for (const [root, branches] of componentTree) out.push(root, ...flattenComponentTree(branches).flat());
2437
+ return Array.from(new Set(out));
2438
+ }
2439
+ //#endregion
2440
+ //#region client/ComponentContext.tsx
2441
+ /**
2442
+ * Resolved view modules, not just their default exports. A route segment's
2443
+ * `Suspense` fallback and error UI come from optional named exports
2444
+ * (`Loading`, `Error`), and those have to be readable synchronously
2445
+ * while rendering — so every path that loads a view chunk records the module
2446
+ * here. Browsers dedupe the underlying dynamic import, so calling
2447
+ * `loadViewModule` repeatedly is free.
2448
+ */
2449
+ var viewModules = /* @__PURE__ */ new Map();
2450
+ var viewModuleListeners = /* @__PURE__ */ new Set();
2451
+ function loadViewModule(name) {
2452
+ const loader = typeof window !== "undefined" ? window.loaders?.[name] : void 0;
2453
+ if (!loader) return Promise.resolve(null);
2454
+ const mark = dictionaryRegistrationMark();
2455
+ return Promise.resolve(loader()).then(async (mod) => {
2456
+ const isNew = !viewModules.has(name);
2457
+ viewModules.set(name, mod);
2458
+ if (isNew) for (const listener of viewModuleListeners) listener();
2459
+ await preloadDictionaries(currentLocale(), mark);
2460
+ return mod;
2461
+ });
2462
+ }
2463
+ function currentLocale() {
2464
+ return getActiveLocale() ?? (typeof window !== "undefined" ? window.__GEMI_DATA__?.i18n?.currentLocale ?? "" : "");
2465
+ }
2466
+ function subscribeViewModules(listener) {
2467
+ viewModuleListeners.add(listener);
2468
+ return () => {
2469
+ viewModuleListeners.delete(listener);
2470
+ };
2471
+ }
2472
+ function getViewModule(name) {
2473
+ return viewModules.get(name);
2474
+ }
2475
+ var viewImportMap = null;
2476
+ if (typeof window !== "undefined" && process.env.NODE_ENV !== "test") {
2477
+ viewImportMap = {};
2478
+ const { componentTree = [] } = window.__GEMI_DATA__ ?? {};
2479
+ for (const viewName of flattenComponentTree(componentTree)) viewImportMap[viewName] = lazy(() => loadViewModule(viewName));
2480
+ }
2481
+ var ComponentsContext = createContext({
2482
+ viewImportMap,
2483
+ getViewModule
2484
+ });
2485
+ var ComponentsProvider = (props) => {
2486
+ const { modules } = props;
2487
+ const value = useMemo(() => ({
2488
+ viewImportMap: props.viewImportMap ?? viewImportMap,
2489
+ getViewModule: modules ? (name) => modules[name] ?? getViewModule(name) : getViewModule
2490
+ }), [props.viewImportMap, modules]);
2491
+ return /* @__PURE__ */ jsx(ComponentsContext.Provider, {
2492
+ value,
2493
+ children: props.children
2494
+ });
2495
+ };
2496
+ //#endregion
2497
+ //#region client/ClientRouterContext.tsx
2498
+ var ClientRouterContext = createContext({});
2499
+ var ClientRouterProvider = (props) => {
2500
+ const { children, pathname, currentPath, is404, is500, routeManifest, cssManifest, modulePreloadManifest, pageData, params, searchParams, breadcrumbs, urlLocaleSegment } = props;
2501
+ const navigationAbortControllerRef = useRef(new AbortController());
2502
+ const [isNavigatingSubject] = useState(() => {
2503
+ return new Subject(false);
2504
+ });
2505
+ const { supportedLocales = [], locale } = useContext(I18nContext);
2506
+ const [progressManager] = useState(new ProgressManager(isNavigatingSubject));
2507
+ const [prefetchCache] = useState(() => new PrefetchCache());
2508
+ const pageDataRef = useRef(structuredClone(pageData));
2509
+ const scrollHistoryRef = useRef(/* @__PURE__ */ new Map());
2510
+ /** Hrefs already announced; `null` until seeded from the shell's own hints. */
2511
+ const preloadedModulesRef = useRef(null);
2512
+ const breadcrumbsCache = useRef(new Map(Object.entries(breadcrumbs)));
2513
+ const initalViewEntries = is404 ? ["404"] : is500 ? ["500"] : routeManifest[pathname] ?? ["404"];
2514
+ const viewEntriesSubject = useRef(new Subject(initalViewEntries));
2515
+ const [routerSubject] = useState(() => {
2516
+ return new Subject({
2517
+ views: initalViewEntries,
2518
+ params,
2519
+ search: searchParams,
2520
+ state: {},
2521
+ pathname,
2522
+ hash: "",
2523
+ action: null,
2524
+ routePath: currentPath,
2525
+ locale
2526
+ });
2527
+ });
2528
+ const [history] = useState(() => {
2529
+ let history = null;
2530
+ if (typeof window !== "undefined") history = createBrowserHistory();
2531
+ return history;
2532
+ });
2533
+ const findMatchingRouteFromParams = useMemo(() => (pathname) => {
2534
+ let routePath = pathname.replace("/en-US", "").replace("/tr-TR", "");
2535
+ routePath = routePath === "" ? "/" : routePath;
2536
+ const candidates = [];
2537
+ for (const route of Object.keys(routeManifest)) if (new Y({ pathname: route }).test({ pathname: routePath })) candidates.push(route);
2538
+ return (candidates.sort((a, b) => {
2539
+ return a.split("/").length + a.split(":").length - (b.split("/").length + b.split(":").length);
2540
+ }) ?? [])[0];
2541
+ }, [routeManifest]);
2542
+ const getViewPathsFromPathname = useMemo(() => (pathname) => {
2543
+ const route = findMatchingRouteFromParams(pathname);
2544
+ return routeManifest[route] ?? [];
2545
+ }, [findMatchingRouteFromParams, routeManifest]);
2546
+ const getRoutePathnameFromHref = useMemo(() => (href) => {
2547
+ return findMatchingRouteFromParams(href);
2548
+ }, [findMatchingRouteFromParams]);
2549
+ const getParams = useMemo(() => (pathname) => {
2550
+ return new Y({ pathname: findMatchingRouteFromParams(pathname) }).exec({ pathname })?.pathname.groups ?? {};
2551
+ }, [findMatchingRouteFromParams]);
2552
+ useEffect(() => {
2553
+ history?.listen(({ location, action }) => {
2554
+ if (!window.scrollHistory) window.scrollHistory = /* @__PURE__ */ new Map();
2555
+ const { hash, pathname, search } = routerSubject.getValue();
2556
+ const key = [
2557
+ pathname,
2558
+ search,
2559
+ hash
2560
+ ].join("");
2561
+ window.scrollHistory.set(key, window.scrollY);
2562
+ let _pathname = location.pathname;
2563
+ let _locale = null;
2564
+ for (const locale of supportedLocales) if (_pathname.startsWith(`/${locale}`)) {
2565
+ _locale = locale;
2566
+ _pathname = _pathname.replace(`/${locale}`, "");
2567
+ break;
2568
+ }
2569
+ _pathname = _pathname === "" ? "/" : _pathname;
2570
+ const routePath = getRoutePathnameFromHref(_pathname);
2571
+ routerSubject.next({
2572
+ views: getViewPathsFromPathname(_pathname),
2573
+ params: getParams(_pathname),
2574
+ search: location.search,
2575
+ state: location.state,
2576
+ pathname: _pathname,
2577
+ action,
2578
+ routePath,
2579
+ hash: location.hash,
2580
+ locale: _locale
2581
+ });
2582
+ });
2583
+ }, [
2584
+ supportedLocales,
2585
+ history,
2586
+ routerSubject,
2587
+ getParams,
2588
+ getRoutePathnameFromHref,
2589
+ getViewPathsFromPathname
2590
+ ]);
2591
+ const updatePageData = (newPageData, breadcrumbs) => {
2592
+ const [key, value] = Object.entries(newPageData)[0];
2593
+ if (!pageDataRef.current?.[key]) pageDataRef.current[key] = {};
2594
+ for (const b in breadcrumbs) breadcrumbsCache.current.set(b, breadcrumbs[b]);
2595
+ pageDataRef.current[key] = value;
2596
+ };
2597
+ const getPageData = (key, pathname) => {
2598
+ return pageDataRef.current[pathname]?.[key];
2599
+ };
2600
+ const setNavigationAbortController = (controller) => {
2601
+ navigationAbortControllerRef.current.abort();
2602
+ navigationAbortControllerRef.current = controller;
2603
+ };
2604
+ const fetchRouteCSS = async (routePath) => {
2605
+ const views = routeManifest[routePath];
2606
+ if (!views) return;
2607
+ const cssFiles = views.flatMap((view) => {
2608
+ return cssManifest?.[view];
2609
+ }).filter(Boolean).filter((file) => !document.getElementById(file));
2610
+ if (cssFiles.length === 0) return;
2611
+ async function fetchCSS(path) {
2612
+ return {
2613
+ content: (await fetch(`/${path}`)).text(),
2614
+ id: path
2615
+ };
2616
+ }
2617
+ const result = await Promise.all(cssFiles?.map((file) => fetchCSS(file)));
2618
+ for (const { content, id } of result) {
2619
+ const style = document.createElement("style");
2620
+ style.id = id;
2621
+ style.textContent = await content;
2622
+ document.head.appendChild(style);
2623
+ }
2624
+ };
2625
+ /**
2626
+ * Announces every chunk a navigation to `routePath` will import.
2627
+ *
2628
+ * `loadViewModule` starts each view's own chunk, but a chunk's static
2629
+ * imports are discoverable only once it has arrived and parsed — so a
2630
+ * `layout -> view -> components` route still costs a round trip per level on
2631
+ * every navigation, holding the transition open for exactly the interval the
2632
+ * shell's head hints remove from the first load (#352). These are the same
2633
+ * per-view lists the shell renders, shipped in the document payload.
2634
+ *
2635
+ * `modulepreload` rather than `import()`: it fills the HTTP cache without
2636
+ * evaluating anything, so warming a link that is never clicked costs a
2637
+ * download and no side effects.
2638
+ */
2639
+ const preloadRouteModules = (routePath) => {
2640
+ if (typeof document === "undefined") return;
2641
+ if (!preloadedModulesRef.current) preloadedModulesRef.current = new Set(Array.from(document.querySelectorAll("link[rel=\"modulepreload\"]"), (link) => link.getAttribute("href") ?? ""));
2642
+ const preloaded = preloadedModulesRef.current;
2643
+ for (const view of routeManifest[routePath] ?? []) for (const href of modulePreloadManifest?.[view] ?? []) {
2644
+ if (preloaded.has(href)) continue;
2645
+ preloaded.add(href);
2646
+ const link = document.createElement("link");
2647
+ link.rel = "modulepreload";
2648
+ link.href = href;
2649
+ document.head.appendChild(link);
2650
+ }
2651
+ };
2652
+ /**
2653
+ * Warms everything a navigation to `target` would need: the route's page
2654
+ * data, its stylesheets and its component chunks.
2655
+ *
2656
+ * The payload is requested *without* the partial-render header, because the
2657
+ * route on screen when the link is prefetched is not necessarily the one it
2658
+ * will be clicked from — a partial response computed against the wrong base
2659
+ * has nothing sound to merge onto. A full payload is always safe to commit.
2660
+ *
2661
+ * It carries `Purpose: prefetch` so applications can tell speculative traffic
2662
+ * from a real visit — a route's handlers run either way, and a `viewport`
2663
+ * page multiplies that by the number of links on it.
2664
+ */
2665
+ const prefetchRoute = async (target) => {
2666
+ if (typeof window === "undefined") return;
2667
+ const { pathname, search = "", localeSegment = "" } = target;
2668
+ const routePath = getRoutePathnameFromHref(pathname);
2669
+ if (!routePath) return;
2670
+ const url = routeDataUrl({
2671
+ pathname,
2672
+ search,
2673
+ localeSegment
2674
+ });
2675
+ fetchRouteCSS(routePath).catch(() => {});
2676
+ preloadRouteModules(routePath);
2677
+ for (const view of routeManifest[routePath] ?? []) loadViewModule(view);
2678
+ await prefetchCache.prime(url, async () => {
2679
+ const response = await fetch(url, { headers: { Purpose: "prefetch" } });
2680
+ if (!response.ok) return null;
2681
+ return await readSettledRoutePayload(response);
2682
+ });
2683
+ };
2684
+ return /* @__PURE__ */ jsxs(ClientRouterContext.Provider, {
2685
+ value: {
2686
+ isNavigatingSubject,
2687
+ prefetchRoute,
2688
+ takePrefetched: (url) => prefetchCache.take(url),
2689
+ clearPrefetchCache: () => prefetchCache.clear(),
2690
+ getViewPathsFromPathname,
2691
+ history,
2692
+ getScrollPosition: (path) => {
2693
+ return scrollHistoryRef.current.get(path) || 0;
2694
+ },
2695
+ viewEntriesSubject: viewEntriesSubject.current,
2696
+ updatePageData,
2697
+ getPageData,
2698
+ getRoutePathnameFromHref,
2699
+ setNavigationAbortController,
2700
+ progressManager,
2701
+ fetchRouteCSS,
2702
+ preloadRouteModules,
2703
+ breadcrumbsCache: breadcrumbsCache.current,
2704
+ routerSubject,
2705
+ urlLocaleSegment
2706
+ },
2707
+ children: [children, import.meta.hot && /* @__PURE__ */ jsx(HttpReload, {})]
2708
+ });
2709
+ };
2710
+ //#endregion
2711
+ //#region client/RouteTransitionProvider.tsx
2712
+ var RouteTransitionContext = createContext({
2713
+ isTransitioning: false,
2714
+ targetPath: "",
2715
+ currentPath: ""
2716
+ });
2717
+ var RouteTransitionProvider = (props) => {
2718
+ const { isPending, isFetching, transitionPath } = props;
2719
+ return /* @__PURE__ */ jsx(RouteTransitionContext.Provider, {
2720
+ value: {
2721
+ isTransitioning: isPending || isFetching,
2722
+ targetPath: transitionPath[1],
2723
+ currentPath: transitionPath[0] || ""
2724
+ },
2725
+ children: props.children
2726
+ });
2727
+ };
2728
+ function useRouteTransition() {
2729
+ const context = useContext(RouteTransitionContext);
2730
+ if (!context) throw new Error("useRouteTransition must be used within a RouteTransitionProvider");
2731
+ return context;
2732
+ }
2733
+ //#endregion
2734
+ //#region ../../node_modules/.bun/react-error-boundary@6.1.1+83d5fd7b249dbeef/node_modules/react-error-boundary/dist/react-error-boundary.js
2735
+ var h = createContext(null);
2736
+ var c = {
2737
+ didCatch: !1,
2738
+ error: null
2739
+ };
2740
+ var m = class extends Component {
2741
+ constructor(e) {
2742
+ super(e), this.resetErrorBoundary = this.resetErrorBoundary.bind(this), this.state = c;
2743
+ }
2744
+ static getDerivedStateFromError(e) {
2745
+ return {
2746
+ didCatch: !0,
2747
+ error: e
2748
+ };
2749
+ }
2750
+ resetErrorBoundary(...e) {
2751
+ const { error: t } = this.state;
2752
+ t !== null && (this.props.onReset?.({
2753
+ args: e,
2754
+ reason: "imperative-api"
2755
+ }), this.setState(c));
2756
+ }
2757
+ componentDidCatch(e, t) {
2758
+ this.props.onError?.(e, t);
2759
+ }
2760
+ componentDidUpdate(e, t) {
2761
+ const { didCatch: o } = this.state, { resetKeys: s } = this.props;
2762
+ o && t.error !== null && C(e.resetKeys, s) && (this.props.onReset?.({
2763
+ next: s,
2764
+ prev: e.resetKeys,
2765
+ reason: "keys"
2766
+ }), this.setState(c));
2767
+ }
2768
+ render() {
2769
+ const { children: e, fallbackRender: t, FallbackComponent: o, fallback: s } = this.props, { didCatch: n, error: a } = this.state;
2770
+ let i = e;
2771
+ if (n) {
2772
+ const u = {
2773
+ error: a,
2774
+ resetErrorBoundary: this.resetErrorBoundary
2775
+ };
2776
+ if (typeof t == "function") i = t(u);
2777
+ else if (o) i = createElement(o, u);
2778
+ else if (s !== void 0) i = s;
2779
+ else throw a;
2780
+ }
2781
+ return createElement(h.Provider, { value: {
2782
+ didCatch: n,
2783
+ error: a,
2784
+ resetErrorBoundary: this.resetErrorBoundary
2785
+ } }, i);
2786
+ }
2787
+ };
2788
+ function C(r = [], e = []) {
2789
+ return r.length !== e.length || r.some((t, o) => !Object.is(t, e[o]));
2790
+ }
2791
+ //#endregion
2792
+ //#region client/WebsocketContext.tsx
2793
+ var WebSocketContext = createContext({});
2794
+ var WebSocketContextProvider = (props) => {
2795
+ const wsRef = useRef(null);
2796
+ function getWS() {
2797
+ return new Promise((resolve) => {
2798
+ if (wsRef.current) resolve(wsRef.current);
2799
+ else {
2800
+ const ws = new WebSocket("ws://localhost:5173/");
2801
+ ws.onopen = () => {
2802
+ wsRef.current = ws;
2803
+ console.log("ws opened");
2804
+ ws.addEventListener("close", () => {
2805
+ console.log("ws closed");
2806
+ wsRef.current = null;
2807
+ });
2808
+ resolve(ws);
2809
+ };
2810
+ }
2811
+ });
2812
+ }
2813
+ const subscribe = async (topic, handler) => {
2814
+ const ws = await getWS();
2815
+ ws.send(JSON.stringify({
2816
+ type: "subscribe",
2817
+ topic
2818
+ }));
2819
+ ws.addEventListener("message", handler);
2820
+ };
2821
+ const unsubscribe = async (topic, handler) => {
2822
+ const ws = await getWS();
2823
+ ws.send(JSON.stringify({
2824
+ type: "unsubscribe",
2825
+ topic
2826
+ }));
2827
+ ws.removeEventListener("message", handler);
2828
+ };
2829
+ const broadcast = async (topic, payload = {}) => {
2830
+ (await getWS()).send(JSON.stringify({
2831
+ type: "broadcast",
2832
+ topic,
2833
+ payload
2834
+ }));
2835
+ };
2836
+ useEffect(() => {
2837
+ return () => {
2838
+ if (wsRef.current) {
2839
+ wsRef.current.close();
2840
+ wsRef.current = null;
2841
+ }
2842
+ };
2843
+ }, []);
2844
+ return /* @__PURE__ */ jsx(WebSocketContext.Provider, {
2845
+ value: {
2846
+ subscribe,
2847
+ unsubscribe,
2848
+ broadcast
2849
+ },
2850
+ children: props.children
2851
+ });
2852
+ };
2853
+ //#endregion
2854
+ //#region client/ThemeProvider.tsx
2855
+ var ThemeContext = createContext({
2856
+ theme: "light",
2857
+ setTheme: (theme) => {}
2858
+ });
2859
+ function storeTheme(theme) {
2860
+ try {
2861
+ localStorage.setItem("theme", theme);
2862
+ } catch (error) {
2863
+ console.error("Failed to store theme in localStorage:", error);
2864
+ }
2865
+ }
2866
+ var ThemeProvider = (props) => {
2867
+ const [theme, setTheme] = useState(() => {
2868
+ if (props.theme) return props.theme;
2869
+ if (typeof window === "undefined") return "light";
2870
+ return localStorage.getItem("theme") || "light";
2871
+ });
2872
+ useEffect(() => {
2873
+ if (theme === "system") window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", ({ matches }) => {
2874
+ document.documentElement.classList.remove("light", "dark");
2875
+ document.documentElement.classList.add(matches ? "dark" : "light");
2876
+ });
2877
+ }, [theme]);
2878
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, {
2879
+ value: {
2880
+ theme,
2881
+ setTheme: (newTheme) => {
2882
+ setTheme(newTheme);
2883
+ storeTheme(newTheme);
2884
+ let documentTheme = newTheme;
2885
+ if (newTheme === "system") documentTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2886
+ document.documentElement.classList.remove("light", "dark");
2887
+ document.documentElement.classList.add(documentTheme);
2888
+ }
2889
+ },
2890
+ children: props.children
2891
+ });
2892
+ };
2893
+ function useTheme() {
2894
+ const context = useContext(ThemeContext);
2895
+ if (!context) throw new Error("useTheme must be used within a ThemeProvider");
2896
+ return context;
2897
+ }
2898
+ //#endregion
2899
+ export { createMemoryHistory as A, QueryError as B, I18nContext as C, useLocation as D, ServerDataProvider as E, applyParams as F, QueryConfigContext as I, QueryManagerContext as L, RouteStateContext as M, RouteStateProvider as N, ProgressManager as O, toVariantKey as P, QueryManagerProvider as R, useNavigate as S, ServerDataContext as T, Subject as V, setActiveLocale as _, m as a, useRoute as b, ClientRouterContext as c, ComponentsProvider as d, loadViewModule as f, registerDictionary as g, loadDictionaryForRender as h, WebSocketContextProvider as i, useParams as j, Action as k, ClientRouterProvider as l, loadDictionary as m, useTheme as n, RouteTransitionProvider as o, subscribeViewModules as p, WebSocketContext as r, useRouteTransition as s, ThemeProvider as t, ComponentsContext as u, readRoutePayload as v, I18nProvider as w, useSearchParams as x, routeDataUrl as y, DEFAULT_STALE_TIME as z };
2900
+
2901
+ //# sourceMappingURL=ThemeProvider-Bk1eZymb.js.map