@pyric/cli 0.1.0-alpha.16 → 0.1.0-alpha.18

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 (419) hide show
  1. package/README.md +42 -12
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts +80 -72
  3. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  4. package/dist/assurance/.generated/conformance-verdicts.js +80 -72
  5. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  6. package/dist/bridge/server/bridge.d.ts.map +1 -1
  7. package/dist/bridge/server/bridge.js +4 -2
  8. package/dist/bridge/server/bridge.js.map +1 -1
  9. package/dist/bridge/server/peer.d.ts.map +1 -1
  10. package/dist/bridge/server/peer.js +1 -0
  11. package/dist/bridge/server/peer.js.map +1 -1
  12. package/dist/cli/database-rules.d.ts.map +1 -1
  13. package/dist/cli/database-rules.js +6 -4
  14. package/dist/cli/database-rules.js.map +1 -1
  15. package/dist/cli/dev-runner.d.ts +9 -0
  16. package/dist/cli/dev-runner.d.ts.map +1 -1
  17. package/dist/cli/dev-runner.js +18 -0
  18. package/dist/cli/dev-runner.js.map +1 -1
  19. package/dist/cli/serve.d.ts.map +1 -1
  20. package/dist/cli/serve.js +62 -6
  21. package/dist/cli/serve.js.map +1 -1
  22. package/dist/cli/verify.js +2 -2
  23. package/dist/cli/verify.js.map +1 -1
  24. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  25. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  26. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  27. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  28. package/dist/conformance/.generated/can-i-use.js +1 -1
  29. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  30. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  31. package/dist/conformance/.generated/conformance-docs.js +1 -1
  32. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  33. package/dist/functions-rtdb/child.d.ts +1 -0
  34. package/dist/functions-rtdb/child.d.ts.map +1 -1
  35. package/dist/functions-rtdb/child.js +11 -1
  36. package/dist/functions-rtdb/child.js.map +1 -1
  37. package/dist/functions-rtdb/development-runtime.d.ts +1 -0
  38. package/dist/functions-rtdb/development-runtime.d.ts.map +1 -1
  39. package/dist/functions-rtdb/development-runtime.js +1 -0
  40. package/dist/functions-rtdb/development-runtime.js.map +1 -1
  41. package/dist/next/client-aliases.d.ts +11 -0
  42. package/dist/next/client-aliases.d.ts.map +1 -0
  43. package/dist/next/client-aliases.js +38 -0
  44. package/dist/next/client-aliases.js.map +1 -0
  45. package/dist/next/dev-rewrites.d.ts +9 -0
  46. package/dist/next/dev-rewrites.d.ts.map +1 -0
  47. package/dist/next/dev-rewrites.js +53 -0
  48. package/dist/next/dev-rewrites.js.map +1 -0
  49. package/dist/next/guard.d.ts +15 -0
  50. package/dist/next/guard.d.ts.map +1 -0
  51. package/dist/next/guard.js +52 -0
  52. package/dist/next/guard.js.map +1 -0
  53. package/dist/next/index.d.ts +12 -0
  54. package/dist/next/index.d.ts.map +1 -0
  55. package/dist/next/index.js +11 -0
  56. package/dist/next/index.js.map +1 -0
  57. package/dist/next/runtime-env.d.ts +7 -0
  58. package/dist/next/runtime-env.d.ts.map +1 -0
  59. package/dist/next/runtime-env.js +13 -0
  60. package/dist/next/runtime-env.js.map +1 -0
  61. package/dist/next/server-external-packages.d.ts +10 -0
  62. package/dist/next/server-external-packages.d.ts.map +1 -0
  63. package/dist/next/server-external-packages.js +34 -0
  64. package/dist/next/server-external-packages.js.map +1 -0
  65. package/dist/next/target-url.d.ts +11 -0
  66. package/dist/next/target-url.d.ts.map +1 -0
  67. package/dist/next/target-url.js +36 -0
  68. package/dist/next/target-url.js.map +1 -0
  69. package/dist/next/turbopack-config.d.ts +9 -0
  70. package/dist/next/turbopack-config.d.ts.map +1 -0
  71. package/dist/next/turbopack-config.js +39 -0
  72. package/dist/next/turbopack-config.js.map +1 -0
  73. package/dist/next/types.d.ts +40 -0
  74. package/dist/next/types.d.ts.map +1 -0
  75. package/dist/next/types.js +5 -0
  76. package/dist/next/types.js.map +1 -0
  77. package/dist/next/webpack-config.d.ts +11 -0
  78. package/dist/next/webpack-config.d.ts.map +1 -0
  79. package/dist/next/webpack-config.js +51 -0
  80. package/dist/next/webpack-config.js.map +1 -0
  81. package/dist/next/with-pyric.d.ts +22 -0
  82. package/dist/next/with-pyric.d.ts.map +1 -0
  83. package/dist/next/with-pyric.js +49 -0
  84. package/dist/next/with-pyric.js.map +1 -0
  85. package/dist/register/app-bridge.d.ts +9 -0
  86. package/dist/register/app-bridge.d.ts.map +1 -0
  87. package/dist/register/app-bridge.js +56 -0
  88. package/dist/register/app-bridge.js.map +1 -0
  89. package/dist/register/hooks.d.ts.map +1 -1
  90. package/dist/register/hooks.js +6 -1
  91. package/dist/register/hooks.js.map +1 -1
  92. package/dist/register/index.js +1 -1
  93. package/dist/register/index.js.map +1 -1
  94. package/dist/register/mapping.d.ts +3 -1
  95. package/dist/register/mapping.d.ts.map +1 -1
  96. package/dist/register/mapping.js +41 -5
  97. package/dist/register/mapping.js.map +1 -1
  98. package/dist/remote/index.d.ts.map +1 -1
  99. package/dist/remote/index.js +5 -3
  100. package/dist/remote/index.js.map +1 -1
  101. package/dist/rtdb/rules-json.d.ts +12 -0
  102. package/dist/rtdb/rules-json.d.ts.map +1 -1
  103. package/dist/rtdb/rules-json.js +98 -0
  104. package/dist/rtdb/rules-json.js.map +1 -1
  105. package/dist/serve/bundler.d.ts.map +1 -1
  106. package/dist/serve/bundler.js +2 -0
  107. package/dist/serve/bundler.js.map +1 -1
  108. package/dist/serve/discovery.d.ts +4 -4
  109. package/dist/serve/discovery.d.ts.map +1 -1
  110. package/dist/serve/discovery.js +59 -38
  111. package/dist/serve/discovery.js.map +1 -1
  112. package/dist/serve/entries/app-ai-passthrough.d.ts +8 -0
  113. package/dist/serve/entries/app-ai-passthrough.d.ts.map +1 -0
  114. package/dist/serve/entries/app-ai-passthrough.js +59 -0
  115. package/dist/serve/entries/app-ai-passthrough.js.map +1 -0
  116. package/dist/serve/entries/auth-helper-core.js +9 -7
  117. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  118. package/dist/serve/entries/auth.d.ts +1 -0
  119. package/dist/serve/entries/auth.d.ts.map +1 -1
  120. package/dist/serve/entries/auth.js +1 -0
  121. package/dist/serve/entries/auth.js.map +1 -1
  122. package/dist/serve/entries/bridge-url.d.ts.map +1 -1
  123. package/dist/serve/entries/bridge-url.js +7 -2
  124. package/dist/serve/entries/bridge-url.js.map +1 -1
  125. package/dist/serve/entries/database.d.ts +1 -0
  126. package/dist/serve/entries/database.d.ts.map +1 -1
  127. package/dist/serve/entries/database.js +1 -0
  128. package/dist/serve/entries/database.js.map +1 -1
  129. package/dist/serve/entries/firestore.d.ts +1 -0
  130. package/dist/serve/entries/firestore.d.ts.map +1 -1
  131. package/dist/serve/entries/firestore.js +1 -0
  132. package/dist/serve/entries/firestore.js.map +1 -1
  133. package/dist/serve/entries/init.d.ts.map +1 -1
  134. package/dist/serve/entries/init.js +4 -2
  135. package/dist/serve/entries/init.js.map +1 -1
  136. package/dist/serve/entries/runtime.js +23 -0
  137. package/dist/serve/entries/runtime.js.map +1 -1
  138. package/dist/serve/entries/storage.d.ts +2 -0
  139. package/dist/serve/entries/storage.d.ts.map +1 -1
  140. package/dist/serve/entries/storage.js +9 -2
  141. package/dist/serve/entries/storage.js.map +1 -1
  142. package/dist/serve/html-injection.d.ts +3 -1
  143. package/dist/serve/html-injection.d.ts.map +1 -1
  144. package/dist/serve/html-injection.js +27 -1
  145. package/dist/serve/html-injection.js.map +1 -1
  146. package/dist/serve/rules.js +2 -2
  147. package/dist/serve/rules.js.map +1 -1
  148. package/dist/serve/runtime/chip-config.d.ts +1 -1
  149. package/dist/serve/runtime/chip-config.d.ts.map +1 -1
  150. package/dist/serve/runtime/chip-config.js +16 -8
  151. package/dist/serve/runtime/chip-config.js.map +1 -1
  152. package/dist/serve/runtime/chip.d.ts.map +1 -1
  153. package/dist/serve/runtime/chip.js +24 -3
  154. package/dist/serve/runtime/chip.js.map +1 -1
  155. package/dist/serve/runtime/status.d.ts +1 -0
  156. package/dist/serve/runtime/status.d.ts.map +1 -1
  157. package/dist/serve/runtime/status.js +71 -13
  158. package/dist/serve/runtime/status.js.map +1 -1
  159. package/dist/serve/sandbox-session.d.ts +1 -0
  160. package/dist/serve/sandbox-session.d.ts.map +1 -1
  161. package/dist/serve/sandbox-session.js +30 -2
  162. package/dist/serve/sandbox-session.js.map +1 -1
  163. package/dist/serve/site-ui/_astro/_slug_.C6QfVOxJ.css +1 -0
  164. package/dist/serve/site-ui/_astro/_studio_.B6b_G1ev.css +1 -0
  165. package/dist/serve/site-ui/_astro/app.B7pBzz5N.js +11 -0
  166. package/dist/serve/site-ui/_astro/app.boex5SnQ.js +1 -0
  167. package/dist/serve/site-ui/_astro/{chess-showcase.CnoxIle5.js → chess-showcase.DDqE-QGe.js} +1 -1
  168. package/dist/serve/site-ui/_astro/{example-runtime.R1d96L6-.js → example-runtime.B0byNQOl.js} +1 -1
  169. package/dist/serve/site-ui/_astro/index.uwPvjH_1.js +1 -0
  170. package/dist/serve/site-ui/_astro/reads.Dh3z0fJy.js +1 -0
  171. package/dist/serve/site-ui/_astro/sandbox-controls.C2IqtoSw.js +1252 -0
  172. package/dist/serve/site-ui/_astro/{seed.EyI3VYEu.js → seed.CCmj00su.js} +1 -1
  173. package/dist/serve/site-ui/auth/index.html +2 -2
  174. package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
  175. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +48 -13
  176. package/dist/serve/site-ui/docs/agent/set-up-your-agent.md +74 -11
  177. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
  178. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
  179. package/dist/serve/site-ui/docs/ai-compat/index.html +85 -85
  180. package/dist/serve/site-ui/docs/ai-compat.md +84 -84
  181. package/dist/serve/site-ui/docs/api-reference/index.html +3 -1
  182. package/dist/serve/site-ui/docs/api-reference.md +2 -0
  183. package/dist/serve/site-ui/docs/app-compat/index.html +28 -28
  184. package/dist/serve/site-ui/docs/app-compat.md +27 -27
  185. package/dist/serve/site-ui/docs/auth-compat/index.html +122 -122
  186. package/dist/serve/site-ui/docs/auth-compat.md +121 -121
  187. package/dist/serve/site-ui/docs/build/ai-logic/index.html +19 -2
  188. package/dist/serve/site-ui/docs/build/ai-logic.md +28 -0
  189. package/dist/serve/site-ui/docs/build/authentication/index.html +1 -1
  190. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
  191. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
  192. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
  193. package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
  194. package/dist/serve/site-ui/docs/conformance-scores/index.html +25 -10
  195. package/dist/serve/site-ui/docs/conformance-scores.md +23 -8
  196. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -6
  197. package/dist/serve/site-ui/docs/create-pyric-reference-api.md +5 -5
  198. package/dist/serve/site-ui/docs/database-compat/index.html +200 -448
  199. package/dist/serve/site-ui/docs/database-compat.md +198 -461
  200. package/dist/serve/site-ui/docs/examples/chess/index.html +2 -2
  201. package/dist/serve/site-ui/docs/examples/index.html +1 -1
  202. package/dist/serve/site-ui/docs/firestore-compat/index.html +186 -195
  203. package/dist/serve/site-ui/docs/firestore-compat.md +184 -195
  204. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +15 -15
  205. package/dist/serve/site-ui/docs/functions-rtdb-compat.md +14 -14
  206. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
  207. package/dist/serve/site-ui/docs/get-started/nextjs/index.html +57 -0
  208. package/dist/serve/site-ui/docs/get-started/nextjs.md +86 -0
  209. package/dist/serve/site-ui/docs/get-started/start-building/index.html +38 -9
  210. package/dist/serve/site-ui/docs/get-started/start-building.md +62 -7
  211. package/dist/serve/site-ui/docs/get-started/vite/index.html +26 -0
  212. package/dist/serve/site-ui/docs/get-started/vite.md +45 -0
  213. package/dist/serve/site-ui/docs/index.json +711 -111
  214. package/dist/serve/site-ui/docs/messaging-compat/index.html +56 -56
  215. package/dist/serve/site-ui/docs/messaging-compat.md +55 -55
  216. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -1
  217. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
  218. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
  219. package/dist/serve/site-ui/docs/overview/index.html +1 -1
  220. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +39 -13
  221. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api.md +28 -2
  222. package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
  223. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +38 -6
  224. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api.md +43 -0
  225. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +9 -1
  226. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +8 -0
  227. package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
  228. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +27 -4
  229. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api.md +23 -0
  230. package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
  231. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
  232. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +1 -1
  233. package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +1 -1
  234. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
  235. package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
  236. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
  237. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
  238. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +1 -1
  239. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
  240. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +1 -1
  241. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
  242. package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
  243. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +123 -0
  244. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +99 -0
  245. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +127 -0
  246. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api.md +174 -0
  247. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
  248. package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +1 -1
  249. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +570 -326
  250. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +198 -6
  251. package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
  252. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +1 -1
  253. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +1 -1
  254. package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +2971 -627
  255. package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +2873 -517
  256. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +1 -1
  257. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
  258. package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +43 -3
  259. package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +8 -0
  260. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +26 -2
  261. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +24 -0
  262. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
  263. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +77 -9
  264. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +28 -13
  265. package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +240 -63
  266. package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +164 -5
  267. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
  268. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
  269. package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +1 -1
  270. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
  271. package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
  272. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
  273. package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +1 -1
  274. package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
  275. package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
  276. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
  277. package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -10
  278. package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api.md +0 -9
  279. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
  280. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +2 -1
  281. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +1 -0
  282. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
  283. package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
  284. package/dist/serve/site-ui/docs/rules-compat/index.html +87 -79
  285. package/dist/serve/site-ui/docs/rules-compat.md +86 -78
  286. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
  287. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
  288. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
  289. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
  290. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
  291. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
  292. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
  293. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
  294. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
  295. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
  296. package/dist/serve/site-ui/docs/storage-compat/index.html +119 -125
  297. package/dist/serve/site-ui/docs/storage-compat.md +118 -124
  298. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
  299. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
  300. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +1 -1
  301. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
  302. package/dist/serve/site-ui/docs/tutorial/index.html +2 -1
  303. package/dist/serve/site-ui/docs/tutorial.md +2 -0
  304. package/dist/serve/site-ui/examples/chess/index.html +1 -1
  305. package/dist/serve/site-ui/examples/firestore-first-write/index.html +1 -1
  306. package/dist/serve/site-ui/firestore/index.html +2 -2
  307. package/dist/serve/site-ui/index.html +2 -2
  308. package/dist/serve/site-ui/llms.txt +8 -4
  309. package/dist/serve/site-ui/rtdb/index.html +2 -2
  310. package/dist/serve/site-ui/settings/index.html +2 -2
  311. package/dist/serve/site-ui/storage/index.html +2 -2
  312. package/dist/serve/site-ui/traffic/index.html +2 -2
  313. package/dist/serve/vite-ai-config.d.ts +4 -1
  314. package/dist/serve/vite-ai-config.d.ts.map +1 -1
  315. package/dist/serve/vite-ai-config.js +83 -19
  316. package/dist/serve/vite-ai-config.js.map +1 -1
  317. package/dist/serve/vite-functions-development.d.ts.map +1 -1
  318. package/dist/serve/vite-functions-development.js +1 -0
  319. package/dist/serve/vite-functions-development.js.map +1 -1
  320. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -1
  321. package/dist/serve/vite-generation-rules-watch.js +61 -14
  322. package/dist/serve/vite-generation-rules-watch.js.map +1 -1
  323. package/dist/serve/vite-module-swap.d.ts +4 -1
  324. package/dist/serve/vite-module-swap.d.ts.map +1 -1
  325. package/dist/serve/vite-module-swap.js +106 -21
  326. package/dist/serve/vite-module-swap.js.map +1 -1
  327. package/dist/serve/vite-plugin.d.ts.map +1 -1
  328. package/dist/serve/vite-plugin.js +45 -5
  329. package/dist/serve/vite-plugin.js.map +1 -1
  330. package/dist/serve/vite-sandbox-generation.js +1 -1
  331. package/dist/serve/vite-sandbox-generation.js.map +1 -1
  332. package/dist/serve/worker/client/resumable.d.ts +30 -0
  333. package/dist/serve/worker/client/resumable.d.ts.map +1 -0
  334. package/dist/serve/worker/client/resumable.js +416 -0
  335. package/dist/serve/worker/client/resumable.js.map +1 -0
  336. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -1
  337. package/dist/serve/worker/client/rtdb-references.js +4 -1
  338. package/dist/serve/worker/client/rtdb-references.js.map +1 -1
  339. package/dist/serve/worker/client/storage.d.ts +16 -2
  340. package/dist/serve/worker/client/storage.d.ts.map +1 -1
  341. package/dist/serve/worker/client/storage.js +57 -6
  342. package/dist/serve/worker/client/storage.js.map +1 -1
  343. package/dist/serve/worker/host/rules.d.ts.map +1 -1
  344. package/dist/serve/worker/host/rules.js +2 -1
  345. package/dist/serve/worker/host/rules.js.map +1 -1
  346. package/dist/serve/worker/index.d.ts +1 -1
  347. package/dist/serve/worker/index.d.ts.map +1 -1
  348. package/dist/serve/worker/index.js +1 -1
  349. package/dist/serve/worker/index.js.map +1 -1
  350. package/dist/serve/worker/serve-init.d.ts.map +1 -1
  351. package/dist/serve/worker/serve-init.js +31 -0
  352. package/dist/serve/worker/serve-init.js.map +1 -1
  353. package/package.json +15 -4
  354. package/src/assurance/.generated/conformance-verdicts.ts +80 -72
  355. package/src/bridge/server/bridge.ts +5 -2
  356. package/src/bridge/server/peer.ts +2 -1
  357. package/src/cli/cli.test.ts +14 -0
  358. package/src/cli/database-rules.ts +6 -4
  359. package/src/cli/dev-runner.ts +21 -0
  360. package/src/cli/serve.ts +63 -5
  361. package/src/cli/verify.ts +2 -2
  362. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  363. package/src/conformance/.generated/can-i-use.ts +1 -1
  364. package/src/conformance/.generated/conformance-docs.ts +1 -1
  365. package/src/functions-rtdb/child.ts +12 -1
  366. package/src/functions-rtdb/development-runtime.ts +2 -0
  367. package/src/next/client-aliases.ts +39 -0
  368. package/src/next/dev-rewrites.ts +77 -0
  369. package/src/next/guard.ts +61 -0
  370. package/src/next/index.ts +16 -0
  371. package/src/next/runtime-env.ts +18 -0
  372. package/src/next/server-external-packages.ts +43 -0
  373. package/src/next/target-url.ts +46 -0
  374. package/src/next/turbopack-config.ts +54 -0
  375. package/src/next/types.ts +47 -0
  376. package/src/next/webpack-config.ts +71 -0
  377. package/src/next/with-pyric.ts +58 -0
  378. package/src/register/app-bridge.ts +79 -0
  379. package/src/register/hooks.ts +6 -1
  380. package/src/register/index.ts +1 -1
  381. package/src/register/mapping.ts +50 -4
  382. package/src/remote/index.ts +7 -5
  383. package/src/rtdb/rules-json.ts +110 -0
  384. package/src/serve/bundler.ts +2 -0
  385. package/src/serve/discovery.ts +65 -44
  386. package/src/serve/entries/app-ai-passthrough.ts +83 -0
  387. package/src/serve/entries/auth-helper-core.ts +9 -7
  388. package/src/serve/entries/auth.ts +1 -0
  389. package/src/serve/entries/bridge-url.ts +9 -2
  390. package/src/serve/entries/database.ts +1 -0
  391. package/src/serve/entries/firestore.ts +1 -0
  392. package/src/serve/entries/init.ts +5 -2
  393. package/src/serve/entries/runtime.ts +25 -0
  394. package/src/serve/entries/storage.ts +12 -1
  395. package/src/serve/html-injection.ts +26 -1
  396. package/src/serve/rules.ts +2 -2
  397. package/src/serve/runtime/chip-config.ts +19 -6
  398. package/src/serve/runtime/chip.ts +24 -3
  399. package/src/serve/runtime/status.ts +76 -13
  400. package/src/serve/sandbox-session.ts +31 -2
  401. package/src/serve/vite-ai-config.ts +86 -19
  402. package/src/serve/vite-functions-development.ts +1 -0
  403. package/src/serve/vite-generation-rules-watch.ts +67 -15
  404. package/src/serve/vite-module-swap.ts +121 -21
  405. package/src/serve/vite-plugin.ts +44 -6
  406. package/src/serve/vite-sandbox-generation.ts +1 -1
  407. package/src/serve/worker/client/resumable.ts +506 -0
  408. package/src/serve/worker/client/rtdb-references.ts +4 -1
  409. package/src/serve/worker/client/storage.ts +77 -7
  410. package/src/serve/worker/host/rules.ts +2 -1
  411. package/src/serve/worker/index.ts +4 -0
  412. package/src/serve/worker/serve-init.ts +30 -0
  413. package/dist/serve/site-ui/_astro/_slug_.BoKXYrnu.css +0 -1
  414. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +0 -1
  415. package/dist/serve/site-ui/_astro/app.4HeLP_FA.js +0 -109
  416. package/dist/serve/site-ui/_astro/app.BgSnCR5G.js +0 -1
  417. package/dist/serve/site-ui/_astro/index.BJiOemMX.js +0 -1
  418. package/dist/serve/site-ui/_astro/reads.BrKNdKAa.js +0 -1
  419. package/dist/serve/site-ui/_astro/sandbox-controls.BTb3EbQp.js +0 -1153
@@ -1,109 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["_astro/seed.EyI3VYEu.js","_astro/sandbox-controls.BTb3EbQp.js","_astro/jsx-runtime.D_zvdyIk.js","_astro/index.DBy5LfQW.js","_astro/reads.BrKNdKAa.js","_astro/index.BJiOemMX.js","_astro/index.DNyk7q8W.js","_astro/RulesCodeEditor.CzwHdCi9.js"])))=>i.map(i=>d[i]);
2
- import{j as a}from"./jsx-runtime.D_zvdyIk.js";import{r as f}from"./index.DBy5LfQW.js";import{r as ja,f as lc,h as Je,t as ka,j as cc,p as uc,k as js,l as Sa,m as dc,n as fc,o as _a,q as Kr,u as hc,v as pc,A as ks,F as Ss,w as pt,d as pe,x as qe,b as At,y as Hr,z as lr,B as un,i as mc,C as yc,D as bc,E as gc,G as vc,H as an,I as xc,J as Kt,K as Fe,L as cr,M as wc,N as jc,O as Ea,P as _s,Z as Ca,Q as kc,R as Sc,S as _c,T as Ec,U as Cc,V as Nc,W as Ac,X as De,Y as Sn,_ as Na,$ as Rc,a0 as Dc,g as Gr,a1 as Aa,a2 as Ic,a3 as $c,a4 as Pc,a5 as Oc,a6 as Uc,a7 as Se,a8 as Tc,a9 as Es,aa as Ra,ab as Mc,ac as Da,ad as mt,ae as lt,af as _n,ag as Lc}from"./sandbox-controls.BTb3EbQp.js";import{r as Bc,t as Ia,w as Cs,a as Fc,g as Jr,b as Rt}from"./reads.BrKNdKAa.js";import{i as $a}from"./index.BJiOemMX.js";import{r as Vc}from"./index.DNyk7q8W.js";const We={maxExpressionLength:256,maxStringLiteralLength:1024,maxAstDepth:16},qc=["serverTimestamp","increment","arrayUnion","arrayRemove","deleteField"],Wc={serverTimestamp:{min:0,max:0},increment:{min:1,max:1},arrayUnion:{min:1,max:1/0},arrayRemove:{min:1,max:1/0},deleteField:{min:0,max:0}};function zc(e){return qc.includes(e)}class Z extends Error{code="invalid-argument";pos;constructor(t,n){super(t),this.name="ExpressionLexError",this.pos=n}}class ye extends Error{code="invalid-argument";pos;constructor(t,n){super(t),this.name="ExpressionParseError",this.pos=n}}const Kc={"(":"lparen",")":"rparen","[":"lbracket","]":"rbracket",",":"comma",".":"dot","?":"question",":":"colon","+":"plus","-":"minus","*":"star","/":"slash","%":"percent"},Hc={true:"true",false:"false",null:"null"};function Gc(e){if(e.length>We.maxExpressionLength)throw new Z(`expression exceeds ${We.maxExpressionLength}-character cap (got ${e.length})`,F(We.maxExpressionLength));const t=[];let n=0;for(;n<e.length;){const r=n,s=e[n];if(s===" "||s===" "||s==="\r"||s===`
3
- `){n+=1;continue}if(s==='"'||s==="'"){const{token:o,next:l}=Xc(e,n,s);if(t.push(o),n=l,n<=r)throw new Z("lexer stalled on string",F(r));continue}if(s>="0"&&s<="9"){const{token:o,next:l}=Yc(e,n);if(t.push(o),n=l,n<=r)throw new Z("lexer stalled on number",F(r));continue}if(En(s)){const{token:o,next:l}=Jc(e,n);t.push(o),n=l;continue}if(s==="$"){const{token:o,next:l}=Ns(e,n,"$","reference");t.push(o),n=l;continue}if(s==="@"){const{token:o,next:l}=Ns(e,n,"@","sentinel");t.push(o),n=l;continue}if(s==="="&&e[n+1]==="="){t.push({kind:"eq",pos:F(n)}),n+=2;continue}if(s==="!"&&e[n+1]==="="){t.push({kind:"neq",pos:F(n)}),n+=2;continue}if(s==="<"){e[n+1]==="="?(t.push({kind:"lte",pos:F(n)}),n+=2):(t.push({kind:"lt",pos:F(n)}),n+=1);continue}if(s===">"){e[n+1]==="="?(t.push({kind:"gte",pos:F(n)}),n+=2):(t.push({kind:"gt",pos:F(n)}),n+=1);continue}if(s==="&"){if(e[n+1]!=="&")throw new Z("unexpected '&' (did you mean '&&'?)",F(n));t.push({kind:"and",pos:F(n)}),n+=2;continue}if(s==="|"){if(e[n+1]!=="|")throw new Z("unexpected '|' (did you mean '||'?)",F(n));t.push({kind:"or",pos:F(n)}),n+=2;continue}if(s==="!"){t.push({kind:"bang",pos:F(n)}),n+=1;continue}if(s==="=")throw new Z("unexpected '=' (did you mean '=='?)",F(n));const i=Kc[s];if(i){t.push({kind:i,pos:F(n)}),n+=1;continue}throw new Z(`unexpected character ${JSON.stringify(s)}`,F(n))}return t.push({kind:"eof",pos:F(e.length)}),t}function F(e){return{offset:e,column:e+1}}function En(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"||e==="_"}function Pa(e){return En(e)||e>="0"&&e<="9"}function Jc(e,t){let n=t+1;for(;n<e.length&&Pa(e[n]);)n+=1;const r=e.slice(t,n),s=Hc[r];return s?{token:{kind:s,pos:F(t)},next:n}:{token:{kind:"identifier",pos:F(t),value:r},next:n}}function Ns(e,t,n,r){const s=t+1;if(s>=e.length||!En(e[s]))throw new Z(`expected identifier after '${n}'`,F(t));let i=s+1;for(;i<e.length&&Pa(e[i]);)i+=1;const o=e.slice(s,i);return{token:{kind:r,pos:F(t),value:o},next:i}}function Yc(e,t){let n=t;const r=e[n];if(n+=1,r==="0"){if(n<e.length&&e[n]>="0"&&e[n]<="9")throw new Z("leading zeros are not allowed in number literals",F(t))}else for(;n<e.length&&e[n]>="0"&&e[n]<="9";)n+=1;let s=!1;if(n<e.length&&e[n]==="."){const l=e[n+1];if(l!==void 0&&l>="0"&&l<="9")for(s=!0,n+=1;n<e.length&&e[n]>="0"&&e[n]<="9";)n+=1;else if(!(l!==void 0&&En(l)))throw new Z("expected digit after '.' in number literal",F(n))}const i=e.slice(t,n),o=Number.parseFloat(i);if(!Number.isFinite(o))throw new Z(`numeric literal '${i}' is not finite`,F(t));if(!s&&!Number.isSafeInteger(o))throw new Z(`integer literal '${i}' exceeds safe integer range`,F(t));return{token:{kind:"number",pos:F(t),value:o},next:n}}function Xc(e,t,n){let r=t+1,s="";for(;r<e.length;){const i=e[r];if(i===n)return{token:{kind:"string",pos:F(t),value:s},next:r+1};if(i==="\\"){const o=e[r+1];if(o===void 0)throw new Z("unterminated escape sequence in string literal",F(r));switch(o){case'"':s+='"';break;case"'":s+="'";break;case"\\":s+="\\";break;case"n":s+=`
4
- `;break;case"t":s+=" ";break;default:throw new Z(`invalid escape sequence '\\${o}' (only \\", \\', \\\\, \\n, \\t are allowed)`,F(r))}r+=2}else{if(i===`
5
- `||i==="\r")throw new Z("unterminated string literal (newline before closing quote)",F(t));s+=i,r+=1}if(s.length>We.maxStringLiteralLength)throw new Z(`string literal exceeds ${We.maxStringLiteralLength}-character cap`,F(t))}throw new Z("unterminated string literal",F(t))}function Qc(e){const t=new Zc(e),n=t.parseExpression();return t.expect("eof","unexpected trailing tokens"),nu(n),n}class Zc{tokens;cursor=0;constructor(t){this.tokens=t}parseExpression(){return this.parseTernary()}parseTernary(){const t=this.parseLogicalOr();if(this.peek().kind!=="question")return t;const n=this.consume(),r=this.parseExpression();this.expect("colon","expected ':' in ternary");const s=this.parseExpression();return{kind:"ternary",cond:t,whenTrue:r,whenFalse:s,pos:n.pos}}parseLogicalOr(){let t=this.parseLogicalAnd();for(;this.peek().kind==="or";){const n=this.consume(),r=this.parseLogicalAnd();t={kind:"logical",op:"||",left:t,right:r,pos:n.pos}}return t}parseLogicalAnd(){let t=this.parseComparison();for(;this.peek().kind==="and";){const n=this.consume(),r=this.parseComparison();t={kind:"logical",op:"&&",left:t,right:r,pos:n.pos}}return t}parseComparison(){let t=this.parseSum();for(;;){const n=eu(this.peek().kind);if(!n)break;const r=this.consume(),s=this.parseSum();t={kind:"binary",op:n,left:t,right:s,pos:r.pos}}return t}parseSum(){let t=this.parseProduct();for(;;){const n=this.peek().kind;if(n!=="plus"&&n!=="minus")break;const r=this.consume(),s=this.parseProduct();t={kind:"binary",op:n==="plus"?"+":"-",left:t,right:s,pos:r.pos}}return t}parseProduct(){let t=this.parseUnary();for(;;){const n=this.peek().kind;if(n!=="star"&&n!=="slash"&&n!=="percent")break;const r=this.consume(),s=this.parseUnary();t={kind:"binary",op:n==="star"?"*":n==="slash"?"/":"%",left:t,right:s,pos:r.pos}}return t}parseUnary(){const t=this.peek().kind;if(t==="minus"||t==="bang"){const n=this.consume(),r=this.parseUnary();return{kind:"unary",op:t==="minus"?"-":"!",operand:r,pos:n.pos}}return this.parsePostfix()}parsePostfix(){let t=this.parsePrimary();for(;;){const n=this.peek().kind;if(n==="dot"){const r=this.consume(),s=this.expect("identifier","expected identifier after '.'");t={kind:"fieldAccess",target:t,field:s.value,pos:r.pos}}else if(n==="lbracket"){const r=this.consume(),s=this.parseExpression();this.expect("rbracket","expected ']'"),t={kind:"indexAccess",target:t,index:s,pos:r.pos}}else break}return t}parsePrimary(){const t=this.peek();switch(t.kind){case"number":return this.consume(),{kind:"literal",value:t.value,pos:t.pos};case"string":return this.consume(),{kind:"literal",value:t.value,pos:t.pos};case"true":return this.consume(),{kind:"literal",value:!0,pos:t.pos};case"false":return this.consume(),{kind:"literal",value:!1,pos:t.pos};case"null":return this.consume(),{kind:"literal",value:null,pos:t.pos};case"reference":return this.consume(),{kind:"reference",alias:t.value,pos:t.pos};case"sentinel":return this.parseSentinelCall();case"lparen":{this.consume();const n=this.parseExpression();return this.expect("rparen","expected ')'"),n}case"identifier":throw new ye(`bare identifier '${t.value}' is not a value (did you mean '$${t.value}' or '@${t.value}'?)`,t.pos);case"eof":throw new ye("unexpected end of expression",t.pos);default:throw new ye("unexpected token",t.pos)}}parseSentinelCall(){const t=this.consume(),n=t.value;if(!zc(n))throw new ye(`unknown sentinel '@${n}' (allowed: serverTimestamp, increment, arrayUnion, arrayRemove, deleteField)`,t.pos);this.expect("lparen",`expected '(' after sentinel '@${n}'`);const r=[];if(this.peek().kind!=="rparen")for(r.push(this.parseExpression());this.peek().kind==="comma";)this.consume(),r.push(this.parseExpression());this.expect("rparen","expected ')' after sentinel arguments");const s=Wc[n];if(r.length<s.min||r.length>s.max){const i=s.max===1/0?`at least ${s.min}`:s.min===s.max?`exactly ${s.min}`:`${s.min}..${s.max}`;throw new ye(`sentinel '@${n}' expects ${i} argument(s), got ${r.length}`,t.pos)}return{kind:"sentinel",name:n,args:r,pos:t.pos}}peek(){return this.tokens[this.cursor]}consume(){const t=this.tokens[this.cursor];return this.cursor+=1,t}expect(t,n){const r=this.peek();if(r.kind!==t)throw new ye(`${n} (got ${tu(r)})`,r.pos);return this.consume()}}function eu(e){switch(e){case"eq":return"==";case"neq":return"!=";case"lt":return"<";case"lte":return"<=";case"gt":return">";case"gte":return">=";default:return null}}function tu(e){return e.kind==="eof"?"end of expression":e.value!==void 0?`${e.kind} ${JSON.stringify(e.value)}`:e.kind}function nu(e){t(e);function t(n){let r=0;switch(n.kind){case"literal":case"reference":r=0;break;case"unary":r=t(n.operand);break;case"binary":case"logical":r=Math.max(t(n.left),t(n.right));break;case"ternary":r=Math.max(t(n.cond),t(n.whenTrue),t(n.whenFalse));break;case"fieldAccess":r=t(n.target);break;case"indexAccess":r=Math.max(t(n.target),t(n.index));break;case"sentinel":r=n.args.length===0?0:Math.max(...n.args.map(t));break}const s=r+1;if(s>We.maxAstDepth)throw new ye(`expression AST exceeds depth cap of ${We.maxAstDepth}`,n.pos);return s}}class oe extends Error{code;pos;constructor(t,n,r){super(n),this.name="EvalError",this.code=t,this.pos=r}}function Mt(e){if(typeof e!="object"||e===null)return!1;const t=e,n=t.__type,r=Object.keys(t);switch(n){case"serverTimestamp":case"deleteField":return r.length===1;case"increment":return r.length===2&&typeof t.value=="number";case"arrayUnion":case"arrayRemove":return r.length===2&&Array.isArray(t.values);default:return!1}}function ue(e,t){return new oe("type-mismatch",t,e.pos)}function le(e,t){switch(e.kind){case"literal":return e.value;case"reference":return ru(e,t);case"sentinel":return su(e,t);case"unary":return iu(e,t);case"binary":return au(e,t);case"logical":return lu(e,t);case"ternary":return cu(e,t);case"fieldAccess":return uu(e,t);case"indexAccess":return du(e,t)}}function ru(e,t){if(!Object.prototype.hasOwnProperty.call(t.reads,e.alias))throw new oe("unknown-reference",`unknown alias '$${e.alias}' (not in reads). Hint: aliases are case-sensitive; sentinels use '@' not '$'.`,e.pos);return t.reads[e.alias]??null}function su(e,t){const n=e.args.map(r=>{const s=le(r,t);if(Mt(s))throw new oe("sentinel-misuse",`sentinel '@${s.__type}' cannot be a sentinel argument`,r.pos);return s});switch(e.name){case"serverTimestamp":return{__type:"serverTimestamp"};case"deleteField":return{__type:"deleteField"};case"increment":{const r=n[0];if(typeof r!="number")throw ue(e,`'@increment' expects a numeric argument, got ${re(r)}`);return dn(r,e),{__type:"increment",value:r}}case"arrayUnion":return{__type:"arrayUnion",values:n};case"arrayRemove":return{__type:"arrayRemove",values:n}}}function iu(e,t){const n=le(e.operand,t);if(ur(n,e),e.op==="-"){if(typeof n!="number")throw ue(e,`unary '-' expects a number, got ${re(n)}`);const r=-n;return dn(r,e),r}if(typeof n!="boolean")throw ue(e,`unary '!' expects a boolean, got ${re(n)}`);return!n}function au(e,t){const n=le(e.left,t),r=le(e.right,t);switch(ur(n,e),ur(r,e),e.op){case"+":if(typeof n=="number"&&typeof r=="number"){const s=n+r;return dn(s,e),s}if(typeof n=="string"&&typeof r=="string")return n+r;throw ue(e,`'+' expects (number, number) or (string, string); got (${re(n)}, ${re(r)})`);case"-":case"*":case"/":case"%":{if(typeof n!="number"||typeof r!="number")throw ue(e,`'${e.op}' expects (number, number); got (${re(n)}, ${re(r)})`);let s;switch(e.op){case"-":s=n-r;break;case"*":s=n*r;break;case"/":s=n/r;break;case"%":s=n%r;break}return dn(s,e),s}case"==":return As(e,n,r);case"!=":return!As(e,n,r);case"<":case"<=":case">":case">=":return ou(e,n,r)}}function As(e,t,n){if(t===null||n===null)return t===n;const r=typeof t;if(r!==typeof n)return!1;if(r==="number"||r==="string"||r==="boolean")return t===n;throw ue(e,"equality between objects/arrays is not supported (compare specific fields instead)")}function ou(e,t,n){if(!(typeof t=="number"&&typeof n=="number"||typeof t=="string"&&typeof n=="string"))throw ue(e,`'${e.op}' expects matching number/number or string/string operands; got (${re(t)}, ${re(n)})`);switch(e.op){case"<":return t<n;case"<=":return t<=n;case">":return t>n;case">=":return t>=n;default:throw new Error("unreachable")}}function lu(e,t){const n=le(e.left,t);if(typeof n!="boolean")throw ue(e,`'${e.op}' expects boolean operands; left is ${re(n)}`);if(e.op==="&&"){if(!n)return!1}else if(n)return!0;const r=le(e.right,t);if(typeof r!="boolean")throw ue(e,`'${e.op}' expects boolean operands; right is ${re(r)}`);return r}function cu(e,t){const n=le(e.cond,t);if(typeof n!="boolean")throw ue(e,`ternary condition must be boolean, got ${re(n)}`);return le(n?e.whenTrue:e.whenFalse,t)}function uu(e,t){const n=le(e.target,t);if(n==null)throw new oe("null-access",`cannot access field '${e.field}' on null`,e.pos);if(typeof n!="object"||Array.isArray(n)||Mt(n))throw ue(e,`cannot access field '${e.field}' on ${re(n)}`);const r=n;return Object.prototype.hasOwnProperty.call(r,e.field)?r[e.field]:null}function du(e,t){const n=le(e.target,t);if(n==null)throw new oe("null-access","cannot index null target",e.pos);const r=le(e.index,t);if(Array.isArray(n)){if(typeof r!="number"||!Number.isInteger(r))throw new oe("invalid-index",`array index must be a non-negative integer, got ${re(r)}`,e.pos);if(r<0)throw new oe("invalid-index",`negative array index ${r} not supported (use length-based indexing in eval)`,e.pos);return r>=n.length?null:n[r]}if(typeof n=="object"&&!Mt(n)){if(typeof r!="string")throw new oe("invalid-index",`object key must be a string, got ${re(r)}`,e.pos);const s=n;return Object.prototype.hasOwnProperty.call(s,r)?s[r]:null}throw ue(e,`cannot index into ${re(n)}`)}function ur(e,t){if(Mt(e))throw new oe("sentinel-misuse",`sentinel '@${e.__type}' cannot be used as an operator operand`,t.pos)}function dn(e,t){if(!Number.isFinite(e))throw new oe("division-by-zero",`arithmetic produced a non-finite value (${Number.isNaN(e)?"NaN":"Infinity"})`,t.pos)}function re(e){if(e===null)return"null";if(Array.isArray(e))return`array(${e.length})`;if(typeof e=="object"&&e!==null){if(Mt(e))return`sentinel '@${e.__type}'`;const t=Object.keys(e);if(t.length===0)return"object {}";const n=t.slice(0,3).join(", "),r=t.length>3?", …":"";return`object {${n}${r}}`}return typeof e}const Oa="$expr";class fn extends Error{code="invalid-argument";path;constructor(t,n){super(t),this.name="ExpressionWalkError",this.path=n}}function fu(e,t){return dr(e,t,"")}function dr(e,t,n){if(e===null)return null;if(typeof e!="object")return e;if(Array.isArray(e)){const i=new Array(e.length);for(let o=0;o<e.length;o+=1)i[o]=dr(e[o],t,n===""?String(o):`${n}.${o}`);return i}const r=e;if(Object.prototype.hasOwnProperty.call(r,Oa))return hu(r,t,n);const s={};for(const i of Object.keys(r))s[i]=dr(r[i],t,n===""?i:`${n}.${i}`);return s}function hu(e,t,n){const r=Object.keys(e);if(r.length!==1)throw new fn(`expression wrapper at '${n||"<root>"}' must have only the '$expr' key, got [${r.map(l=>JSON.stringify(l)).join(", ")}]`,n);const s=e[Oa];if(typeof s!="string")throw new fn(`'$expr' value at '${n||"<root>"}' must be a string, got ${yu(s)}`,n);const i=mu(s,n);return pu(i,t,n)}function pu(e,t,n){try{return le(e,t)}catch(r){if(r instanceof oe){const s=new oe(r.code,`at '${n||"<root>"}': ${r.message}`,r.pos);throw s.cause=r,s}throw r}}function mu(e,t){try{return Qc(Gc(e))}catch(n){throw n instanceof Z?Rs(n,Z,t):n instanceof ye?Rs(n,ye,t):n}}function Rs(e,t,n){const r=new t(`at '${n||"<root>"}': ${e.message}`,e.pos);return r.cause=e,r}function yu(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function bu(e){const{resolveSandbox:t,resolveModulesFn:n}=e;return[{name:"firestore_simulator_create",description:'Seed the session\'s local Firestore environment with rules and optional initial documents. Resets any prior state. Supports `rules_version = "2+modules"` — modules resolve in-process before seeding. Returns the lint result + document count for verification.',parameters:{type:"object",properties:{rules:{type:"string",description:"Firestore security rules source (version 2 or 2+modules)."},documents:{type:"object",description:'Initial documents keyed by full path, e.g. `{ "users/u1": { name: "alice" } }`.',additionalProperties:!0}},required:["rules"]},async execute(r){const{rules:s,documents:i}=r;let o=s;if(o.includes("'2+modules'")||o.includes('"2+modules"')){if(!n)return{ok:!1,summary:"Module resolve unavailable: this builder was not wired with `resolveModulesFn`. Use a package entry that wires module resolution, such as pyric/rules/node, instead of importing the impl directly.",data:{code:"NO_MODULE_RESOLVER"}};const u=n(o);if(!u.success)return{ok:!1,summary:`Module resolve failed: ${u.error.message}`,data:u};o=u.data.resolved}const c=(await t()).seed({rules:o,documents:i??{}});return{ok:!0,summary:`Seeded sandbox with ${Object.keys(i??{}).length} document(s)`,data:{lint:c,documentCount:Object.keys(i??{}).length}}}},{name:"firestore_simulator_execute",description:"Execute a single write (create / update / delete) against the seeded sandbox. Rules evaluate against the in-memory state; allow → state mutates and the op is logged, deny → state unchanged and `debugMessages` explain the rule decision.",parameters:{type:"object",properties:{method:{type:"string",enum:["create","update","delete"]},path:{type:"string",description:"Document path, e.g. `users/u1`."},auth:{description:"Auth context. `null` for unauthenticated. Otherwise `{ uid, token? }` where `token` is the custom-claims object."},data:{type:"object",description:"Document data. Required for create / update.",additionalProperties:!0}},required:["method","path","auth"]},async execute(r){const{method:s,path:i,auth:o,data:l}=r,u=(await t()).execute({method:s,path:i,auth:o,data:l});return{ok:u.allowed,summary:u.allowed?`${s} on ${i} allowed`:`${s} on ${i} denied`,data:{allowed:u.allowed,debugMessages:u.debugMessages}}}},{name:"firestore_simulator_read",description:"Read a document (`get`) or list a collection (`list`) from the seeded sandbox. Default uses admin access (bypasses rules). Set `evaluateRules: true` with an `auth` context to test read access control through the rules engine.",parameters:{type:"object",properties:{path:{type:"string",description:"Doc path for `get`, collection path for `list`."},method:{type:"string",enum:["get","list"],description:"Default `get`."},auth:{description:"Auth context. Required when `evaluateRules` is true."},evaluateRules:{type:"boolean",description:"Evaluate read rules against `auth`. Default false (admin read)."}},required:["path"]},async execute(r){const{path:s,method:i,auth:o,evaluateRules:l}=r,c=await t();if(l){const u=c.execute({method:i??"get",path:s,auth:o??null});return{ok:u.allowed,summary:u.allowed?`${i??"get"} on ${s} allowed`:`${i??"get"} on ${s} denied`,data:{allowed:u.allowed,document:u.data,debugMessages:u.debugMessages}}}return i==="list"?{ok:!0,summary:`Listed ${s}`,data:{documents:c.listDocuments(s)}}:{ok:!0,summary:`Read ${s}`,data:{document:c.getDocument(s)}}}},{name:"firestore_simulator_batch",description:"Execute multiple writes atomically. All operations must pass rules — if any denies, none apply. Rules evaluate each op against pre-batch state (no cross-visibility within the batch).",parameters:{type:"object",properties:{operations:{type:"array",items:{type:"object",properties:{method:{type:"string",enum:["create","update","delete"]},path:{type:"string"},data:{type:"object",additionalProperties:!0}},required:["method","path"]}},auth:{description:"Auth context for every op. `null` for unauthenticated."}},required:["operations","auth"]},async execute(r){const{operations:s,auth:i}=r,l=(await t()).batch(s,i);return{ok:l.allowed,summary:l.allowed?`Batch of ${s.length} op(s) committed`:`Batch of ${s.length} op(s) rejected by rules. To SEED data, use the admin data tool firestore_batch_write; to test rules, pass an auth the rules permit.`,data:{allowed:l.allowed,results:l.results}}}},{name:"firestore_create_with_auto_id",description:"Create a document at `<collection>/<auto-id>` with a Firestore-compatible 20-char alphanumeric id (mirrors the live SDK `addDoc()` flow). Rules evaluate as for an explicit-id `create`. Returns the minted path so the caller can re-read the doc without a side channel.",parameters:{type:"object",properties:{collection:{type:"string",description:"Collection path under which to mint the new document, e.g. `users` or `users/u1/posts`."},auth:{description:"Auth context. `null` for unauthenticated. Otherwise `{ uid, token? }`."},data:{type:"object",description:"Document data.",additionalProperties:!0}},required:["collection","auth","data"]},async execute(r){const{collection:s,auth:i,data:o}=r,l=await t(),{path:c,result:u}=l.createWithAutoId(s,o,i);return{ok:u.allowed,summary:u.allowed?`Created ${c}`:`Create at ${c} denied by rules (as ${i?i.uid:"unauthenticated"}). To SEED data, use the admin data tool firestore_add_document; to test rules, pass an auth the rules permit.`,data:{path:c,allowed:u.allowed,debugMessages:u.debugMessages}}}},{name:"firestore_simulator_undo",description:"Undo the last allowed write. Restores state to immediately before that op. Returns the undone event, or a `{ undone: false }` outcome when the log is empty.",parameters:{type:"object",properties:{}},async execute(){const s=(await t()).undo();return s?{ok:!0,summary:`Undid ${s.method} on ${s.path}`,data:{undone:!0,event:{method:s.method,path:s.path}}}:{ok:!0,summary:"Nothing to undo",data:{undone:!1}}}},{name:"firestore_simulator_redo",description:"Re-apply the most recently undone write. Pairs with `firestore_simulator_undo`. Returns the re-applied event, or `{ redone: false }` when the undo stack is empty (no recent undo to redo).",parameters:{type:"object",properties:{}},async execute(){const s=(await t()).redo();return s?{ok:s.allowed,summary:s.allowed?`Redid ${s.event?.method??"op"} on ${s.event?.path??"?"}`:"Redo restored a denied event (no state change)",data:{redone:!0,allowed:s.allowed,event:s.event?{method:s.event.method,path:s.event.path}:null,debugMessages:s.debugMessages}}:{ok:!0,summary:"Nothing to redo",data:{redone:!1}}}},{name:"firestore_simulator_events",description:'Return every event the sandbox has seen — allowed and denied — with timestamps, auth, and debug messages. Useful for audit / replay / "why did this rule deny?" investigations.',parameters:{type:"object",properties:{}},async execute(){return{ok:!0,summary:"Event log",data:{events:(await t()).getEvents().map(s=>({id:s.id,method:s.method,path:s.path,allowed:s.allowed,auth:s.auth,debugMessages:s.debugMessages}))}}}},{name:"firestore_simulator_transaction",description:'Run a declarative transaction. Reads are captured server-side and referenced from write data via `{ "$expr": "..." }` wrappers — agents never see the read values, eliminating the "round-trip the doc through context" cost. Expression DSL: arithmetic (+ - * / %), comparison, &&/||/?:, $alias.field references, string literals in either "double" or \'single\' quotes, and @sentinel(...) calls (@increment, @serverTimestamp, @arrayUnion, @arrayRemove, @deleteField). Reads are omitted from the response by default; set `includeReads: true` when debugging a denial.',parameters:{type:"object",properties:{auth:{description:"Auth context for rule eval. `null` for unauthenticated."},readOnly:{type:"boolean",description:"Hint that the transaction is read-only. v1: writes are still committed; `readOnlyViolation: true` surfaces on the response if any was queued."},includeReads:{type:"boolean",description:"Default false. When true, the response includes the captured read data + per-write debugMessages."},reads:{type:"object",description:"Reads keyed by alias. Aliases referenced from write expressions as `$alias` (e.g. `$src.balance`).",additionalProperties:{type:"string"}},writes:{type:"array",minItems:1,items:{type:"object",properties:{method:{type:"string",enum:["create","update","set","delete"]},path:{type:"string"},data:{type:"object",additionalProperties:!0}},required:["method","path"]},description:"Write operations to apply atomically."}},required:["reads","writes","auth"]},async execute(r){const{auth:s,readOnly:i,includeReads:o,reads:l,writes:c}=r;for(let p=0;p<c.length;p+=1){const h=c[p];if(h.method==="delete"&&h.data!==void 0)return{ok:!1,summary:`writes[${p}]: 'delete' must not include 'data'`,data:{code:"INVALID_INPUT"}};if(h.method!=="delete"&&h.data===void 0)return{ok:!1,summary:`writes[${p}]: '${h.method}' requires 'data'`,data:{code:"INVALID_INPUT"}}}const u=await t(),d=o===!0;try{const p=u.transaction(m=>{const y={};for(const[g,x]of Object.entries(l)){const v=m.get(x).data();y[g]=v===void 0?null:v}for(let g=0;g<c.length;g+=1){const x=c[g];if(x.method==="delete"){m.delete(x.path);continue}const b=fu(x.data,{reads:y});if(b===null||typeof b!="object"||Array.isArray(b))throw new fn(`writes[${g}].data resolved to a non-object`,`writes.${g}.data`);const v=b;switch(x.method){case"create":m.create(x.path,v);break;case"update":m.update(x.path,v);break;case"set":m.set(x.path,v);break}}},{auth:s,readOnly:i}),h={allowed:p.allowed,writes:p.writes.map(m=>{const y={path:m.path,method:m.method,allowed:m.allowed};return m.error&&(y.error={code:m.error.code,message:m.error.message}),d&&(y.debugMessages=m.debugMessages),y})};return p.error&&(h.error={code:p.error.code,message:p.error.message}),p.readOnlyViolation&&(h.readOnlyViolation=!0),d&&(h.reads=p.reads.map(m=>({path:m.path,data:m.data}))),{ok:p.allowed,summary:p.allowed?`Transaction committed (${c.length} write(s))`:"Transaction rolled back",data:h}}catch(p){if(p instanceof fn||p instanceof Z||p instanceof ye||p instanceof oe)return{ok:!1,summary:`Transaction failed: ${p.message}`,data:{allowed:!1,writes:[],error:{code:"invalid-argument",message:p.message}}};throw p}}}]}function Ua(e){return bu({resolveSandbox:e.resolveSandbox,resolveModulesFn:ja})}const gu=`RtdbExpr {
6
- Expr = Ternary
7
-
8
- Ternary
9
- = Logical "?" Ternary ":" Ternary -- ternary
10
- | Logical
11
-
12
- Logical
13
- = Logical "&&" Comparison -- and
14
- | Logical "||" Comparison -- or
15
- | Comparison
16
-
17
- Comparison
18
- = Comparison "===" Additive -- strictEq
19
- | Comparison "!==" Additive -- strictNeq
20
- | Comparison ">=" Additive -- gte
21
- | Comparison "<=" Additive -- lte
22
- | Comparison ">" Additive -- gt
23
- | Comparison "<" Additive -- lt
24
- | Comparison "==" Additive -- looseEq
25
- | Comparison "!=" Additive -- looseNeq
26
- | Additive
27
-
28
- Additive
29
- = Additive "+" Multiplicative -- add
30
- | Additive "-" Multiplicative -- sub
31
- | Multiplicative
32
-
33
- Multiplicative
34
- = Multiplicative "*" UnaryExpr -- mul
35
- | Multiplicative "/" UnaryExpr -- div
36
- | Multiplicative "%" UnaryExpr -- mod
37
- | UnaryExpr
38
-
39
- UnaryExpr
40
- = "!" UnaryExpr -- not
41
- | "-" UnaryExpr -- neg
42
- | CallExpr
43
-
44
- CallExpr
45
- = CallExpr "." ident "(" ListOf<Expr, ","> ")" -- methodCall
46
- | CallExpr "." ident -- memberAccess
47
- | CallExpr "[" Expr "]" -- indexAccess
48
- | Primary
49
-
50
- Primary
51
- = "(" Expr ")" -- paren
52
- | Array
53
- | literal
54
- | ident
55
-
56
- Array = "[" ListOf<Expr, ","> "]"
57
-
58
- literal
59
- = number
60
- | string
61
- | regex
62
- | bool
63
- | null
64
-
65
- number
66
- = digit+ "." digit+ -- float
67
- | digit+ -- int
68
-
69
- string
70
- = "\\"" doubleStringChar* "\\"" -- double
71
- | "'" singleStringChar* "'" -- single
72
-
73
- doubleStringChar
74
- = "\\\\" any -- escape
75
- | ~"\\"" any -- char
76
-
77
- singleStringChar
78
- = "\\\\" any -- escape
79
- | ~"'" any -- char
80
-
81
- regex = "/" regexBody "/" regexFlags
82
-
83
- regexBody = regexChar+
84
-
85
- regexChar
86
- = "\\\\" any -- escape
87
- | ~("/" | "\\n") any -- char
88
-
89
- regexFlags = alnum*
90
-
91
- bool
92
- = "true" ~identChar -- true
93
- | "false" ~identChar -- false
94
-
95
- null = "null" ~identChar
96
-
97
- ident = "$"? identStart identChar*
98
-
99
- identStart = letter | "_"
100
-
101
- identChar = alnum | "_" | "$"
102
- }
103
- `;let Ds;function Ta(){return Ds??=lc(gu),Ds}function Cn(e){return Ta().match(e.trim())}function Nn(){return Ta().createSemantics()}let Vn;function vu(){if(Vn)return Vn;const e=Nn();return e.addOperation("identifiers",{_nonterminal(...t){return t.flatMap(n=>n.identifiers())},_iter(...t){return t.flatMap(n=>n.identifiers())},_terminal(){return[]},CallExpr_methodCall(t,n,r,s,i,o){return[...t.identifiers(),...i.asIteration().children.flatMap(l=>l.identifiers())]},CallExpr_memberAccess(t,n,r){return t.identifiers()},ident(t,n,r){return[this.sourceString]}}),Vn=e,e}function xu(e){const t=Cn(e);if(t.failed())return{raw:e,valid:!1,errors:[{code:"PARSE_ERROR",message:t.message??"Parse failed"}],warnings:[],referencedIdentifiers:[]};const n=vu()(t).identifiers(),r=[...new Set(n)];return{raw:e,valid:!0,errors:[],warnings:[],referencedIdentifiers:r}}function Ma(e,t=""){const n=$a();return Je(n).seed({rules:t,baseDocuments:e.firestore}),{sandbox:n,rules:t,base:e,events:[],discarded:!1}}function wu(e,t){ju(e);const n=Je(e.sandbox).snapshot(),r=ku(t);return _u(r,n)}function La(e){e.discarded||(e.discarded=!0,e.sandbox.dispose())}function ju(e){if(e.discarded)throw new Error("Branch has been discarded or promoted; create a new fork.")}function ku(e){return Su(e)?Je(e).snapshot():e.firestore}function Su(e){return typeof e.snapshot=="function"}function _u(e,t){const n=[],r=new Set([...Object.keys(e),...Object.keys(t)]);for(const s of r){const i=e[s],o=t[s];if(i===void 0&&o!==void 0){n.push({kind:"real-divergence",path:s,before:void 0,after:o});continue}if(i!==void 0&&o===void 0){n.push({kind:"real-divergence",path:s,before:i,after:void 0});continue}i===void 0||o===void 0||Eu(s,i,o,n)}return n}function Eu(e,t,n,r){s(t,n,"");function s(i,o,l){if(i===o)return;const c=i!==null&&typeof i=="object"&&!Array.isArray(i),u=o!==null&&typeof o=="object"&&!Array.isArray(o);if(c&&u){const d=i,p=o,h=new Set([...Object.keys(d),...Object.keys(p)]);for(const m of h){const y=l?`${l}.${m}`:m;s(d[m],p[m],y)}return}if(Array.isArray(i)&&Array.isArray(o)){const d=Math.max(i.length,o.length);for(let p=0;p<d;p++)s(i[p],o[p],`${l}[${p}]`);return}fr(i,o)||r.push({kind:"real-divergence",path:e,field:l||void 0,before:i,after:o})}}function fr(e,t){if(e===t)return!0;if(e===null||t===null||typeof e!="object"||typeof t!="object")return!1;const n=Array.isArray(e),r=Array.isArray(t);if(n!==r)return!1;if(n&&r){if(e.length!==t.length)return!1;for(let c=0;c<e.length;c++)if(!fr(e[c],t[c]))return!1;return!0}const s=e,i=t,o=Object.keys(s),l=Object.keys(i);if(o.length!==l.length)return!1;for(const c of o)if(!Object.prototype.hasOwnProperty.call(i,c)||!fr(s[c],i[c]))return!1;return!0}function Ba(e){return typeof e=="string"?e:e._internalPath.segments.join(".")}function Dt(e,...t){const n=ka(e),r=cc(e),s=uc(e);let i,o;try{i=t.map(u=>u.prepareSandbox?.(n)??u)}catch(u){throw js(u)}const l=u=>{let d=s(u);for(const p of i)d=p.applySandbox(d);return d};try{o=l(Sa(n))}catch(u){throw js(u)}const c=dc(o,n,u=>l(u));return r?fc(c,n,r):c}function Cu(e,t,n){return Fa(Ba(e),t,n,!1)}function Fa(e,t,n,r){return{applySandbox:i=>i.where(e,t,n),prepareSandbox:r?void 0:i=>{const o=_a(n,i,t==="in"||t==="not-in");return Fa(e,t,o.executionValue,!0)},_sandboxFilter:{kind:"where",field:e,op:t,value:n}}}function Is(e,t){const n=Ba(e);return{applySandbox:r=>r.orderBy(n,t)}}function hn(e){return{applySandbox:t=>t.limit(e)}}function Nu(e){if(e.length!==1)return!1;const t=e[0];return t!==null&&typeof t=="object"&&"data"in t&&typeof t.data=="function"}function Au(...e){return Nu(e)?Va(e[0],!1,!0):qa(e,!1,!0)}function Va(e,t,n,r=!1){return{applySandbox:s=>n?s.startCursorFromSnapshot(e,t):s.endCursorFromSnapshot(e,t),prepareSandbox:r?void 0:()=>{const s=Bc(e),i=s.data(),o=Object.freeze({id:s.id,ref:s.ref,exists:i!==void 0,data:()=>i});return Va(o,t,n,!0)}}}function qa(e,t,n,r=!1){return{applySandbox:s=>n?s.startCursor([...e],t):s.endCursor([...e],t),prepareSandbox:r?void 0:s=>qa(e.map(i=>_a(i,s).executionValue),t,n,!0)}}function Ru(e,t,n,r){const s=ka(e);Kr(s).markStarted();const i=Iu(s,e),o=$u(t,n,r,s,e),l=Pu(o,s),c=l.length===3?i.onSnapshot(l[0],l[1],l[2]):l.length===2?i.onSnapshot(l[0],l[1]):i.onSnapshot(l[0]);if(!s.own)return c;let u=!1;const d=()=>{u||(u=!0,c())},p=()=>{u||(d(),Du(l)?.(new pt("aborted","The operation was aborted.")))},h=s.own(p);return()=>{h(),d()}}function Du(e){const t=e.at(-1);if(typeof t=="function"&&e.length>=3)return t;if(t&&typeof t=="object"){const n=t.error;if(typeof n=="function")return n}}function Iu(e,t){const n=hc(t);if(e.kind==="sandbox")return n;const r=pc.get(n);if(!r)throw new TypeError("pyric/firestore: live ref missing rebuild closure for onSnapshot.");return r(Sa(e))}function Wa(e){if(typeof e!="object"||e===null)return!1;const t=e;return typeof t.next=="function"||typeof t.error=="function"||typeof t.complete=="function"}function $u(e,t,n,r,s){if(typeof e=="object"&&e!==null&&!Wa(e)){const o=t;return typeof o=="function"?[e,$s(o,r,s),n??hr]:o&&typeof o=="object"?[e,Ps(o,r,s)]:[e]}return typeof e=="function"?[$s(e,r,s),t??hr]:e&&typeof e=="object"?[Ps(e,r,s)]:[e]}function Pu(e,t){if(t.kind!=="sandbox-live")return e;const n=e[0];return typeof n=="object"&&n!==null&&!Wa(n)?[{...n,[Ss]:!0,...t.authScope?{[ks]:t.authScope}:{}},...e.slice(1)]:[{[Ss]:!0,...t.authScope?{[ks]:t.authScope}:{}},...e]}function za(e,t,n){if(!e||typeof e!="object")return e;const r=e;if(typeof r.data=="function"&&Cs(e,t),Array.isArray(r.docs)){for(const s of r.docs)Cs(s,t);Fc(e,e,t,n,"listener")}return e}function hr(e){console.error("pyric/firestore: Uncaught Error in snapshot listener:",e)}function $s(e,t,n){return r=>{e(za(Ia(r,t),t,n)),Kr(t).notifySnapshotDelivered()}}function Ps(e,t,n){return{...e,next:e.next?r=>{e.next(za(Ia(r,t),t,n)),Kr(t).notifySnapshotDelivered()}:void 0,error:e.error??hr}}const Ce={description:"Identity to act as. Omit or 'admin' = admin write that BYPASSES rules (sandbox seeding). { uid, claims? } = act as that user with rules ENFORCED.",oneOf:[{type:"string",enum:["admin"]},{type:"object",properties:{uid:{type:"string"},claims:{type:"object",description:"Custom claims forwarded to the rule context (request.auth.token)."}},required:["uid"]}]},Ou=["<","<=","==","!=",">=",">","in","not-in","array-contains","array-contains-any"],Uu={type:"object",properties:{field:{type:"string"},op:{type:"string",enum:[...Ou]},value:{}},required:["field","op","value"]};function Ka(e){const{resolveDb:t}=e;return[{name:"firestore_get_document",description:"Get a Firestore document by path. Admin by default; pass `as:{uid}` to read with rules enforced as that user.",parameters:{type:"object",properties:{path:{type:"string",description:'e.g. "users/alice"'},as:Ce},required:["path"]},async execute(n){const r=n,s=await t(r.as),i=pe(s,r.path),o=await Jr(i),l=typeof o.exists=="function"?o.exists():o.exists;return{ok:!0,summary:l?`Got ${r.path}`:`No document at ${r.path}`,data:{exists:l,data:l?o.data():null}}}},{name:"firestore_list_documents",description:"List documents in a collection. Supports orderBy + limit. Admin by default; pass `as:{uid}` to enforce rules.",parameters:{type:"object",properties:{collection:{type:"string"},orderBy:{type:"string"},limit:{type:"number"},as:Ce},required:["collection"]},async execute(n){const r=n,s=await t(r.as),i=qe(s,r.collection),o=[];r.orderBy&&o.push(Is(r.orderBy)),r.limit&&o.push(hn(r.limit));const l=await Rt(Dt(i,...o));return{ok:!0,summary:`${l.size} docs in ${r.collection}`,data:{docs:l.docs.map(c=>({id:c.id,data:c.data()}))}}}},{name:"firestore_create_document",description:"Create or replace a Firestore document at an explicit path. Admin by default (bypasses rules — for seeding); pass `as:{uid}` to write as that user with rules enforced.",parameters:{type:"object",properties:{path:{type:"string"},data:{type:"object"},as:Ce},required:["path","data"]},async execute(n){const r=n,s=await t(r.as);return await At(pe(s,r.path),r.data),{ok:!0,summary:`Created ${r.path}`}}},{name:"firestore_add_document",description:"Add a document with an auto-generated id under a collection (mirrors the Web SDK addDoc). Admin by default — the right tool for seeding; pass `as:{uid}` to write as a user with rules enforced. Returns the minted path.",parameters:{type:"object",properties:{collection:{type:"string",description:'Collection to add the doc under, e.g. "users" or "users/u1/posts".'},data:{type:"object"},as:Ce},required:["collection","data"]},async execute(n){const r=n,s=await t(r.as),i=await Hr(qe(s,r.collection),r.data);return{ok:!0,summary:`Created ${i.path}`,data:{path:i.path,id:i.id}}}},{name:"firestore_update_document",description:"Merge fields into an existing Firestore document. Admin by default; pass `as:{uid}` to enforce rules.",parameters:{type:"object",properties:{path:{type:"string"},data:{type:"object"},as:Ce},required:["path","data"]},async execute(n){const r=n,s=await t(r.as);return await lr(pe(s,r.path),r.data),{ok:!0,summary:`Updated ${r.path}`}}},{name:"firestore_delete_document",description:"Delete a Firestore document. Admin by default; pass `as:{uid}` to enforce rules.",parameters:{type:"object",properties:{path:{type:"string"},as:Ce},required:["path"]},async execute(n){const r=n,s=await t(r.as);return await un(pe(s,r.path)),{ok:!0,summary:`Deleted ${r.path}`}}},{name:"firestore_batch_write",description:"Apply many writes (set / update / delete) in ONE call — the efficient way to seed or bulk-edit (one call, not N). Applied in order; stops on the first failure. Admin by default; pass `as:{uid}` to apply them as a user with rules enforced. Up to 500 ops.",parameters:{type:"object",properties:{operations:{type:"array",description:"Writes applied in order; stops on the first failure (NOT atomic — earlier writes are not rolled back).",minItems:1,maxItems:500,items:{type:"object",properties:{op:{type:"string",enum:["set","update","delete"]},path:{type:"string"},data:{type:"object",description:"Required for set/update; ignored for delete."}},required:["op","path"]}},as:Ce},required:["operations"]},async execute(n){const r=n;if(r.operations.length===0||r.operations.length>500)return{ok:!1,summary:`firestore_batch_write: operations must be 1..500 (got ${r.operations.length}).`};const s=await t(r.as);for(const i of r.operations){const o=pe(s,i.path);i.op==="set"?await At(o,i.data??{}):i.op==="update"?await lr(o,i.data??{}):await un(o)}return{ok:!0,summary:`Applied ${r.operations.length} write(s)`,data:{count:r.operations.length}}}},{name:"firestore_query_where",description:"Query a collection with one or more where clauses (AND-semantics) + optional orderBy + limit. For OR semantics use a single where clause with the `in` / `array-contains-any` op. Admin by default; pass `as:{uid}` to enforce rules.",parameters:{type:"object",properties:{collection:{type:"string"},where:{type:"array",description:"One or more where clauses. AND across clauses.",items:Uu,minItems:1},orderBy:{type:"string"},limit:{type:"number"},as:Ce},required:["collection","where"]},async execute(n){const r=n,s=await t(r.as),i=qe(s,r.collection),o=r.where.map(c=>Cu(c.field,c.op,c.value));r.orderBy&&o.push(Is(r.orderBy)),r.limit&&o.push(hn(r.limit));const l=await Rt(Dt(i,...o));return{ok:!0,summary:`${l.size} matches in ${r.collection}`,data:{docs:l.docs.map(c=>({id:c.id,data:c.data()}))}}}}]}function Ha(e){const{resolveSandbox:t}=e;return[{name:"sandbox_inspect",description:"Single-call sandbox diagnostic. Returns current rules source, lint summary, doc count by collection, and recent denials + requests. Use this FIRST when debugging unexpected sandbox behavior — it surfaces the rules / state / event log without forcing per-tool grep.",parameters:{type:"object",properties:{recentEventLimit:{type:"number",description:"Cap on recent denials/requests returned. Default 10.",default:10}}},async execute(n){const r=n,s=await t(),i=mc(s,{recentEventLimit:r.recentEventLimit});return{ok:!0,summary:`rules: ${i.rules.isEmpty?"EMPTY (setRules has not been called)":`${i.rules.sizeBytes}B, ${i.rules.lint.errors} errors / ${i.rules.lint.warnings} warnings`} · docs: ${i.documents.totalCount} across ${Object.keys(i.documents.byCollection).length} collections · events: ${i.events.totalCount} total, ${i.events.recentDenials.length} recent denials`,data:i}}}]}const Tu="modulepreload",Mu=function(e){return"/__pyric/ui/"+e},Os={},Ga=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){let o=function(u){return Promise.all(u.map(d=>Promise.resolve(d).then(p=>({status:"fulfilled",value:p}),p=>({status:"rejected",reason:p}))))};document.getElementsByTagName("link");const l=document.querySelector("meta[property=csp-nonce]"),c=l?.nonce||l?.getAttribute("nonce");s=o(n.map(u=>{if(u=Mu(u),u in Os)return;Os[u]=!0;const d=u.endsWith(".css"),p=d?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${p}`))return;const h=document.createElement("link");if(h.rel=d?"stylesheet":Tu,d||(h.as="script"),h.crossOrigin="",h.href=u,c&&h.setAttribute("nonce",c),document.head.appendChild(h),d)return new Promise((m,y)=>{h.addEventListener("load",m),h.addEventListener("error",()=>y(new Error(`Unable to preload CSS for ${u}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return s.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})};function Ja(e){return e.kind==="session_boundary"&&e.phase==="reset"}function Lu(e,t){return Ja(t)?[t]:[...e,t]}const Ya=f.createContext(null),Xa={status:"disabled",handles:null,events:[]};function Bu({children:e}){return a.jsx(Ya.Provider,{value:Xa,children:e})}function Ee(){return f.useContext(Ya)??Xa}function xt(e,t){return`${e.replace(/\/$/,"")}${t}`}function Fu(e){const t=e;return{async read(n){const r=await fetch(xt(t,`/__pyric/workspace?path=${encodeURIComponent(n)}`));if(r.status===404)return null;if(!r.ok)throw new Error(`workspace.read(${n}) → ${r.status}`);return r.text()},async write(n,r){const s=await fetch(xt(t,`/__pyric/workspace?path=${encodeURIComponent(n)}`),{method:"PUT",body:r});if(!s.ok)throw new Error(`workspace.write(${n}) → ${s.status}`)},async list(n){const r=n?`?dir=${encodeURIComponent(n)}`:"",s=await fetch(xt(t,`/__pyric/workspace/list${r}`));if(!s.ok)throw new Error(`workspace.list(${n??""}) → ${s.status}`);return await s.json()},async remove(n){const r=await fetch(xt(t,`/__pyric/workspace?path=${encodeURIComponent(n)}`),{method:"DELETE"});if(!r.ok)throw new Error(`workspace.remove(${n}) → ${r.status}`)},watch(n){const r=new EventSource(xt(t,"/__pyric/workspace/watch")),s=i=>{try{n(JSON.parse(i.data))}catch{}};return r.addEventListener("change",s),()=>{r.removeEventListener("change",s),r.close()}}}}function wt(e,t){return`${e.replace(/\/$/,"")}${t}`}function Vu(e){const t=e;return{async list(){const n=await fetch(wt(t,"/__pyric/projects"));if(!n.ok)throw new Error(`projects.list() → ${n.status}`);return await n.json()},async open(n){const r=await fetch(wt(t,`/__pyric/projects/${encodeURIComponent(n)}`));if(!r.ok)throw new Error(`projects.open(${n}) → ${r.status}`);return{meta:await r.json(),workspace:Fu(t)}},async create(n){const r=await fetch(wt(t,"/__pyric/projects"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)});if(!r.ok)throw new Error(`projects.create() → ${r.status}`);return await r.json()},async update(n,r){const s=await fetch(wt(t,`/__pyric/projects/${encodeURIComponent(n)}`),{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(r)});if(!s.ok)throw new Error(`projects.update(${n}) → ${s.status}`)},async remove(n){const r=await fetch(wt(t,`/__pyric/projects/${encodeURIComponent(n)}`),{method:"DELETE"});if(!r.ok)throw new Error(`projects.remove(${n}) → ${r.status}`)}}}function qu(e,t){return`${e.replace(/\/$/,"")}${t}`}function qn(e){return/auth/i.test(e)?"auth":"firestore"}function Wu(e){const t=e,r={"content-type":"application/json","x-pyric-writer":`studio-${Math.random().toString(36).slice(2)}`},s=new Map,i=c=>qu(t,`/__pyric/state?section=${qn(c)}`),o=async c=>{const u=qn(c),d=s.get(u);if(d)return d;const p=await fetch(i(c));let h=new Map;if(p.ok){const m=await p.text();m&&m!=="null"&&(h=yc(m))}else if(p.status!==404)throw new Error(`persistence.read(${c}) → ${p.status}`);return s.set(u,h),h},l=async(c,u)=>{const d=await fetch(i(c),{method:"POST",headers:r,body:bc(u)});if(d.status===423)throw new Error("persistence.write blocked, another tab holds the persist writer lock");if(!d.ok)throw new Error(`persistence.write(${c}) → ${d.status}`)};return{async getRecord(c,u){return(await o(c)).get(u)??null},async listRecords(c){return[...(await o(c)).keys()]},async putRecords(c,u){const d=await o(c);for(const[p,h]of u)d.set(p,h);await l(c,d)},async deleteRecords(c,u){const d=await o(c);for(const p of u)d.delete(p);await l(c,d)},async clear(c){s.set(qn(c),new Map);const u=await fetch(i(c),{method:"POST",headers:r,body:"null"});if(!u.ok&&u.status!==423)throw new Error(`persistence.clear(${c}) → ${u.status}`)}}}const zu="local";function Ku(){const e=new Map,t=new Set,n=r=>{for(const s of t)s(r)};return{async read(r){return e.has(r)?e.get(r):null},async write(r,s){const i=e.has(r)?"update":"create";e.set(r,s),n({path:r,type:i})},async list(r){const s=r?`${r.replace(/\/+$/,"")}/`:"",i=[];for(const o of e.keys())s&&!o.startsWith(s)||i.push({path:o,kind:"file"});return i},async remove(r){e.delete(r)&&n({path:r,type:"delete"})},watch(r){return t.add(r),()=>t.delete(r)}}}function Hu(){const e=Ku();let t={id:zu,title:"Local Project",createdAt:Date.now(),updatedAt:Date.now()};return{async list(){return[t]},async open(n){if(n!==t.id)throw new Error(`Static Studio runs in single-project mode — no project '${n}'.`);return{meta:t,workspace:e}},async create(){throw new Error("Static Studio runs in single-project mode — creating additional projects is not supported.")},async update(n,r){n===t.id&&(t={...t,...r,updatedAt:Date.now()})},async remove(){}}}const Gu="/__pyric/sdk/worker.js",Ne="pyric-shared-worker",Ju="/__pyric/ui/";function Qa(e=typeof document>"u"?void 0:document){const t=e?.querySelector('meta[name="pyric-worker-v"]')?.getAttribute("content")?.trim()||null;return{studioUrl:Ju,worker:{url:Gu,name:Ne,servedEpoch:t}}}const pn="pyric:worker-generation",jt="pyric:worker-generation-probe";function Yu(e,t){const n=e&&/^[a-f0-9]{16}$/.test(e)?e:null;if(!t)return n?`${Ne}:${n}`:Ne;try{const r=t.getItem(pn);return r&&/^[a-f0-9]{16}$/.test(r)?`${Ne}:${r}`:n?(t.setItem(pn,n),`${Ne}:${n}`):Ne}catch{return n?`${Ne}:${n}`:Ne}}function Xu(e,t){if(!/^[a-f0-9]{16}$/.test(e))throw new Error("Pyric cannot replace the worker: invalid served worker epoch.");if(!t)throw new Error("Pyric cannot replace the worker because origin storage is unavailable. Close all tabs for this origin and reopen the app.");try{if(t.setItem(pn,e),t.getItem(pn)!==e)throw new Error("the worker generation could not be read back")}catch(n){throw new Error("Pyric cannot replace the worker because origin storage is unavailable. Close all tabs for this origin and reopen the app.",{cause:n})}}function Qu(e){if(!e?.removeItem)throw new Error("Pyric cannot replace the worker because origin storage is unavailable. Close all tabs for this origin and reopen the app.");try{const t=e.getItem(jt);if(e.setItem(jt,"ok"),e.getItem(jt)!=="ok")throw new Error("the worker generation probe could not be read back");t===null?e.removeItem(jt):e.setItem(jt,t)}catch(t){throw new Error("Pyric cannot replace the worker because origin storage is unavailable. Close all tabs for this origin and reopen the app.",{cause:t})}}function Zu(e){const t=e.schedule??(s=>{setTimeout(s,100)});let n=!1;const r=e.subscribeReload(s=>{if(!n){try{e.commitGeneration(s)}catch(i){e.onPreparationError?.(i);return}n=!0,t(e.reload)}});return{async request(){e.preflight(),await e.retire()},dispose:r}}function ed(){let e=null;const t=new Set;return{get currentUser(){return e},set currentUser(n){if(e!==n){e=n;for(const r of[...t])r(n)}},onCurrentUserChanged(n){return t.add(n),()=>t.delete(n)}}}const Za=new WeakMap;let pr;function td(e,t,n=ed()){const r=e.name,s=n===t?void 0:{},i=new Map,o=new Set,l={app:e,sandbox:t,session:n,services:i,cleanups:o,assertAlive(){if(l.deleted)throw new pt("app/app-deleted",`Firebase: Firebase App named '${r}' already deleted (app/app-deleted).`)},...s?{authScope:s}:{},service(c,u){const d=i.get(c);if(d!==void 0)return d;l.assertAlive();const p=u();return i.set(c,p),p},onDelete(c){return l.deleted?(c(),()=>{}):(o.add(c),()=>o.delete(c))},deleted:!1};return Za.set(e,l),l}function nd(e){pr=e}gc({resolve(e,t){const n=typeof e=="object"&&e!==null?Za.get(e):void 0;if(n)return n},defaultApp(){if(!pr)throw new TypeError("No default sandbox app registry is installed - import and initialize pyric/app before calling a service factory without an app.");return pr()}});const rd="[DEFAULT]",sd=new Map;function id(e,t){return new pt(`app/${e}`,`Firebase: ${t} (app/${e}).`)}function ad(e){return id("no-app",`No Firebase App '${e}' has been created - call initializeApp() first`)}function od(e=rd){const t=sd.get(e);if(!t)throw ad(e);return t.app}nd(od);let ld=0,cd=0;function T(){return`op-${++ld}`}function yt(){return`sub-${++cd}`}const ct=new Map,It=new Map,$t=new Map,bt=new WeakSet,mr=new Set;function ud(e){return mr.add(e),()=>mr.delete(e)}function eo(){return Object.assign(new Error("Firebase App was deleted"),{code:"app/app-deleted"})}function Lt(e,t,n,r){return bt.has(e)?!1:(It.set(t,n),e.postMessage(r),!0)}function dd(e,t,n,r){return bt.has(e)?!1:($t.set(t,{port:e,next:n}),e.postMessage(r),!0)}function Bt(e,t){It.delete(t),$t.delete(t),bt.has(e)||e.postMessage({t:"unsub",subId:t})}function fd(e){bt.add(e);const t=eo();for(const[n,r]of[...ct])r.port===e&&(ct.delete(n),r.reject(t));for(const[n,r]of[...It])r.port===e&&(It.delete(n),r.service==="firestore"&&r.error?.(new pt("aborted","The operation was aborted.")));for(const[n,r]of[...$t])r.port===e&&$t.delete(n);e.onmessage=null}function Us(e,t){if(t.denialContext===void 0||typeof fetch!="function")return;const n={kind:e,code:t.code,message:t.message,denialContext:t.denialContext,...typeof t.remediation=="string"?{remediation:t.remediation}:{}};try{fetch("/__pyric/denials",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)}).catch(()=>{})}catch{}}function Yr(e){e.onmessage=t=>{const n=t.data;if(n.t==="res"){const r=ct.get(n.id);if(!r)return;if(ct.delete(n.id),n.ok)r.resolve(n.value);else{const s=new Error(n.error.message);s.code=n.error.code,n.error.denialContext!==void 0&&(s.denialContext=n.error.denialContext),n.error.aiEnvelope!==void 0&&(s.aiEnvelope=n.error.aiEnvelope),Us("read",s),r.reject(s)}}else if(n.t==="snap"){const r=It.get(n.subId);if(!r)return;const s=n.value??{};if(s.__error){const i=s.__error,o=new Error(i.message);o.code=i.code,i.denialContext!==void 0&&(o.denialContext=i.denialContext),i.aiEnvelope!==void 0&&(o.aiEnvelope=i.aiEnvelope),Us("listener",o),r.error?r.error(o):console.error("pyric/firestore: Uncaught Error in snapshot listener:",o);return}r.next(n.value)}else if(n.t==="event"){const r=$t.get(n.subId);r&&r.next(n.events)}else if(n.t==="runtime-reload")for(const r of mr)r(n)}}let ut;function Ts(e){ut=e&&e.mode==="app-session"?void 0:e}function hd(){return ut}let yr;function pd(e){yr=e}function Xr(e){return yr&&(e.t==="op"||e.t==="sub")?{...e,issuer:yr}:e}function Qr(e,t){return bt.has(e)?Promise.reject(eo()):new Promise((n,r)=>{const s=t;ct.set(s.id,{port:e,resolve:n,reject:r}),e.postMessage(t)})}function W(e,t){return Qr(e,Xr(t))}function to(e,t,n,r){const s=t.id;let i;const o=new Promise((l,c)=>{i=setTimeout(()=>{ct.delete(s)&&c(new Error(r))},n)});return Promise.race([W(e,t),o]).finally(()=>{i&&clearTimeout(i)})}function de(e,t){if(bt.has(e)&&!t.method.startsWith("rtdb."))return Promise.reject(new pt("failed-precondition","The client has already been terminated."));const n=ut?{...t,actAs:ut}:t;return W(e,n)}async function md(e,t,n={}){const r=n.timeoutMs??12e3;await to(e.port,{t:"op",id:T(),method:"retireRuntime",targetEpoch:t},r,`Timed out waiting for the Pyric worker to retire after ${r}ms.`)}function yd(e){return ud(t=>e(t.epoch))}function bd(e,t,n={}){if(typeof SharedWorker>"u")throw new Error("SharedWorker is not available. Open this page over http:// (not file://) and use a supported browser (Chrome 4+, Firefox 29+, Safari 16.4+).");const r=new SharedWorker(e,{type:"classic",name:t??"pyric-shared-worker"});n.onError&&r.addEventListener("error",i=>{const o=i.message||`failed to load ${String(e)}`;n.onError?.(new Error(`Pyric SharedWorker error: ${o}`))});const s=r.port;return Yr(s),s.start(),{__kind:"client-db",port:s}}async function gd(e,t={}){const n=T(),r=t.timeoutMs??2e3;return(await to(e.port,{t:"op",id:n,method:"getRuntimeEpoch"},r,`Timed out waiting for the Pyric SharedWorker version handshake after ${r}ms.`)).version}async function vd(e){return(await W(e.port,{t:"op",id:T(),method:"getVersion"})).instanceId??""}async function xd(e){return(await W(e.port,{t:"op",id:T(),method:"exportState"})).bundle}async function wd(e,t){await W(e.port,{t:"op",id:T(),method:"importState",bundle:t})}async function jd(e,t){await W(e.port,{t:"op",id:T(),method:"saveBranch",name:t})}async function kd(e){return(await W(e.port,{t:"op",id:T(),method:"listBranches"})).branches??[]}async function Sd(e,t){await W(e.port,{t:"op",id:T(),method:"switchBranch",name:t})}async function _d(e,t){await W(e.port,{t:"op",id:T(),method:"deleteBranch",name:t})}async function Ed(e,t,n){return await W(e.port,{t:"tool",id:T(),name:t,args:n})}function Cd(e,t){return Qr(e.port,{...t,issuer:void 0,relaySource:"remote",t:"op",id:T()})}function Nd(e,t,n){if(t.target==="events")throw new Error("event-stream subscriptions cannot be relayed over the bridge yet (needs bounded backpressure — slice 2)");const r=yt();return Lt(e.port,r,{port:e.port,next:n,error:i=>n({__error:{code:i.code??"unknown",message:i instanceof Error?i.message:String(i)}})},{...t,issuer:void 0,relaySource:"remote",t:"sub",subId:r})||queueMicrotask(()=>n({__error:{code:"app/app-deleted",message:"Firebase App was deleted"}})),()=>{Bt(e.port,r)}}function Ad(e){const t=(e??"/").split("/").filter(Boolean).join("/");return t?`/${t}`:"/"}const Rd=[];function Dd(e){for(const t of[...Rd])t.port===e&&t.close()}const Id=5e3;function $d(){return Object.assign(new Error("Timed out waiting for SharedWorker app cleanup acknowledgment. Close all tabs using this pyric dev origin so the worker can restart."),{code:"app/delete-timeout"})}async function Pd(e,t={}){let n;try{const r=Qr(e.port,{t:"disconnect",id:T()}),s=new Promise((i,o)=>{n=setTimeout(()=>o($d()),t.ackTimeoutMs??Id)});await Promise.race([r,s])}finally{n!==void 0&&clearTimeout(n),Dd(e.port),fd(e.port),e.port.close()}}function Zr(e){return e.split("/").at(-1)??e}function Od(e,...t){const n=("port"in e,e.port);let r;if(e.__kind==="client-db"){if(t.length===0)throw new TypeError("doc(db, path) requires a path segment.");r=t.join("/")}else{const i=e.descriptor.path;r=t.length>0?`${i}/${t.join("/")}`:i}return{__kind:"doc-ref",descriptor:{__ref:"doc",path:r},port:n,id:Zr(r),path:r}}function Ud(e,...t){const n=e.port;if(t.length===0)throw new TypeError("collection() requires a path segment.");let r;return e.__kind==="client-db"?r=t.join("/"):r=`${e.descriptor.path}/${t.join("/")}`,{__kind:"coll-ref",descriptor:{__ref:"collection",path:r},port:n,id:Zr(r),path:r}}function Td(e){return{_descriptor:{kind:"limit",n:e}}}function Md(...e){return{_descriptor:{kind:"startAfter",values:e}}}function Ld(e,...t){const n=(e.__kind==="coll-ref",e.descriptor),r=e.__kind==="query"?e.descriptor.constraints:[];return{__kind:"query",descriptor:{__ref:"query",source:n.__ref==="query"?n.source:n,constraints:[...r,...t.map(i=>i._descriptor)]},port:e.port}}function Bd(e){return vc(JSON.parse(e.json))}const no=8*1024*1024;function Fd(e,t){const n=new Error(`${t} is ${e} bytes — over the ${no/1048576} MiB storage op cap (MAX_STORAGE_OP_BYTES). Streaming/resumable transfers are not supported on the sandbox backend; split the object or keep it under the cap.`);return n.code="payload-too-large",n}function Vd(e){let t="";for(let r=0;r<e.length;r+=32768){const s=e.subarray(r,r+32768);t+=String.fromCharCode.apply(null,s)}return btoa(t)}function qd(e){return Bd(e)}function es(e,t){const n=e.exists&&e.data?qd(e.data):void 0,r=e.path??e.id,s={__kind:"doc-ref",descriptor:{__ref:"doc",path:r},port:t,id:e.id,path:r};return{id:e.id,path:r,ref:s,exists:()=>e.exists,data:()=>n}}function ro(e,t){const n=e.docs.map(r=>es(r,t));return{size:n.length,empty:n.length===0,docs:n}}async function Wd(e){const t=await de(e.port,{t:"op",id:T(),method:"getDoc",path:e.descriptor.path});return es(t,e.port)}async function zd(e){const t=await de(e.port,{t:"op",id:T(),method:"getDocs",source:(e.__kind==="coll-ref",e.descriptor)});return ro(t,e.port)}async function Kd(e){return(await de(e.port,{t:"op",id:T(),method:"listRootCollections"})).ids}async function Hd(e,t){return(await de(e.port,{t:"op",id:T(),method:"listSubcollections",docPath:t})).ids}function Gd(e,t,n){const r=yt(),s=e.port,i={port:s,service:"firestore",next:c=>{const u=c;"docs"in u?t(ro(u,s)):t(es(u,s))},error:n},o=(e.__kind==="doc-ref"||e.__kind==="coll-ref",e.descriptor);return!Lt(s,r,i,Xr(ut?{t:"sub",subId:r,target:o,actAs:ut}:{t:"sub",subId:r,target:o}))&&n&&queueMicrotask(()=>n(new Error("Firebase App was deleted"))),()=>{Bt(s,r)}}async function Jd(e,t,n){await de(e.port,{t:"op",id:T(),method:"setDoc",path:e.descriptor.path,data:t,options:n})}async function Yd(e){await de(e.port,{t:"op",id:T(),method:"deleteDoc",path:e.descriptor.path})}async function Xd(e,t){const n=await de(e.port,{t:"op",id:T(),method:"addDoc",collectionPath:e.descriptor.path,data:t});return{__kind:"doc-ref",descriptor:{__ref:"doc",path:n.path},port:e.port,id:n.id,path:n.path}}async function Qd(e,t){return await W(e.port,{t:"op",id:T(),method:"admin.listDocuments",path:t})}function Zd(e,t){const n=yt(),r=e.port;return dd(r,n,t,{t:"sub",subId:n,target:"events"}),()=>{Bt(r,n)}}async function ef(e){return await W(e.port,{t:"op",id:T(),method:"getSnapshot"})}async function tf(e){return await W(e.port,{t:"op",id:T(),method:"resetAll"})??{errors:[]}}const nf=15e3;function rf(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`page-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function Ms(){return typeof location>"u"?"/":`${location.pathname}${location.search}${location.hash}`}function Ls(){return typeof document>"u"?"visible":document.visibilityState==="hidden"?"hidden":"visible"}function sf(e){const{db:t,kind:n}=e,r=e.clientId??rf(),s=e.heartbeatIntervalMs??nf;let i=!1,o=null;const l=()=>{W(t.port,{t:"op",id:T(),method:"presence.register",clientId:r,kind:n,route:Ms(),visibility:Ls()}).catch(()=>{})},c=()=>{W(t.port,{t:"op",id:T(),method:"presence.heartbeat",clientId:r}).catch(()=>{})},u=()=>{W(t.port,{t:"op",id:T(),method:"presence.update",clientId:r,route:Ms(),visibility:Ls()}).catch(()=>{})},d=()=>{W(t.port,{t:"op",id:T(),method:"presence.disconnect",clientId:r}).catch(()=>{})};l(),typeof document<"u"&&document.addEventListener("visibilitychange",u),typeof window<"u"&&(window.addEventListener("popstate",u),window.addEventListener("hashchange",u),window.addEventListener("pagehide",p),o=setInterval(()=>{i||c()},s));function p(){h()}function h(){i||(i=!0,o!=null&&(clearInterval(o),o=null),typeof document<"u"&&document.removeEventListener("visibilitychange",u),typeof window<"u"&&(window.removeEventListener("popstate",u),window.removeEventListener("hashchange",u),window.removeEventListener("pagehide",p)),d())}return{clientId:r,kind:n,stop:h}}function af(e,t){const n=yt();return Lt(e.port,n,{port:e.port,next:r=>{t(r)}},{t:"sub",subId:n,target:"presence"}),()=>{Bt(e.port,n)}}const of=Symbol("pyric.clientUser.port");function lf(e,t){const n={uid:t.uid,email:t.email,emailVerified:t.emailVerified,displayName:t.displayName,photoURL:t.photoURL,phoneNumber:t.phoneNumber,isAnonymous:t.isAnonymous,providerId:t.providerId,providerData:t.providerData,async getIdToken(r){return await W(e,{t:"op",id:T(),method:"auth.getIdToken",forceRefresh:r})},async getIdTokenResult(r){return await W(e,{t:"op",id:T(),method:"auth.getIdTokenResult",forceRefresh:r})}};return Object.defineProperty(n,of,{value:e,enumerable:!1}),n}function cf(e,t){return t?lf(e,t):null}function uf(e,t){let n;if(typeof e=="object"&&"__kind"in e&&e.__kind==="client-db")n=e.port;else{if(typeof SharedWorker>"u")throw new Error("SharedWorker is not available. Open this page over http:// (not file://) and use a supported browser (Chrome 4+, Firefox 29+, Safari 16.4+).");n=new SharedWorker(e,{type:"classic",name:"pyric-shared-worker"}).port,n.start(),Yr(n)}const r={__kind:"client-auth",port:n,currentUser:null},s=yt();return Lt(n,s,{port:n,next:i=>{r.currentUser=cf(n,i)}},{t:"sub",subId:s,target:"authState"}),r}async function df(e){return await W(e.port,{t:"op",id:T(),method:"auth.listUsers"})}async function ff(e,t){return await W(e.port,{t:"op",id:T(),method:"auth.adminCreateUser",request:t})}async function hf(e,t,n){return await W(e.port,{t:"op",id:T(),method:"auth.adminUpdateUser",uid:t,request:n})}async function pf(e,t){await W(e.port,{t:"op",id:T(),method:"auth.adminDeleteUser",uid:t})}async function mf(e){await W(e.port,{t:"op",id:T(),method:"auth.adminClearUsers"})}async function yf(e){return await W(e.port,{t:"op",id:T(),method:"auth.getProviderConfig"})}async function bf(e,t,n){await W(e.port,{t:"op",id:T(),method:"auth.setProviderConfig",providerId:t,enabled:n})}function gf(e){return e.replace(/^\/+|\/+$/g,"")}function vf(e,t){let n;if(typeof e=="object"&&"__kind"in e&&e.__kind==="client-db")n=e.port;else{if(typeof SharedWorker>"u")throw new Error("SharedWorker is not available. Open this page over http:// (not file://) and use a supported browser.");n=new SharedWorker(e,{type:"classic",name:"pyric-shared-worker"}).port,n.start(),Yr(n)}return{__kind:"client-storage",port:n}}function xf(e,t){const n=gf(t??"");let r;if(e.__kind==="client-storage")r=n;else{const s=e.fullPath;r=n?s?`${s}/${n}`:n:s}return{__kind:"storage-ref",port:e.port,fullPath:r,name:Zr(r)}}async function wf(e){const t=await de(e.port,{t:"op",id:T(),method:"storage.listAll",path:e.fullPath}),n=r=>({__kind:"storage-ref",port:e.port,fullPath:r.fullPath,name:r.name});return{items:t.items.map(n),prefixes:t.prefixes.map(n)}}async function jf(e){return await de(e.port,{t:"op",id:T(),method:"storage.getMetadata",path:e.fullPath})}async function kf(e){return await de(e.port,{t:"op",id:T(),method:"storage.getBlob",path:e.fullPath})}async function Sf(e,t,n){const r=t instanceof Blob?new Uint8Array(await t.arrayBuffer()):t instanceof ArrayBuffer?new Uint8Array(t):t;if(r.byteLength>no)throw Fd(r.byteLength,`uploadBytes payload for '${e.fullPath}'`);const s=n?.contentType??(t instanceof Blob&&t.type?t.type:void 0),i=await de(e.port,{t:"op",id:T(),method:"storage.putBytes",path:e.fullPath,dataB64:Vd(r),...s!==void 0?{contentType:s}:{},...n!==void 0?{metadata:n}:{}});return{ref:e,metadata:i}}async function _f(e){await de(e.port,{t:"op",id:T(),method:"storage.deleteObject",path:e.fullPath})}new Array(12).fill(0);async function Ef(e){return W(e.port,{t:"op",id:T(),method:"rtdb.adminSnapshot"})}async function Cf(e,t,n){await W(e.port,{t:"op",id:T(),method:"rtdb.set",path:t,value:n,actAs:{mode:"admin"}})}async function Nf(e,t,n){await W(e.port,{t:"op",id:T(),method:"rtdb.update",path:t,values:n,actAs:{mode:"admin"}})}async function Af(e,t){await W(e.port,{t:"op",id:T(),method:"rtdb.remove",path:t,actAs:{mode:"admin"}})}function Rf(e,t,n,r){const s=yt();return!Lt(e.port,s,{port:e.port,next:o=>n(o?.value??null),error:r},Xr({t:"sub",subId:s,target:{service:"rtdb",path:Ad(t)},actAs:{mode:"admin"}}))&&r&&queueMicrotask(()=>r(new Error("FIREBASE FATAL ERROR: Database has been deleted."))),()=>Bt(e.port,s)}function Df(e){const t=new Set;let n={servedEpoch:e.servedEpoch,runningEpoch:null,updateAvailable:!1,updating:!1,error:null};const r=c=>{n={...n,...c};for(const u of t)u()},s=e.storage,i=e.servedEpoch;let o=null;const l=()=>i?(o??=Zu({targetEpoch:i,retire:()=>e.retire?e.retire(i):md(e.db,i),subscribeReload:e.subscribeReload??yd,preflight:e.preflight??(()=>Qu(s)),commitGeneration:e.remember??(c=>Xu(c,s)),onPreparationError:c=>r({updating:!1,error:c instanceof Error?c.message:String(c)}),reload:e.reload??(()=>window.location.reload()),...e.schedule?{schedule:e.schedule}:{}}),o):null;return(e.readVersion??(()=>gd(e.db)))().then(c=>r({runningEpoch:c,updateAvailable:!!(i&&c!=="dev"&&c!==i)})).catch(c=>r({error:c instanceof Error?c.message:String(c)})),{getSnapshot:()=>n,subscribe(c){return t.add(c),l(),()=>{t.delete(c),t.size===0&&(o?.dispose(),o=null)}},async update(){const c=l();if(!c||!n.updateAvailable||n.updating)throw new Error("No Pyric worker update is available.");r({updating:!0,error:null});try{await c.request()}catch(u){throw r({updating:!1,error:u instanceof Error?u.message:String(u)}),u}},dispose(){t.clear(),o?.dispose(),o=null}}}function If(e={}){const t=Qa(e.document??(typeof document>"u"?void 0:document));let n=e.storage;if(!n)try{n=typeof localStorage>"u"?void 0:localStorage}catch{n=void 0}return{url:e.workerUrl??t.worker.url,name:Yu(t.worker.servedEpoch,n)}}const $f="/__pyric/sdk/worker.js";function Pf(e){let t=[],n=!1;const r=new Set;let s=null;function i(){s||(s=Zd(e,o=>{const l=!n;n=!0;const c=l?[]:[...t];for(const u of o)Ja(u)&&(c.length=0),c.push(u);t=c;for(const u of o)for(const d of r)d(u)}))}return{history:()=>t,subscribe:o=>(r.add(o),i(),()=>{r.delete(o),r.size===0&&s&&(s(),s=null,n=!1,t=[])})}}function Of(e=$f){if(typeof SharedWorker>"u")return null;pd("studio");let t;try{const c=If({workerUrl:e});t=bd(c.url,c.name)}catch{return null}let n;try{n=typeof localStorage>"u"?void 0:localStorage}catch{n=void 0}const r=Df({db:t,servedEpoch:Qa(typeof document>"u"?void 0:document).worker.servedEpoch,storage:n});Ts({mode:"admin"});const s=sf({db:t,kind:"studio"}),i=Pf(t),o=uf(t);let l=!1;return{db:t,runtime:r,dispose:async()=>{l||(l=!0,s.stop(),r.dispose(),await Pd(t).catch(()=>{}))},presenceClientId:s.clientId,subscribePresence:c=>af(t,c),instanceId:()=>vd(t),exportState:()=>xd(t),importState:c=>wd(t,c),saveBranch:c=>jd(t,c),listBranches:()=>kd(t),switchBranch:c=>Sd(t,c),deleteBranch:c=>_d(t,c),feed:i,setLens:c=>Ts(c),getLens:()=>hd(),listRootCollections:()=>Kd(t),listSubcollections:c=>Hd(t,c),listDocuments:async c=>(await Qd(t,c)).map(({path:u,phantom:d})=>({path:u,phantom:d})),readRtdbState:()=>Ef(t),setRtdbValue:(c,u)=>Cf(t,c,u),updateRtdbValue:(c,u)=>Nf(t,c,u),deleteRtdbValue:c=>Af(t,c),subscribeRtdbValue:(c,u,d)=>Rf(t,c,u,d),firestoreApi:{collection:Ud,doc:Od,getDoc:Wd,getDocs:zd,onSnapshot:Gd,setDoc:Jd,deleteDoc:Yd,addDoc:Xd,query:Ld,limit:Td,startAfter:Md},auth:o,authApi:{listUsers:()=>df(o),subscribeUsers:(c,u)=>i.subscribe(d=>{d.kind==="service_mutation"&&d.service==="auth"&&u()}),createUser:(c,u)=>ff(o,u),updateUser:(c,u,d)=>hf(o,u,d),deleteUser:(c,u)=>pf(o,u),clearUsers:()=>mf(o),getAuthProviderConfig:()=>yf(o),setAuthProviderConfig:(c,u,d)=>bf(o,u,d),subscribeAuthProviderConfig:(c,u)=>i.subscribe(d=>{d.kind==="service_mutation"&&d.op==="provider_config_update"&&u()})},storage:vf(t),storageApi:{ref:xf,listAll:wf,getMetadata:jf,getBlob:kf,uploadBytes:Sf,deleteObject:_f},getSnapshot:()=>ef(t),resetAll:()=>tf(t)}}const Bs=5174,Fs="/sandbox",Uf=4001,Tf="worker-relay";function Mf(e){if(e===null||typeof e!="object")return!1;const t=e.type;return t==="hello"||t==="hello-ack"||t==="attach"||t==="attach-ack"||t==="tool-call"||t==="tool-result"||t==="worker-op"||t==="worker-res"||t==="worker-sub"||t==="worker-unsub"||t==="worker-snap"||t==="ping"||t==="pong"}function br(e){if(e===null||typeof e!="object")return null;if(typeof Blob<"u"&&e instanceof Blob)return"Blob";if(e instanceof ArrayBuffer)return"ArrayBuffer";if(ArrayBuffer.isView(e))return e.constructor?.name??"TypedArray";if(Array.isArray(e)){for(const t of e){const n=br(t);if(n)return n}return null}for(const t of Object.values(e)){const n=br(t);if(n)return n}return null}function Vs(e,t){const n=br(t);if(!n)return;const r=new Error(`worker ${e} produced a binary payload (${n}) that cannot cross the JSON bridge relay — it would be silently corrupted by JSON.stringify. Use the base64 storage ops instead ('storage.getBytes' / 'storage.putBytes'), which carry bytes as JSON-safe 'dataB64' strings; 'storage.getBlob' is MessagePort-only.`);throw r.code="invalid-argument",r}function qs(e,t){return{code:e.code,severity:t,message:e.message,path:e.path,origin:"validate"}}let Ve=[],gr=!1,vr=!1,xr=!1,Wn;function Lf(){if(Wn)return Wn;const e=Nn();return e.addOperation("lint",{_nonterminal(...t){t.forEach(n=>n.lint())},_iter(...t){t.forEach(n=>n.lint())},_terminal(){},CallExpr_methodCall(t,n,r,s,i,o){t.lint(),i.asIteration().children.forEach(l=>l.lint()),r.sourceString==="child"&&t.sourceString==="data"&&(xr=!0)},ident(t,n,r){const s=this.sourceString;s==="data"&&(gr=!0),s==="newData"&&(vr=!0)},bool_true(t){Ve.push({code:"HARDCODED_TRUE",message:"Rule expression is hardcoded to true"})},bool_false(t){Ve.push({code:"HARDCODED_FALSE",message:"Rule expression is hardcoded to false"})},Comparison_looseEq(t,n,r){Ve.push({code:"LOOSE_EQUALITY",message:"Use '===' instead of '=='"}),t.lint(),r.lint()},Comparison_looseNeq(t,n,r){Ve.push({code:"LOOSE_INEQUALITY",message:"Use '!==' instead of '!='"}),t.lint(),r.lint()}}),Wn=e,e}function Bf(e,t="read"){const n=Cn(e);return n.failed()?[]:(Ve=[],gr=!1,vr=!1,xr=!1,Lf()(n).lint(),t==="write"&&gr&&!vr&&!xr&&Ve.push({code:"DATA_IN_WRITE",message:"Write rule references 'data' but not 'newData'; consider using 'newData' to check incoming data"}),[...Ve])}const Ff={read:new Set(["auth","data","root","now"]),write:new Set(["auth","data","newData","root","now"]),validate:new Set(["auth","data","newData","root","now"])},Vf=new Set(["val","exists","hasChild","hasChildren","isString","isNumber","isBoolean","child","parent","getPriority"]),qf=new Set(["matches","contains","beginsWith","endsWith","replace","toLowerCase","toUpperCase","length"]),Wf=new Set([...Vf,...qf]);let Nt=[],on="read",so=new Set,zn;function zf(){if(zn)return zn;const e=Nn();return e.addOperation("validate",{_nonterminal(...t){t.forEach(n=>n.validate())},_iter(...t){t.forEach(n=>n.validate())},_terminal(){},CallExpr_methodCall(t,n,r,s,i,o){t.validate();const l=r.sourceString;Wf.has(l)||Nt.push({code:"UNKNOWN_METHOD",message:`Unknown method '${l}'`}),i.asIteration().children.forEach(c=>c.validate())},CallExpr_memberAccess(t,n,r){t.validate()},CallExpr_indexAccess(t,n,r,s){t.validate(),r.validate()},ident(t,n,r){const s=this.sourceString;if(t.sourceString==="$")return;const o=Ff[on];o&&(!o.has(s)&&!so.has(s)&&Nt.push({code:"UNKNOWN_IDENTIFIER",message:`Identifier '${s}' is not allowed in '${on}' context`}),s==="newData"&&on==="read"&&Nt.push({code:"NEWDATA_IN_READ",message:"'newData' is not available in 'read' context"}))}}),zn=e,e}function Kf(e,t,n=[]){const r=Cn(e);return r.failed()?[]:(Nt=[],on=t,so=new Set(n.map(s=>s.startsWith("$")?s.slice(1):s)),zf()(r).validate(),[...Nt])}const Hf=new Set(["__proto__","prototype","constructor"]);function Ws(e,t){return Hf.has(t)?null:typeof e=="string"?t==="length"?e.length:null:e===null||typeof e!="object"||!Object.hasOwn(e,t)?null:e[t]??null}class ke{_value;_path;_root;constructor(t,n="/",r){this._value=t??null,this._path=n,this._root=r!==void 0?r:t}val(){return this._value}exists(){return this._value!==null&&this._value!==void 0}hasChild(t){return this.child(t).exists()}hasChildren(t){return Array.isArray(t)?t.every(n=>this.hasChild(String(n))):typeof this._value=="object"&&this._value!==null&&Object.keys(this._value).length>0}isString(){return typeof this._value=="string"}isNumber(){return typeof this._value=="number"}isBoolean(){return typeof this._value=="boolean"}child(t){const n=t.split("/").filter(i=>i.length>0);let r=this._value,s=this._path;for(const i of n){if(r==null||typeof r!="object"){r=null,s=`${s}/${i}`.replace(/\/+/g,"/");break}r=Object.hasOwn(r,i)?r[i]??null:null,s=`${s==="/"?"":s}/${i}`}return new ke(r,s,this._root)}parent(){if(this._path==="/")return null;const t=this._path.split("/").filter(s=>s.length>0);t.pop();const n="/"+t.join("/"),r=new ke(this._root,"/");return n==="/"?r:r.child(t.join("/"))}getPriority(){return null}}class Gf{value;constructor(t){this.value=t}matches(t){return(t instanceof RegExp?t:new RegExp(t)).test(this.value)}contains(t){return this.value.includes(t)}beginsWith(t){return this.value.startsWith(t)}endsWith(t){return this.value.endsWith(t)}replace(t,n){if(t instanceof RegExp){const r=t.flags.includes("g")?t.flags:`${t.flags}g`;return this.value.replace(new RegExp(t.source,r),n)}return t===""?this.value:this.value.split(t).join(n)}toLowerCase(){return this.value.toLowerCase()}toUpperCase(){return this.value.toUpperCase()}get length(){return this.value.length}}let Ae={auth:null,data:new ke(null),newData:new ke(null),root:new ke(null),now:Date.now(),pathVariableBindings:{}},Kn;function Jf(){if(Kn)return Kn;const e=Nn();return e.addOperation("eval",{Expr(t){return t.eval()},Ternary_ternary(t,n,r,s,i){return t.eval()?r.eval():i.eval()},Ternary(t){return t.eval()},Logical_and(t,n,r){return t.eval()&&r.eval()},Logical_or(t,n,r){return t.eval()||r.eval()},Logical(t){return t.eval()},Comparison_strictEq(t,n,r){return t.eval()===r.eval()},Comparison_strictNeq(t,n,r){return t.eval()!==r.eval()},Comparison_gte(t,n,r){return t.eval()>=r.eval()},Comparison_lte(t,n,r){return t.eval()<=r.eval()},Comparison_gt(t,n,r){return t.eval()>r.eval()},Comparison_lt(t,n,r){return t.eval()<r.eval()},Comparison_looseEq(t,n,r){return t.eval()==r.eval()},Comparison_looseNeq(t,n,r){return t.eval()!=r.eval()},Comparison(t){return t.eval()},Additive_add(t,n,r){return t.eval()+r.eval()},Additive_sub(t,n,r){return t.eval()-r.eval()},Additive(t){return t.eval()},Multiplicative_mul(t,n,r){return t.eval()*r.eval()},Multiplicative_div(t,n,r){return t.eval()/r.eval()},Multiplicative_mod(t,n,r){return t.eval()%r.eval()},Multiplicative(t){return t.eval()},UnaryExpr_not(t,n){return!n.eval()},UnaryExpr_neg(t,n){return-n.eval()},UnaryExpr(t){return t.eval()},CallExpr_methodCall(t,n,r,s,i,o){const l=t.eval(),c=r.sourceString,u=i.asIteration().children.map(d=>d.eval());if(l instanceof ke)switch(c){case"val":return l.val();case"exists":return l.exists();case"hasChild":return l.hasChild(String(u[0]));case"hasChildren":return l.hasChildren(u.length>0?u[0]:void 0);case"isString":return l.isString();case"isNumber":return l.isNumber();case"isBoolean":return l.isBoolean();case"child":return l.child(String(u[0]));case"parent":return l.parent();case"getPriority":return l.getPriority();default:throw new Error(`Unknown DataSnapshot method: ${c}`)}if(typeof l=="string"){const d=new Gf(l);switch(c){case"matches":return d.matches(u[0]);case"contains":return d.contains(String(u[0]));case"beginsWith":return d.beginsWith(String(u[0]));case"endsWith":return d.endsWith(String(u[0]));case"replace":return d.replace(u[0],String(u[1]));case"toLowerCase":return d.toLowerCase();case"toUpperCase":return d.toUpperCase();default:throw new Error(`Unknown string method: ${c}`)}}throw new Error(`Unknown method '${c}' for the given value.`)},CallExpr_memberAccess(t,n,r){const s=t.eval();return s==null?null:Ws(s,r.sourceString)},CallExpr_indexAccess(t,n,r,s){const i=t.eval(),o=r.eval();return i==null?null:Ws(i,String(o))},CallExpr(t){return t.eval()},Primary_paren(t,n,r){return n.eval()},Primary(t){return t.eval()},Array(t,n,r){return n.asIteration().children.map(s=>s.eval())},literal(t){return t.eval()},number_float(t,n,r){return parseFloat(this.sourceString)},number_int(t){return parseInt(this.sourceString,10)},number(t){return t.eval()},string_double(t,n,r){return JSON.parse(this.sourceString)},string_single(t,n,r){return n.children.map(s=>s.sourceString).join("")},string(t){return t.eval()},regex(t,n,r,s){return new RegExp(n.sourceString,s.sourceString)},bool_true(t){return!0},bool_false(t){return!1},bool(t){return t.eval()},null(t){return null},ident(t,n,r){const s=this.sourceString;if(s in Ae.pathVariableBindings)return Ae.pathVariableBindings[s];switch(s){case"auth":return Ae.auth;case"data":return Ae.data;case"newData":return Ae.newData;case"root":return Ae.root;case"now":return Ae.now;default:return}}}),Kn=e,e}function io(e,t){const n=Cn(e);if(n.failed())throw new Error(n.message??"RTDB expression failed to parse");return Ae=t,Jf()(n).eval()}const Yf=an({operation:Ea(["read","write","validate"]),path:Fe().min(1).startsWith("/"),auth:wc([an({uid:Fe(),token:cr(Kt())}),jc()]),mockData:cr(Kt()),newData:Kt().optional(),updates:xc(an({path:Fe().min(1).startsWith("/"),value:Kt()})).optional()});Ea(["INVALID_INPUT","NO_MATCHING_RULE","EVALUATION_ERROR"]);an({allowed:_s(),unsupported:_s().optional(),matchedPath:Fe(),matchedRule:Fe(),reason:Fe(),pathVariableBindings:cr(Fe())});function Xf(e){const t=e.val();return t===null||typeof t!="object"?[]:Object.keys(t)}function Qf(e,t,n,r,s,i){let o=null;function l(u,d,p,h,m){if(!p.exists())return null;const y=u.validate;if(y){if(!y.parsed.valid)o||(o={node:u,rule:y,bindings:h,unsupported:!0});else if(!io(y.raw,s(d,p,h)))return{node:u,rule:y,bindings:h}}for(const g of u.children){const x=g.path.split("/").filter(Boolean);if(x.length===0)continue;const b=x[x.length-1],v=b.startsWith("$");if(m.length>0){if(!v&&m[0]!==b)continue;return l(g,d.child(m[0]),p.child(m[0]),v?{...h,[b]:m[0]}:h,m.slice(1))}if(v)for(const w of Xf(p)){const k=l(g,d.child(w),p.child(w),{...h,[b]:w},[]);if(k)return k}else{const w=l(g,d.child(b),p.child(b),h,[]);if(w)return w}}return null}return l(e,t,n,r,i)??o}function ao(e,t,n,r=0){const s=[{node:e,pathVariableBindings:{...n},depth:r}];if(t.length===0)return s;for(const i of e.children){const o=i.path.split("/").filter(Boolean);if(o.length===0)continue;const l=o[o.length-1],c=l.startsWith("$");if(c||t[0]===l){const u=c?{...n,[l]:t[0]}:{...n},d=ao(i,t.slice(1),u,r+1);return s.push(...d),s}}return s}function wr(e,t,n){if(t.length===0)return n??null;const[r,...s]=t,i=e!==null&&typeof e=="object"&&!Array.isArray(e)?{...e}:{},o=Object.hasOwn(i,r)?i[r]:null,l=wr(o,s,n);return l==null?delete i[r]:i[r]=l,i}function Zf(e,t,n,r){if(!r||r.length===0)return wr(e,t,n??null);let s=e;for(const i of r){const o=i.path.split("/").filter(Boolean);s=wr(s,o,i.value??null)}return s}class eh{execute(t,n){const r=Yf.safeParse(n);if(!r.success)return{success:!1,error:{code:"INVALID_INPUT",message:r.error.message,recoverable:!0}};const{operation:s,path:i,auth:o,mockData:l,newData:c,updates:u}=r.data;try{const d=i.split("/").filter(Boolean),p=t,h=ao(p,d,{}),m=new ke(l,"/"),y=s==="read"?l:Zf(l,d,c,u),g=new ke(y,"/"),x=(k,j,S)=>{const C={};for(const[O,I]of Object.entries(S))C[O]=I,C[O.slice(1)]=I;return{auth:o?{uid:o.uid,token:o.token}:null,data:k,newData:j,root:m,now:Date.now(),pathVariableBindings:C}};let b;for(const k of h){const j=k.node[s];if(!j)continue;if(!j.parsed.valid){b||(b=k);continue}const S=d.slice(0,k.depth).join("/"),C=m.child(S),O=g.child(S);if(io(j.raw,x(C,O,k.pathVariableBindings))){if(s==="write"){const $=Qf(p,m,g,{},x,d);if($)return{success:!0,data:{allowed:!1,unsupported:$.unsupported===!0,matchedPath:$.node.path,matchedRule:$.rule.raw,reason:$.unsupported?`Validation rule at '${$.node.path}' contains an expression the simulator cannot evaluate: ${$.rule.raw} — not evaluated; production may reject this write.`:"Validation rule evaluated to false",pathVariableBindings:$.bindings}}}return{success:!0,data:{allowed:!0,matchedPath:k.node.path,matchedRule:j.raw,reason:"Rule expression evaluated to true",pathVariableBindings:k.pathVariableBindings}}}}if(b){const k=b.node[s];return{success:!0,data:{allowed:!1,unsupported:!0,matchedPath:b.node.path,matchedRule:k.raw,reason:`'${s}' rule at '${b.node.path}' contains an expression the simulator cannot evaluate: ${k.raw} — not evaluated; production may reject or allow this ${s}.`,pathVariableBindings:b.pathVariableBindings}}}const v=h[h.length-1],w=v.node[s];return w?{success:!0,data:{allowed:!1,matchedPath:v.node.path,matchedRule:w.raw,reason:"Rule expression evaluated to false",pathVariableBindings:v.pathVariableBindings}}:{success:!1,error:{code:"NO_MATCHING_RULE",message:`No '${s}' rule found for path '${i}'`,recoverable:!0}}}catch(d){return{success:!1,error:{code:"EVALUATION_ERROR",message:d instanceof Error?d.message:String(d),recoverable:!1}}}}}const th=new Set([".read",".write",".validate",".indexOn"]);function oo(e,t,n=[]){const r=xu(e),s=r.valid?Kf(e,t,n):r.errors,i=r.valid?Bf(e,t):[];return{raw:e,parsed:{...r,errors:s,warnings:i}}}function lo(e,t,n){const r={path:t,pathVariables:[...n],children:[]};for(const[i,o]of[[".read","read"],[".write","write"],[".validate","validate"]]){const l=e[i];l!==void 0&&(r[o]=oo(String(l),o,n))}const s=e[".indexOn"];s!==void 0&&(r.indexOn=Array.isArray(s)?s.map(String):[String(s)]);for(const[i,o]of Object.entries(e)){if(th.has(i)||typeof o!="object"||o===null)continue;const l=t==="/"?`/${i}`:`${t}/${i}`,c=i.startsWith("$")?[...n,i]:[...n];r.children.push(lo(o,l,c))}return r}function co(e){if(!e||typeof e!="object")throw new Error("Invalid rules JSON: expected an object");const t=e;if(!("rules"in t))throw new Error('Invalid rules JSON: missing top-level "rules" key');if(typeof t.rules!="object"||t.rules===null)throw new Error('Invalid rules JSON: "rules" must be an object');return lo(t.rules,"/",[])}function Hn(e){return e==="true"?!0:e==="false"?!1:e}function uo(e){const t={};e.read&&(t[".read"]=Hn(e.read.raw)),e.write&&(t[".write"]=Hn(e.write.raw)),e.validate&&(t[".validate"]=Hn(e.validate.raw)),e.indexOn&&(t[".indexOn"]=e.indexOn);for(const n of e.children){const r=n.path.split("/").filter(Boolean);t[r[r.length-1]]=uo(n)}return t}function nh(e){if(!e||typeof e!="object"||!("path"in e))throw new Error("Invalid compiled rules: expected a rules node with a 'path' property");return{rules:uo(e)}}function ts(e,t){return new eh().execute(e,t)}const ge=e=>e,zs=(...e)=>ge(e.map(t=>`(${t})`).join(" && ")),rh=(...e)=>ge(e.map(t=>`(${t})`).join(" || ")),fo=e=>e,sh=()=>fo("newData.hasChildren()"),ih=e=>fo(`newData.hasChild("${e}")`);function ho(e,t){const n=e.shape,r=[],s={};for(const[l,c]of Object.entries(n)){const u=c,d=u instanceof kc,p=d?u.unwrap():u;d||r.push(l);const h=po(p,l),m=t?.[l];if(m&&m.length>0?s[l]={validate:zs(h,...m)}:s[l]={validate:h},p instanceof Ca){const y=ho(p);s[l]={validate:y.validate,children:y.children}}}const i=[sh()];for(const l of r)i.push(ih(l));return{validate:zs(...i),children:s}}function po(e,t){if(e instanceof Sc)return ge("newData.isString()");if(e instanceof _c)return ge("newData.isNumber()");if(e instanceof Ec)return ge("newData.isBoolean()");if(e instanceof Cc){const n=e.options;return ge(n.map(r=>`newData.val() === "${r}"`).join(" || "))}if(e instanceof Nc){const n=e.value;return ge(typeof n=="string"?`newData.val() === "${n}"`:`newData.val() === ${n}`)}if(e instanceof Ac){const n=e._def.options;return rh(...n.map(r=>po(r,t)))}if(e instanceof Ca)return ge("newData.hasChildren()");throw new Error(`Unsupported Zod type for RTDB rules: ${e.constructor.name} on field "${t}"`)}function ah(e){let t;if(typeof e=="function"){const s=[];e({path:(i,o)=>s.push([i,o])}),t=s}else t=Object.entries(e);const n=mo(t);n.sort((s,i)=>{const o=s[0]==="/"?0:s[0].split("/").filter(Boolean).length,l=i[0]==="/"?0:i[0].split("/").filter(Boolean).length;return o-l||s[0].localeCompare(i[0])});const r={path:"/",pathVariables:[],children:[]};for(const[s]of n)s!=="/"&&oh(r,s);for(const[s,i]of n){const o=s==="/"?r:ns(r,s);o&&lh(r,o,i,s)}return r}function oh(e,t){const n=t.split("/").filter(Boolean);let r=e;for(let s=0;s<n.length;s++){const i="/"+n.slice(0,s+1).join("/"),o=n.slice(0,s+1).filter(c=>c.startsWith("$"));let l=r.children.find(c=>c.path===i);l||(l={path:i,pathVariables:o,children:[]},r.children.push(l)),r=l}}function lh(e,t,n,r){const s=r.split("/").filter(i=>i.startsWith("$"));if(n.read&&(t.read=Xe(n.read,"read",s)),n.write&&(t.write=Xe(n.write,"write",s)),n.validate&&(t.validate=Xe(n.validate,"validate",s)),n.schema){const i=ho(n.schema,n.fieldConstraints);t.validate||(t.validate=Xe(i.validate,"validate",s));for(const[o,l]of Object.entries(i.children)){const c=`${r}/${o}`;let u=t.children.find(d=>d.path===c);if(u||(u={path:c,pathVariables:s,children:[]},t.children.push(u)),u.validate=Xe(l.validate,"validate",s),"children"in l&&l.children)for(const[d,p]of Object.entries(l.children)){const h=`${c}/${d}`;let m=u.children.find(y=>y.path===h);m||(m={path:h,pathVariables:s,children:[]},u.children.push(m)),m.validate=Xe(p.validate,"validate",s)}}}if(n.indexOn){const i=r.split("/").filter(Boolean);if(i[i.length-1]?.startsWith("$")){const l="/"+i.slice(0,-1).join("/"),c=ns(e,l);c&&(c.indexOn=n.indexOn)}}}function mo(e){const t=[];for(const[n,r]of e){const{children:s,...i}=r;if(t.push([n,i]),s){const o=Object.entries(s).map(([l,c])=>[n+l,c]);t.push(...mo(o))}}return t}function Xe(e,t,n){return oo(String(e),t,n)}function ns(e,t){if(e.path===t)return e;for(const n of e.children){const r=ns(n,t);if(r)return r}return null}function ch(e){return e==null?null:typeof e=="string"?{uid:e,token:{}}:{uid:e.uid,token:e.token??{}}}function uh(e){return{operation:e.operation,path:e.path,auth:ch(e.auth),mockData:e.mockData??e.data??{},...e.newData!==void 0?{newData:e.newData}:{}}}function Gn(e,t,n,r){return(n?.parsed[r]??[]).map(s=>({path:e,rule:t,code:s.code,message:s.message}))}function jr(e,t){const n=[...Gn(e.path,".read",e.read,t),...Gn(e.path,".write",e.write,t),...Gn(e.path,".validate",e.validate,t)];for(const r of e.children)n.push(...jr(r,t));return n}class dh{definition;constructor(t){this.definition=t}compile(){return ah(this.definition.paths)}toJSON(){return nh(this.compile())}check(){try{const t=this.compile(),n=jr(t,"errors"),r=jr(t,"warnings");return{ok:n.length===0,errors:n,warnings:r}}catch(t){return{ok:!1,errors:[{path:"/",rule:"ruleset",code:"COMPILE_ERROR",message:t instanceof Error?t.message:String(t)}],warnings:[]}}}simulate(t){return ts(this.compile(),uh(t))}}function fh(e){return new dh(e)}function hh(e){const t=e;return typeof t.toJSON=="function"&&typeof t.simulate=="function"&&typeof t.check=="function"}function ph(e){const t=e;return typeof t=="object"&&t!==null&&"rules"in t&&!("paths"in t)&&typeof t.toJSON!="function"}class Jn{doc;constructor(t){this.doc=t}lint(){const t=this.doc.check();return[...t.errors.map(n=>qs(n,"error")),...t.warnings.map(n=>qs(n,"warning"))]}runOne(t){const n=this.doc.simulate({operation:t.operation,path:t.path,auth:t.auth??null,...t.data!==void 0?{data:t.data}:{},...t.newData!==void 0?{newData:t.newData}:{}});if(!n.success)return{case:t,...t.description!==void 0?{description:t.description}:{},expectation:t.expectation,decision:"UNSUPPORTED",passed:!1,unsupported:!0,matchedPath:t.path,matchedRule:t.operation,reason:n.error.message};const r=n.data,s=r.unsupported===!0,i=s?"UNSUPPORTED":r.allowed?"ALLOW":"DENY",o=!s&&i===t.expectation;return{case:t,...t.description!==void 0?{description:t.description}:{},expectation:t.expectation,decision:i,passed:o,unsupported:s,matchedPath:r.matchedPath,matchedRule:r.matchedRule,reason:r.reason}}simulate(t){const n=t.map(o=>this.runOne(o));let r=0,s=0,i=0;for(const o of n)o.unsupported?i++:o.passed?r++:s++;return{passed:r,failed:s,unsupported:i,cases:n}}explain(t){const n=this.runOne(t);return{decision:n.decision,expectation:n.expectation,passed:n.passed,unsupported:n.unsupported,matchedPath:n.matchedPath,matchedRule:n.matchedRule,reason:n.reason}}toJSON(){return this.doc.toJSON()}}function mh(e){return e==null?null:typeof e=="string"?{uid:e,token:{}}:{uid:e.uid,token:e.token??{}}}class yh{json;compiled;constructor(t){this.json=t,this.compiled=co(t)}toJSON(){return this.json}compile(){return this.compiled}check(){return{ok:!0,errors:[],warnings:[]}}simulate(t){return ts(this.compiled,{operation:t.operation,path:t.path,auth:mh(t.auth),mockData:t.mockData??t.data??{},...t.newData!==void 0?{newData:t.newData}:{}})}}function bh(e){return hh(e)?new Jn(e):ph(e)?new Jn(new yh(e)):new Jn(fh(e))}const gh=new Set(["__proto__","prototype","constructor"]);function B(e){if(e===""||e==="/")return[];const t=e.split("/").filter(n=>n.length>0);for(const n of t)if(gh.has(n))throw new Error(`Invalid RTDB path segment '${n}': the keys __proto__, prototype, and constructor are reserved and cannot appear in a path.`);return t}function G(e){return e.length===0?"/":"/"+e.join("/")}function Re(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(n=>Re(n));const t={};for(const[n,r]of Object.entries(e))t[n]=Re(r);return t}function Ks(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function dt(e,t){if(Object.is(e,t))return!0;if(Array.isArray(e)||Array.isArray(t))return!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?!1:e.every((s,i)=>dt(s,t[i]));if(!Ks(e)||!Ks(t))return!1;const n=Object.keys(e),r=Object.keys(t);return n.length!==r.length?!1:n.every(s=>s in t&&dt(e[s],t[s]))}class vh{root={};snapshot(){return Re(this.root)}restore(t){this.root=Re(t)}read(t){const n=B(t);let r=this.root;for(const s of n){if(r===null||typeof r!="object"||Array.isArray(r))return null;const i=r;if(!Object.hasOwn(i,s))return null;r=i[s]}return Re(r)}write(t,n){const r=B(t),s=this.read(t);if(r.length===0)return n===null?(this.root={},s):(this.root=Re(n),s);(this.root===null||typeof this.root!="object"||Array.isArray(this.root))&&(this.root={});let i=this.root;for(let l=0;l<r.length-1;l++){const c=r[l],u=Object.hasOwn(i,c)?i[c]:void 0;if(u==null||typeof u!="object"||Array.isArray(u)){const d={};i[c]=d,i=d}else i=u}const o=r[r.length-1];return n===null?(delete i[o],this.trim(r)):i[o]=Re(n),s}multiUpdate(t){const r=Object.entries(t).map(([i,o])=>({path:G(B(i)),value:o}));for(let i=0;i<r.length;i++)for(let o=i+1;o<r.length;o++){const l=r[i].path,c=r[o].path;if(l===c)throw new Error(`multi-path update: duplicate path '${l}'.`);const u=l==="/"?"/":l+"/",d=c==="/"?"/":c+"/";if(l!=="/"&&c.startsWith(u))throw new Error(`multi-path update: '${c}' is a descendant of '${l}'.`);if(c!=="/"&&l.startsWith(d))throw new Error(`multi-path update: '${l}' is a descendant of '${c}'.`)}const s=[];for(const{path:i,value:o}of r){const l=this.write(i,o);s.push({path:i,prior:l})}return s}shallowUpdate(t,n){const r=[],s=B(t);for(const[i,o]of Object.entries(n)){const l=[...s,...B(i)],c=G(l),u=this.write(c,o);r.push({path:c,prior:u})}return r}trim(t){if(!(this.root===null||typeof this.root!="object"||Array.isArray(this.root)))for(let n=t.length-1;n>=1;n--){const r=t.slice(0,n),s=t[n-1];let i=this.root;for(let l=0;l<r.length-1;l++){const c=i[r[l]];if(c==null||typeof c!="object"||Array.isArray(c))return;i=c}const o=i[s];if(o!==void 0&&typeof o=="object"&&o!==null&&!Array.isArray(o)&&Object.keys(o).length===0){delete i[s];continue}return}}}function xh(e,t){return e==="/"||t==="/"?!0:e===t||e.startsWith(`${t}/`)||t.startsWith(`${e}/`)}class wh{version=0;activeVersions=[];mutations=[];get entries(){return this.mutations}get currentVersion(){return this.version}begin(){const t=this.version;return this.activeVersions.push(t),t}mark(t="/"){this.version+=1,this.activeVersions.length>0&&this.mutations.push({version:this.version,paths:(Array.isArray(t)?t:[t]).map(n=>G(B(n)))})}conflictsSince(t,n){const r=G(B(n));return this.mutations.some(s=>s.version>t&&s.paths.some(i=>xh(r,i)))}release(t){const n=this.activeVersions.lastIndexOf(t);if(n>=0&&this.activeVersions.splice(n,1),this.activeVersions.length===0){this.mutations.length=0;return}const r=Math.min(...this.activeVersions),s=this.mutations.findIndex(i=>i.version>r);s<0?this.mutations.length=0:s>0&&this.mutations.splice(0,s)}}function we(e){return e==="unsupported"?"unsupported":"deny"}function je(e){return G(B(e))}class jh{sandbox;nextId=0;constructor(t){this.sandbox=t}nextListenerId(){return this.nextId+=1,`rtdb-listener-${this.nextId.toString(36)}`}nextGroupId(t){return this.nextId+=1,`rtdb-${t}-${this.nextId.toString(36)}`}mutation(t,n,r,s={}){if(this.sandbox)try{De(this.sandbox,Sn({service:"rtdb",op:n,path:r,auth:t,before:s.before,after:s.after,detail:s.detail}),{service:"rtdb"})}catch{}}operation(t,n,r,s,i,o={}){if(this.sandbox)try{De(this.sandbox,Na({service:"rtdb",method:n,path:je(r),auth:t,result:s,origin:o.origin??"user",durationMs:o.durationMs,reasons:i?.reasons,rules:i?{engine:"rtdb",matchedPath:i.matchedPath,matchedRule:i.matchedRule,pathVariableBindings:i.pathVariableBindings,reason:i.reason,errorCode:i.errorCode}:void 0,request:o.request,resourceBefore:o.resourceBefore,resourceAfter:o.resourceAfter,groupId:o.groupId,groupKind:o.groupKind,triggeredBy:o.triggeredBy,detail:o.detail,at:o.at}),{service:"rtdb"})}catch{}}commit(t,n,r,s={}){if(this.sandbox)try{De(this.sandbox,Rc({service:"rtdb",method:n,path:je(r),auth:t,data:s.data,priorState:s.priorState,nextState:s.nextState,groupId:s.groupId,groupKind:s.groupKind,replay:s.replay,detail:s.detail}),{service:"rtdb"})}catch{}}listener(t,n,r,s={}){if(this.sandbox)try{De(this.sandbox,Dc({service:"rtdb",phase:t,listenerId:n.id,target:{kind:s.event??"value",path:je(n.path)},auth:r,result:s.result,size:s.size,sample:s.sample,reason:s.reason,error:s.error,triggeredBy:s.triggeredBy,detail:s.detail}),{service:"rtdb"})}catch{}}}class kh{values=new Map;get(t){return this.values.get(G(B(t)))??null}forChild(t){const n=B(t);return r=>this.get(G([...n,r]))}clear(){this.values.clear()}clearAtOrBelow(t){const n=G(B(t)),r=n==="/"?"/":`${n}/`;for(const s of this.values.keys())(s===n||s.startsWith(r))&&this.values.delete(s)}replace(t,n){this.clearAtOrBelow(t),n!==null&&this.values.set(G(B(t)),n)}set(t,n){const r=G(B(t));n===null?this.values.delete(r):this.values.set(r,n)}stateAtOrBelow(t){const n=G(B(t)),r=n==="/"?"/":`${n}/`;return JSON.stringify([...this.values].filter(([s])=>s===n||s.startsWith(r)).sort(([s],[i])=>s.localeCompare(i)))}applyUpdate(t){for(const n of t){const r=this.get(n.path);this.clearAtOrBelow(n.path),n.value!==null&&r!==null&&this.values.set(G(B(n.path)),r)}}entries(){return this.values.entries()}restore(t){this.values.clear();for(const[n,r]of Object.entries(t))this.values.set(G(B(n)),r)}}function mn(e){if(e!==null&&typeof e!="string"&&(typeof e!="number"||!Number.isFinite(e)))throw new Error("priority must be a valid Firebase priority (string, finite number, or null)")}function ve(){const e=new Error("PERMISSION_DENIED: Permission denied");return e.code="PERMISSION_DENIED",e}class Sh{compiled=null;setRules(t){if(t===null){this.compiled=null;return}this.compiled=co(t)}hasRules(){return this.compiled!==null}check(t,n,r){return this.evaluate(t,n,r).check}evaluate(t,n,r){if(this.compiled===null)return{check:"allow",reasons:["No RTDB rules loaded; default allow."]};const s=r.auth===null?null:{uid:r.auth.uid,token:r.auth.token??{}},i=ts(this.compiled,{operation:t,path:n==="/"?"/":n,auth:s,mockData:r.mockData,newData:r.newData,updates:r.updates});return i.success?i.data.unsupported?{check:"unsupported",reasons:[`${i.data.matchedPath} ${t} UNSUPPORTED: ${i.data.reason}`],matchedPath:i.data.matchedPath,matchedRule:i.data.matchedRule,reason:i.data.reason,pathVariableBindings:i.data.pathVariableBindings}:{check:i.data.allowed?"allow":"deny",reasons:[`${i.data.matchedPath} ${t} ${i.data.allowed?"ALLOW":"DENY"}: ${i.data.reason}`],matchedPath:i.data.matchedPath,matchedRule:i.data.matchedRule,reason:i.data.reason,pathVariableBindings:i.data.pathVariableBindings}:i.error.code==="NO_MATCHING_RULE"?{check:"no-rule",reasons:[i.error.message],errorCode:i.error.code,errorMessage:i.error.message}:{check:"no-rule",reasons:[i.error.message],errorCode:i.error.code,errorMessage:i.error.message}}}class _h{tree=new vh;rules=new Sh;activeRules=null;valueListeners=new Set;childListeners=new Set;priorities=new kh;mutations=new wh;events;writeSubscribers=new Set;resetGeneration=0;constructor(t){this.events=new jh(t)}notifyWrite(){for(const t of this.writeSubscribers)try{t()}catch{}}}function rs(e,t){if(e===t)return 0;if(e===null)return-1;if(t===null)return 1;const n=Hs(e),r=Hs(t);return n!==r?n-r:typeof e=="number"&&typeof t=="number"?e<t?-1:e>t?1:0:typeof e=="boolean"&&typeof t=="boolean"?e===t?0:e?1:-1:typeof e=="string"&&typeof t=="string"?e<t?-1:e>t?1:0:0}function Hs(e){return e===null?0:typeof e=="boolean"?1:typeof e=="number"?2:typeof e=="string"?3:4}const Eh=/^-?(0*)\d{1,10}$/,Ch=-2147483648,Nh=2147483647;function Gs(e){if(Eh.test(e)){const t=Number(e);if(t>=Ch&&t<=Nh)return t}return null}function yn(e,t){if(e===t)return 0;const n=Gs(e),r=Gs(t);return n!==null?r!==null?n-r===0?e.length-t.length:n-r:-1:r!==null?1:e<t?-1:1}function Pt(e,t,n,r=null){const s=e??{kind:"priority"};switch(s.kind){case"key":return t;case"value":return n;case"priority":return r;case"child":{if(n===null||typeof n!="object"||Array.isArray(n))return null;const i=s.path.split("/").filter(l=>l.length>0);let o=n;for(const l of i){if(o===null||typeof o!="object"||Array.isArray(o))return null;o=o[l]??null}return o}}}function ze(e,t,n=()=>null){if(e===null||typeof e!="object"||Array.isArray(e))return[];let s=Object.entries(e).map(([o,l])=>({key:o,value:l,priority:n(o)}));const i=t.orderBy?.kind==="key";s.sort((o,l)=>{if(i)return yn(o.key,l.key);const c=Pt(t.orderBy,o.key,o.value,o.priority),u=Pt(t.orderBy,l.key,l.value,l.priority),d=rs(c,u);return d!==0?d:yn(o.key,l.key)});for(const o of t.bounds)s=s.filter(l=>Ah(o,l,t.orderBy));if(t.limit){const o=t.limit.n;t.limit.kind==="limitToFirst"?s=s.slice(0,o):s=o>=s.length?s:s.slice(s.length-o)}return s}function Ah(e,t,n){const s=n?.kind==="key"?yn(t.key,String(e.value)):rs(Pt(n,t.key,t.value,t.priority),e.value),i=o=>yn(t.key,o);switch(e.kind){case"startAt":return s>0?!0:s<0?!1:e.key===void 0||i(e.key)>=0;case"startAfter":return s>0?!0:s<0||e.key===void 0?!1:i(e.key)>0;case"endAt":return s<0?!0:s>0?!1:e.key===void 0||i(e.key)<=0;case"endBefore":return s<0?!0:s>0||e.key===void 0?!1:i(e.key)<0;case"equalTo":return s!==0?!1:e.key===void 0||i(e.key)===0}}function Js(e){return e.length===0?null:Object.fromEntries(e.map(({key:t,value:n})=>[t,n]))}function Rh(e,t){return e.length===t.length&&e.every((n,r)=>{const s=t[r];return n.key===s.key&&n.priority===s.priority&&dt(n.value,s.value)})}function ss(e){const t=new Error(`permission_denied at ${G(B(e))}: Client doesn't have permission to access the desired data.`);return t.code="PERMISSION_DENIED",t}class Dh{state;constructor(t){this.state=t}onValue(t,n,r,s,i,o){const l=Date.now(),c=this.state.rules.evaluate("read",n==="/"?"/":n,{auth:t,mockData:this.state.tree.snapshot()});if(c.check!=="allow"){if(this.state.events.operation(t,"listen",n,we(c.check),c,{at:l,durationMs:Date.now()-l,request:s?{query:s}:void 0,origin:"listener"}),this.state.events.listener("errored",{id:this.state.events.nextListenerId(),path:n},t,{event:"value",result:"deny",error:{code:"PERMISSION_DENIED",message:"PERMISSION_DENIED: Permission denied",reasons:c.reasons}}),i)return queueMicrotask(()=>{o?.(),i(ss(n))}),()=>{};throw ve()}return this.attach(t,n,r,s,{origin:"listener",result:"allow",evaluation:c,at:l},i,o)}adminOnValue(t,n,r){return this.attach(null,t,n,r,{origin:"admin",result:"not-applicable",evaluation:void 0,at:Date.now()})}attach(t,n,r,s,i,o,l){const c=this.state.events.nextListenerId();this.state.events.operation(t,"listen",n,i.result,i.evaluation,{at:i.at,durationMs:Date.now()-i.at,request:s?{query:s}:void 0,origin:i.origin});const u={id:c,auth:t,cb:r,path:n,query:s,cancelCallback:o,onCanceled:l};if(this.state.valueListeners.add(u),this.state.events.listener("attach",u,t,{event:"value",result:"allow",detail:s?{query:s}:void 0}),s){const d=ze(this.state.tree.read(n),s,this.state.priorities.forChild(n));u.lastWindow=d,this.deliverInitial(u,{val:Js(d),exists:d.length>0,key:this.key(n),rows:d},{initial:!0,query:!0})}else{const d=this.snapshot(n);u.lastValue=d.val,u.lastPriorityState=this.state.priorities.stateAtOrBelow(n),this.deliverInitial(u,d,{initial:!0})}return()=>{this.state.valueListeners.delete(u),this.state.events.listener("detach",u,t,{event:"value"})}}fanOut(t){if(this.state.valueListeners.size===0)return;const n=t.map(r=>G(B(r)));for(const r of this.state.valueListeners){const s=G(B(r.path));if(!n.some(l=>Ih(s,l)))continue;if(r.query){const l=ze(this.state.tree.read(r.path),r.query,this.state.priorities.forChild(r.path));if(Rh(r.lastWindow??[],l)){this.state.events.listener("suppressed",r,r.auth,{event:"value",reason:"no-op",detail:{query:!0}});continue}r.lastWindow=l,this.deliver(r,{val:Js(l),exists:l.length>0,key:this.key(r.path),rows:l},{query:!0});continue}const i=this.snapshot(r.path),o=this.state.priorities.stateAtOrBelow(r.path);if(dt(r.lastValue??null,i.val)&&r.lastPriorityState===o){this.state.events.listener("suppressed",r,r.auth,{event:"value",reason:"no-op"});continue}r.lastValue=i.val,r.lastPriorityState=o,this.deliver(r,i,{})}}off(t,n){const r=G(B(t));for(const s of[...this.state.valueListeners])G(B(s.path))===r&&(n!==void 0&&s.cb!==n||(this.state.valueListeners.delete(s),this.state.events.listener("detach",s,s.auth,{event:"value"})))}count(){return this.state.valueListeners.size}snapshot(t){const n=this.state.tree.read(t);return{val:n,exists:n!==null,key:this.key(t)}}key(t){const n=B(t);return n.length===0?null:n[n.length-1]}deliver(t,n,r){this.state.events.listener("delivery",t,t.auth,{event:"value",size:n.rows?.length??(n.exists?1:0),sample:n.val,detail:r});try{t.cb(n)}catch(s){this.state.events.listener("errored",t,t.auth,{event:"value",result:"error",error:{message:s instanceof Error?s.message:String(s)},detail:r})}}deliverInitial(t,n,r){try{t.cb(n),this.state.events.listener("delivery",t,t.auth,{event:"value",size:n.rows?.length??(n.exists?1:0),sample:n.val,detail:r})}catch(s){this.state.events.listener("errored",t,t.auth,{event:"value",result:"error",error:{message:s instanceof Error?s.message:String(s)},detail:r})}}}function Ih(e,t){if(e===t||e==="/")return!0;const n=`${e}/`,r=t==="/"?"/":`${t}/`;return t.startsWith(n)||e.startsWith(r)}function Qe(e,t){const n=e.findIndex(r=>r.key===t);return n>0?e[n-1].key:null}function kt(e,t){const n=e.findIndex(r=>r.key===t);return n>0?e[n-1].key:null}function Ys(e,t){if(t===void 0)return null;const n=B(e),r=B(t);return r.length!==n.length+1||!n.every((s,i)=>r[i]===s)?null:r[r.length-1]??null}class $h{state;constructor(t){this.state=t}onChild(t,n,r,s,i,o,l){const c=Date.now(),u=this.state.events.nextListenerId(),d=this.state.rules.evaluate("read",r==="/"?"/":r,{auth:t,mockData:this.state.tree.snapshot()});if(d.check!=="allow"){if(this.state.events.operation(t,"listen",r,we(d.check),d,{at:c,durationMs:Date.now()-c,origin:"listener",detail:{event:n}}),this.state.events.listener("errored",{id:u,path:r},t,{event:n,result:"deny",error:{code:"PERMISSION_DENIED",message:"PERMISSION_DENIED: Permission denied",reasons:d.reasons}}),o)return queueMicrotask(()=>{l?.(),o(ss(r))}),()=>{};throw ve()}this.state.events.operation(t,"listen",r,"allow",d,{at:c,durationMs:Date.now()-c,origin:"listener",detail:{event:n}});const p={id:u,auth:t,event:n,path:r,cb:s,spec:i,cancelCallback:o,onCanceled:l};if(this.state.childListeners.add(p),this.state.events.listener("attach",p,t,{event:n,result:"allow",detail:i?{query:i}:void 0}),i){const h=ze(this.state.tree.read(r),i,this.state.priorities.forChild(r));if(p.lastWindow=h,n==="child_added")for(const{key:m,value:y}of h)this.deliver(p,{key:m,val:y,previousChildName:Qe(h,m)},{initial:!0,query:!0})}else if(n==="child_added")for(const{key:h,val:m}of this.directChildren(r)){const y=this.directChildren(r);this.deliver(p,{key:h,val:m,previousChildName:kt(y,h)},{initial:!0})}return()=>{this.state.childListeners.delete(p),this.state.events.listener("detach",p,t,{event:n})}}off(t,n,r){const s=G(B(t));for(const i of[...this.state.childListeners])n!==void 0&&i.event!==n||G(B(i.path))===s&&(r!==void 0&&i.cb!==r||(this.state.childListeners.delete(i),this.state.events.listener("detach",i,i.auth,{event:i.event})))}snapshotParents(){const t=new Map;for(const n of this.state.childListeners){const r=G(B(n.path));t.has(r)||t.set(r,new Map(this.directChildren(r).map(({key:s,val:i})=>[s,i])))}return t}fanOut(t,n){if(this.state.childListeners.size===0)return;const r=new Map;for(const s of this.state.childListeners){if(s.spec){this.fanOutQuery(s,n);continue}const i=G(B(s.path)),o=r.get(i)??[];o.push(s),r.set(i,o)}for(const[s,i]of r){const o=t.get(s)??new Map,l=new Map(this.directChildren(s).map(({key:h,val:m})=>[h,m])),c=[...l].map(([h,m])=>({key:h,val:m})),u=[...o].map(([h,m])=>({key:h,val:m})),d={child_added:[],child_changed:[],child_removed:[],child_moved:[]};for(const[h,m]of l)o.has(h)?dt(o.get(h),m)||d.child_changed.push({key:h,val:m,previousChildName:kt(c,h)}):d.child_added.push({key:h,val:m,previousChildName:kt(c,h)});for(const[h,m]of o)l.has(h)||d.child_removed.push({key:h,val:m,previousChildName:kt(u,h)});const p=Ys(s,n);p!==null&&o.has(p)&&l.has(p)&&d.child_moved.push({key:p,val:l.get(p),previousChildName:kt(c,p)});for(const h of i)for(const m of d[h.event])this.deliver(h,m,{})}}count(){return this.state.childListeners.size}directChildren(t){const n=this.state.tree.read(t);return n===null||typeof n!="object"||Array.isArray(n)?[]:ze(n,{orderBy:{kind:"priority"},bounds:[],limit:null},this.state.priorities.forChild(t)).map(({key:r,value:s})=>({key:r,val:s}))}fanOutQuery(t,n){const r=t.lastWindow??[],s=ze(this.state.tree.read(t.path),t.spec,this.state.priorities.forChild(t.path));t.lastWindow=s;const i=new Map(r.map(c=>[c.key,c.value])),o=new Map(s.map(c=>[c.key,c.value])),l=[];if(t.event==="child_added")for(const c of s)i.has(c.key)||l.push({key:c.key,val:c.value,previousChildName:Qe(s,c.key)});else if(t.event==="child_changed")for(const c of s)i.has(c.key)&&!dt(i.get(c.key),c.value)&&l.push({key:c.key,val:c.value,previousChildName:Qe(s,c.key)});else if(t.event==="child_removed")for(const c of r)o.has(c.key)||l.push({key:c.key,val:c.value,previousChildName:Qe(r,c.key)});else if(t.spec?.orderBy&&t.spec.orderBy.kind!=="key"){const c=t.spec.orderBy.kind==="priority"?Ys(t.path,n):null;let u=!1;if(c!==null){const d=s.find(p=>p.key===c);d&&i.has(c)&&(l.push({key:d.key,val:d.value,previousChildName:Qe(s,d.key)}),u=!0)}if(!u){const d=new Map(r.map(p=>[p.key,p]));for(const p of s){const h=d.get(p.key);if(!h)continue;const m=Pt(t.spec.orderBy,h.key,h.value,h.priority),y=Pt(t.spec.orderBy,p.key,p.value,p.priority);rs(m,y)!==0&&l.push({key:p.key,val:p.value,previousChildName:Qe(s,p.key)})}}}for(const c of l)this.deliver(t,c,{query:!0})}deliver(t,n,r){this.state.events.listener("delivery",t,t.auth,{event:t.event,size:1,sample:r.query?{key:n.key,val:n.val}:n,detail:r});try{t.cb(n)}catch(s){this.state.events.listener("errored",t,t.auth,{event:t.event,result:"error",error:{message:s instanceof Error?s.message:String(s)},detail:r})}}}function Ph(e){if(e!==null&&typeof e=="object"&&!Array.isArray(e)){const t=e,n=t.priorities;if(t[".pyricRtdbPersistence"]===1&&"data"in t&&n!==null&&typeof n=="object"&&!Array.isArray(n)){const r={};for(const[s,i]of Object.entries(n))(typeof i=="string"||typeof i=="number"&&Number.isFinite(i))&&(r[s]=i);return{data:t.data??null,priorities:r}}}return{data:e,priorities:{}}}class Oh{state;values;children;constructor(t,n,r){this.state=t,this.values=n,this.children=r}exportTree(){return this.state.tree.snapshot()}exportState(){return{".pyricRtdbPersistence":1,data:this.state.tree.snapshot(),priorities:Object.fromEntries(this.state.priorities.entries())}}restore(t){const n=this.children.snapshotParents(),r=Ph(t);this.state.tree.restore(r.data??{}),this.state.priorities.restore(r.priorities),this.state.mutations.mark("/"),this.values.fanOut(["/"]),this.children.fanOut(n)}reset(){this.state.resetGeneration+=1,this.restore(null)}subscribe(t){return this.state.writeSubscribers.add(t),()=>{this.state.writeSubscribers.delete(t)}}}const Xs="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";let Qs=0;const Te=new Array(12).fill(0);function Uh(e=Date.now()){const t=e===Qs;Qs=e;const n=new Array(8);let r=e;for(let i=7;i>=0;i--)n[i]=Xs.charAt(r%64),r=Math.floor(r/64);if(r!==0)throw new Error("RTDB push-id: timestamp overflow.");let s=n.join("");if(t){let i;for(i=11;i>=0&&Te[i]===63;i--)Te[i]=0;if(i<0)for(let o=0;o<12;o++)Te[o]=Math.floor(Math.random()*64);else Te[i]=(Te[i]??0)+1}else for(let i=0;i<12;i++)Te[i]=Math.floor(Math.random()*64);for(let i=0;i<12;i++)s+=Xs.charAt(Te[i]);if(s.length!==20)throw new Error(`RTDB push-id: bad length ${s.length}.`);return s}const Th=/[\[\].#$/\u0000-\u001F\u007F]/;function Mh(e){return e.length!==0&&!Th.test(e)}function Lh(e){return typeof e=="number"&&(Number.isNaN(e)||e===1/0||e===-1/0)}function Bh(e){return e===".priority"||e===".value"||e===".sv"}function Fh(e,t){kr(e,t,"set")}function kr(e,t,n){if(e===void 0)throw new Error(`${n} failed: value argument contains undefined in property '${t}'`);if(typeof e=="function")throw new Error(`${n} failed: value argument contains a function in property '${t}'`);if(Lh(e))throw new Error(`${n} failed: value argument contains ${String(e)} in property '${t}'`);if(!(e===null||typeof e!="object")){if(Array.isArray(e)){for(let r=0;r<e.length;r++){if(!(r in e))continue;const s=e[r];s!==void 0&&kr(s,`${t}/${r}`,n)}return}for(const[r,s]of Object.entries(e)){if(!Bh(r)&&!Mh(r))throw new Error(`${n} failed: value argument contains an invalid key (${r}) in path ${t}. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"`);kr(s,`${t}/${r}`,n)}}}function Be(e,t){return Fh(e,t),Sr(e)}function Sr(e){if(e==null)return null;if(typeof e!="object")return e;if(Array.isArray(e)){const n={};for(let r=0;r<e.length;r++){if(!(r in e))continue;const s=Sr(e[r]);s!==null&&(n[String(r)]=s)}return Object.keys(n).length===0?null:n}const t={};for(const[n,r]of Object.entries(e)){if(n===".sv"){t[n]=r;continue}const s=Sr(r);s!==null&&(t[n]=s)}return Object.keys(t).length===0?null:t}function ln(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(o=>ln(o));const t=e,n=Object.keys(t);let r=n.length>0,s=0;for(const o of n)if(/^(0|[1-9]\d*)$/.test(o))s=Math.max(s,Number(o));else{r=!1;break}if(r&&s<2*n.length){const o=[];for(let l=0;l<=s;l++){const c=t[String(l)];o[l]=c===void 0?null:ln(c)}return o}const i={};for(const[o,l]of Object.entries(t))i[o]=ln(l);return i}function Vh(e){return e===null||typeof e!="object"?!1:e[".sv"]==="timestamp"}function qh(e){if(e===null||typeof e!="object")return!1;const t=e[".sv"];return t!==null&&typeof t=="object"&&typeof t.increment=="number"}function xe(e,t,n){if(Vh(e))return t;if(qh(e)){const i=e[".sv"].increment;return(typeof n=="number"?n:0)+i}if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map((i,o)=>xe(i,t,Array.isArray(n)?n[o]:void 0));const r=n!==null&&typeof n=="object"&&!Array.isArray(n)?n:void 0,s={};for(const[i,o]of Object.entries(e))s[i]=xe(o,t,r?r[i]:void 0);return s}function Zs(){return new Error("permission_denied")}class Wh{state;values;children;constructor(t,n,r){this.state=t,this.values=n,this.children=r}run(t,n,r,s){const i=s?.applyLocally!==!1,o=B(n),l=o.length===0?null:o[o.length-1];let c=null,u,d=0,p=!1;do{d+=1;const w=this.state.mutations.begin();c=this.state.tree.read(n);const k=c===null?null:ln(Re(c));let j=!1;try{u=r(k),j=this.state.mutations.conflictsSince(w,n)}finally{this.state.mutations.release(w)}if(!j||u===void 0){p=!0;break}}while(d<25);if(!p)throw new Error("maxretry");const h=this.state.events.nextGroupId("transaction");if(u===void 0)return this.state.events.operation(t,"transaction",n,"not-applicable",void 0,{origin:"transaction",groupId:h,groupKind:"transaction",resourceBefore:{data:c,exists:c!==null},detail:{committed:!1,aborted:!0}}),{committed:!1,val:c,key:l};const m=Date.now(),y=Be(xe(u,m,c),n==="/"?"":n);if(i){const w=this.state.tree.snapshot(),k=Object.fromEntries(this.state.priorities.entries()),j=this.state.priorities.get(n),S=this.children.snapshotParents();this.state.tree.write(n,y),this.state.priorities.replace(n,j),this.values.fanOut([n]),this.children.fanOut(S);const C=Date.now(),O=this.state.rules.evaluate("write",n==="/"?"/":n,{auth:t,mockData:w,newData:y});if(O.check!=="allow"){this.state.events.operation(t,"transaction",n,we(O.check),O,{at:C,durationMs:Date.now()-C,origin:"transaction",request:{data:u,resourceData:u},resourceBefore:{data:c,exists:c!==null},resourceAfter:{data:y,exists:y!==null},groupId:h,groupKind:"transaction"});const I=this.children.snapshotParents();throw this.state.tree.restore(w),this.state.priorities.restore(k),this.values.fanOut([n]),this.children.fanOut(I),Zs()}return this.recordCommit(t,n,u,c,y,h,m,C,!0,O),{committed:!0,val:y,key:l}}const g=Date.now(),x=this.state.rules.evaluate("write",n==="/"?"/":n,{auth:t,mockData:this.state.tree.snapshot(),newData:y});if(x.check!=="allow")throw this.state.events.operation(t,"transaction",n,we(x.check),x,{at:g,durationMs:Date.now()-g,origin:"transaction",request:{data:u,resourceData:u},resourceBefore:{data:c,exists:c!==null},resourceAfter:{data:y,exists:y!==null},groupId:h,groupKind:"transaction"}),Zs();this.state.events.operation(t,"transaction",n,"allow",x,{at:g,durationMs:Date.now()-g,origin:"transaction",request:{data:u,resourceData:u},resourceBefore:{data:c,exists:c!==null},resourceAfter:{data:y,exists:y!==null},groupId:h,groupKind:"transaction"});const b=this.state.priorities.get(n),v=this.children.snapshotParents();return this.state.tree.write(n,y),this.state.priorities.replace(n,b),this.state.mutations.mark(n),this.values.fanOut([n]),this.children.fanOut(v),this.finishEvents(t,n,u,c,y,h,m,!1),this.state.notifyWrite(),{committed:!0,val:y,key:l}}recordCommit(t,n,r,s,i,o,l,c,u,d){this.state.events.operation(t,"transaction",n,"allow",d,{at:c,durationMs:Date.now()-c,origin:"transaction",request:{data:r,resourceData:r},resourceBefore:{data:s,exists:s!==null},resourceAfter:{data:i,exists:i!==null},groupId:o,groupKind:"transaction"}),this.finishEvents(t,n,r,s,i,o,l,u),this.state.mutations.mark(n),this.state.notifyWrite()}finishEvents(t,n,r,s,i,o,l,c){this.state.events.commit(t,"transaction",n,{data:r,priorState:s,nextState:i,groupId:o,groupKind:"transaction",replay:{requestTime:l},detail:{committed:!0,applyLocally:c}}),this.state.events.mutation(t,"transaction",je(n),{before:s,after:i,detail:{committed:!0}})}}class zh{state;values;children;constructor(t,n,r){this.state=t,this.values=n,this.children=r}adminSet(t,n){if(mn(n),this.state.tree.read(t)===null)return;const r=this.children.snapshotParents(),s=this.state.priorities.get(t)!==n;this.state.priorities.set(t,n),this.state.mutations.mark(t),s&&this.values.fanOut([t]),this.children.fanOut(r,s?t:void 0),this.state.notifyWrite()}set(t,n,r){mn(r);const s=this.state.tree.read(n),i=Date.now(),o=this.state.rules.evaluate("write",n==="/"?"/":n,{auth:t,mockData:this.state.tree.snapshot(),newData:s}),l=this.state.priorities.get(n),c={at:i,durationMs:Date.now()-i,request:{data:r},resourceBefore:{data:s,exists:s!==null},resourceAfter:{data:s,exists:s!==null},detail:{priority:r,priorPriority:l}};if(o.check!=="allow")throw this.state.events.operation(t,"setPriority",n,we(o.check),o,c),ve();if(this.state.events.operation(t,"setPriority",n,"allow",o,c),s===null)return;const u=this.children.snapshotParents(),d=l!==r;this.state.priorities.set(n,r),this.state.mutations.mark(n),d&&this.values.fanOut([n]),this.children.fanOut(u,d?n:void 0),d&&(this.state.events.commit(t,"setPriority",n,{data:r,priorState:l,nextState:r,detail:{priority:r,priorPriority:l}}),this.state.events.mutation(t,"setPriority",je(n),{before:l,after:r,detail:{priorityMetadata:!0}})),this.state.notifyWrite()}}function ei(e){return e.length===0?null:Object.fromEntries(e.map(({key:t,value:n})=>[t,n]))}class Kh{state;values;children;priorityWrites;constructor(t,n,r){this.state=t,this.values=n,this.children=r,this.priorityWrites=new zh(t,n,r)}setData(t){this.state.tree.restore({}),this.state.priorities.clear();for(const[n,r]of Object.entries(t))this.state.tree.write(n,Be(xe(r,Date.now()),n==="/"?"":n));this.state.mutations.mark("/"),this.state.notifyWrite()}setRules(t){this.state.rules.setRules(t),this.state.activeRules=t===null?null:structuredClone(t),this.cancelDeniedListeners()}getActiveRules(){return this.state.activeRules===null?null:structuredClone(this.state.activeRules)}snapshotState(){return this.state.tree.snapshot()}adminGet(t){const n=this.state.tree.read(t);return this.state.events.operation(null,"get",t,"not-applicable",void 0,{origin:"admin",resourceBefore:{data:n,exists:n!==null}}),n}adminGetQuery(t,n){const r=ze(this.state.tree.read(t),n,this.state.priorities.forChild(t));return this.state.events.operation(null,"get",t,"not-applicable",void 0,{origin:"admin",request:{query:n},resourceBefore:{data:ei(r),exists:r.length>0}}),r}adminSet(t,n){this.adminSetWithPriority(t,n,null,!1)}adminSetWithPriority(t,n,r,s=!0){mn(r);const i=Date.now(),o=this.state.tree.read(t),l=Be(xe(n,i,o),t==="/"?"":t),c=l===null?"remove":"set";this.state.events.operation(null,c,t,"not-applicable",void 0,{origin:"admin",request:{data:n,resourceData:n},resourceBefore:{data:o,exists:o!==null},resourceAfter:{data:l,exists:l!==null}});const u=this.children.snapshotParents(),d=this.state.priorities.get(t),p=this.state.priorities.stateAtOrBelow(t);this.state.tree.write(t,l),this.state.priorities.replace(t,l===null?null:r);const h=p!==this.state.priorities.stateAtOrBelow(t);this.changed([t],u,h?t:void 0);const m=this.state.tree.read(t);this.state.events.commit(null,m===null?"remove":"set",t,{data:n,priorState:o,nextState:m,replay:{requestTime:i},detail:s?{admin:!0,priority:r,priorPriority:d}:{admin:!0}}),this.state.notifyWrite()}adminUpdate(t,n){const r=Date.now(),s=this.state.tree.read(t),i=this.resolvePatch(t,n,r),o=Object.keys(n).some(u=>u.includes("/"));this.state.events.operation(null,"update",t,"not-applicable",void 0,{origin:"admin",request:{data:n,resourceData:n},resourceBefore:{data:s,exists:s!==null},detail:o?{admin:!0,multiPath:!0,paths:Object.keys(i)}:{admin:!0,multiPath:!1,keys:Object.keys(n)}});const l=this.children.snapshotParents();o?this.state.tree.multiUpdate(i):this.state.tree.shallowUpdate(t,Object.fromEntries(Object.entries(i).map(([u,d])=>[B(u).at(-1),d]))),this.state.priorities.applyUpdate(Object.entries(i).map(([u,d])=>({path:u,value:d}))),this.changed(Object.keys(i),l);const c=o?{admin:!0,multiPath:!0,paths:Object.keys(i)}:{admin:!0,multiPath:!1,keys:Object.keys(n)};this.state.events.commit(null,"update",t,{data:n,priorState:s,nextState:this.state.tree.read(t),replay:{requestTime:r},detail:c}),this.state.notifyWrite()}adminRemove(t){this.adminSet(t,null)}adminSetPriority(t,n){this.priorityWrites.adminSet(t,n)}get(t,n){const r=Date.now(),s=this.state.tree.read(n),i=this.readEvaluation(t,n);if(i.check!=="allow")throw this.state.events.operation(t,"get",n,we(i.check),i,{at:r,durationMs:Date.now()-r,resourceBefore:{data:s,exists:s!==null}}),ve();return this.state.events.operation(t,"get",n,"allow",i,{at:r,durationMs:Date.now()-r,resourceBefore:{data:s,exists:s!==null}}),this.state.tree.read(n)}getQuery(t,n,r){const s=Date.now(),i=this.readEvaluation(t,n);if(i.check!=="allow")throw this.state.events.operation(t,"get",n,we(i.check),i,{at:s,durationMs:Date.now()-s,request:{query:r}}),ve();const o=ze(this.state.tree.read(n),r,this.state.priorities.forChild(n));return this.state.events.operation(t,"get",n,"allow",i,{at:s,durationMs:Date.now()-s,request:{query:r},resourceBefore:{data:ei(o),exists:o.length>0}}),o}set(t,n,r){this.setInternal(t,n,r,"set",null,!1)}setWithPriority(t,n,r,s){mn(s),this.setInternal(t,n,r,"set",s,!0)}remove(t,n){this.setInternal(t,n,null,"remove",null,!1)}setPriority(t,n,r){this.priorityWrites.set(t,n,r)}validateSet(t,n,r){const s=Be(xe(r,Date.now(),this.state.tree.read(n)),n==="/"?"":n);if(this.writeEvaluation(t,n,s).check!=="allow")throw ve()}validateUpdate(t,n,r){const s=this.state.tree.snapshot(),i=Object.entries(r).map(([o,l])=>{const c=G([...B(n),...B(o)]);return{path:c,value:Be(xe(l,Date.now(),this.state.tree.read(c)),c)}});for(const o of i)if(this.state.rules.evaluate("write",o.path,{auth:t,mockData:s,newData:o.value,...i.length>1?{updates:i}:{}}).check!=="allow")throw ve()}update(t,n,r){const s=Date.now(),i=this.resolvePatch(n,r,s),o=Object.keys(r).some(y=>y.includes("/")),l=this.state.tree.snapshot(),c=Object.entries(i).map(([y,g])=>({path:y,value:g})),u=Object.fromEntries(Object.entries(i).map(([y,g])=>[B(y).at(-1),g])),d=this.state.events.nextGroupId("update");for(const y of c){const g=Date.now(),x=this.state.tree.read(y.path),b=this.state.rules.evaluate("write",y.path,{auth:t,mockData:l,newData:y.value,...o?{updates:c}:{}}),v={at:g,durationMs:Date.now()-g,origin:"batch",request:{data:y.value,resourceData:y.value},resourceBefore:{data:x,exists:x!==null},resourceAfter:{data:y.value,exists:y.value!==null},groupId:d,groupKind:"batch",detail:o?{multiPath:!0,rootPath:je(n)}:{multiPath:!1,rootPath:je(n),key:B(y.path).at(-1)}};if(b.check!=="allow")throw this.state.events.operation(t,"update",y.path,we(b.check),b,v),ve();this.state.events.operation(t,"update",y.path,"allow",b,v)}const p=this.state.tree.read(n),h=this.children.snapshotParents();o?this.state.tree.multiUpdate(i):this.state.tree.shallowUpdate(n,u),this.state.priorities.applyUpdate(c),this.changed(Object.keys(i),h);const m=this.state.tree.read(n);this.state.events.commit(t,"update",n,{data:r,priorState:p,nextState:m,groupId:d,groupKind:"batch",replay:{requestTime:s},detail:o?{multiPath:!0,paths:Object.keys(i)}:{multiPath:!1,keys:Object.keys(u)}}),this.state.events.mutation(t,"update",je(n),{after:o?i:u,detail:o?{multiPath:!0,paths:Object.keys(i)}:{multiPath:!1,keys:Object.keys(u)}}),this.state.notifyWrite()}setInternal(t,n,r,s,i,o){const l=Date.now(),c=Be(xe(r,l,this.state.tree.read(n)),n==="/"?"":n),u=this.state.tree.read(n),d=this.state.priorities.get(n),p=Date.now(),h=this.writeEvaluation(t,n,c),m={at:p,durationMs:Date.now()-p,request:{data:r,resourceData:r},resourceBefore:{data:u,exists:u!==null},resourceAfter:{data:c,exists:c!==null}};if(h.check!=="allow")throw this.state.events.operation(t,s,n,we(h.check),h,m),ve();this.state.events.operation(t,s,n,"allow",h,m);const y=this.children.snapshotParents(),g=this.state.priorities.stateAtOrBelow(n);this.state.tree.write(n,c),this.state.priorities.replace(n,c===null?null:i);const x=g!==this.state.priorities.stateAtOrBelow(n);this.changed([n],y,x?n:void 0);const b=this.state.tree.read(n),v=b===null?"remove":s;this.state.events.commit(t,v,n,{data:r,priorState:u,nextState:b,replay:{requestTime:l},...o?{detail:{priority:i,priorPriority:d}}:{}}),this.state.events.mutation(t,v,je(n),{before:u,after:b}),this.state.notifyWrite()}resolvePatch(t,n,r){return Object.fromEntries(Object.entries(n).map(([s,i])=>{const o=G([...B(t),...B(s)]);return[o,Be(xe(i,r,this.state.tree.read(o)),o)]}))}changed(t,n,r){this.state.mutations.mark(t),this.values.fanOut(t),this.children.fanOut(n,r)}cancelDeniedListeners(){const t=this.state.tree.snapshot(),n=[];for(const s of[...this.state.valueListeners])this.state.rules.evaluate("read",s.path,{auth:s.auth,mockData:t}).check!=="allow"&&(this.state.valueListeners.delete(s),n.push(s));const r=[];for(const s of[...this.state.childListeners])this.state.rules.evaluate("read",s.path,{auth:s.auth,mockData:t}).check!=="allow"&&(this.state.childListeners.delete(s),r.push(s));for(const s of[...n,...r]){try{s.onCanceled?.()}catch{}try{s.cancelCallback?.(ss(s.path))}catch{}}}readEvaluation(t,n){return this.state.rules.evaluate("read",n==="/"?"/":n,{auth:t,mockData:this.state.tree.snapshot()})}writeEvaluation(t,n,r){return this.state.rules.evaluate("write",n==="/"?"/":n,{auth:t,mockData:this.state.tree.snapshot(),newData:r})}}class Hh{state;values;children;writes;transactions;persistence;constructor(t){this.state=new _h(t),this.values=new Dh(this.state),this.children=new $h(this.state),this.writes=new Kh(this.state,this.values,this.children),this.transactions=new Wh(this.state,this.values,this.children),this.persistence=new Oh(this.state,this.values,this.children)}get connectionResetGeneration(){return this.state.resetGeneration}get transactionMutationHistory(){return this.state.mutations.entries}invalidateConnectionQueues(){this.state.resetGeneration+=1}getPriority(t){return this.state.priorities.get(t)}setData(t){this.writes.setData(t)}setRules(t){this.writes.setRules(t)}getActiveRules(){return this.writes.getActiveRules()}snapshotState(){return this.writes.snapshotState()}adminGet(t){return this.writes.adminGet(t)}adminGetQuery(t,n){return this.writes.adminGetQuery(t,n)}adminSet(t,n){this.writes.adminSet(t,n)}adminSetWithPriority(t,n,r){this.writes.adminSetWithPriority(t,n,r)}adminUpdate(t,n){this.writes.adminUpdate(t,n)}adminRemove(t){this.writes.adminRemove(t)}adminSetPriority(t,n){this.writes.adminSetPriority(t,n)}get(t,n){return this.writes.get(t,n)}getQuery(t,n,r){return this.writes.getQuery(t,n,r)}set(t,n,r){this.writes.set(t,n,r)}setWithPriority(t,n,r,s){this.writes.setWithPriority(t,n,r,s)}update(t,n,r){this.writes.update(t,n,r)}remove(t,n){this.writes.remove(t,n)}setPriority(t,n,r){this.writes.setPriority(t,n,r)}validateSet(t,n,r){this.writes.validateSet(t,n,r)}validateUpdate(t,n,r){this.writes.validateUpdate(t,n,r)}onValue(t,n,r,s,i,o){return this.values.onValue(t,n,r,s,i,o)}adminOnValue(t,n,r){return this.values.adminOnValue(t,n,r)}runTransaction(t,n,r,s){return this.transactions.run(t,n,r,s)}onChild(t,n,r,s,i,o,l){return this.children.onChild(t,n,r,s,i,o,l)}off(t,n,r){(n===void 0||n==="value")&&this.values.off(t,r),n!=="value"&&this.children.off(t,n,r)}exportTree(){return this.persistence.exportTree()}exportPersistenceState(){return this.persistence.exportState()}restoreTree(t){this.persistence.restore(t)}resetTree(){this.persistence.reset()}subscribeWrites(t){return this.persistence.subscribe(t)}mintKey(){return Uh()}listenerCount(){return this.values.count()}childListenerCount(){return this.children.count()}}const ti=new WeakMap;function yo(e){let t=ti.get(e);if(t)return t;t=new Hh(e),ti.set(e,t);const n=t;return e.onEvent(r=>{r.kind==="session_boundary"&&r.phase==="reset"&&n.invalidateConnectionQueues()}),e.registerPersistableService("rtdb",{snapshot:()=>n.exportPersistenceState(),restore:r=>{n.restoreTree(r)},subscribe:r=>n.subscribeWrites(r),reset:()=>{n.resetTree()}}),t}function Gh(e){return yo(e).getActiveRules()}function ni(e){return yo(e).snapshotState()}function Jh(e,t){return e==="/"?`/${t}`:`${e}/${t}`}function ri(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function Yh(e){const t=(e??"/").split("/").filter(Boolean);return t.length===0?"/":`/${t.join("/")}`}function Xh(e,t){let n=e;for(const r of t.split("/").filter(Boolean)){if(n===null||typeof n!="object"||Array.isArray(n))return null;n=n[r]}return n??null}function bo(e,t,n,r,s){if(e===null||typeof e!="object"||Array.isArray(e))return{path:t,childCount:0,truncated:!1,children:[],schema:{},valueType:ri(e)};const i=Object.entries(e).sort(([p],[h])=>p.localeCompare(h)),o={},l=[];for(const[p,h]of i)h!==null&&typeof h=="object"&&!Array.isArray(h)?l.push([p,h]):o[p]=ri(h);const c=n>=r&&l.length>0,u=i.length>s,d=n>=r?[]:l.slice(0,s).map(([p,h])=>bo(h,Jh(t,p),n+1,r,s));return{path:t,childCount:i.length,truncated:c||u,children:d,schema:o}}function Qh(e,t={}){const n=Yh(t.path),r=t.maxDepth??10,s=t.maxChildren??100;return bo(Xh(e,n),n,0,r,s)}function go(e){return e.children.reduce((t,n)=>t+1+go(n),0)}function vo(e){return[{name:"rtdb_simulate_access",description:"Simulate one read, write, or validate operation against the RTDB rules and data currently loaded in the local sandbox. No production database is contacted and no prior rules-loading tool call is required.",parameters:{type:"object",properties:{operation:{type:"string",enum:["read","write","validate"]},path:{type:"string"},auth:{anyOf:[{type:"null"},{type:"object",properties:{uid:{type:"string"},claims:{type:"object"}},required:["uid"]}]},newData:{}},required:["operation","path"]},async execute(t){const n=t,r=await e.resolveSandbox(),s=Gh(r);if(!s)return{ok:!1,summary:"No RTDB rules are loaded in the local sandbox.",data:{code:"NO_ACTIVE_RULES"}};const i=ni(r),o=i!==null&&typeof i=="object"&&!Array.isArray(i)?i:{},l={expectation:"ALLOW",operation:n.operation,path:n.path,auth:n.auth?{uid:n.auth.uid,token:n.auth.claims??{}}:null,data:o,...n.newData!==void 0?{newData:n.newData}:{}},c=bh(s).simulate([l]).cases[0];return{ok:!c.unsupported,summary:c.unsupported?`Simulation unsupported: ${c.reason}`:`Simulation: ${c.decision.toLowerCase()}`,data:{decision:c.decision,allowed:c.decision==="ALLOW",unsupported:c.unsupported,matchedPath:c.matchedPath,matchedRule:c.matchedRule,reason:c.reason}}}},{name:"rtdb_crawl_structure",description:"Describe the structure of the RTDB data currently loaded in the local sandbox without returning leaf values or contacting a production database.",parameters:{type:"object",properties:{path:{type:"string",description:"Root-relative path to inspect. Defaults to /."},maxDepth:{type:"number",minimum:0,description:"Maximum object depth to return. Defaults to 10."},maxChildren:{type:"number",minimum:1,description:"Maximum object children to return per node. Defaults to 100."}}},async execute(t){const n=t,r=await e.resolveSandbox(),s=Qh(ni(r),n);return{ok:!0,summary:`Crawled ${go(s)} object paths from ${s.path}`,data:s}}}]}function Zh(e){const t=Je(e),n=r=>r&&r!=="admin"?Gr(e.withAuth({uid:r.uid,token:r.claims})):Aa(e);return[...Ua({resolveSandbox:()=>t}),...Ka({resolveDb:n}),...Ha({resolveSandbox:()=>e}),...vo({resolveSandbox:()=>e})]}function ep(e){const t=new Map(Zh(e).map(n=>[n.name,n]));return async(n,r)=>{const s=t.get(n);if(!s)throw new rp(n);const i={signal:new AbortController().signal},o=await s.execute(r,i);return{ok:o.ok,summary:o.summary,data:o.data}}}const si=new WeakMap;async function tp(e,t,n){let r=si.get(e);return r||(r=ep(e),si.set(e,r)),r(t,n)}const np=(()=>{const e=async()=>{throw new Error("SANDBOX_TOOL_NAMES: stub resolver should never be invoked")};return[...Ua({resolveSandbox:e}),...Ka({resolveDb:e}),...Ha({resolveSandbox:e}),...vo({resolveSandbox:e})].map(t=>t.name)})();class rp extends Error{tool;constructor(t){super(`unknown sandbox tool: ${t}`),this.tool=t,this.name="UnknownToolError"}}const sp=500,ip=3e4,ap=2e3,op=.5,lp=3;function cp(e,t={}){const n=up(t.url),r=t.sandboxId??dp(),s=t.dispatcher??tp,i=t.toolNames??[...np],o=t.initialReconnectDelayMs??sp,l=t.maxReconnectDelayMs??ip,c=t.noReconnect??!1,u=t.onStateChange??(()=>{}),d=t.standbyPollMs??ap,p=t.fetchImpl??(R=>fetch(R)),h=t.workerRelay??null;let m=null,y=!1,g=0,x=null,b=null,v=0,w={kind:"connecting"};const k=new Map;function j(){for(const R of k.values())try{R()}catch{}k.clear()}function S(R){w=R;try{u(R)}catch{}}function C(R){if(m&&m.readyState===WebSocket.OPEN)try{m.send(JSON.stringify(R))}catch{}}function O(){if(y)return;S({kind:"connecting"});let R;try{R=new WebSocket(n)}catch(P){X(`failed to open WebSocket: ${P instanceof Error?P.message:String(P)}`);return}m=R,R.onopen=()=>{g=0;const P={type:"hello",protocol:1,tools:i,sandboxId:r,...h?{capabilities:[Tf]}:{}};C(P)},R.onmessage=P=>{let U;try{U=JSON.parse(typeof P.data=="string"?P.data:"")}catch{return}if(Mf(U)){if(U.type==="hello-ack"){S({kind:"connected",bridgeVersion:U.bridgeVersion});return}if(U.type==="tool-call"){I(U);return}if(U.type==="worker-op"){$(U);return}if(U.type==="worker-sub"){N(U);return}if(U.type==="worker-unsub"){const D=k.get(U.subId);if(D){k.delete(U.subId);try{D()}catch{}}return}if(U.type==="ping"){C({type:"pong",id:U.id});return}}},R.onclose=P=>{const U=P.reason||`closed (code ${P.code})`;if(m=null,j(),P.code===Uf){E();return}X(U)},R.onerror=()=>{}}async function I(R){let P;try{const U=await s(e,R.name,R.args??{});P={type:"tool-result",id:R.id,ok:!0,result:U}}catch(U){P={type:"tool-result",id:R.id,ok:!1,error:{code:U instanceof Error?U.name:"Error",message:U instanceof Error?U.message:String(U)}}}C(P)}async function $(R){if(h)try{const P=await h.op(R.op);Vs(`op '${R.op.method}'`,P),C({type:"worker-res",id:R.id,ok:!0,value:P})}catch(P){const U=P.denialContext;C({type:"worker-res",id:R.id,ok:!1,error:{code:P.code??"unknown",message:P instanceof Error?P.message:String(P),...U!==void 0?{denialContext:U}:{}}})}}function N(R){if(h&&!k.has(R.subId))try{const P=h.subscribe(R.sub,U=>{try{Vs(`subscription '${R.subId}'`,U)}catch(D){C({type:"worker-snap",subId:R.subId,value:{__error:{code:D.code??"invalid-argument",message:D instanceof Error?D.message:String(D)}}});return}C({type:"worker-snap",subId:R.subId,value:U})});k.set(R.subId,P)}catch(P){const U=P.denialContext;C({type:"worker-snap",subId:R.subId,value:{__error:{code:P.code??"unknown",message:P instanceof Error?P.message:String(P),...U!==void 0?{denialContext:U}:{}}}})}}function _(){try{const R=new URL(n);R.protocol=R.protocol==="wss:"?"https:":"http:";const P=R.origin;return[`${P}/__pyric/health`,`${P}/health`]}catch{return[]}}function E(){if(!y){if(c){S({kind:"disconnected",reason:"replaced by a newer sandbox peer"});return}g=0,v=0,S({kind:"standby"}),A()}}function A(){if(y)return;const R=d*(1+Math.random()*op);b=setTimeout(()=>{b=null,q()},R)}async function q(){if(y)return;let R=null;for(const P of _())try{const U=await p(P);if(!U.ok)continue;const D=await U.json();if(typeof D.sandboxConnected=="boolean"){R=!D.sandboxConnected;break}}catch{}if(!y){if(R===!0){O();return}if(R===!1){v=0,A();return}if(v+=1,v>=lp){X("standby health poll unreachable");return}A()}}function X(R){if(y)return;if(c){S({kind:"disconnected",reason:R});return}g+=1;const P=Math.min(o*2**(g-1),l);S({kind:"reconnecting",attempt:g,delayMs:P}),x=setTimeout(()=>{x=null,O()},P)}return O(),{disconnect(){if(y=!0,j(),x&&(clearTimeout(x),x=null),b&&(clearTimeout(b),b=null),m){try{m.close()}catch{}m=null}S({kind:"disconnected",reason:"client closed"})},state(){return w}}}function up(e){if(e)return e;if(typeof window<"u"){const t=window.__PYRIC_BRIDGE_URL__;if(t)return t;const n=window.location.hostname||"localhost";return`${window.location.protocol==="https:"?"wss:":"ws:"}//${n}:${Bs}${Fs}`}return`ws://localhost:${Bs}${Fs}`}function dp(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`sb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function fp(e,t){try{const n=new URL(e,t.href).pathname;return`${t.protocol==="https:"?"wss:":"ws:"}//${t.host}${n}`}catch{return e}}function hp(e,t){return{url:t,dispatcher:(n,r,s)=>Ed(e,r,s),workerRelay:{op:n=>Cd(e,n),subscribe:(n,r)=>Nd(e,n,r)}}}async function pp(e,t={}){const n=t.baseUrl??"",r=t.fetchImpl??(typeof fetch<"u"?fetch:null),s=u=>t.onStateChange?.({kind:"disconnected",reason:u});if(!r)return s("no fetch available"),null;let i;try{const u=await r(`${n}/__pyric/init.json`);if(!u.ok)return s("not served"),null;i=(await u.json()).bridgeUrl??null}catch{return s("not served"),null}if(!i)return s("bridge off"),null;const o=t.locationLike??(typeof window<"u"?window.location:null),l=o?fp(i,o):i,c=cp(null,{...hp(e,l),...t.onStateChange?{onStateChange:t.onStateChange}:{},...t.initialReconnectDelayMs!==void 0?{initialReconnectDelayMs:t.initialReconnectDelayMs}:{},...t.maxReconnectDelayMs!==void 0?{maxReconnectDelayMs:t.maxReconnectDelayMs}:{}});return console.info("[pyric studio] registered as the sandbox bridge peer at",l),c}const mp={};function yp(){return!1}function bp(){let e={kind:"connecting"};const t=new Set;return{get:()=>e,subscribe(n){return t.add(n),()=>t.delete(n)},set(n){e=n;for(const r of t)r()}}}function gp(e,t={}){if(e==="local"){const n=t.baseUrl??"",r=yp(),s=t.persistence==="memory"||r?Ic():Wu(n),i=t.disableLive?null:Of(t.workerUrl),o=i?bp():null;let l=!1,c=null;return i&&o&&pp(i.db,{baseUrl:n,onStateChange:u=>o.set(u)}).then(u=>{l?u?.disconnect():c=u}),{mode:e,projects:r?Hu():Vu(n),persistence:s,...i?{live:i}:{},...o?{bridge:o}:{},dispose(){l=!0,c?.disconnect(),i?.dispose()}}}throw new Error(`createStudioEnvironment(${e}): only 'local' is wired in v1 (T3). 'browser'/'hosted' land in A3.`)}const xo=f.createContext(null),vp={status:"pending",env:null,error:null};function xp(e){try{return{status:"ready",env:gp(e),error:null}}catch(t){return{status:"error",env:null,error:t instanceof Error?t:new Error(String(t))}}}function wp({mode:e="local",children:t}){const[n,r]=f.useState(null);f.useEffect(()=>{const i=xp(e);return r({mode:e,state:i}),()=>{i.status==="ready"&&i.env.dispose()}},[e]);const s=n?.mode===e?n.state:vp;return a.jsx(xo.Provider,{value:s,children:t})}function fe(){const e=f.useContext(xo);if(!e)throw new Error("useEnvironment must be used within an <EnvironmentProvider>");return e}const jp="pyric-studio:theme",cn="dark";function kp(){return cn}function Sp(){typeof document>"u"||document.documentElement.setAttribute("data-theme","dark")}const _p=f.createContext(null);function Ep({children:e}){const[t,n]=f.useState(kp);f.useEffect(()=>{Sp();try{localStorage.setItem(jp,cn)}catch{}},[t]);const r="dark",s=f.useCallback(l=>n(cn),[]),i=f.useCallback(()=>n(cn),[]),o=f.useMemo(()=>({choice:t,resolvedTheme:r,setChoice:s,cycleChoice:i}),[t,r,s,i]);return a.jsx(_p.Provider,{value:o,children:e})}function wo(){const e=typeof import.meta<"u"&&"/__pyric/ui/"||"/";return e.endsWith("/")?e:`${e}/`}function Cp(e){const t={};for(const n of e.replace(/^\?/,"").split("&")){if(!n)continue;const r=n.indexOf("="),s=r===-1?n:n.slice(0,r),i=r===-1?"":n.slice(r+1);s&&(t[decodeURIComponent(s)]=decodeURIComponent(i))}return t}function is(e,t="",n=wo()){let r=e;const s=n.replace(/\/$/,"");n!=="/"&&(e===s||e.startsWith(n))&&(r=e.slice(s.length));const i=r.split("/").filter(Boolean).map(c=>decodeURIComponent(c)),[o="",...l]=i;return{tab:o,rest:l,query:Cp(t)}}function Np(e,t=wo()){const n=[e.tab,...e.rest??[]].filter(s=>s!=null&&s!=="").map(s=>encodeURIComponent(s)).join("/"),r=Object.entries(e.query??{}).filter(([,s])=>s!=null&&s!=="").map(([s,i])=>`${encodeURIComponent(s)}=${encodeURIComponent(String(i))}`).join("&");return`${t}${n}${r?`?${r}`:""}`}const _r="pyric:studio:navigated",Ap={tab:"",rest:[],query:{}};function jo(){return typeof window<"u"?window.location.pathname+window.location.search:""}function be(){return typeof window>"u"?Ap:is(window.location.pathname,window.location.search)}function Rp(e){return e.tab==="home"?{...e,tab:""}:e}function An(e){return Np(Rp(e))}function ko(){typeof window<"u"&&window.dispatchEvent(new Event(_r))}function ce(e){if(typeof window>"u")return;const t=An(e);jo()!==t&&(window.history.pushState(null,"",t),ko())}function bn(e){typeof window>"u"||(window.history.replaceState(null,"",An(e)),ko())}function Ft(e){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",e),window.addEventListener(_r,e),()=>{window.removeEventListener("popstate",e),window.removeEventListener(_r,e)})}function Dp(e,t){const n=f.useCallback(i=>e.includes(i)?i:t,[e,t]),r=f.useSyncExternalStore(Ft,()=>n(be().tab),()=>t);f.useEffect(()=>{const i=typeof window<"u"?window.location.hash:"";if(i.length>1){const l=i.slice(1),c=l.indexOf("?"),u=is(`/${c===-1?l:l.slice(0,c)}`,c===-1?"":l.slice(c),"/");if(e.includes(u.tab)){bn(u);return}}const o=be();o.tab!==""&&!e.includes(o.tab)&&bn({tab:n(o.tab)})},[n]);const s=f.useCallback(i=>{const o=n(i);o!==r&&ce({tab:o})},[n,r]);return[r,s]}let Er=null;function Ip(e){Er=e}function $p(){return Er?(Er(),!0):!1}function Pp(e){return(e.metaKey||e.ctrlKey)&&!e.altKey&&!e.shiftKey&&(e.key==="k"||e.key==="K")}const Op=[{id:"home",label:"Home",description:"What is happening in the sandbox, and where to go next."},{id:"firestore",label:"Firestore",description:"Browse and edit collections, documents, and references."},{id:"auth",label:"Auth",description:"View and edit users, claims, providers, and account state."},{id:"rtdb",label:"RTDB",description:"Browse and edit RTDB data in the shared sandbox."},{id:"storage",label:"Storage",description:"Browse buckets, inspect objects, upload, and delete files."},{id:"traffic",label:"Traffic",description:"Watch sandbox requests, listener activity, and rule decisions."},{id:"assurance",label:"Assurance",description:"Compare intended access with qualified local sandbox behavior."},{id:"settings",label:"Settings",description:"Configure models, keys, theme, sandbox maintenance, and diagnostics."}];function Up({assuranceEnabled:e=!1}={}){return Op.filter(t=>t.id!=="assurance"||e)}const Ke=Up({assuranceEnabled:!1}),Tp=Ke.map(e=>e.id);function Mp(e){return Ke.find(t=>t.id===e)??Ke[0]}function Lp(e,t){const n=e.toLowerCase(),r=t.toLowerCase();let s=0;for(const i of r)if(i===n[s]&&s++,s===n.length)return!0;return s===n.length}const Bp=7;function Fp(e,t){const n=e.trim();if(!n)return[];const r=t.filter(p=>p.id!=="settings"),s=[],i=[],o=[],[l="",...c]=n.split(/\s+/),u=c.join(" ");for(const p of r){const h={id:`tab:${p.id}`,label:`Go to ${p.label}`,hint:p.description,target:{tab:p.id}},m=p.label.toLowerCase();if(m.startsWith(n.toLowerCase())?s.push(h):Lp(n,p.label)&&i.push(h),u&&(m===l.toLowerCase()||m.startsWith(l.toLowerCase()))){const y=u.split("/").filter(Boolean);p.id==="firestore"||p.id==="storage"?o.push({id:`deep:${p.id}:${u}`,label:`Open /${y.join("/")} in ${p.label}`,hint:p.id==="firestore"?"Firestore path":"Storage object path",target:{tab:p.id,rest:y}}):p.id==="auth"?o.push({id:`deep:auth:${u}`,label:`Open user ${u} in Auth`,hint:"Auth uid",target:{tab:"auth",rest:[u]}}):p.id==="traffic"&&o.push({id:`deep:traffic:${u}`,label:`Open ${u} in the rules inspector`,hint:"Traffic event id",target:{tab:"traffic",query:{inspect:u}}})}}const d=n.match(/^gs:\/\/[^/]+\/(.+)$/);if(d){const p=d[1].split("/").filter(Boolean);o.unshift({id:`deep:storage:${d[1]}`,label:`Open ${d[1]} in Storage`,hint:"Storage object path",target:{tab:"storage",rest:p}})}else if(n.includes("/")&&!n.includes(" ")){const p=n.split("/").filter(Boolean);p.length&&o.push({id:`deep:firestore:${n}`,label:`Open /${p.join("/")} in Firestore`,hint:"Firestore path",target:{tab:"firestore",rest:p}})}return[...s,...o,...i].slice(0,Bp)}function Cr(e){return`${e.kind}:${e.target.tab}:${(e.target.rest??[]).join("/")}`}const Nr={docsPerCollection:50,collectionsScanned:20,users:100,objects:200,storageListCalls:20,subcollections:30,subcollectionRpcCalls:40};async function Vp(e,t,{maxObjects:n,maxListCalls:r}){const s=[],i=[e];let o=0;for(;i.length&&s.length<n&&o<r;){o++;const l=await t(i.shift());for(const c of l.items){if(s.length>=n)break;s.push(c.fullPath)}i.push(...l.prefixes)}return s}async function qp(e,t,n,{maxSubcollections:r,maxRpcCalls:s,docsPerCollection:i}){const o=[],l=[],c=[...e];let u=0;for(;c.length&&o.length<r&&u<s;){const d=c.shift();u++;let p=[];try{p=await t(d)}catch{continue}for(const h of p){if(o.length>=r)break;const m=`${d}/${h}`;o.push(m);try{const y=await n(m,i);for(const g of y.slice(0,i))l.push(g),c.push(g)}catch{}}}return{subcollections:o,documents:l}}const Wp=5;function gn(e,t){const n=e.toLowerCase(),r=t.toLowerCase();if(!n||!r)return 0;if(r===n)return 1e3;if(r.startsWith(n))return 900-Math.min(r.length-n.length,100);const s=r.indexOf(n);if(s!==-1)return 700-Math.min(s,100);let i=0,o=-1,l=-1;for(let u=0;u<r.length&&i<n.length;u++)r[u]===n[i]&&(o===-1&&(o=u),l=u,i++);if(i!==n.length)return 0;const c=l-o+1;return Math.max(1,400-(c-n.length)*10-Math.min(o,50))}const zp={collection:"Firestore collections",document:"Firestore documents",subcollection:"Firestore subcollections",user:"Auth users",object:"Storage objects","rtdb-key":"RTDB keys"},Kp=["collection","document","subcollection","user","object","rtdb-key"];function Hp(e){switch(e.kind){case"collection":return"Firestore collection";case"document":return"Firestore document";case"subcollection":return e.alt?`Subcollection of /${e.alt}`:"Subcollection";case"user":return e.alt?`Auth user · uid ${e.alt}`:"Auth user";case"object":return"Storage object";case"rtdb-key":return"RTDB top-level key"}}function So(e){return e.endsWith("/")?{base:e.slice(0,-1),trailing:!0}:{base:e,trailing:!1}}function Gp(e,t){const{base:n,trailing:r}=So(e);if(!n)return 0;const s=n.split("/"),i=t.split("/");if(s.length>i.length)return 0;const o=s.length-1;for(let l=0;l<o;l++)if(s[l].toLowerCase()!==i[l].toLowerCase())return 0;return r?s[o].toLowerCase()===i[o].toLowerCase()?850:0:gn(s[o],i[o])}function Jp(e,t){const{base:n,trailing:r}=So(e);if(!n||n.includes("/"))return 0;const s=t.split("/").pop()??t;return r?s.toLowerCase()===n.toLowerCase()?850:0:gn(n,s)}function ii(e,t,n,r=Wp){const s=e.trim();if(!s)return[];const i=[],o=Fp(e,t);o.length&&i.push({kind:"navigate",title:"Go to",results:o});for(const l of Kp){const c=l==="document"||l==="subcollection",u=l==="collection"||l==="subcollection",d=new Map;for(const h of n)h.kind===l&&d.set(Cr(h),h);const p=[...d.values()].map(h=>({entry:h,score:Math.max(gn(s,h.label),h.alt?gn(s,h.alt):0,c?Gp(s,h.label):0,u?Jp(s,h.label):0)})).filter(h=>h.score>0).sort((h,m)=>m.score-h.score||h.entry.label.localeCompare(m.entry.label)).slice(0,r);p.length&&i.push({kind:l,title:zp[l],results:p.map(({entry:h})=>({id:Cr(h),label:h.label,hint:Hp(h),target:h.target}))})}return i}function ai(e){return e.flatMap(t=>t.results)}function Yp(e){return{kind:"collection",label:e,target:{tab:"firestore",rest:[e]}}}function oi(e){return{kind:"document",label:e,target:{tab:"firestore",rest:e.split("/").filter(Boolean)}}}function Xp(e){const t=e.split("/").filter(Boolean),n=t.slice(0,-1).join("/");return{kind:"subcollection",label:e,alt:n||void 0,target:{tab:"firestore",rest:t}}}function Qp(e){return e.email?{kind:"user",label:e.email,alt:e.uid,target:{tab:"auth",rest:[e.uid]}}:{kind:"user",label:e.uid,target:{tab:"auth",rest:[e.uid]}}}function Zp(e){return{kind:"object",label:e,target:{tab:"storage",rest:e.split("/").filter(Boolean)}}}function em(e){return{kind:"rtdb-key",label:e,target:{tab:"rtdb",rest:[e]}}}async function tm(e,t={},n){const r={...Nr,...t},s=[],i=d=>{d.length&&(s.push(...d),n?.(d))},o=(async()=>{let d=[];try{d=await e.listRootCollections?.()??[]}catch{d=[]}d.length&&i(d.map(Yp));const p=[];if(e.listDocumentPaths)for(const h of d.slice(0,r.collectionsScanned))try{const y=(await e.listDocumentPaths(h,r.docsPerCollection)).slice(0,r.docsPerCollection);p.push(...y),i(y.map(oi))}catch{}if(e.listSubcollections&&e.listDocumentPaths)try{const{subcollections:h,documents:m}=await qp(p,e.listSubcollections,e.listDocumentPaths,{maxSubcollections:r.subcollections,maxRpcCalls:r.subcollectionRpcCalls,docsPerCollection:r.docsPerCollection});i(h.map(Xp)),i(m.map(oi))}catch{}})(),l=(async()=>{if(e.listUsers)try{const d=await e.listUsers(r.users);i(d.slice(0,r.users).map(Qp))}catch{}})(),c=(async()=>{if(e.listStorageObjectPaths)try{const d=await e.listStorageObjectPaths(r.objects);i(d.slice(0,r.objects).map(Zp))}catch{}})(),u=(async()=>{if(e.listRtdbTopLevelKeys)try{i((await e.listRtdbTopLevelKeys()).map(em))}catch{}})();return await Promise.allSettled([o,l,c,u]),s}const _o=Symbol("pyric/auth/target"),nm=Symbol("pyric.user.internal");function V(e,t){return new pt(e,`Firebase: ${t} (${e}).`)}const Eo={PASSWORD:"password"},Yn={EMAIL_LINK:"emailLink",EMAIL_PASSWORD:"password"};class Rn{providerId;signInMethod;constructor(t,n){this.providerId=t,this.signInMethod=n}toJSON(){return{providerId:this.providerId,signInMethod:this.signInMethod}}static fromJSON(t){const n=typeof t=="string"?rm(t):t;if(!n)return null;const r=n.providerId,s=n.signInMethod;if(typeof r!="string"||typeof s!="string")return null;if(r===Eo.PASSWORD){const i=typeof n.email=="string"?n.email:"",o=typeof n.password=="string"?n.password:"";return new sm(i,o,s)}return new Rn(r,s)}}function rm(e){try{const t=JSON.parse(e);return typeof t=="object"&&t!==null?t:null}catch{return null}}class sm extends Rn{email;secret;constructor(t,n,r=Yn.EMAIL_PASSWORD){super(Eo.PASSWORD,r),this.email=t,Object.defineProperty(this,"secret",{value:n,enumerable:!1,writable:!1})}get password(){return this.signInMethod===Yn.EMAIL_PASSWORD?this.secret:null}get emailLink(){return this.signInMethod===Yn.EMAIL_LINK?this.secret:null}toJSON(){return{providerId:this.providerId,signInMethod:this.signInMethod,email:this.email,password:this.secret}}}class Dn extends Rn{idToken;accessToken;secret;constructor(t,n,r={}){super(t,n),this.idToken=r.idToken,this.accessToken=r.accessToken,this.secret=r.secret}toJSON(){return{providerId:this.providerId,signInMethod:this.signInMethod,idToken:this.idToken,accessToken:this.accessToken,secret:this.secret}}}function as(e,t){return t?new Dn(e,e):null}class nt{static PROVIDER_ID="google.com";static GOOGLE_SIGN_IN_METHOD="google.com";providerId=nt.PROVIDER_ID;addScope(t){return this}setCustomParameters(t){return this}static credentialFromResult(t){return as(nt.PROVIDER_ID,t)}static credentialFromError(t){return null}static credential(t,n){return new Dn(nt.PROVIDER_ID,nt.GOOGLE_SIGN_IN_METHOD,{idToken:t??void 0,accessToken:n??void 0})}}class rt{static PROVIDER_ID="facebook.com";static FACEBOOK_SIGN_IN_METHOD="facebook.com";providerId=rt.PROVIDER_ID;addScope(t){return this}setCustomParameters(t){return this}static credentialFromResult(t){return as(rt.PROVIDER_ID,t)}static credentialFromError(t){return null}static credential(t){return new Dn(rt.PROVIDER_ID,rt.FACEBOOK_SIGN_IN_METHOD,{accessToken:t})}}class st{static PROVIDER_ID="github.com";static GITHUB_SIGN_IN_METHOD="github.com";providerId=st.PROVIDER_ID;addScope(t){return this}setCustomParameters(t){return this}static credentialFromResult(t){return as(st.PROVIDER_ID,t)}static credentialFromError(t){return null}static credential(t){return new Dn(st.PROVIDER_ID,st.GITHUB_SIGN_IN_METHOD,{accessToken:t})}}const Co=[nt.PROVIDER_ID,"apple.com",rt.PROVIDER_ID,st.PROVIDER_ID,"twitter.com","microsoft.com","yahoo.com"];function os(e,t=!1){const n=e[_o];if(!n)throw new TypeError("pyric/auth: unrecognized Auth handle — was it produced by getAuth(...)?");return t||n.assertAlive?.(),n}class im{mockResults=new Map;resolver=null;redirectResult=null;setMockResult(t,n){this.mockResults.set(t,n)}consumeMockResult(t){const n=this.mockResults.get(t);return n&&this.mockResults.delete(t),n}setResolver(t){this.resolver=t}getResolver(){return this.resolver}setRedirectResult(t){this.redirectResult=t}takeRedirectResult(){const t=this.redirectResult;return this.redirectResult=null,t}actionCodes=new Map;nextCodeSerial=1;outbox=[];mailResolver=null;mintActionCode(t){const n=`sandbox-oob-${this.nextCodeSerial++}`;return this.actionCodes.set(n,t),n}stageActionCode(t,n){this.actionCodes.set(t,n)}peekActionCode(t){return this.actionCodes.get(t)}consumeActionCode(t){const n=this.actionCodes.get(t);return n&&this.actionCodes.delete(t),n}setMailResolver(t){this.mailResolver=t}deliverMail(t){if(this.outbox.push(t),this.mailResolver)try{this.mailResolver.deliver(t)}catch{}}takeMail(t){const n=t===void 0?this.outbox.length>0?0:-1:this.outbox.findIndex(r=>r.email.toLowerCase()===t.toLowerCase());return n<0?null:this.outbox.splice(n,1)[0]??null}listMail(){return[...this.outbox]}}function am(e,t,n){let r=5381;const s=JSON.stringify(t)+":"+String(n);for(let o=0;o<s.length;o++)r=(r<<5)+r+s.charCodeAt(o)|0;const i=(r>>>0).toString(16).padStart(8,"0");return`sandbox-id-token-${e}-${i}`}function Me(e){if(typeof e!="string"||e.length===0)throw V("auth/invalid-email","Error");const t=e.indexOf("@");if(t<=0||t===e.length-1)throw V("auth/invalid-email","Error")}function St(e){if(typeof e!="string"||e.length<6)throw V("auth/weak-password","Password should be at least 6 characters")}function No(){return{usersByEmail:new Map,usersByUid:new Map,userDbSubscribers:new Set,providerConfig:new Map([["password",!0],["anonymous",!0]]),providerConfigSubscribers:new Set,counters:{nextAdminUserId:1,nextAnonymousId:1}}}const om="__pyric_no_password__";class Ao{usersByEmail;usersByUid;authStateSubs=[];idTokenSubs=[];userDbSubs;beforeStateSubs=[];sharedCounters;flow=new im;sandbox;session;cachedUser=null;lastNotifiedUid=null;applyingTransition=!1;tokenCache=new Map;nextTokenSerial=1;persistenceMode="LOCAL";signInProviderByUid=new Map;providerConfig;providerConfigSubs;providerEnforcementDelegated=!1;constructor(t,n=t,r=No(),s){this.sandbox=t,this.session=n,this.usersByEmail=r.usersByEmail,this.usersByUid=r.usersByUid,this.userDbSubs=r.userDbSubscribers,this.providerConfig=r.providerConfig,this.providerConfigSubs=r.providerConfigSubscribers,this.sharedCounters=r.counters,this.cachedUser=this.buildUserFromState(n.currentUser),this.lastNotifiedUid=this.cachedUser?.uid??null;const i=n.onCurrentUserChanged(o=>{if(this.applyingTransition)return;const l=o===null?null:o.uid,c=this.cachedUser?.uid??null;l!==c&&(this.cachedUser=this.buildUserFromState(o)),this.notifyAuthListeners()});s?.(()=>{i(),this.authStateSubs.length=0,this.idTokenSubs.length=0,this.beforeStateSubs.length=0})}getCurrentUser(){return this.cachedUser}subscribe(t,n){const r=t==="auth-state"?this.authStateSubs:this.idTokenSubs,s={observer:n,hasFired:!1,lastValue:null};return r.push(s),queueMicrotask(()=>{r.includes(s)&&(s.hasFired&&s.lastValue===this.cachedUser||this.deliverOne(s,this.cachedUser))}),()=>{const i=r.indexOf(s);i!==-1&&r.splice(i,1)}}fanOut(t="both"){const n=this.cachedUser;if(t==="both"||t==="auth-state")for(const r of[...this.authStateSubs])this.deliverOne(r,n);if(t==="both"||t==="id-token")for(const r of[...this.idTokenSubs])this.deliverOne(r,n)}notifyAuthListeners(){this.fanOut("id-token");const t=this.cachedUser?.uid??null;this.lastNotifiedUid!==t&&(this.lastNotifiedUid=t,this.fanOut("auth-state"))}deliverOne(t,n){t.hasFired=!0,t.lastValue=n;const r=t.observer;try{typeof r=="function"?r(n):r.next&&r.next(n)}catch{}}makeStored(t){return{email:null,password:null,displayName:null,phoneNumber:null,photoUrl:null,customClaims:{},isAnonymous:!1,providerUserInfo:[],disabled:!1,emailVerified:!1,createdAt:new Date().toISOString(),lastLoginAt:null,...t}}notifyUsersChanged(){for(const t of[...this.userDbSubs])try{t()}catch{}}emitAuthEvent(t,n={}){try{De(this.sandbox,Sn({service:"auth",op:t,path:n.path,auth:n.auth??this.session.currentUser,before:n.before,after:n.after,detail:n.detail}),{service:"auth"})}catch{}}subscribeUsers(t){return this.userDbSubs.add(t),()=>{this.userDbSubs.delete(t)}}isProviderEnabled(t){return this.providerConfig.get(t)??!0}listProviderConfig(){return[...this.providerConfig.entries()].map(([t,n])=>({providerId:t,enabled:n}))}setProviderConfig(t,n){const r=this.providerConfig.get(t)??!0;r!==n&&(this.providerConfig.set(t,n),this.notifyProviderConfigChanged(),this.emitAuthEvent("provider_config_update",{path:t,auth:null,before:{providerId:t,enabled:r},after:{providerId:t,enabled:n}}))}notifyProviderConfigChanged(){for(const t of[...this.providerConfigSubs])try{t()}catch{}}subscribeProviderConfig(t){return this.providerConfigSubs.add(t),()=>{this.providerConfigSubs.delete(t)}}setProviderEnforcementDelegated(t){this.providerEnforcementDelegated=t}assertProviderEnabled(t){if(!this.providerEnforcementDelegated&&!this.isProviderEnabled(t))throw V("auth/operation-not-allowed",`${t} sign-in is disabled for this sandbox project. Enable it with sandbox.setAuthProviderConfig(auth, '${t}', true).`)}exportProviderConfig(){return Object.fromEntries(this.providerConfig)}restoreProviderConfig(t){if(this.providerConfig.clear(),t&&typeof t=="object")for(const[n,r]of Object.entries(t))typeof r=="boolean"&&this.providerConfig.set(n,r);else this.providerConfig.set("password",!0),this.providerConfig.set("anonymous",!0);this.notifyProviderConfigChanged()}getPersistenceMode(){return this.persistenceMode}setPersistenceMode(t){this.persistenceMode!==t&&(this.persistenceMode=t,this.notifySessionChanged())}sessionChangeSubs=new Set;notifySessionChanged(){for(const t of[...this.sessionChangeSubs])try{t()}catch{}}subscribeSession(t){return this.sessionChangeSubs.add(t),()=>{this.sessionChangeSubs.delete(t)}}seedUsers(t){for(const n of t){const r=this.usersByUid.get(n.uid);r?.email&&r.email.toLowerCase()!==n.email.toLowerCase()&&this.usersByEmail.delete(r.email.toLowerCase());const s=this.makeStored({uid:n.uid,email:n.email,password:n.password,displayName:n.displayName??null,customClaims:n.customClaims??{},providerUserInfo:[{providerId:n.providerId??"password"}]});this.usersByEmail.set(n.email.toLowerCase(),s),this.usersByUid.set(n.uid,s)}t.length>0&&this.notifyUsersChanged()}exportUsers(){const t=[];for(const n of this.usersByUid.values()){if(n.email===null)continue;const r={uid:n.uid,email:n.email,password:n.password??om,providerId:n.providerUserInfo[0]?.providerId??"password"};n.displayName!==null&&(r.displayName=n.displayName),Object.keys(n.customClaims).length>0&&(r.customClaims=n.customClaims),t.push(r)}return t}restoreSession(t){const n=this.usersByUid.get(t);if(!n)throw V("auth/user-not-found",`restoreSession: no identity with uid ${t}.`);if(n.disabled)throw V("auth/user-disabled",`restoreSession: user ${t} is disabled.`);const r=n.isAnonymous?"anonymous":n.providerUserInfo[0]?.providerId??"password",s=this.buildUserFromStored(n);return this.setCurrentUser(s,r),s}findByEmail(t){return this.usersByEmail.get(t.toLowerCase())}findByUid(t){return this.usersByUid.get(t)}mintActionCode(t){return this.flow.mintActionCode(t)}stageActionCode(t,n){this.flow.stageActionCode(t,n)}peekActionCode(t){return this.flow.peekActionCode(t)}consumeActionCode(t){return this.flow.consumeActionCode(t)}deliverMail(t){this.flow.deliverMail(t)}takeMail(t){return this.flow.takeMail(t)}listMail(){return this.flow.listMail()}setMailResolver(t){this.flow.setMailResolver(t)}setEmailVerified(t,n){const r=this.requireByEmail(t);return r.emailVerified!==n&&(r.emailVerified=n,this.notifyUsersChanged(),this.emitAuthEvent("user_update",{path:r.uid,after:this.toRecord(r),detail:{emailVerified:n}})),r}setPasswordByEmail(t,n){St(n);const r=this.requireByEmail(t);return r.password=n,this.notifyUsersChanged(),this.emitAuthEvent("user_update",{path:r.uid,after:this.toRecord(r),detail:{passwordReset:!0}}),r}changeEmail(t,n){Me(n);const r=this.requireByEmail(t),s=n.toLowerCase(),i=this.usersByEmail.get(s);if(i&&i.uid!==r.uid)throw V("auth/email-already-in-use",`An account already exists for ${n}.`);return r.email&&this.usersByEmail.delete(r.email.toLowerCase()),r.email=n,r.emailVerified=!0,this.usersByEmail.set(s,r),this.notifyUsersChanged(),this.emitAuthEvent("user_update",{path:r.uid,after:this.toRecord(r),detail:{emailChanged:n}}),r}upsertEmailLinkUser(t){Me(t);const n=t.toLowerCase(),r=this.usersByEmail.get(n);if(r)return r.providerUserInfo.some(o=>o.providerId==="password")||r.providerUserInfo.push({providerId:"password"}),r.emailVerified=!0,this.notifyUsersChanged(),{stored:r,isNewUser:!1};const s=`email-${n}-${this.usersByEmail.size+1}`,i=this.makeStored({uid:s,email:t,providerUserInfo:[{providerId:"password"}]});return i.emailVerified=!0,this.usersByEmail.set(n,i),this.usersByUid.set(s,i),this.notifyUsersChanged(),this.emitAuthEvent("user_create",{path:s,after:this.toRecord(i),detail:{emailLink:!0}}),{stored:i,isNewUser:!0}}linkProvider(t,n,r){const s=this.usersByUid.get(t);if(!s)throw V("auth/user-not-found",`linkWithCredential: no identity with uid ${t}.`);if(s.providerUserInfo.some(o=>o.providerId===n))throw V("auth/provider-already-linked",`User can only be linked to one identity for the given provider (${n}).`);const i=r?.email;if(i){Me(i);const o=i.toLowerCase(),l=this.usersByEmail.get(o);if(l&&l.uid!==t)throw V("auth/email-already-in-use",`An account already exists for ${i}.`);r.password!==void 0&&r.password!==null&&(St(r.password),s.password=r.password),s.email&&s.email.toLowerCase()!==o&&this.usersByEmail.delete(s.email.toLowerCase()),s.email=i,this.usersByEmail.set(o,s),r.emailVerified!==void 0&&(s.emailVerified=r.emailVerified)}return s.providerUserInfo.push({providerId:n}),s.isAnonymous&&(s.isAnonymous=!1),this.notifyUsersChanged(),this.emitAuthEvent("user_update",{path:t,after:this.toRecord(s),detail:{linked:n}}),s}unlinkProvider(t,n){const r=this.usersByUid.get(t);if(!r)throw V("auth/user-not-found",`unlink: no identity with uid ${t}.`);const s=r.providerUserInfo.findIndex(i=>i.providerId===n);if(s<0)throw V("auth/no-such-provider",`User was not linked to an account with the given provider (${n}).`);return r.providerUserInfo.splice(s,1),n==="password"&&(r.password=null),this.notifyUsersChanged(),this.emitAuthEvent("user_update",{path:t,after:this.toRecord(r),detail:{unlinked:n}}),r}requireByEmail(t){const n=this.usersByEmail.get(t.toLowerCase());if(!n)throw V("auth/user-not-found",`No user found for ${t}.`);return n}createEmailPasswordUser(t,n){Me(t),St(n);const r=t.toLowerCase();if(this.usersByEmail.has(r))throw V("auth/email-already-in-use",`An account already exists for ${t}.`);const s=`email-${r}-${this.usersByEmail.size+1}`,i=this.makeStored({uid:s,email:t,password:n,providerUserInfo:[{providerId:"password"}]});return this.usersByEmail.set(r,i),this.usersByUid.set(s,i),this.notifyUsersChanged(),this.emitAuthEvent("user_create",{path:s,after:this.toRecord(i)}),i}beforeAuthStateChanged(t,n){const r={callback:t,onAbort:n,active:!0};return this.beforeStateSubs.push(r),()=>{r.active=!1}}async runBeforeStateChange(t){if(t===this.cachedUser)return;const n=[];try{for(const r of this.beforeStateSubs)r.active&&(await r.callback(t),r.onAbort&&n.push(r.onAbort))}catch(r){n.reverse();for(const i of n)try{i()}catch{}const s=r instanceof Error?r.message:String(r);throw V("auth/login-blocked",s)}}transitionCurrentUser(t,n){return!this.beforeStateSubs.some(s=>s.active)||t===this.cachedUser?(this.setCurrentUser(t,n),Promise.resolve()):this.runBeforeStateChange(t).then(()=>{this.setCurrentUser(t,n)})}setCurrentUser(t,n){if(t===null){const o=this.cachedUser;this.cachedUser=null,this.applyingTransition=!0;try{this.session.currentUser=null}finally{this.applyingTransition=!1}o&&(this.tokenCache.delete(o.uid),this.notifyAuthListeners(),this.notifySessionChanged(),this.emitAuthEvent("sign_out",{path:o.uid,auth:{uid:o.uid}}));return}n!==void 0&&this.signInProviderByUid.set(t.uid,n);const r=this.usersByUid.get(t.uid),s=r?.customClaims??{};n!==void 0&&r&&(r.lastLoginAt=new Date().toISOString(),this.notifyUsersChanged()),this.cachedUser=t,this.tokenCache.set(t.uid,this.mintToken(t.uid,s));const i={uid:t.uid,token:s};this.applyingTransition=!0;try{this.session.currentUser=i}finally{this.applyingTransition=!1}this.notifyAuthListeners(),this.notifySessionChanged(),n!==void 0&&this.emitAuthEvent("sign_in",{path:t.uid,auth:i,after:{uid:t.uid,isAnonymous:t.isAnonymous,email:t.email},detail:{providerId:n??"anonymous"}})}setMockResult(t,n){this.flow.setMockResult(t,n)}consumeMockResult(t){return this.flow.consumeMockResult(t)}setResolver(t){this.flow.setResolver(t)}getResolver(){return this.flow.getResolver()}setRedirectResult(t){this.flow.setRedirectResult(t)}takeRedirectResult(){return this.flow.takeRedirectResult()}recordProviderSignIn(t,n){let r=!1,s=this.usersByUid.get(t.uid);s||(s=this.makeStored({uid:t.uid,email:t.email,displayName:t.displayName,isAnonymous:t.isAnonymous}),this.usersByUid.set(t.uid,s),t.email&&this.usersByEmail.set(t.email.toLowerCase(),s),r=!0),s.providerUserInfo.some(i=>i.providerId===n)||(s.providerUserInfo.push({providerId:n}),r=!0),r&&this.notifyUsersChanged()}createSignInCredential(t){const{providerId:n}=t;let r;if("uid"in t){const s=this.usersByUid.get(t.uid);if(!s)throw V("auth/user-not-found",`createSignInCredential: no identity with uid ${t.uid}. Use the {spec} shape to create one.`);r=s}else{const{spec:s}=t,i=this.usersByEmail.get(s.email.toLowerCase());i?r=i:(r=this.makeStored({uid:s.uid??lm(),email:s.email,displayName:s.displayName??null,customClaims:s.customClaims??{}}),this.usersByUid.set(r.uid,r),this.usersByEmail.set(s.email.toLowerCase(),r),this.notifyUsersChanged())}return r.providerUserInfo.some(s=>s.providerId===n)||(r.providerUserInfo.push({providerId:n}),this.notifyUsersChanged()),{user:this.buildUserFromStored(r),providerId:n,operationType:"signIn"}}listIdentities(){return[...this.usersByUid.values()].map(t=>({uid:t.uid,email:t.email,displayName:t.displayName,providerId:t.isAnonymous?"anonymous":t.providerUserInfo[0]?.providerId??"password",providerUserInfo:[...t.providerUserInfo],isAnonymous:t.isAnonymous,customClaims:t.customClaims}))}toRecord(t){return{uid:t.uid,email:t.email,displayName:t.displayName,phoneNumber:t.phoneNumber,photoUrl:t.photoUrl,customClaims:{...t.customClaims},providerUserInfo:t.providerUserInfo.map(n=>({...n})),isAnonymous:t.isAnonymous,disabled:t.disabled,emailVerified:t.emailVerified,createdAt:t.createdAt,lastLoginAt:t.lastLoginAt}}listUsers(){return[...this.usersByUid.values()].map(t=>this.toRecord(t))}sanitizeLinkedProviders(t,n,r){const s=new Set,i=[];for(const o of t){const l=o?.providerId?.trim();if(!l)throw V("auth/argument-error",`${r}: providerUserInfo entries need a non-empty providerId.`);l==="password"||l==="anonymous"||s.has(l)||(s.add(l),i.push({providerId:l}))}return n&&i.unshift({providerId:"password"}),i}createUser(t){const n=t.uid??`user-${this.sharedCounters.nextAdminUserId++}`;if(this.usersByUid.has(n))throw V("auth/uid-already-exists",`createUser: a user with uid ${n} already exists.`);if(t.email!==void 0&&(Me(t.email),this.usersByEmail.has(t.email.toLowerCase())))throw V("auth/email-already-in-use",`An account already exists for ${t.email}.`);if(t.password!==void 0&&(St(t.password),t.email===void 0))throw V("auth/invalid-email","createUser: a password requires an email.");const r=this.makeStored({uid:n,email:t.email??null,password:t.password??null,displayName:t.displayName??null,phoneNumber:t.phoneNumber??null,photoUrl:t.photoUrl??null,customClaims:t.customClaims??{},disabled:t.disabled??!1,emailVerified:t.emailVerified??!1,providerUserInfo:this.sanitizeLinkedProviders(t.providerUserInfo??[],t.password!==void 0,"createUser")});this.usersByUid.set(n,r),r.email&&this.usersByEmail.set(r.email.toLowerCase(),r),this.notifyUsersChanged();const s=this.toRecord(r);return this.emitAuthEvent("user_create",{path:n,auth:null,after:s}),s}updateUser(t,n){const r=this.usersByUid.get(t);if(!r)throw V("auth/user-not-found",`No user found for uid ${t}.`);const s=this.toRecord(r);if(n.email!==void 0){Me(n.email);const o=n.email.toLowerCase(),l=this.usersByEmail.get(o);if(l&&l!==r)throw V("auth/email-already-in-use",`An account already exists for ${n.email}.`);r.email&&this.usersByEmail.delete(r.email.toLowerCase()),r.email=n.email,this.usersByEmail.set(o,r)}n.password!==void 0&&(St(n.password),r.password=n.password,r.providerUserInfo.some(o=>o.providerId==="password")||r.providerUserInfo.push({providerId:"password"})),n.providerUserInfo!==void 0&&(r.providerUserInfo=this.sanitizeLinkedProviders(n.providerUserInfo,r.password!==null,"updateUser")),n.displayName!==void 0&&(r.displayName=n.displayName),n.customClaims!==void 0&&(r.customClaims={...n.customClaims}),n.disabled!==void 0&&(r.disabled=n.disabled),n.emailVerified!==void 0&&(r.emailVerified=n.emailVerified),this.notifyUsersChanged();const i=this.toRecord(r);return this.emitAuthEvent("user_update",{path:t,auth:null,before:s,after:i}),i}deleteUser(t){const n=this.usersByUid.get(t);if(!n)throw V("auth/user-not-found",`No user found for uid ${t}.`);const r=this.toRecord(n);this.usersByUid.delete(t),n.email&&this.usersByEmail.get(n.email.toLowerCase())===n&&this.usersByEmail.delete(n.email.toLowerCase()),this.tokenCache.delete(t),this.signInProviderByUid.delete(t),this.notifyUsersChanged(),this.emitAuthEvent("user_delete",{path:t,auth:null,before:r})}clearUsers(){if(this.usersByUid.size===0&&this.usersByEmail.size===0)return;const t=this.usersByUid.size;this.usersByUid.clear(),this.usersByEmail.clear(),this.notifyUsersChanged(),this.emitAuthEvent("users_clear",{path:"*",auth:null,detail:{count:t}})}assertSignInAllowed(t){if(this.usersByUid.get(t)?.disabled)throw V("auth/user-disabled","The user account has been disabled by an administrator.")}buildUserFromStored(t){return this.makeUser({uid:t.uid,email:t.email,displayName:t.displayName,isAnonymous:t.isAnonymous,claims:t.customClaims,photoURL:t.photoUrl,emailVerified:t.emailVerified,phoneNumber:t.phoneNumber,providers:t.providerUserInfo})}mintAnonymousUser(){const t=`anonymous-${this.sharedCounters.nextAnonymousId++}`,n=this.makeStored({uid:t,isAnonymous:!0});return this.usersByUid.set(t,n),this.notifyUsersChanged(),this.emitAuthEvent("user_create",{path:t,after:this.toRecord(n),detail:{isAnonymous:!0}}),this.makeUser({uid:t,email:null,displayName:null,isAnonymous:!0,claims:{}})}mintDetachedSession(t){switch(t.kind){case"anonymous":return this.assertProviderEnabled("anonymous"),this.establishDetachedSession(this.mintAnonymousUser(),"anonymous");case"password":return this.assertProviderEnabled("password"),this.establishDetachedSession(this.buildUserFromStored(this.validatePassword(t.email,t.password)),"password");case"createPassword":return this.assertProviderEnabled("password"),this.establishDetachedSession(this.buildUserFromStored(this.createEmailPasswordUser(t.email,t.password)),"password");case"uid":{const n=this.usersByUid.get(t.uid);if(!n)throw V("auth/user-not-found",`mintSession: no identity with uid ${t.uid}.`);if(n.disabled)throw V("auth/user-disabled",`mintSession: user ${t.uid} is disabled.`);const r=n.isAnonymous?"anonymous":n.providerUserInfo[0]?.providerId??"password";return this.establishDetachedSession(this.buildUserFromStored(n),r)}}}establishDetachedSession(t,n){this.signInProviderByUid.set(t.uid,n);const r=this.usersByUid.get(t.uid),s=r?.customClaims??{};r&&(r.lastLoginAt=new Date().toISOString(),this.notifyUsersChanged()),this.tokenCache.set(t.uid,this.mintToken(t.uid,s));const i={uid:t.uid,token:s};return this.emitAuthEvent("sign_in",{path:t.uid,auth:i,after:{uid:t.uid,isAnonymous:t.isAnonymous,email:t.email},detail:{providerId:n,session:"connection"}}),{user:t,state:i}}buildUserFromState(t){if(t===null)return null;const n=this.usersByUid.get(t.uid);return n?this.buildUserFromStored({...n,customClaims:t.token??n.customClaims}):this.makeUser({uid:t.uid,email:null,displayName:null,isAnonymous:t.uid.startsWith("anonymous-"),claims:t.token??{}})}mintToken(t,n){const r=new Date,s=new Date(r.getTime()+100*365*24*60*60*1e3),i=this.nextTokenSerial++,o=am(t,n,i),l=this.signInProviderByUid.get(t)??null,c={sub:t,aud:"pyric-sandbox",iss:"https://sandbox.pyric.dev",auth_time:Math.floor(r.getTime()/1e3),iat:Math.floor(r.getTime()/1e3),exp:Math.floor(s.getTime()/1e3),...n,firebase:{sign_in_provider:l}},u={token:o,claims:c,expirationTime:s.toISOString(),issuedAtTime:r.toISOString(),authTime:r.toISOString(),signInProvider:l};return{token:o,result:u}}getIdTokenFor(t,n,r){if(r){const o=this.mintToken(t,n);return this.tokenCache.set(t,o),this.fanOut("id-token"),o.token}const s=this.tokenCache.get(t);if(s)return s.token;const i=this.mintToken(t,n);return this.tokenCache.set(t,i),i.token}getIdTokenResultFor(t,n,r){if(r){const o=this.mintToken(t,n);return this.tokenCache.set(t,o),this.fanOut("id-token"),o.result}const s=this.tokenCache.get(t);if(s)return s.result;const i=this.mintToken(t,n);return this.tokenCache.set(t,i),i.result}makeUser(t){const n=t.photoURL??null,r=t.phoneNumber??null,s=t.emailVerified??!1,i="firebase",o=t.providers??[{providerId:"password"}],l=t.isAnonymous?[]:o.map(u=>({uid:t.uid,displayName:t.displayName,email:t.email,phoneNumber:r,photoURL:n,providerId:u.providerId})),c={uid:t.uid,email:t.email,emailVerified:s,displayName:t.displayName,photoURL:n,phoneNumber:r,isAnonymous:t.isAnonymous,providerId:i,providerData:l,getIdToken:async u=>this.getIdTokenFor(t.uid,this.liveClaims(t.uid,t.claims),u===!0),getIdTokenResult:async u=>this.getIdTokenResultFor(t.uid,this.liveClaims(t.uid,t.claims),u===!0)};return Object.defineProperty(c,nm,{value:{updateProfile:u=>(this.updateProfileFor(c,u),Promise.resolve()),delete:()=>(this.deleteFor(c),Promise.resolve()),updateEmail:u=>(this.updateEmailFor(c,u),Promise.resolve()),updatePassword:u=>(this.updatePasswordFor(c,u),Promise.resolve()),reload:()=>(this.reloadFor(c),Promise.resolve()),target:this.selfTarget()},enumerable:!1}),c}selfTarget(){return{kind:"sandbox",sandbox:this.sandbox,backend:this}}updateProfileFor(t,n){const r=this.usersByUid.get(t.uid),s=r?this.toRecord(r):void 0;r&&(n.displayName!==void 0&&(r.displayName=n.displayName),n.photoURL!==void 0&&(r.photoUrl=n.photoURL)),this.applyProfileToUser(t,n),this.cachedUser&&this.cachedUser.uid===t.uid&&this.cachedUser!==t&&this.applyProfileToUser(this.cachedUser,n),this.notifyUsersChanged(),this.emitAuthEvent("user_update",{path:t.uid,auth:{uid:t.uid},before:s,after:r?this.toRecord(r):void 0,detail:{displayName:n.displayName,photoURL:n.photoURL}})}applyProfileToUser(t,n){const r=t;n.displayName!==void 0&&(r.displayName=n.displayName),n.photoURL!==void 0&&(r.photoURL=n.photoURL);const s=t.providerData?.[0];s&&(n.displayName!==void 0&&(s.displayName=n.displayName),n.photoURL!==void 0&&(s.photoURL=n.photoURL))}updateProfileByUid(t,n){const r=this.usersByUid.get(t);if(!r)throw V("auth/user-not-found",`updateProfile: no identity with uid ${t}.`);const s=this.toRecord(r);n.displayName!==void 0&&(r.displayName=n.displayName),n.photoURL!==void 0&&(r.photoUrl=n.photoURL),this.cachedUser&&this.cachedUser.uid===t&&this.applyProfileToUser(this.cachedUser,n),this.notifyUsersChanged();const i=this.toRecord(r);return this.emitAuthEvent("user_update",{path:t,auth:{uid:t},before:s,after:i,detail:{displayName:n.displayName,photoURL:n.photoURL}}),i}deleteFor(t){this.usersByUid.has(t.uid)&&this.deleteUser(t.uid),this.cachedUser&&this.cachedUser.uid===t.uid&&this.setCurrentUser(null)}updateEmailFor(t,n){this.updateUser(t.uid,{email:n}),this.applyEmailToUser(t,n),this.cachedUser&&this.cachedUser.uid===t.uid&&this.cachedUser!==t&&this.applyEmailToUser(this.cachedUser,n)}applyEmailToUser(t,n){t.email=n;const r=t.providerData?.[0];r&&(r.email=n)}updatePasswordFor(t,n){this.updateUser(t.uid,{password:n})}reloadFor(t){const n=this.usersByUid.get(t.uid);if(!n)throw V("auth/user-token-expired","The user's credential is no longer valid. The user must sign in again.");this.applyStoredToUser(t,n),this.cachedUser&&this.cachedUser.uid===t.uid&&this.cachedUser!==t&&this.applyStoredToUser(this.cachedUser,n)}applyStoredToUser(t,n){const r=t;r.email=n.email,r.displayName=n.displayName,r.photoURL=n.photoUrl,r.emailVerified=n.emailVerified,r.phoneNumber=n.phoneNumber}liveClaims(t,n){return this.usersByUid.get(t)?.customClaims??n}validatePassword(t,n){if(Me(t),typeof n!="string"||n.length===0)throw V("auth/missing-password","A non-empty password must be provided");const r=this.findByEmail(t);if(!r)throw V("auth/user-not-found",`No user found for ${t}.`);if(r.disabled)throw V("auth/user-disabled","The user account has been disabled by an administrator.");if(r.password!==n)throw V("auth/wrong-password","Invalid password.");return r}}function lm(){return`provider-${globalThis.crypto.randomUUID()}`}const li=new WeakSet,Ht=new WeakMap;function Ro(e,t,n,r="[DEFAULT]"){return cm(e,t),um(e,t,n,r)}function cm(e,t){li.has(e)||(li.add(e),e.registerPersistableService("auth",{snapshot:()=>({users:t.exportUsers(),providers:t.exportProviderConfig()}),restore:n=>{const r=n;t.clearUsers(),Array.isArray(r?.users)&&r.users.length>0&&t.seedUsers(r.users),t.restoreProviderConfig(r?.providers)},reset:()=>{t.clearUsers(),t.restoreProviderConfig(void 0)},subscribe:n=>{const r=t.subscribeUsers(n),s=t.subscribeProviderConfig(n);return()=>{r(),s()}}}))}function ci(e){return{snapshot:()=>null,restore:()=>{},session:{currentUid:()=>e.session.currentUser?.uid??null,restore:(t,n)=>{e.backend.setPersistenceMode(n),e.backend.restoreSession(t)},mode:()=>e.backend.getPersistenceMode(),subscribe:t=>(e.subscribers.add(t),e.unsubscribeBackend||(e.unsubscribeBackend=e.backend.subscribeSession(()=>{for(const n of e.subscribers)n()})),()=>{e.subscribers.delete(t),e.subscribers.size===0&&(e.unsubscribeBackend?.(),e.unsubscribeBackend=void 0)})}}}function um(e,t,n,r){let s=Ht.get(e);s||(s=new Map,Ht.set(e,s));const i=`auth-session:${r}`,o=s.get(i);if(o){const u=++o.generation;return o.unregisterService?.(),o.unregisterService=void 0,o.unsubscribeBackend?.(),o.unsubscribeBackend=void 0,o.backend=t,o.session=n,o.unregisterService=e.registerPersistableService(i,ci(o)),()=>{o.generation===u&&(o.unregisterService?.(),o.unregisterService=void 0,o.unsubscribeBackend?.(),o.unsubscribeBackend=void 0,o.subscribers.clear(),s.get(i)===o&&s.delete(i),s.size===0&&Ht.delete(e))}}const l={backend:t,session:n,subscribers:new Set,generation:1};s.set(i,l),l.unregisterService=e.registerPersistableService(i,ci(l));const c=l.generation;return()=>{l.generation===c&&(l.unregisterService?.(),l.unregisterService=void 0,l.unsubscribeBackend?.(),l.unsubscribeBackend=void 0,l.subscribers.clear(),s.get(i)===l&&s.delete(i),s.size===0&&Ht.delete(e))}}async function jk(e){const{backend:t}=os(e);t.assertProviderEnabled("anonymous");const n=t.getCurrentUser();if(n?.isAnonymous)return{user:n,providerId:null,operationType:"signIn",_additionalUserInfo:{isNewUser:!1,profile:{},providerId:null}};const r=t.mintAnonymousUser();return await t.transitionCurrentUser(r,"anonymous"),{user:r,providerId:null,operationType:"signIn",_additionalUserInfo:{isNewUser:!0,profile:{},providerId:null}}}async function dm(e){const t=os(e,!0);try{t.assertAlive?.()}catch(n){if(n.code==="app/app-deleted")return;throw n}await t.backend.transitionCurrentUser(null)}const ui=new WeakMap,di=new WeakMap,fi=new WeakMap;function Do(e){let t=di.get(e);return t||(t=No(),di.set(e,t)),t}function fm(e){let t=ui.get(e);return t||(t=new Ao(e,e,Do(e)),ui.set(e,t),Ro(e,t,e)),t}function hm(e,t){return t.service("auth/backend",()=>{const{sandbox:n,session:r}=t,s=new Ao(n,r,Do(n),i=>{t.onDelete(i)});return t.onDelete(Ro(n,s,r,e.name)),s})}function Io(e){if(e===void 0)return Io($c());const t=Pc(e);if(t)return t.service("auth/default",()=>{const n={kind:"sandbox",sandbox:t.sandbox,backend:hm(e,t),own:r=>t.onDelete(r),assertAlive:()=>t.assertAlive()};return hi(n,e)});if(pm(e)){let n=fi.get(e);return n||(n=hi({kind:"sandbox",sandbox:e,backend:fm(e)}),fi.set(e,n),n)}throw new TypeError("pyric/auth is a sandbox-only mirror. Package resolution must leave firebase/auth unchanged for production; activate pyric dev or @pyric/cli/register before importing to select the sandbox.")}function pm(e){return typeof e=="object"&&e!==null&&typeof e.onCurrentUserChanged=="function"&&typeof e.withAuth=="function"}function hi(e,t){const n={[_o]:e,...t?{app:t}:{},signOut(){return dm(n)}};return Object.defineProperty(n,"currentUser",{enumerable:!0,get(){return e.backend.getCurrentUser()}})}function K(e){return os(e)}const he={setUser(e,t){K(e).backend.setCurrentUser(t)},setAuthFlowResolver(e,t){K(e).backend.setResolver(t)},setAuthMailResolver(e,t){K(e).backend.setMailResolver(t)},takeAuthMail(e,t){return K(e).backend.takeMail(t)},listAuthMail(e){return K(e).backend.listMail()},mockActionCode(e,t,n){K(e).backend.stageActionCode(t,n)},listIdentities(e){return K(e).backend.listIdentities()},createSignInCredential(e,t){return K(e).backend.createSignInCredential(t)},mockSignInResult(e,t){const n=t.providerId;if(!n)throw new Oc("invalid-argument","sandbox.mockSignInResult: result.providerId is required so the next signInWithPopup / signInWithCredential call can match.");K(e).backend.setMockResult(n,t)},seedUsers(e,t){K(e).backend.seedUsers(t)},exportUsers(e){return K(e).backend.exportUsers()},restoreSession(e,t){return K(e).backend.restoreSession(t)},mintSession(e,t){return K(e).backend.mintDetachedSession(t)},listUsers(e){return K(e).backend.listUsers()},createUser(e,t){return K(e).backend.createUser(t)},updateUser(e,t,n){return K(e).backend.updateUser(t,n)},updateProfile(e,t,n){return K(e).backend.updateProfileByUid(t,n)},deleteUser(e,t){K(e).backend.deleteUser(t)},clearUsers(e){K(e).backend.clearUsers()},subscribeUsers(e,t){return K(e).backend.subscribeUsers(t)},getAuthProviderConfig(e){return K(e).backend.listProviderConfig()},setAuthProviderConfig(e,t,n){K(e).backend.setProviderConfig(t,n)},assertAuthProviderEnabled(e,t){K(e).backend.assertProviderEnabled(t)},delegateProviderEnforcement(e,t){K(e).backend.setProviderEnforcementDelegated(t)},subscribeAuthProviderConfig(e,t){return K(e).backend.subscribeProviderConfig(t)}},Ar="pyric-storage";function mm(e){return e?`${Ar}:${e}`:Ar}const ym=1,me="blobs",ie="metadata";function bm(e=Ar){return vm(e).then(t=>new gm(t))}class gm{db;constructor(t){this.db=t}async put(t,n,r){const s=this.db.transaction([me,ie],"readwrite");s.objectStore(me).put(n,t),s.objectStore(ie).put(r,t),await Gt(s)}async getBlob(t){const n=this.db.transaction(me,"readonly");return Xn(n.objectStore(me).get(t))}async getMetadata(t){const n=this.db.transaction(ie,"readonly");return Xn(n.objectStore(ie).get(t))}async putMetadata(t,n){const r=this.db.transaction(ie,"readwrite");r.objectStore(ie).put(n,t),await Gt(r)}async delete(t){const n=this.db.transaction([me,ie],"readwrite");n.objectStore(me).delete(t),n.objectStore(ie).delete(t),await Gt(n)}async listByPrefix(t){const n=this.db.transaction(ie,"readonly"),r=IDBKeyRange.bound(t,t+"￿",!1,!1);return Xn(n.objectStore(ie).getAll(r))}async reset(){const t=this.db.transaction([me,ie],"readwrite");t.objectStore(me).clear(),t.objectStore(ie).clear(),await Gt(t)}close(){this.db.close()}}function vm(e){return new Promise((t,n)=>{const r=indexedDB.open(e,ym);r.addEventListener("upgradeneeded",()=>{const s=r.result;s.objectStoreNames.contains(me)||s.createObjectStore(me),s.objectStoreNames.contains(ie)||s.createObjectStore(ie)}),r.addEventListener("success",()=>t(r.result)),r.addEventListener("error",()=>n(r.error)),r.addEventListener("blocked",()=>n(new Error(`IndexedDB open blocked for db "${e}"`)))})}function Xn(e){return new Promise((t,n)=>{e.addEventListener("success",()=>t(e.result)),e.addEventListener("error",()=>n(e.error))})}function Gt(e){return new Promise((t,n)=>{e.addEventListener("complete",()=>t()),e.addEventListener("error",()=>n(e.error)),e.addEventListener("abort",()=>n(e.error??new Error("IndexedDB transaction aborted")))})}function pi(e){switch(e){case"read":return["get","list"];case"write":return["create","update","delete"];default:return[e]}}const xm=new Set(["&&","||","==","!=","<",">","<=",">=","+","-","*","/","%"]);function $o(e){return{segments:e.path.segments.map(wm),children:e.children.map($o),allows:e.allows.map(t=>({verbs:t.operations,condition:H(t.condition)})),functions:e.functions.map(Rr)}}function wm(e){switch(e.type){case"literal":return{kind:"literal",value:e.value};case"wildcard":return{kind:"param",name:e.name};case"recursive":return{kind:"wildcard",name:e.name}}}function Rr(e){return{name:e.name,params:e.parameters,lets:e.lets.map(t=>({name:t.name,value:H(t.value)})),body:H(e.body)}}function H(e){switch(e.type){case"literal":return typeof e.value=="number"&&e.raw.includes(".")?{kind:"literal",value:new Se(e.value)}:{kind:"literal",value:e.value};case"identifier":return{kind:"ident",name:e.name};case"memberAccess":return{kind:"member",target:H(e.object),name:e.property};case"methodCall":return{kind:"methodcall",target:H(e.object),method:e.method,args:e.args.map(H)};case"bracketAccess":return{kind:"index",target:H(e.object),index:H(e.index)};case"sliceAccess":return{kind:"slice",target:H(e.object),start:H(e.start),end:H(e.end)};case"binaryOp":if(!xm.has(e.op))throw new SyntaxError(`Unsupported binary operator '${e.op}' in storage rules.`);return{kind:"binary",op:e.op,left:H(e.left),right:H(e.right)};case"unaryOp":if(e.op!=="!"&&e.op!=="-")throw new SyntaxError(`Unsupported unary operator '${e.op}' in storage rules.`);return{kind:"unary",op:e.op,arg:H(e.operand)};case"ternary":return{kind:"ternary",cond:H(e.condition),then:H(e.consequent),else:H(e.alternate)};case"inExpr":return{kind:"in",element:H(e.element),collection:H(e.collection)};case"isExpr":return{kind:"is",value:H(e.value),typeName:e.typeName};case"listLiteral":return{kind:"list",elements:e.elements.map(H)};case"mapLiteral":return{kind:"map",entries:e.entries.map(t=>({key:H(t.key),value:H(t.value)}))};case"pathLiteral":return{kind:"path",segments:e.segments.map(t=>typeof t=="string"?{kind:"literal",value:t}:{kind:"interp",expr:H(t)})};case"functionCall":return{kind:"call",name:e.name,args:e.args.map(H)};default:{const t=e;throw new SyntaxError(`Unsupported expression construct: ${JSON.stringify(t)}`)}}}function Dr(e){const t=Uc(e);if(!t.ok)throw new SyntaxError(`Storage rules parse error at line ${t.error.line}, column ${t.error.column}: expected ${t.error.expected}.`);const n=t.ast;if(n.service.name!=="firebase.storage")throw new SyntaxError(`Expected 'service firebase.storage', got 'service ${n.service.name}'.`);const r={segments:[],children:[$o(n.service.match)],allows:[],functions:[...(n.imports??[]).flatMap(s=>s.functions.map(i=>({name:i,params:[],lets:[],body:{kind:"literal",value:null},unresolvedImport:s.module}))),...(n.functions??[]).map(Rr),...(n.service.functions??[]).map(Rr)]};return Po(r,new Map),{_root:r,_version:n.version}}function Po(e,t){const n=new Map(t);for(const r of e.functions)n.set(r.name,r);e.visibleFuncs=n;for(const r of e.functions)r.declScope=n;for(const r of e.children)Po(r,n)}function Q(e,t){if(e.kind==="methodcall"&&e.target.kind==="ident"&&e.target.name==="firestore"&&!t.has("firestore")&&(e.method==="get"||e.method==="exists"))return!0;switch(e.kind){case"member":return Q(e.target,t);case"index":return Q(e.target,t)||Q(e.index,t);case"slice":return[e.target,e.start,e.end].some(n=>Q(n,t));case"unary":return Q(e.arg,t);case"ternary":return[e.cond,e.then,e.else].some(n=>Q(n,t));case"in":return Q(e.element,t)||Q(e.collection,t);case"is":return Q(e.value,t);case"list":return e.elements.some(n=>Q(n,t));case"map":return e.entries.some(({key:n,value:r})=>Q(n,t)||Q(r,t));case"binary":return Q(e.left,t)||Q(e.right,t);case"call":return e.args.some(n=>Q(n,t));case"methodcall":return Q(e.target,t)||e.args.some(n=>Q(n,t));case"path":return e.segments.some(n=>n.kind==="interp"&&Q(n.expr,t));case"ident":case"literal":return!1}}function Oo(e,t=new Set){const n=new Set(t);for(const r of e.segments)r.kind!=="literal"&&n.add(r.name);if(e.allows.some(({condition:r})=>r&&Q(r,n)))return!0;for(const r of e.functions){const s=new Set([...n,...r.params]);for(const i of r.lets){if(Q(i.value,s))return!0;s.add(i.name)}if(Q(r.body,s))return!0}return e.children.some(r=>Oo(r,n))}function jm(e,t,n,r,s){const i=new Set;for(const o of r)o.startsWith("storage-rules#")&&i.add(o);return Oo(s._root)&&i.add("storage-rules#131"),Object.freeze({targetService:"firebase.storage",source:e,modules:Object.freeze([...t]),bundledModules:Object.freeze([...n]),evidenceIds:Object.freeze([...i].sort())})}const km="pyric-default",In=Symbol("pyric/storage/target");function He(e){return e.currentAuth?.()??e.context.auth}class Sm{backend;rules;constructor(t,n=null){this.backend=t,this.rules=n}}const mi=new WeakMap,yi=new WeakMap,_m=new WeakMap;function Em(e,t,n){const r=mi.get(e);if(r){const l=yi.get(e)??null;if(t.rules!==void 0&&t.rules!==l)throw new Error(`pyric/storage: ${n} received a rules source, but this sandbox's storage service is already open ${l===null?"without rules":"with a different rules source"} — rules are honored only on the FIRST storage call per Sandbox, so these rules would be silently discarded. Configure rules on the first storage call for this sandbox.`);return r}let s=null,i=null;if(t.rules){let l=t.rules,c=[],u=[],d=[];if(s=Dr(l),s._version==="2+modules"){const p=ja(l);if(!p.success)throw new SyntaxError(`Storage rules module resolution failed (${p.error.code}): ${p.error.message}`);l=p.data.resolved,c=p.data.modules,u=p.data.bundledModules,d=p.data.evidenceIds,s=Dr(l)}i=jm(l,c,u,d,s)}const o=bm(t.dbName??mm(t.projectId)).then(l=>new Sm(l,s));return mi.set(e,o),yi.set(e,t.rules??null),_m.set(e,i),e.registerPersistableService("storage",{snapshot:()=>null,restore:()=>{},reset:async()=>{await(await o).backend.reset()}}),o}function Qn(e){return e instanceof Mc}const bi=new WeakMap,gi=new WeakMap;function Cm(e,t={}){const n=!Qn(e),r=Qn(e)?e.sandbox:e,s=Em(r,t,"getAdminStorageSandbox");if(n){const d=gi.get(r);if(d)return d}const i=Qn(e)?e:r.withAuth(null),o=i.operationContext.authLens.mode==="admin"?i:Ra(i,{source:i.operationContext.source,authLens:{mode:"admin"},...i.operationContext.planId===void 0?{}:{planId:i.operationContext.planId}}),l=bi.get(i);if(l)return l;const c={kind:"sandbox",sandbox:r,context:o,bucket:t.bucket??km,servicePromise:s,admin:!0},u=Object.freeze({[In]:c});return bi.set(i,u),n&&gi.set(r,u),u}function gt(e,t){const n=Tc(t,Es(e.context.operationContext));return{...t,...Es(n),service:"storage"}}function _e(e){const t=e[In];if(!t)throw new TypeError("pyric/storage: not a FirebaseStorage handle — was it produced by getStorageSandbox?");return t}function Vt(e){return _e(e).servicePromise}function Nm(e){return`storage/${e}`}class qt extends Error{code;constructor(t,n){const r=Nm(t);super(`${r}: ${n}`),this.name="StorageError",this.code=r,Object.setPrototypeOf(this,qt.prototype)}}function Uo(e){return new qt("object-not-found",`no object at "${e}".`)}function Am(e,t,n){return new qt("unauthorized",`${e} "${t}" denied by rules${n}.`)}function ls(e){return new qt("invalid-root-operation",`${e} cannot operate on the root reference.`)}function Ot(e,t){return Dm(e)?(_e(e.storage),new Ut(e.storage,Rm(e.fullPath,t??""))):(_e(e),new Ut(e,To(t??"")))}class Ut{storage;bucket;fullPath;constructor(t,n){this.storage=t;const r=_e(t);this.bucket=r.bucket,this.fullPath=n}get name(){if(this.fullPath==="")return"";const t=this.fullPath.lastIndexOf("/");return t===-1?this.fullPath:this.fullPath.slice(t+1)}get parent(){if(this.fullPath==="")return null;const t=this.fullPath.lastIndexOf("/"),n=t===-1?"":this.fullPath.slice(0,t);return new Ut(this.storage,n)}get root(){return this.fullPath===""?this:new Ut(this.storage,"")}toString(){return`gs://${this.bucket}/${this.fullPath}`}}function To(e){return e===""?"":e.split("/").filter(t=>t.length>0).join("/")}function Rm(e,t){const n=To(t);return e===""?n:n===""?e:`${e}/${n}`}function Dm(e){if(e===null||typeof e!="object"||In in e)return!1;const t=e;return typeof t.fullPath=="string"&&t.storage!==void 0}class M extends Error{}class ee{message;constructor(t){this.message=t}}function z(e){return e instanceof ee}function $e(e){if(typeof e=="number")return e;if(e instanceof Se)return e.value}function Pe(e){if(e===null||typeof e!="object"||Array.isArray(e))return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function at(e,t){if(e===t)return!0;if(e==null||t==null)return e==null&&t==null;const n=$e(e),r=$e(t);if(n!==void 0&&r!==void 0)return n===r;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((s,i)=>at(s,t[i]));if(Pe(e)&&Pe(t)){const s=Object.keys(e),i=Object.keys(t);return s.length===i.length&&s.every(o=>Object.prototype.hasOwnProperty.call(t,o)&&at(e[o],t[o]))}return!1}function ae(e){return e===null?"null":e===void 0?"undefined":e instanceof Se?"float":typeof e}function Im(e,t){if(e.target.kind==="ident"&&e.target.name==="timestamp"&&!(e.target.name in t.locals)&&!(e.target.name in t.params))return Um(e,t);if(e.target.kind==="ident"&&e.target.name==="duration"&&!(e.target.name in t.locals)&&!(e.target.name in t.params))return Om(e,t);if(e.target.kind==="ident"&&e.target.name==="firestore"&&!(e.target.name in t.locals)&&!(e.target.name in t.params))return $m(e,t);if(e.method==="matches")return Tm(e,t);if(e.method==="split")return Mm(e,t);if(e.method==="size")return Lm(e,t);if(e.method==="keys")return Bm(e,t);if(e.method==="hasAll")return Fm(e,t);if(e.method==="get")return Vm(e,t);throw new M(`unsupported method .${e.method}()`)}function $m(e,t){if(e.method!=="get"&&e.method!=="exists")throw new M(`unsupported method firestore.${e.method}()`);if(!t.firestoreLookup)throw new M(`firestore.${e.method}() is unsupported here — no Firestore lookup capability is configured`);if(e.args.length!==1)throw new M(`firestore.${e.method}() expects a single path argument`);const n=e.args[0];if(n.kind!=="path")throw new M(`firestore.${e.method}() requires a /databases/.../documents/... path literal`);const r=Pm(n,t);if(!t.firestoreAccesses.has(r)){if(t.firestoreAccesses.size>=2)throw new M("firestore access limit exceeded: at most two distinct documents");t.firestoreAccesses.add(r)}if(e.method==="exists")return t.firestoreLookup.exists(r);const s=t.firestoreLookup.get(r);return s===null?new ee(`firestore.get() targeted a nonexistent document: ${r}`):{data:s}}function Pm(e,t){const n=e.segments.map(s=>{if(s.kind==="literal")return s.value;const i=L(s.expr,t);if(typeof i=="string")return i;if(typeof i=="number")return String(i);throw new M(`Firestore path interpolation resolved to ${ae(i)} (expected a string)`)});if(n.length<4||n[0]!=="databases"||n[2]!=="documents")throw new M(`malformed Firestore path — expected /databases/<db>/documents/... , got /${n.join("/")}`);if(n[1]!=="(default)")throw new M(`Storage rules may access only the default Firestore database, got ${n[1]}`);const r=n.slice(3);if(r.length===0||r.length%2!==0)throw new M(`Firestore path does not point at a document (needs an even segment count): ${r.join("/")}`);return r.join("/")}const vi={w:10080*60*1e3,d:1440*60*1e3,h:3600*1e3,m:60*1e3,s:1e3,ms:1,ns:1e-6};function Om(e,t){if(e.method!=="value")throw new M(`unsupported duration.${e.method}()`);const n=e.args.map(o=>L(o,t));if(n.length!==2||typeof n[0]!="number"||typeof n[1]!="string")throw new M("duration.value() expects (magnitude: number, unit: string)");const[r,s]=n,i=vi[s];if(i===void 0)throw new M(`duration.value() got unknown unit "${s}" — expected one of ${Object.keys(vi).join(", ")}`);return r*i}function Um(e,t){const n=e.args.map(r=>L(r,t));if(e.method==="value"){if(n.length!==1||typeof n[0]!="number")throw new M("timestamp.value() expects (epochMillis: number)");return n[0]}if(e.method==="date"){if(n.length!==3||!n.every(o=>typeof o=="number"))throw new M("timestamp.date() expects (year, month, day) numbers");const[r,s,i]=n;return Date.UTC(r,s-1,i)}throw new M(`unsupported timestamp.${e.method}()`)}function Tm(e,t){const n=L(e.target,t);if(z(n))return n;if(typeof n!="string")throw new M(`matches() requires a string target, got ${ae(n)}`);if(e.args.length!==1)throw new M("matches() expects a single pattern argument");const r=L(e.args[0],t);if(typeof r!="string")throw new M("matches() pattern must be a string");const s=/\\[1-9]/.test(r),i=/\(\?<?[=!]/.test(r);if(s||i)throw new M(`matches() pattern uses an RE2-unsupported construct (${s?"backreference":"lookaround"}) that production would reject`);let o;try{o=new RegExp(`^(?:${r})$`)}catch(l){throw new M(`matches() invalid regex pattern: ${l.message}`)}return o.test(n)}function Mm(e,t){const n=L(e.target,t);if(z(n))return n;if(typeof n!="string")throw new M(`split() requires a string target, got ${ae(n)}`);if(e.args.length!==1)throw new M("split() expects a single pattern argument");const r=L(e.args[0],t);if(typeof r!="string")throw new M("split() pattern must be a string");const s=/\\[1-9]/.test(r),i=/\(\?<?[=!]/.test(r);if(s||i)throw new M(`split() pattern uses an RE2-unsupported construct (${s?"backreference":"lookaround"}) that production would reject`);let o;try{o=new RegExp(r)}catch(l){throw new M(`split() invalid regex pattern: ${l.message}`)}return n.split(o)}function Lm(e,t){const n=L(e.target,t);if(z(n))return n;if(e.args.length!==0)throw new M("size() expects no arguments");if(typeof n=="string"||Array.isArray(n))return n.length;if(Pe(n))return Object.keys(n).length;throw new M(`size() requires a string, list, or map target, got ${ae(n)}`)}function Bm(e,t){const n=L(e.target,t);if(z(n))return n;if(e.args.length!==0)throw new M("keys() expects no arguments");if(!Pe(n))throw new M(`keys() requires a map target, got ${ae(n)}`);return Object.keys(n)}function Fm(e,t){const n=L(e.target,t);if(z(n))return n;if(!Array.isArray(n))throw new M(`hasAll() requires a list or set target, got ${ae(n)}`);if(e.args.length!==1)throw new M("hasAll() expects one list or set argument");const r=L(e.args[0],t);if(z(r))return r;if(!Array.isArray(r))throw new M("hasAll() argument must be a list or set");return r.every(s=>n.some(i=>at(i,s)))}function Vm(e,t){const n=L(e.target,t);if(z(n))return n;if(!Pe(n))throw new M(`get() requires a map target, got ${ae(n)}`);if(e.args.length!==2)throw new M("get() expects a key and default value");const r=L(e.args[0],t);if(z(r))return r;if(typeof r!="string")throw new M("get() key must be a string");const s=L(e.args[1],t);return z(s)?s:Object.prototype.hasOwnProperty.call(n,r)?n[r]:s}function qm(e){return e.split("/").filter(t=>t.length>0)}function Zn(e){return"/"+e.map(t=>t.kind==="literal"?t.value:t.kind==="param"?`{${t.name}}`:`{${t.name}=**}`).join("/")}function Wm(e,t,n){let r=0;const s={...n};for(let i=0;i<e.length;i++){const o=e[i];if(o.kind==="wildcard")return s[o.name]=t.slice(r),{left:[],params:s};if(r>=t.length)return null;if(o.kind==="literal"){if(t[r]!==o.value)return null;r++}else s[o.name]=t[r],r++}return{left:t.slice(r),params:s}}function Mo(e,t,n=new Date,r){const s=n.getTime(),i=qm(t.request.path),o=[],l=new Set,c=new Set(pi(t.request.method));function u(p,h,m){const y=Wm(p.segments,h,m);if(!y)return!1;const g=y.params,x=y.left;if(x.length===0)for(const b of p.allows){const v=new Set(b.verbs.flatMap(pi));if(![...c].some(j=>v.has(j)))continue;let k;try{const j=b.condition?L(b.condition,{input:t,now:s,params:g,locals:{},funcs:p.visibleFuncs??new Map,depth:0,firestoreLookup:r,firestoreAccesses:l}):!0;if(z(j)){o.push(`match ${Zn(p.segments)} ${t.request.method}: ${j.message}`);continue}k=tt(j)}catch(j){if(j instanceof M){o.push(`match ${Zn(p.segments)} ${t.request.method}: ${j.message}`);continue}throw j}if(k)return!0;o.push(`match ${Zn(p.segments)} ${t.request.method}: condition false`)}for(const b of p.children)if(u(b,x,g))return!0;return!1}const d=u(e._root,i,{});return!d&&o.length===0&&o.push(`no rule matches ${t.request.method} /${i.join("/")}`),{allowed:d,reasons:o}}function xi(e,t){if(!Pe(e)&&!Array.isArray(e))return new ee(`Property ${t} is undefined on ${ae(e)}.`);if(!Object.hasOwn(e,t))return new ee(`Property ${t} is undefined on object.`);const n=e[t];return n===void 0?new ee(`Property ${t} is undefined on object.`):n}function tt(e){return z(e)?!1:e!==!1&&e!==null&&e!==void 0&&!(typeof e=="number"&&Number.isNaN(e))}const wi=20;function L(e,t){switch(e.kind){case"literal":return e.value;case"ident":return e.name in t.locals?t.locals[e.name]:e.name==="request"?Gm(t.input,t.now):e.name==="resource"?t.input.resource===null?new ee("Null value error."):Hm(t.input.resource):e.name in t.params?t.params[e.name]:void 0;case"member":{const n=L(e.target,t);return z(n)?n:n==null?new ee("Null value error."):xi(n,e.name)}case"index":{const n=L(e.target,t);if(z(n))return n;if(n==null)return new ee("Null value error.");const r=L(e.index,t);return z(r)?r:xi(n,String(r))}case"call":return zm(e,t);case"methodcall":return Im(e,t);case"path":throw new M("a Firestore path literal is only valid as an argument to firestore.get()/exists()");case"unary":{const n=L(e.arg,t);return z(n)?n:e.op==="-"?n instanceof Se?new Se(-n.value):typeof n!="number"?new ee(`Unary '-' applied to ${ae(n)}.`):-n:!tt(n)}case"ternary":{const n=L(e.cond,t);return z(n)?n:tt(n)?L(e.then,t):L(e.else,t)}case"in":{const n=L(e.element,t);if(z(n))return n;const r=L(e.collection,t);return z(r)?r:Array.isArray(r)?r.some(s=>at(s,n)):Pe(r)?typeof n=="string"&&Object.prototype.hasOwnProperty.call(r,n):new ee(`'in' applied to ${ae(r)} (expected a list or map).`)}case"is":{const n=L(e.value,t);return z(n)?n:Km(n,e.typeName)}case"list":{const n=[];for(const r of e.elements){const s=L(r,t);if(z(s))return s;n.push(s)}return n}case"map":{const n={};for(const r of e.entries){const s=L(r.key,t);if(z(s))return s;if(typeof s!="string")return new ee(`Map literal key is ${ae(s)} (expected a string).`);const i=L(r.value,t);if(z(i))return i;n[s]=i}return n}case"slice":{const n=L(e.target,t);if(z(n))return n;const r=L(e.start,t);if(z(r))return r;const s=L(e.end,t);return z(s)?s:typeof r!="number"||typeof s!="number"||!Number.isInteger(r)||!Number.isInteger(s)?new ee("Slice bounds must be integers."):Array.isArray(n)||typeof n=="string"?r<0||s<r||s>n.length?new ee(`Slice bounds [${r}:${s}] out of range for ${ae(n)} of size ${n.length}.`):n.slice(r,s):new ee(`Slice applied to ${ae(n)} (expected a list or string).`)}case"binary":{if(e.op==="&&"){const s=L(e.left,t);return z(s)?s:tt(s)?L(e.right,t):s}if(e.op==="||"){const s=L(e.left,t);if(z(s)){const i=L(e.right,t);return tt(i)?i:s}return tt(s)?s:L(e.right,t)}const n=L(e.left,t);if(z(n))return n;const r=L(e.right,t);if(z(r))return r;switch(e.op){case"==":return at(n,r);case"!=":return!at(n,r);case"<":return Jt(n,r)<0;case">":return Jt(n,r)>0;case"<=":return Jt(n,r)<=0;case">=":return Jt(n,r)>=0;case"+":return Le(n,r,(s,i)=>s+i);case"-":return Le(n,r,(s,i)=>s-i);case"*":return Le(n,r,(s,i)=>s*i);case"/":return it(n)||it(r)?Le(n,r,(s,i)=>s/i):$e(r)===0?new ee("Division by zero."):Le(n,r,(s,i)=>Math.trunc(s/i));case"%":return it(n)||it(r)?Le(n,r,(s,i)=>s%i):$e(r)===0?new ee("Modulo by zero."):Le(n,r,(s,i)=>s%i)}}}}function zm(e,t){const n=t.funcs.get(e.name);if(!n)throw new M(`undefined function ${e.name}()`);if(n.unresolvedImport!==void 0)throw new M(`function ${e.name}() is imported from '${n.unresolvedImport}', but import module resolution is not implemented`);if(n.params.length!==e.args.length)throw new M(`function ${e.name}() expects ${n.params.length} argument(s), got ${e.args.length}`);const r=t.depth+1;if(r>wi)throw new M(`function ${e.name}() exceeded max call depth ${wi}`);const s=e.args.map(l=>L(l,t)),i={};n.params.forEach((l,c)=>{i[l]=s[c]});const o={input:t.input,now:t.now,params:{},locals:i,funcs:n.declScope??new Map,depth:r,firestoreLookup:t.firestoreLookup,firestoreAccesses:t.firestoreAccesses};for(const l of n.lets)i[l.name]=L(l.value,o);return L(n.body,o)}function Km(e,t){switch(t){case"string":return typeof e=="string";case"bool":return typeof e=="boolean";case"int":return typeof e=="number"&&Number.isInteger(e);case"float":return e instanceof Se||typeof e=="number"&&!Number.isInteger(e);case"number":return e instanceof Se||typeof e=="number";case"list":return Array.isArray(e);case"map":return Pe(e);default:return new ee(`'is ${t}' is not supported by the storage evaluator.`)}}function it(e){return e instanceof Se}function Jt(e,t){const n=$e(e),r=$e(t);return n!==void 0&&r!==void 0?n-r:typeof e=="string"&&typeof t=="string"?e<t?-1:e>t?1:0:Number.NaN}function Le(e,t,n){const r=$e(e),s=$e(t);if(r===void 0||s===void 0)return;const i=n(r,s);return it(e)||it(t)?new Se(i):i}function Hm(e){return{size:e.size,contentType:e.contentType,metadata:e.metadata,name:e.name,bucket:e.bucket,generation:e.generation,metageneration:e.metageneration,timeCreated:ji(e.timeCreated),updated:ji(e.updated)}}function ji(e){if(e===void 0)return;const t=Date.parse(e);return Number.isNaN(t)?void 0:t}function Gm(e,t){return{auth:e.request.auth??new ee("Property auth is undefined on object."),resource:e.request.resource??new ee("Property resource is undefined on object."),method:e.request.method,path:e.request.path,time:t}}function Wt(e,t,n,r){const s=n?.kind==="sandbox"?gt(n,r):r;if(n?.kind==="sandbox"&&n.admin===!0){Yt(n,t,"not-applicable",void 0,"admin",!1,s);return}if(!e.rules){Yt(n,t,"allow",void 0,"user",!1,s);return}const i=n?Jm(t,n.bucket):t,o=Mo(e.rules,i,void 0,Ym(n));if(!o.allowed){Yt(n,t,"deny",o.reasons,"user",!0,s);const l=o.reasons.length>0?` — ${o.reasons.join("; ")}`:"";throw Am(t.request.method,t.request.path,l)}Yt(n,t,"allow",o.reasons,"user",!0,s)}function Jm(e,t){const n=e.request.path.replace(/^\/+/,"");return{...e,request:{...e.request,path:n===""?`b/${t}/o`:`b/${t}/o/${n}`}}}function Yt(e,t,n,r,s,i,o){if(e)try{De(e.sandbox,Na({service:"storage",method:t.request.method,path:t.request.path,auth:t.request.auth,result:n,origin:s,reasons:r,rulesDisposition:s==="admin"?{kind:"bypassed",reason:"admin"}:i?{kind:"evaluated",verdict:n==="deny"?"deny":"allow"}:{kind:"not-evaluated",reason:"no-rules"},rules:i?{engine:"storage",reason:r&&r.length>0?r.join("; "):void 0}:void 0}),{...o,service:"storage"})}catch{}}function Ym(e){if(!e)return;const t=e.sandbox.admin;return{get:n=>t.getDocument(n),exists:n=>t.getDocument(n)!==null}}function $n(e){return e?{size:e.size,contentType:e.contentType,metadata:e.customMetadata,name:Xm(e.fullPath,e.bucket),bucket:e.bucket,timeCreated:e.timeCreated,updated:e.updated,generation:ki(e.generation),metageneration:ki(e.metageneration)}:null}function Xm(e,t){if(e===void 0)return;const n=e.startsWith("/")?e.slice(1):e;if(t!==void 0){const s=`b/${t}/o/`;if(n.startsWith(s))return n.slice(s.length)}const r=/^b\/[^/]+\/o\//.exec(n);return r?n.slice(r[0].length):n}function ki(e){if(e===void 0)return;const t=Number(e);return Number.isFinite(t)?t:void 0}function Qm(e){return{size:e.size,contentType:e.contentType,metadata:e.customMetadata}}function Lo(e){return{...e}}async function Zm(e){ey(e,"getMetadata");const t=_e(e.storage),n=gt(t),r=await Vt(e.storage),s=await r.backend.getMetadata(e.fullPath);if(Wt(r,{request:{auth:He(t),method:"get",path:e.fullPath},resource:$n(s)},t,n),!s)throw Uo(e.fullPath);return Lo(s)}function ey(e,t){if(e.fullPath==="")throw ls(t)}const ty="application/octet-stream";async function ny(e,t,n,r){ay(e,"uploadBytes");const s=_e(e.storage),i=gt(s,r),o=sy(t,n?.contentType),l=ry({ref:e,blob:o,settable:n}),c=await Vt(e.storage),u=await c.backend.getMetadata(e.fullPath);Wt(c,{request:{auth:He(s),method:u?"update":"create",path:e.fullPath,resource:Qm({size:l.size,contentType:l.contentType,customMetadata:l.customMetadata})},resource:$n(u)},s,i),await c.backend.put(e.fullPath,o,l);try{De(s.sandbox,Sn({service:"storage",op:"object_put",path:e.fullPath,auth:He(s),before:u??void 0,after:l,detail:{bucket:e.bucket,size:l.size,contentType:l.contentType,overwrite:u!=null}}),i)}catch{}return{ref:e,metadata:Lo(l)}}function ry(e){const{ref:t,blob:n,settable:r}=e,s=(e.now??new Date).toISOString(),i=iy(e.now??new Date),o=t.name;return{fullPath:t.fullPath,name:o,bucket:t.bucket,generation:i,metageneration:"1",timeCreated:s,updated:s,size:n.size,contentType:r?.contentType||n.type||ty,cacheControl:r?.cacheControl,contentDisposition:r?.contentDisposition,contentEncoding:r?.contentEncoding,contentLanguage:r?.contentLanguage,customMetadata:r?.customMetadata}}function sy(e,t){return e instanceof Blob?t&&t!==e.type?new Blob([e],{type:t}):e:new Blob([e],{type:t??""})}function iy(e){return String(e.getTime())}function ay(e,t){if(e.fullPath==="")throw ls(t)}async function oy(e,t){return Fo(e,"getBlob"),ly(e,t)}async function Bo(e,t){Fo(e,"deleteObject");const n=_e(e.storage),r=gt(n,t),s=await Vt(e.storage),i=await s.backend.getMetadata(e.fullPath);Wt(s,{request:{auth:He(n),method:"delete",path:e.fullPath},resource:$n(i)},n,r),await s.backend.delete(e.fullPath);try{De(n.sandbox,Sn({service:"storage",op:"object_delete",path:e.fullPath,auth:He(n),before:i??void 0,detail:{bucket:e.bucket}}),r)}catch{}}async function ly(e,t){const n=_e(e.storage),r=gt(n),s=await Vt(e.storage),i=await s.backend.getMetadata(e.fullPath);Wt(s,{request:{auth:He(n),method:"get",path:e.fullPath},resource:$n(i)},n,r);const o=await s.backend.getBlob(e.fullPath);if(!o)throw Uo(e.fullPath);return typeof t=="number"&&o.size>t?o.slice(0,t):o}function Fo(e,t){if(e.fullPath==="")throw ls(t)}async function cs(e){const t=e.storage,n=_e(t),r=gt(n),s=await Vt(t);Wt(s,{request:{auth:He(n),method:"list",path:e.fullPath},resource:null},n,r);const i=e.fullPath===""?"":`${e.fullPath}/`,o=await s.backend.listByPrefix(i),l=[],c=new Set,u=[];for(const d of o){if(!d.fullPath.startsWith(i))continue;const p=d.fullPath.slice(i.length);if(p==="")continue;const h=p.indexOf("/");if(h===-1)l.push(Ot(t,d.fullPath));else{const m=p.slice(0,h),y=`${i}${m}`;c.has(y)||(c.add(y),u.push(Ot(t,y)))}}return u.sort((d,p)=>d.fullPath<p.fullPath?-1:d.fullPath>p.fullPath?1:0),{items:l,prefixes:u}}function cy(e,t,n){const r={name:n,options:structuredClone(t),automaticDataCollectionEnabled:!0};return td(r,e),r}const uy=Object.freeze({source:Object.freeze({kind:"studio"}),authLens:Object.freeze({mode:"admin"})});function dy(e){return Ra(e.withAuth(null),uy)}const fy="pyric-studio";function Vo(e,t){return e.listDocuments(t).map(({path:n,phantom:r})=>({path:n,phantom:r}))}let hy=0;function py(e){const t=cy(e,{projectId:"pyric-studio"},`pyric-studio-${hy++}`),n=Je(e),r=dy(e);return{sandbox:e,app:t,firestore:Gr(e),adminFirestore:Aa(r),auth:Io(e),storage:Cm(r),listRootCollections:()=>n.listRootCollections(),listSubcollections:s=>n.listSubcollections(s),listDocuments:s=>Vo(n,s)}}function my(e,t){const[n,r]=f.useState(!1),[s,i]=f.useState(null),o=f.useMemo(()=>$a(),[]),l=f.useMemo(()=>{try{return py(o)}catch(u){return i(u instanceof Error?u:new Error(String(u))),null}},[o]);return f.useEffect(()=>{let u=!1;if(!e){r(!1);return}return o.enablePersistence({key:fy,injectedBackend:e}).then(()=>{u||r(!0)}).catch(d=>{u||i(d instanceof Error?d:new Error(String(d)))}),()=>{u=!0}},[o,e]),s?{status:"error",handles:null,error:s}:l?e!=null&&n||t==="ready"?{status:"ready",handles:l}:{status:"pending",handles:null}:{status:"error",handles:null,error:new Error("Studio: failed to construct the sandbox data handles.")}}function yy(e){const t=e.rules?.engine??e.service;return t==="rtdb"||t==="storage"?t:"firestore"}function by(e){switch(yy(e)){case"firestore":return{impersonate:{kind:"live",tool:"worker setLens({mode:'as',uid}) → Firestore replay"},editedRuleset:{kind:"live",tool:"fork + firestore_lint_rules + firestore_simulate_rules"}};case"rtdb":return{impersonate:{kind:"pending",tool:"rtdb_simulate_access",hint:"RTDB re-runs through the local rules simulator as this user once the Studio worker exposes rtdb_simulate_access. This is a simulation, not a live re-issue — RTDB has no live local enforcement path."},editedRuleset:{kind:"pending",tool:"RulesEvaluator.setRules + rtdb_simulate_access",hint:"Editing the RTDB ruleset re-simulates the write once the worker exposes the RTDB simulator. Note: there is no whole-ruleset RTDB linter yet (rtdb_build_expression lints a single expression)."}};case"storage":return{impersonate:{kind:"absent",missingTool:"storage_simulate_rules",hint:"Storage rules are enforced and evaluated allow/deny events open this inspector, but Studio has no Storage replay operation to re-run this request as a user."},editedRuleset:{kind:"absent",missingTool:"storage_simulate_rules + edited-rules deployment seam",hint:"Storage rules are enforced and denial events are inspectable. Testing an edit still needs a Studio Storage replay operation plus a temporary edited-rules deployment seam."}}}}function gy(e){return Da(e)?.rules.kind==="evaluated"}function vy(e){return"service"in e&&typeof e.service=="string"?e.service:"firestore"}function xy(e){const t=e.request;if(t){if("resourceData"in t&&t.resourceData!==void 0)return t.resourceData;if("data"in t)return t.data}}function wy(e){const t=[];for(const n of e)gy(n)&&t.push(jy(n));return t.sort((n,r)=>r.at-n.at)}function jy(e){const t={id:e.id,at:e.at,result:e.result==="allow"?"allow":e.result==="unsupported"?"unsupported":"deny",method:e.method,service:vy(e),path:e.path??"(service)",auth:e.auth,reasons:e.reasons??[],origin:e.origin,unsupported:e.result==="unsupported"};"matchedRule"in e&&e.matchedRule&&(t.matchedRule=e.matchedRule),"evaluatedRule"in e&&e.evaluatedRule&&(t.evaluatedRule=e.evaluatedRule),"rules"in e&&e.rules&&(t.rules=e.rules);const n=xy(e);return n!==void 0&&(t.resourceData=n),e.resourceBefore&&(t.resourceBefore={data:e.resourceBefore.data,exists:e.resourceBefore.exists}),t}const Si=/^Rule #(\d+) \(([^)]+)\) → (ALLOW|deny|unsupported)/;function ky(e){const t=e.rules?.engine??e.service;return t==="rtdb"||t==="storage"?t:"firestore"}function Sy(e){if(e.rules?.reason==="Validation rule evaluated to false")return"validate";const t=e.method;return t==="get"||t==="list"||t==="listen"?"read":"write"}function _y(e){const t=ky(e),n=e.reasons.filter(s=>Si.test(s)),r=e.reasons.filter(s=>!Si.test(s));if(e.unsupported)return{headline:`The simulator hit an unmodelled rules feature evaluating ${e.method} ${e.path}.`,engine:t,ruleLines:n,otherLines:r,implicitDeny:!1};if(e.result==="allow"){if(t==="firestore"&&e.matchedRule){const i=e.matchedRule,o=`Rule #${i.ruleIndex} (${i.operations.join(", ")})`;return{headline:`${o} allowed ${e.method} on ${e.path}.`,engine:t,ruleNode:o,ruleLines:n,otherLines:r,implicitDeny:!1}}return!e.matchedRule&&!e.rules&&!e.evaluatedRule&&n.length===0?{headline:`This ${e.method} on ${e.path} succeeded, but no rules evaluation was recorded for it — rules likely never ran (an admin/bypass operation from a worker that didn't stamp its lens, or a pre-provenance event).`,engine:t,ruleLines:n,otherLines:r,implicitDeny:!1,noEvaluation:!0}:{headline:`Rules allowed ${e.method} on ${e.path}.`,engine:t,...e.rules?.matchedRule?{ruleExpression:e.rules.matchedRule}:{},ruleLines:n,otherLines:r,implicitDeny:!1}}return t==="rtdb"?Cy(e,n,r):t==="storage"?Ny(e,n,r):Ey(e,n,r)}function Ey(e,t,n){const r=!e.matchedRule;let s,i;if(r)s=`No rule allowed ${e.method} on ${e.path}: implicit deny (no matching \`allow\`).`;else{const o=e.matchedRule;i=`Rule #${o.ruleIndex} (${o.operations.join(", ")})`,s=`${i} denied ${e.method} on ${e.path}.`}return{headline:s,engine:"firestore",ruleNode:i,ruleLines:t,otherLines:n,implicitDeny:r}}function Cy(e,t,n){const r=e.rules,s=Sy(e),i=!r?.matchedPath||r?.errorCode==="NO_MATCHING_RULE",o=r?.pathVariableBindings&&Object.keys(r.pathVariableBindings).length>0?r.pathVariableBindings:void 0;let l,c;return i?l=`No \`.${s}\` rule granted ${e.method} on ${e.path}: RTDB implicit deny (no rule matched).`:s==="validate"?(c=`${r.matchedPath} .validate`,l=`The \`.validate\` rule at \`${r.matchedPath}\` rejected the proposed value for ${e.method} ${e.path}.`):(c=`${r.matchedPath} .${s}`,l=`The \`.${s}\` rule at \`${r.matchedPath}\` evaluated false for ${e.method} ${e.path}.`),{headline:l,engine:"rtdb",ruleNode:c,ruleExpression:r?.matchedRule,phase:s,bindings:o,ruleLines:t,otherLines:n,implicitDeny:i}}function Ny(e,t,n){const r=e.reasons.find(l=>/^match\s/.test(l)),i=e.reasons.some(l=>/^no rule matches/.test(l))||!r;return{headline:i?`No \`match\` block allowed ${e.method} on ${e.path}: Storage implicit deny (no rule matched).`:`A \`match\` block condition evaluated false for ${e.method} on ${e.path}.`,engine:"storage",ruleNode:i?void 0:r,ruleLines:t,otherLines:n,implicitDeny:i}}function Ay(e){return!!e.auth?.uid}function Ry(e){return e.skipped?"skipped":e.error!==void 0?"error":e.value===!0?"true":e.value===!1?"false":"value"}function Dy(e){const t=e.evaluatedRule?.expressionTrace;if(!t||t.length===0)return[];const n=t.map(s=>({source:s.source,outcome:Ry(s),...s.value!==void 0?{value:s.value}:{},...s.error!==void 0?{error:s.error}:{},...s.letBinding?{letBinding:s.letBinding.name}:{},...s.inlinedFrom?{inlinedFrom:s.inlinedFrom.name}:{},depth:0,children:[]})),r=[];return t.forEach((s,i)=>{s.parent===null||s.parent===void 0||!n[s.parent]?r.push(n[i]):(n[i].depth=n[s.parent].depth+1,n[s.parent].children.push(n[i]))}),r}function Iy(e){const t=[{name:"request.auth",present:e.auth!==null,value:e.auth,...e.auth===null?{absentNote:"request.auth was null — the request was unauthenticated."}:{}},{name:"request.method",present:!0,value:e.method},{name:"request.path",present:!0,value:e.path}],n=e.method==="get"||e.method==="list"||e.method==="listen";return t.push({name:"request.resource.data",present:e.resourceData!==void 0,value:e.resourceData??null,...e.resourceData===void 0?{absentNote:n?"A read carries no proposed write, so request.resource.data is absent.":"No proposed write payload was captured for this denial."}:{}}),t.push({name:"resource",present:e.resourceBefore!==void 0,value:e.resourceBefore?{data:e.resourceBefore.data,exists:e.resourceBefore.exists}:null,...e.resourceBefore===void 0?{absentNote:"The rule evaluated no existing document (e.g. a list/query, or the doc did not exist)."}:{}}),t}function $y(e){const t=Je(e.sandbox);return{sandbox:e.sandbox,app:e.app,firestore:e.firestore,adminFirestore:e.adminFirestore,auth:e.auth,storage:e.storage,listRootCollections:()=>t.listRootCollections(),listSubcollections:n=>t.listSubcollections(n),listDocuments:n=>Vo(t,n)}}function Oe(){const e=Ee(),t=fe(),n=t.status==="ready"?t.env.persistence:void 0,r=my(n,t.status),s=t.status==="ready"?t.env.live:void 0,i=Py(s);return f.useMemo(()=>{switch(e.status){case"ready":return{status:"ready",handles:$y(e.handles)};case"pending":return{status:"pending",handles:null};case"error":return{status:"error",handles:null,error:e.error};case"disabled":{if(s&&r.status==="ready"){const o=s.db;return{status:"ready",firestoreApi:s.firestoreApi,authApi:s.authApi,storageApi:s.storageApi,handles:{...r.handles,firestore:o,adminFirestore:o,auth:s.auth,storage:s.storage,listRootCollections:()=>i,listSubcollections:l=>s.listSubcollections(l),listDocuments:l=>s.listDocuments(l)}}}return r}}},[e,r,s,i])}function Py(e){const[t,n]=f.useState([]);return f.useEffect(()=>{if(!e){n([]);return}let r=!0;const s=()=>{e.listRootCollections().then(o=>{r&&n(o)}).catch(()=>{})};try{e.setLens({mode:"admin"})}catch{}s();const i=e.feed.subscribe(()=>s());return()=>{r=!1,i()}},[e]),t}const vn=500;function er(e){return e.length>vn?e.slice(-vn):e}function zt(){const e=Ee(),t=fe(),n=t.status==="ready"?t.env.live?.feed:void 0,r=e.status==="ready",[s,i]=f.useState([]);f.useEffect(()=>{if(r||!n){i([]);return}return i(er(n.history())),n.subscribe(c=>i(u=>er(Lu(u,c))))},[r,n]);const o=f.useMemo(()=>r?er(e.events):[],[r,e]);return r?o:s}function Oy(e){return e.kind==="request"||e.kind==="operation"}function Uy(e){const t=Da(e);if(!t)throw new Error("Studio traffic adapter received a non-operation event");return e.kind==="request"?{...e,operationContext:t.context,rulesDisposition:t.rules}:{kind:"operation",service:e.service,id:e.id,at:e.at,durationMs:e.durationMs,method:e.method,path:e.path??"(service)",auth:e.auth,result:e.result,reasons:e.reasons??[],request:e.request,resourceBefore:e.resourceBefore,resourceAfter:e.resourceAfter,origin:e.origin,groupId:e.groupId,groupKind:e.groupKind,triggeredBy:e.triggeredBy,operationContext:t.context,rulesDisposition:t.rules}}function Ty(){const e=zt();return f.useMemo(()=>e.filter(Oy).map(Uy),[e])}function My(){const e=zt();return f.useMemo(()=>wy(e),[e])}function Ly(){const e=Oe();return f.useCallback(async t=>{if(e.status!=="ready")throw new Error("No sandbox available to seed.");const n=e.handles.adminFirestore,r=e.firestoreApi?.doc??pe,s=e.firestoreApi?.setDoc??At;let i=0;const o=[];for(const l of t)try{await s(r(n,l.path),l.data),i++}catch(c){o.push(`${l.path}: ${c instanceof Error?c.message:String(c)}`)}return{written:i,errors:o}},[e])}function By(){const e=Oe();return f.useCallback(async t=>{if(e.status!=="ready")throw new Error("No sandbox available to seed auth.");const n=e.handles.auth,r=e.authApi?.createUser??he.createUser;let s=0;const i=[];for(const o of t)try{await r(n,o.request),s++}catch(l){const c=o.request.uid??o.request.email??"<auto>";i.push(`${c}: ${l instanceof Error?l.message:String(l)}`)}return{created:s,errors:i}},[e])}function Fy(){const e=Oe(),t=fe(),n=t.status==="ready"?t.env.live:void 0;return f.useCallback(async()=>{if(e.status!=="ready")throw new Error("No sandbox to clear.");const r=[];try{const s=n?await n.resetAll():await e.handles.sandbox.resetAll();r.push(...s?.errors??[])}catch(s){r.push(`reset: ${s instanceof Error?s.message:String(s)}`)}return{errors:r}},[e,n])}function Vy(){const e=Fy(),t=Ly(),n=By(),r=Ee();return f.useCallback(async()=>{const s=await e();if(r.status==="ready"){const{applySeed:i,deploySeedRules:o}=await Ga(async()=>{const{applySeed:l,deploySeedRules:c}=await import("./seed.EyI3VYEu.js");return{applySeed:l,deploySeedRules:c}},__vite__mapDeps([0,1,2,3,4,5,6]));o(r.handles.sandbox),await i(r.handles)}else try{const i=await fetch("/__pyric/init.json").then(c=>c.ok?c.json():null),o=i?.seed;o&&await t(Object.entries(o).map(([c,u])=>({path:c,data:u})));const l=i?.authUsers;Array.isArray(l)&&await n(l.map(c=>({request:c})))}catch(i){s.errors.push(`reseed: ${i instanceof Error?i.message:String(i)}`)}return s},[e,t,n,r])}function qy(){const e=Ee(),t=fe(),n=t.status==="ready"?t.env.live:void 0,r=e.status==="ready"?e.handles.sandbox:null;return f.useCallback(async()=>r?r.snapshot():n?n.getSnapshot():null,[r,n])}function us(){const e=fe(),t=e.status==="ready"?e.env.live:void 0,[n,r]=f.useState("");return f.useEffect(()=>{if(!t){r("");return}let s=!1;return t.instanceId().then(i=>{s||r(i)}),()=>{s=!0}},[t]),n}function Wy(){const e=fe(),t=e.status==="ready"?e.env.live:void 0;return f.useCallback(async()=>t?t.exportState():null,[t])}function zy(){const e=fe(),t=e.status==="ready"?e.env.live:void 0;return f.useCallback(async n=>t?(await t.importState(n),!0):!1,[t])}function Ky(){const e=fe(),t=e.status==="ready"?e.env.live:void 0,[n,r]=f.useState([]),s=f.useCallback(async()=>{r(t?await t.listBranches():[])},[t]);f.useEffect(()=>{s()},[s]);const i=f.useCallback(async c=>{t&&(await t.saveBranch(c),await s())},[t,s]),o=f.useCallback(async c=>{t&&await t.switchBranch(c)},[t]),l=f.useCallback(async c=>{t&&(await t.deleteBranch(c),await s())},[t,s]);return{branches:n,save:i,switchTo:o,remove:l}}function Hy(){const e=Ee(),t=e.status==="ready",[n,r]=f.useState("");return f.useEffect(()=>{if(t)return;let s=!0;return fetch("/__pyric/init.json").then(i=>i.ok?i.json():null).then(i=>{s&&i&&typeof i.rules=="string"&&r(i.rules)}).catch(()=>{}),()=>{s=!1}},[t]),f.useMemo(()=>{if(e.status!=="ready")return n;try{return Je(e.handles.sandbox).getRules()}catch{return""}},[e,n])}function Gy(e){let t=!0;return n=>{const r=t;t=!1,e(s=>Yy(s,n,r))}}function Jy(e){const t=new Map;for(const n of e)t.set(Cr(n),n);return[...t.values()]}function Yy(e,t,n){return Jy(n?t:[...e??[],...t])}const Xy=3e4;function qo(){const e=Oe(),t=fe(),[n,r]=f.useState(null),[s,i]=f.useState(!1),o=f.useRef(!1),l=f.useRef(e);l.current=e;const c=t.status==="ready"?t.env.live:void 0,u=f.useRef(c);u.current=c;const d=f.useRef(null),p=f.useRef(0),h=f.useRef(null),m=f.useRef(0),y=f.useCallback(x=>{const b=l.current;if(b.status!=="ready")return;const v=++p.current;o.current=!0,i(!0);const w=b.handles,k=w.adminFirestore,j=b.firestoreApi?.collection??qe,S=b.firestoreApi?.query??Dt,C=b.firestoreApi?.getDocs??Rt,O=b.firestoreApi?.limit??hn,I=b.storageApi?.ref??Ot,$=b.storageApi?.listAll??cs,N=b.authApi?.listUsers??he.listUsers,_={listRootCollections:()=>w.listRootCollections(),listDocumentPaths:async(A,q)=>(await C(S(j(k,A),O(q)))).docs.slice(0,q).map(R=>`${A}/${R.id}`),listSubcollections:A=>Promise.resolve(w.listSubcollections(A)),listUsers:async A=>(await Promise.resolve(N(w.auth))).slice(0,A).map(X=>({uid:X.uid,email:X.email??null})),listStorageObjectPaths:A=>Vp(I(w.storage,""),$,{maxObjects:A,maxListCalls:Nr.storageListCalls}),listRtdbTopLevelKeys:async()=>{const A=u.current;if(!A)return[];const q=Date.now()-m.current<Xy;if(h.current!==null&&q&&!x?.rtdbLikely)return h.current;const X=await A.readRtdbState(),R=X===null||typeof X!="object"||Array.isArray(X)?[]:Object.keys(X);return h.current=R,m.current=Date.now(),R}},E=Gy(A=>r(A));tm(_,Nr,A=>{v===p.current&&E(A)}).catch(()=>{}).finally(()=>{if(v===p.current&&(o.current=!1,i(!1),r(A=>A??[]),d.current)){const A=d.current;d.current=null,y(A)}})},[]),g=f.useCallback(x=>{if(l.current.status==="ready"){if(o.current){d.current={...d.current,...x};return}y(x)}},[y]);return f.useEffect(()=>{e.status==="ready"&&n===null&&!o.current&&y()},[e,n,y]),{entries:n,building:s,ensure:g}}const Qy=150;function Zy(e){return e.startsWith("/")||/rtdb/i.test(e)}function Wo({autoFocus:e,onNavigated:t,onEscape:n,exposeFocus:r}){const[s,i]=f.useState(""),[o,l]=f.useState(""),[c,u]=f.useState(0),[d,p]=f.useState(!1),h=f.useRef(null),{entries:m,building:y,ensure:g}=qo();f.useEffect(()=>{if(r)return r(()=>h.current?.focus()),()=>r(null)},[r]),f.useEffect(()=>{e&&h.current?.focus()},[e]),f.useEffect(()=>{const j=setTimeout(()=>l(s),Qy);return()=>clearTimeout(j)},[s]);const x=f.useMemo(()=>ii(o,Ke,m??[]),[o,m]),b=f.useMemo(()=>ai(x),[x]);f.useEffect(()=>{u(j=>b.length===0?0:Math.min(j,b.length-1))},[b.length]);const v=j=>{j&&(i(""),l(""),p(!1),ce(j.target),t?.(j.target))},w=()=>{if(s===o){v(b[c]??b[0]);return}const j=ai(ii(s,Ke,m??[]));v(j[0])};let k=0;return a.jsxs("div",{className:"studio-home__command",children:[a.jsx("div",{className:"studio-home__command-row",children:a.jsx("input",{ref:h,className:"studio-home__command-input",type:"text",value:s,placeholder:"Jump to a surface, collection, doc, user, or object…","aria-label":"Command input",role:"combobox","aria-expanded":d&&b.length>0,"aria-autocomplete":"list",onFocus:()=>{g(),p(!0)},onBlur:()=>p(!1),onChange:j=>{const S=j.target.value;i(S),p(!0),Zy(S)&&g({rtdbLikely:!0})},onKeyDown:j=>{if(j.key==="ArrowDown")j.preventDefault(),u(S=>Math.min(S+1,Math.max(b.length-1,0)));else if(j.key==="ArrowUp")j.preventDefault(),u(S=>Math.max(S-1,0));else if(j.key==="Enter")w();else if(j.key==="Escape"){if(n){n();return}i(""),l(""),p(!1)}}})}),d&&!x.length&&y&&m===null?a.jsx("div",{className:"studio-home__command-results",role:"status","aria-live":"polite",children:a.jsx("span",{className:"studio-home__command-group-title",children:"Indexing sandbox…"})}):null,d&&x.length?a.jsx("div",{className:"studio-home__command-results",role:"listbox","aria-label":"Suggestions",onMouseDown:j=>j.preventDefault(),children:x.map(j=>{const S=k;return k+=j.results.length,a.jsxs("div",{className:"studio-home__command-group",children:[a.jsx("span",{className:"studio-home__command-group-title","aria-hidden":"true",children:j.title}),a.jsx("ul",{className:"studio-home__command-group-list",children:j.results.map((C,O)=>{const I=S+O;return a.jsx("li",{children:a.jsxs("button",{type:"button",role:"option","aria-selected":I===c,className:"studio-home__command-result","data-active":I===c?"true":void 0,onMouseEnter:()=>u(I),onClick:()=>v(C),children:[a.jsx("span",{className:"studio-home__command-label",children:C.label}),a.jsx("span",{className:"studio-home__command-sub",children:C.hint})]})},C.id)})})]},j.kind)})}):null]})}function eb({onClose:e}){const t=f.useRef(null);return f.useEffect(()=>(t.current=document.activeElement,()=>{const n=t.current;n instanceof HTMLElement&&n.focus()}),[]),f.useEffect(()=>{const n=r=>{r.key==="Escape"&&e()};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[e]),a.jsx("div",{className:"studio__cmdk-backdrop",onMouseDown:e,children:a.jsx("div",{className:"studio__cmdk",role:"dialog","aria-modal":"true","aria-label":"Command",onMouseDown:n=>n.stopPropagation(),children:a.jsx(Wo,{autoFocus:!0,onEscape:e,onNavigated:e})})})}const tb={status:"loading",payload:null},Xt={status:"absent",payload:null};let xn=tb,_i=!1;const Ir=new Set;function Qt(e){xn=e;for(const t of Ir)t()}function nb(){if(!_i){if(_i=!0,typeof fetch>"u"){xn=Xt;return}fetch("/__pyric/init.json").then(async e=>{if(!e.ok||!(e.headers.get("content-type")??"").includes("json"))return Qt(Xt);const n=await e.json();Qt({status:"ready",payload:n})}).catch(()=>Qt(Xt))}}function rb(e){return Ir.add(e),nb(),()=>Ir.delete(e)}function Pn(){return f.useSyncExternalStore(rb,()=>xn,()=>xn)}function sb(e){return e.kind==="absent"?"absent":e.sandboxConnected?"available":"idle"}function ib(e,t){if(e!==200||typeof t!="object"||t===null)return{kind:"absent"};const n=t.sandboxConnected;return typeof n!="boolean"?{kind:"absent"}:{kind:"json",sandboxConnected:n}}async function ab(e){try{const t=await e("/__pyric/health");return t.ok?(t.headers.get("content-type")??"").includes("json")?ib(t.status,await t.json()):{kind:"absent"}:{kind:"absent"}}catch{return{kind:"absent"}}}function ob(e=5e3){const[t,n]=f.useState("checking");return f.useEffect(()=>{if(typeof fetch>"u"){n("absent");return}let r=!0,s=null;const i=async()=>{const u=sb(await ab(fetch));return r&&(n(u),u==="absent"&&s&&(clearInterval(s),s=null)),u},o=()=>typeof document>"u"||document.visibilityState!=="hidden",l=()=>{s||(s=setInterval(()=>{o()&&i()},e))},c=()=>{o()&&i()};return i().then(u=>{r&&u!=="absent"&&l()}),typeof document<"u"&&document.addEventListener("visibilitychange",c),()=>{r=!1,s&&clearInterval(s),typeof document<"u"&&document.removeEventListener("visibilitychange",c)}},[e]),t}const lb="Only pages in this browser profile, on this origin, connected to this shared sandbox worker. Other profiles, incognito windows, origins, or worker names are not visible.";function cb(e,t){const n=Math.max(0,t-e);return n<5e3?"just now":n<6e4?`${Math.floor(n/1e3)}s ago`:n<36e5?`${Math.floor(n/6e4)}m ago`:`${Math.floor(n/36e5)}h ago`}function ub(e){return e==="studio"?"Studio":"App"}function db(e,t,n=Date.now()){const r=e.clients.length,s=e.clients.map(o=>({clientId:o.clientId,kindLabel:ub(o.kind),route:o.route||"/",visibilityLabel:o.visibility==="hidden"?"Hidden":"Visible",isThisPage:o.clientId===t,freshnessLabel:cb(o.lastSeen,n)}));s.sort((o,l)=>o.isThisPage!==l.isThisPage?o.isThisPage?-1:1:o.kindLabel!==l.kindLabel?o.kindLabel==="Studio"?-1:1:o.route.localeCompare(l.route));const i=s.filter(o=>!o.isThisPage).length;return{count:r,chipLabel:r===1?"1 page connected":`${r} pages connected`,prominent:r>1,clients:s,boundaryCopy:lb,otherCount:i}}function fb(){const e=fe(),t=e.status==="ready"&&e.env.live?e.env.live:null,[n,r]=f.useState(null);return f.useEffect(()=>{if(!t){r(null);return}const s=t.presenceClientId;return t.subscribePresence(i=>{r(db(i,s))})},[t]),n}const hb={servedEpoch:null,runningEpoch:null,updateAvailable:!1,updating:!1,error:null},pb=()=>()=>{},Ei=()=>hb;function mb(){const e=fe(),t=Pn(),n=ob(),r=fb(),[s,i]=f.useState(!1),o=f.useRef(null),l=e.status==="ready"?e.env.live?.runtime:void 0,c=f.useSyncExternalStore(l?.subscribe??pb,l?.getSnapshot??Ei,l?.getSnapshot??Ei),d=t.status==="ready"&&e.status==="ready"&&!e.env.live,p=e.status==="error",h=c.error?"worker update failed":p?"backend error":d?"worker unreachable":null,m=c.error??(p?e.error.message:"Served, but the shared sandbox worker is not reachable; data views may be stale. Open Settings diagnostics."),y=n==="available";return f.useEffect(()=>{if(!s)return;const g=x=>{x.key==="Escape"&&(i(!1),o.current?.focus())};return document.addEventListener("keydown",g),()=>document.removeEventListener("keydown",g)},[s]),a.jsxs("div",{className:"studio__status","aria-label":"Studio status",children:[c.updateAvailable?a.jsxs("button",{type:"button",className:"studio-chip studio-chip--warn",disabled:c.updating,title:"The Studio backend is running older code. Update every connected page to the served worker version.",onClick:()=>void l?.update().catch(()=>{}),children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),c.updating?"updating worker…":"update worker"]}):null,h?a.jsxs("a",{className:"studio-chip studio-chip--warn",href:An({tab:"settings"}),title:m,onClick:g=>{g.preventDefault(),ce({tab:"settings"})},children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),h]}):null,r&&r.count>0?a.jsxs("span",{className:"studio-presence",children:[a.jsxs("button",{ref:o,type:"button",className:r.prominent?"studio-chip studio-chip--live studio-presence__trigger":"studio-chip studio-presence__trigger","aria-haspopup":"dialog","aria-expanded":s,"aria-controls":"studio-presence-panel",title:r.otherCount>0?`${r.chipLabel}. ${r.otherCount} other page${r.otherCount===1?"":"s"} can keep the worker alive.`:`${r.chipLabel}. Expand for details.`,onClick:()=>i(g=>!g),children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),r.chipLabel]}),s?a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"studio-presence__backdrop",onMouseDown:()=>i(!1)}),a.jsxs("div",{id:"studio-presence-panel",className:"studio-presence__panel",role:"dialog","aria-label":"Connected pages",children:[a.jsx("p",{className:"studio-presence__lead",children:r.count===1?"This page is the only connection to the shared sandbox worker.":`${r.count} pages share this sandbox worker. Closing this page alone will not restart it.`}),a.jsx("ul",{className:"studio-presence__list",children:r.clients.map(g=>a.jsxs("li",{className:"studio-presence__item",children:[a.jsxs("div",{className:"studio-presence__item-head",children:[a.jsx("span",{className:"studio-presence__kind",children:g.kindLabel}),g.isThisPage?a.jsx("span",{className:"studio-presence__this",children:"This page"}):null]}),a.jsx("div",{className:"studio-presence__route",title:g.route,children:g.route}),a.jsxs("div",{className:"studio-presence__meta",children:[g.visibilityLabel," · ",g.freshnessLabel]})]},g.clientId))}),a.jsx("p",{className:"studio-presence__boundary",children:r.boundaryCopy})]})]}):null]}):null,y?a.jsxs("span",{className:"studio-chip studio-chip--live",title:"MCP bridge available — a sandbox peer is connected; external agents can reach this sandbox.",children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),"MCP bridge"]}):null]})}function yb(e,t){const n=e.triggeredBy,r=t.triggeredBy;return!n&&!r?!0:!n||!r?!1:n.method===r.method&&n.path===r.path}function Ci(e,t,n){let r=0;for(const s of n)s.result==="deny"&&r++;return{type:"group",kind:e,key:t,events:n,count:n.length,denies:r}}function bb({events:e,groupBatches:t=!0,groupListenerRuns:n=!0}){return f.useMemo(()=>{const r=[];let s=0;for(;s<e.length;){const i=e[s];if(t&&i.groupId){let o=s+1;for(;o<e.length&&e[o].groupId===i.groupId;)o++;const l=e.slice(s,o),c=i.origin==="transaction"?"transaction":"batch";r.push(Ci(c,i.groupId,l)),s=o;continue}if(n&&i.origin==="listener"){let o=s+1;for(;o<e.length&&e[o].origin==="listener"&&!e[o].groupId&&yb(e[o],i);)o++;const l=e.slice(s,o);if(l.length>1){const c=i.triggeredBy?`${i.triggeredBy.method}:${i.triggeredBy.path}`:"unknown";r.push(Ci("listener-run",`listener-run:${c}:${s}`,l))}else r.push({type:"single",event:i});s=o;continue}r.push({type:"single",event:i}),s++}return{items:r}},[e,t,n])}const gb={buckets:[],total:0,denies:0,maxCount:0,outOfWindow:0};function vb({events:e,window:t,bucketCount:n=30}){return f.useMemo(()=>xb(e,t,n),[e,t.start,t.end,n])}function xb(e,t,n=30){const r=t.end-t.start;if(n<=0||r<=0)return gb;const s=r/n,i=new Array(n).fill(0),o=new Array(n).fill(0);let l=0,c=0,u=0;for(const h of e){const m=h.at;if(m<t.start||m>=t.end){u++;continue}let y=Math.floor((m-t.start)/s);y>=n&&(y=n-1),i[y]++,l++,h.result==="deny"&&(o[y]++,c++)}let d=0;for(const h of i)h>d&&(d=h);return{buckets:i.map((h,m)=>{const y=o[m];return{index:m,start:t.start+m*s,end:t.start+(m+1)*s,count:h,denies:y,allows:h-y,heightRatio:d===0?0:h/d,denyHeightRatio:d===0?0:y/d}}),total:l,denies:c,maxCount:d,outOfWindow:u}}const wb=new Set(["get","list"]),jb=new Set(["create","update","set"]),kb=new Set(["delete","remove"]),Sb=[{key:"reads",label:"Read ops"},{key:"writes",label:"Writes"},{key:"deletes",label:"Deletes"}],_b=[{key:"allows",label:"Allows"},{key:"denies",label:"Denies"},{key:"errors",label:"Errors"}];function On(e){return e.origin==="admin"}function Eb(e,t=On){return e.result==="allow"||t(e)?wb.has(e.method)?"reads":jb.has(e.method)?"writes":kb.has(e.method)?"deletes":null:null}function Cb(e,t=On){return t(e)?null:e.result==="allow"?"allows":e.result==="deny"?"denies":e.result==="error"?"errors":null}const Nb=e=>({points:[],series:e.map(t=>({key:t.key,label:t.label,values:[],total:0})),maxValue:0});function zo(e,t,n,r,s){const i=t.end-t.start;if(n<=0||i<=0)return Nb(r);const o=i/n,l=new Map(r.map(h=>[h.key,new Array(n).fill(0)])),c=new Map(r.map(h=>[h.key,0]));for(const h of e){const m=h.at;if(m<t.start||m>=t.end)continue;const y=s(h);if(y==null)continue;let g=Math.floor((m-t.start)/o);g>=n&&(g=n-1);const x=l.get(y);x[g]++,c.set(y,(c.get(y)??0)+1)}let u=0;for(const h of l.values())for(const m of h)m>u&&(u=m);const d=new Array(n);for(let h=0;h<n;h++)d[h]={index:h,start:t.start+h*o,end:t.start+(h+1)*o};const p=r.map(h=>({key:h.key,label:h.label,values:l.get(h.key),total:c.get(h.key)??0}));return{points:d,series:p,maxValue:u}}function Ab(e,t,n=24,r=On){return zo(e,t,n,Sb,s=>Eb(s,r))}function Rb(e,t,n=24,r=On){return zo(e,t,n,_b,s=>Cb(s,r))}function Db({events:e,window:t,bucketCount:n=24,isAdmin:r}){return f.useMemo(()=>Ab(e,t,n,r),[e,t.start,t.end,n,r])}function Ib({events:e,window:t,bucketCount:n=24,isAdmin:r}){return f.useMemo(()=>Rb(e,t,n,r),[e,t.start,t.end,n,r])}function ot({children:e,kind:t,className:n,ariaLabel:r}){return a.jsx("span",{"data-pyric-badge":"","data-pyric-badge-kind":t,className:n,"aria-label":r,children:r?a.jsx("span",{"aria-hidden":"true",children:e}):e})}function Tt(e){const t=new Date(e),n=r=>String(r).padStart(2,"0");return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function Ko({event:e,selected:t,onSelect:n,renderClassification:r,formatTime:s=Tt,className:i}){return a.jsxs("button",{type:"button",onClick:()=>n?.(e),className:i,"data-pyric-traffic-row":"","data-pyric-result":e.result,"data-pyric-origin":e.origin,"data-pyric-method":e.method,"data-pyric-selected":t?"":void 0,children:[a.jsx("span",{"data-pyric-traffic-time":"",children:s(e.at)}),a.jsx("span",{"data-pyric-traffic-service":e.service??"",children:e.service??""}),a.jsx(ot,{kind:e.method,children:e.method}),a.jsx("span",{"data-pyric-traffic-path":"",children:e.path||"/"}),r?r(e):null]})}var ds=Vc();function Ze(e,t,n){let r=n.initialDeps??[],s,i=!0;function o(){var l,c,u;let d;n.key&&((l=n.debug)!=null&&l.call(n))&&(d=Date.now());const p=e();if(!(p.length!==r.length||p.some((y,g)=>r[g]!==y)))return s;r=p;let m;if(n.key&&((c=n.debug)!=null&&c.call(n))&&(m=Date.now()),s=t(...p),n.key&&((u=n.debug)!=null&&u.call(n))){const y=Math.round((Date.now()-d)*100)/100,g=Math.round((Date.now()-m)*100)/100,x=g/16,b=(v,w)=>{for(v=String(v);v.length<w;)v=" "+v;return v};console.info(`%c⏱ ${b(g,5)} /${b(y,5)} ms`,`
104
- font-size: .6rem;
105
- font-weight: bold;
106
- color: hsl(${Math.max(0,Math.min(120-120*x,120))}deg 100% 31%);`,n?.key)}return n?.onChange&&!(i&&n.skipInitialOnChange)&&n.onChange(s),i=!1,s}return o.updateDeps=l=>{r=l},o}function Ni(e,t){if(e===void 0)throw new Error("Unexpected undefined");return e}const $b=(e,t)=>Math.abs(e-t)<1.01,Pb=(e,t,n)=>{let r;return function(...s){e.clearTimeout(r),r=e.setTimeout(()=>t.apply(this,s),n)}},Ai=e=>{const{offsetWidth:t,offsetHeight:n}=e;return{width:t,height:n}},Ob=e=>e,Ub=e=>{const t=Math.max(e.startIndex-e.overscan,0),n=Math.min(e.endIndex+e.overscan,e.count-1),r=[];for(let s=t;s<=n;s++)r.push(s);return r},Tb=(e,t)=>{const n=e.scrollElement;if(!n)return;const r=e.targetWindow;if(!r)return;const s=o=>{const{width:l,height:c}=o;t({width:Math.round(l),height:Math.round(c)})};if(s(Ai(n)),!r.ResizeObserver)return()=>{};const i=new r.ResizeObserver(o=>{const l=()=>{const c=o[0];if(c?.borderBoxSize){const u=c.borderBoxSize[0];if(u){s({width:u.inlineSize,height:u.blockSize});return}}s(Ai(n))};e.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(l):l()});return i.observe(n,{box:"border-box"}),()=>{i.unobserve(n)}},Ri={passive:!0},Di=typeof window>"u"?!0:"onscrollend"in window,Mb=(e,t)=>{const n=e.scrollElement;if(!n)return;const r=e.targetWindow;if(!r)return;let s=0;const i=e.options.useScrollendEvent&&Di?()=>{}:Pb(r,()=>{t(s,!1)},e.options.isScrollingResetDelay),o=d=>()=>{const{horizontal:p,isRtl:h}=e.options;s=p?n.scrollLeft*(h&&-1||1):n.scrollTop,i(),t(s,d)},l=o(!0),c=o(!1);n.addEventListener("scroll",l,Ri);const u=e.options.useScrollendEvent&&Di;return u&&n.addEventListener("scrollend",c,Ri),()=>{n.removeEventListener("scroll",l),u&&n.removeEventListener("scrollend",c)}},Lb=(e,t,n)=>{if(t?.borderBoxSize){const r=t.borderBoxSize[0];if(r)return Math.round(r[n.options.horizontal?"inlineSize":"blockSize"])}return e[n.options.horizontal?"offsetWidth":"offsetHeight"]},Bb=(e,{adjustments:t=0,behavior:n},r)=>{var s,i;const o=e+t;(i=(s=r.scrollElement)==null?void 0:s.scrollTo)==null||i.call(s,{[r.options.horizontal?"left":"top"]:o,behavior:n})};class Fb{constructor(t){this.unsubs=[],this.scrollElement=null,this.targetWindow=null,this.isScrolling=!1,this.scrollState=null,this.measurementsCache=[],this.itemSizeCache=new Map,this.laneAssignments=new Map,this.pendingMeasuredCacheIndexes=[],this.prevLanes=void 0,this.lanesChangedFlag=!1,this.lanesSettling=!1,this.scrollRect=null,this.scrollOffset=null,this.scrollDirection=null,this.scrollAdjustments=0,this.elementsCache=new Map,this.now=()=>{var n,r,s;return((s=(r=(n=this.targetWindow)==null?void 0:n.performance)==null?void 0:r.now)==null?void 0:s.call(r))??Date.now()},this.observer=(()=>{let n=null;const r=()=>n||(!this.targetWindow||!this.targetWindow.ResizeObserver?null:n=new this.targetWindow.ResizeObserver(s=>{s.forEach(i=>{const o=()=>{const l=i.target,c=this.indexFromElement(l);if(!l.isConnected){this.observer.unobserve(l);return}this.shouldMeasureDuringScroll(c)&&this.resizeItem(c,this.options.measureElement(l,i,this))};this.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(o):o()})}));return{disconnect:()=>{var s;(s=r())==null||s.disconnect(),n=null},observe:s=>{var i;return(i=r())==null?void 0:i.observe(s,{box:"border-box"})},unobserve:s=>{var i;return(i=r())==null?void 0:i.unobserve(s)}}})(),this.range=null,this.setOptions=n=>{Object.entries(n).forEach(([r,s])=>{typeof s>"u"&&delete n[r]}),this.options={debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:Ob,rangeExtractor:Ub,onChange:()=>{},measureElement:Lb,initialRect:{width:0,height:0},scrollMargin:0,gap:0,indexAttribute:"data-index",initialMeasurementsCache:[],lanes:1,isScrollingResetDelay:150,enabled:!0,isRtl:!1,useScrollendEvent:!1,useAnimationFrameWithResizeObserver:!1,laneAssignmentMode:"estimate",...n}},this.notify=n=>{var r,s;(s=(r=this.options).onChange)==null||s.call(r,this,n)},this.maybeNotify=Ze(()=>(this.calculateRange(),[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]),n=>{this.notify(n)},{key:!1,debug:()=>this.options.debug,initialDeps:[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]}),this.cleanup=()=>{this.unsubs.filter(Boolean).forEach(n=>n()),this.unsubs=[],this.observer.disconnect(),this.rafId!=null&&this.targetWindow&&(this.targetWindow.cancelAnimationFrame(this.rafId),this.rafId=null),this.scrollState=null,this.scrollElement=null,this.targetWindow=null},this._didMount=()=>()=>{this.cleanup()},this._willUpdate=()=>{var n;const r=this.options.enabled?this.options.getScrollElement():null;if(this.scrollElement!==r){if(this.cleanup(),!r){this.maybeNotify();return}this.scrollElement=r,this.scrollElement&&"ownerDocument"in this.scrollElement?this.targetWindow=this.scrollElement.ownerDocument.defaultView:this.targetWindow=((n=this.scrollElement)==null?void 0:n.window)??null,this.elementsCache.forEach(s=>{this.observer.observe(s)}),this.unsubs.push(this.options.observeElementRect(this,s=>{this.scrollRect=s,this.maybeNotify()})),this.unsubs.push(this.options.observeElementOffset(this,(s,i)=>{this.scrollAdjustments=0,this.scrollDirection=i?this.getScrollOffset()<s?"forward":"backward":null,this.scrollOffset=s,this.isScrolling=i,this.scrollState&&this.scheduleScrollReconcile(),this.maybeNotify()})),this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0})}},this.rafId=null,this.getSize=()=>this.options.enabled?(this.scrollRect=this.scrollRect??this.options.initialRect,this.scrollRect[this.options.horizontal?"width":"height"]):(this.scrollRect=null,0),this.getScrollOffset=()=>this.options.enabled?(this.scrollOffset=this.scrollOffset??(typeof this.options.initialOffset=="function"?this.options.initialOffset():this.options.initialOffset),this.scrollOffset):(this.scrollOffset=null,0),this.getFurthestMeasurement=(n,r)=>{const s=new Map,i=new Map;for(let o=r-1;o>=0;o--){const l=n[o];if(s.has(l.lane))continue;const c=i.get(l.lane);if(c==null||l.end>c.end?i.set(l.lane,l):l.end<c.end&&s.set(l.lane,!0),s.size===this.options.lanes)break}return i.size===this.options.lanes?Array.from(i.values()).sort((o,l)=>o.end===l.end?o.index-l.index:o.end-l.end)[0]:void 0},this.getMeasurementOptions=Ze(()=>[this.options.count,this.options.paddingStart,this.options.scrollMargin,this.options.getItemKey,this.options.enabled,this.options.lanes,this.options.laneAssignmentMode],(n,r,s,i,o,l,c)=>(this.prevLanes!==void 0&&this.prevLanes!==l&&(this.lanesChangedFlag=!0),this.prevLanes=l,this.pendingMeasuredCacheIndexes=[],{count:n,paddingStart:r,scrollMargin:s,getItemKey:i,enabled:o,lanes:l,laneAssignmentMode:c}),{key:!1}),this.getMeasurements=Ze(()=>[this.getMeasurementOptions(),this.itemSizeCache],({count:n,paddingStart:r,scrollMargin:s,getItemKey:i,enabled:o,lanes:l,laneAssignmentMode:c},u)=>{if(!o)return this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),[];if(this.laneAssignments.size>n)for(const m of this.laneAssignments.keys())m>=n&&this.laneAssignments.delete(m);this.lanesChangedFlag&&(this.lanesChangedFlag=!1,this.lanesSettling=!0,this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),this.pendingMeasuredCacheIndexes=[]),this.measurementsCache.length===0&&!this.lanesSettling&&(this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach(m=>{this.itemSizeCache.set(m.key,m.size)}));const d=this.lanesSettling?0:this.pendingMeasuredCacheIndexes.length>0?Math.min(...this.pendingMeasuredCacheIndexes):0;this.pendingMeasuredCacheIndexes=[],this.lanesSettling&&this.measurementsCache.length===n&&(this.lanesSettling=!1);const p=this.measurementsCache.slice(0,d),h=new Array(l).fill(void 0);for(let m=0;m<d;m++){const y=p[m];y&&(h[y.lane]=m)}for(let m=d;m<n;m++){const y=i(m),g=this.laneAssignments.get(m);let x,b;const v=c==="estimate"||u.has(y);if(g!==void 0&&this.options.lanes>1){x=g;const S=h[x],C=S!==void 0?p[S]:void 0;b=C?C.end+this.options.gap:r+s}else{const S=this.options.lanes===1?p[m-1]:this.getFurthestMeasurement(p,m);b=S?S.end+this.options.gap:r+s,x=S?S.lane:m%this.options.lanes,this.options.lanes>1&&v&&this.laneAssignments.set(m,x)}const w=u.get(y),k=typeof w=="number"?w:this.options.estimateSize(m),j=b+k;p[m]={index:m,start:b,size:k,end:j,key:y,lane:x},h[x]=m}return this.measurementsCache=p,p},{key:!1,debug:()=>this.options.debug}),this.calculateRange=Ze(()=>[this.getMeasurements(),this.getSize(),this.getScrollOffset(),this.options.lanes],(n,r,s,i)=>this.range=n.length>0&&r>0?Vb({measurements:n,outerSize:r,scrollOffset:s,lanes:i}):null,{key:!1,debug:()=>this.options.debug}),this.getVirtualIndexes=Ze(()=>{let n=null,r=null;const s=this.calculateRange();return s&&(n=s.startIndex,r=s.endIndex),this.maybeNotify.updateDeps([this.isScrolling,n,r]),[this.options.rangeExtractor,this.options.overscan,this.options.count,n,r]},(n,r,s,i,o)=>i===null||o===null?[]:n({startIndex:i,endIndex:o,overscan:r,count:s}),{key:!1,debug:()=>this.options.debug}),this.indexFromElement=n=>{const r=this.options.indexAttribute,s=n.getAttribute(r);return s?parseInt(s,10):(console.warn(`Missing attribute name '${r}={index}' on measured element.`),-1)},this.shouldMeasureDuringScroll=n=>{var r;if(!this.scrollState||this.scrollState.behavior!=="smooth")return!0;const s=this.scrollState.index??((r=this.getVirtualItemForOffset(this.scrollState.lastTargetOffset))==null?void 0:r.index);if(s!==void 0&&this.range){const i=Math.max(this.options.overscan,Math.ceil((this.range.endIndex-this.range.startIndex)/2)),o=Math.max(0,s-i),l=Math.min(this.options.count-1,s+i);return n>=o&&n<=l}return!0},this.measureElement=n=>{if(!n){this.elementsCache.forEach((o,l)=>{o.isConnected||(this.observer.unobserve(o),this.elementsCache.delete(l))});return}const r=this.indexFromElement(n),s=this.options.getItemKey(r),i=this.elementsCache.get(s);i!==n&&(i&&this.observer.unobserve(i),this.observer.observe(n),this.elementsCache.set(s,n)),(!this.isScrolling||this.scrollState)&&this.shouldMeasureDuringScroll(r)&&this.resizeItem(r,this.options.measureElement(n,void 0,this))},this.resizeItem=(n,r)=>{var s;const i=this.measurementsCache[n];if(!i)return;const o=this.itemSizeCache.get(i.key)??i.size,l=r-o;l!==0&&(((s=this.scrollState)==null?void 0:s.behavior)!=="smooth"&&(this.shouldAdjustScrollPositionOnItemSizeChange!==void 0?this.shouldAdjustScrollPositionOnItemSizeChange(i,l,this):i.start<this.getScrollOffset()+this.scrollAdjustments)&&this._scrollToOffset(this.getScrollOffset(),{adjustments:this.scrollAdjustments+=l,behavior:void 0}),this.pendingMeasuredCacheIndexes.push(i.index),this.itemSizeCache=new Map(this.itemSizeCache.set(i.key,r)),this.notify(!1))},this.getVirtualItems=Ze(()=>[this.getVirtualIndexes(),this.getMeasurements()],(n,r)=>{const s=[];for(let i=0,o=n.length;i<o;i++){const l=n[i],c=r[l];s.push(c)}return s},{key:!1,debug:()=>this.options.debug}),this.getVirtualItemForOffset=n=>{const r=this.getMeasurements();if(r.length!==0)return Ni(r[Ho(0,r.length-1,s=>Ni(r[s]).start,n)])},this.getMaxScrollOffset=()=>{if(!this.scrollElement)return 0;if("scrollHeight"in this.scrollElement)return this.options.horizontal?this.scrollElement.scrollWidth-this.scrollElement.clientWidth:this.scrollElement.scrollHeight-this.scrollElement.clientHeight;{const n=this.scrollElement.document.documentElement;return this.options.horizontal?n.scrollWidth-this.scrollElement.innerWidth:n.scrollHeight-this.scrollElement.innerHeight}},this.getOffsetForAlignment=(n,r,s=0)=>{if(!this.scrollElement)return 0;const i=this.getSize(),o=this.getScrollOffset();r==="auto"&&(r=n>=o+i?"end":"start"),r==="center"?n+=(s-i)/2:r==="end"&&(n-=i);const l=this.getMaxScrollOffset();return Math.max(Math.min(l,n),0)},this.getOffsetForIndex=(n,r="auto")=>{n=Math.max(0,Math.min(n,this.options.count-1));const s=this.getSize(),i=this.getScrollOffset(),o=this.measurementsCache[n];if(!o)return;if(r==="auto")if(o.end>=i+s-this.options.scrollPaddingEnd)r="end";else if(o.start<=i+this.options.scrollPaddingStart)r="start";else return[i,r];if(r==="end"&&n===this.options.count-1)return[this.getMaxScrollOffset(),r];const l=r==="end"?o.end+this.options.scrollPaddingEnd:o.start-this.options.scrollPaddingStart;return[this.getOffsetForAlignment(l,r,o.size),r]},this.scrollToOffset=(n,{align:r="start",behavior:s="auto"}={})=>{const i=this.getOffsetForAlignment(n,r),o=this.now();this.scrollState={index:null,align:r,behavior:s,startedAt:o,lastTargetOffset:i,stableFrames:0},this._scrollToOffset(i,{adjustments:void 0,behavior:s}),this.scheduleScrollReconcile()},this.scrollToIndex=(n,{align:r="auto",behavior:s="auto"}={})=>{n=Math.max(0,Math.min(n,this.options.count-1));const i=this.getOffsetForIndex(n,r);if(!i)return;const[o,l]=i,c=this.now();this.scrollState={index:n,align:l,behavior:s,startedAt:c,lastTargetOffset:o,stableFrames:0},this._scrollToOffset(o,{adjustments:void 0,behavior:s}),this.scheduleScrollReconcile()},this.scrollBy=(n,{behavior:r="auto"}={})=>{const s=this.getScrollOffset()+n,i=this.now();this.scrollState={index:null,align:"start",behavior:r,startedAt:i,lastTargetOffset:s,stableFrames:0},this._scrollToOffset(s,{adjustments:void 0,behavior:r}),this.scheduleScrollReconcile()},this.getTotalSize=()=>{var n;const r=this.getMeasurements();let s;if(r.length===0)s=this.options.paddingStart;else if(this.options.lanes===1)s=((n=r[r.length-1])==null?void 0:n.end)??0;else{const i=Array(this.options.lanes).fill(null);let o=r.length-1;for(;o>=0&&i.some(l=>l===null);){const l=r[o];i[l.lane]===null&&(i[l.lane]=l.end),o--}s=Math.max(...i.filter(l=>l!==null))}return Math.max(s-this.options.scrollMargin+this.options.paddingEnd,0)},this._scrollToOffset=(n,{adjustments:r,behavior:s})=>{this.options.scrollToFn(n,{behavior:s,adjustments:r},this)},this.measure=()=>{this.itemSizeCache=new Map,this.laneAssignments=new Map,this.notify(!1)},this.setOptions(t)}scheduleScrollReconcile(){if(!this.targetWindow){this.scrollState=null;return}this.rafId==null&&(this.rafId=this.targetWindow.requestAnimationFrame(()=>{this.rafId=null,this.reconcileScroll()}))}reconcileScroll(){if(!this.scrollState||!this.scrollElement)return;if(this.now()-this.scrollState.startedAt>5e3){this.scrollState=null;return}const r=this.scrollState.index!=null?this.getOffsetForIndex(this.scrollState.index,this.scrollState.align):void 0,s=r?r[0]:this.scrollState.lastTargetOffset,i=1,o=s!==this.scrollState.lastTargetOffset;if(!o&&$b(s,this.getScrollOffset())){if(this.scrollState.stableFrames++,this.scrollState.stableFrames>=i){this.scrollState=null;return}}else this.scrollState.stableFrames=0,o&&(this.scrollState.lastTargetOffset=s,this.scrollState.behavior="auto",this._scrollToOffset(s,{adjustments:void 0,behavior:"auto"}));this.scheduleScrollReconcile()}}const Ho=(e,t,n,r)=>{for(;e<=t;){const s=(e+t)/2|0,i=n(s);if(i<r)e=s+1;else if(i>r)t=s-1;else return s}return e>0?e-1:0};function Vb({measurements:e,outerSize:t,scrollOffset:n,lanes:r}){const s=e.length-1,i=c=>e[c].start;if(e.length<=r)return{startIndex:0,endIndex:s};let o=Ho(0,s,i,n),l=o;if(r===1)for(;l<s&&e[l].end<n+t;)l++;else if(r>1){const c=Array(r).fill(0);for(;l<s&&c.some(d=>d<n+t);){const d=e[l];c[d.lane]=d.end,l++}const u=Array(r).fill(n+t);for(;o>=0&&u.some(d=>d>=n);){const d=e[o];u[d.lane]=d.start,o--}o=Math.max(0,o-o%r),l=Math.min(s,l+(r-1-l%r))}return{startIndex:o,endIndex:l}}const Ii=typeof document<"u"?f.useLayoutEffect:f.useEffect;function qb({useFlushSync:e=!0,...t}){const n=f.useReducer(()=>({}),{})[1],r={...t,onChange:(i,o)=>{var l;e&&o?ds.flushSync(n):n(),(l=t.onChange)==null||l.call(t,i,o)}},[s]=f.useState(()=>new Fb(r));return s.setOptions(r),Ii(()=>s._didMount(),[]),Ii(()=>s._willUpdate()),s}function Wb(e){return qb({observeElementRect:Tb,observeElementOffset:Mb,scrollToFn:Bb,...e})}function fs({items:e,estimateSize:t,renderItem:n,overscan:r=5,className:s,height:i="100%",getItemKey:o}){const l=f.useRef(null),c=typeof t=="function"?t:()=>t,u=Wb({count:e.length,getScrollElement:()=>l.current,estimateSize:c,overscan:r});return a.jsx("div",{ref:l,className:s,"data-pyric-ui":"virtual-list",style:{height:i,overflowY:"auto",contain:"strict"},children:a.jsx("div",{"data-pyric-virtual-inner":!0,style:{height:`${u.getTotalSize()}px`,width:"100%",position:"relative"},children:u.getVirtualItems().map(d=>{const p=e[d.index],h=o?o(p,d.index):d.key;return a.jsx("div",{"data-pyric-virtual-row":!0,"data-index":d.index,ref:u.measureElement,style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${d.start}px)`},children:n(p,d.index)},h)})})})}const zb={batch:"batch write",transaction:"transaction","listener-run":"listener re-evals"};function Kb({group:e,defaultExpanded:t=!1,onSelect:n,selectedId:r,renderClassification:s,formatTime:i,className:o}){const[l,c]=f.useState(t);return a.jsxs("div",{className:o,"data-pyric-traffic-group":"","data-pyric-group-kind":e.kind,"data-pyric-expanded":l?"":void 0,children:[a.jsxs("button",{type:"button",onClick:()=>c(u=>!u),"data-pyric-traffic-group-header":"","data-pyric-group-kind":e.kind,"aria-expanded":l,children:[a.jsx("span",{"data-pyric-group-kind-label":"",children:zb[e.kind]}),a.jsxs("span",{"data-pyric-group-count":"",children:["×",e.count]}),e.denies>0?a.jsxs("span",{"data-pyric-group-denies":"",children:[e.denies," denied"]}):null]}),l?a.jsx("ul",{"data-pyric-traffic-group-members":"",children:e.events.map(u=>a.jsx("li",{"data-pyric-traffic-entry":"","data-pyric-traffic-id":u.id,children:a.jsx(Ko,{event:u,selected:u.id===r,onSelect:n,renderClassification:s,formatTime:i})},u.id))}):null]})}function Hb(e){return e<0?0:e>1?1:e}function tr(e,t){const n=t.end-t.start;return n<=0?0:Hb((e-t.start)/n)}function Gb({events:e,buckets:t,window:n,bucketCount:r=30,brush:s,onBrush:i,renderBucketSummary:o,liveAt:l,header:c,axis:u,emptyState:d,className:p}){const h=f.useId(),[m,y]=f.useState(null),[g,x]=f.useState(null),b=vb({events:e??[],window:n,bucketCount:r}),v=t??b,{buckets:w,total:k}=v,j=m??g,S=j===null?null:w.find(_=>_.index===j)??null,C=S!==null&&s?.start===S.start&&s.end===S.end;if(w.length===0)return a.jsx("div",{className:p,"data-pyric-ui":"traffic-timeline","data-pyric-empty":"",children:d});const O=k===0,I=l===void 0?n.end:l,$=I==null?null:tr(I,n),N=typeof u=="function"?u(n):u;return a.jsxs("div",{className:p,"data-pyric-ui":"traffic-timeline","data-pyric-empty":O?"":void 0,children:[c!==void 0&&a.jsx("div",{"data-pyric-timeline-header":"",children:c}),a.jsxs("div",{"data-pyric-timeline-chart":"",children:[a.jsx("div",{"data-pyric-timeline-bars":"",role:i?"group":"img","aria-label":"request volume over time",children:w.map(_=>a.jsx(Jb,{bucket:_,window:n,onBrush:i,onHover:o?y:void 0,onFocus:o?x:void 0,summaryId:o&&!C&&S?.index===_.index?h:void 0,selected:s?.start===_.start&&s.end===_.end},_.index))}),S&&o&&!C?a.jsx("div",{id:h,role:"tooltip","data-pyric-bucket-summary":"",style:{"--pyric-bucket-summary-x":(S.index+.5)/Math.max(w.length,1)},children:o(S)}):null,s&&a.jsx("div",{"data-pyric-brush":"","aria-hidden":"true",style:{"--pyric-brush-left":tr(s.start,n),"--pyric-brush-right":1-tr(s.end,n)}}),$!=null&&a.jsx("div",{"data-pyric-live":"","aria-hidden":"true",style:{"--pyric-live-x":$}})]}),N!=null&&a.jsx("div",{"data-pyric-timeline-axis":"",children:N})]})}function Jb({bucket:e,window:t,onBrush:n,onHover:r,onFocus:s,summaryId:i,selected:o}){const l=n!==void 0,c=`${e.count} ${e.count===1?"request":"requests"}`,u=`${e.denies} denied`;return a.jsxs("button",{type:"button","data-pyric-bucket":"","data-pyric-bucket-index":e.index,"data-pyric-bucket-count":e.count,"data-pyric-bucket-denies":e.denies,"data-pyric-has-denies":e.denies>0?"":void 0,"data-pyric-bucket-selected":o?"":void 0,disabled:!l,"aria-label":`${c}, ${u}`,"aria-describedby":i,"aria-pressed":l?o:void 0,onPointerEnter:r?()=>r(e.index):void 0,onPointerLeave:r?()=>r(null):void 0,onFocus:s?()=>s(e.index):void 0,onBlur:s?()=>s(null):void 0,onClick:l?()=>n?.({start:e.start,end:e.end}):void 0,style:{"--pyric-bucket-h":e.heightRatio,"--pyric-bucket-deny-h":e.denyHeightRatio},children:[a.jsx("span",{"data-pyric-bucket-allow":"","aria-hidden":"true"}),a.jsx("span",{"data-pyric-bucket-deny":"","aria-hidden":"true"})]})}const Yb=e=>String(e);function Xb({series:e,visible:t,onToggle:n,formatValue:r=Yb,className:s}){const i=t!==void 0&&n!==void 0;return a.jsx("div",{className:s,"data-pyric-ui":"traffic-metric-cards",role:i?"group":void 0,children:e.map((o,l)=>{const c=t?t.has(o.key):!0,u=a.jsxs(a.Fragment,{children:[a.jsx("span",{"data-pyric-metric-swatch":"","aria-hidden":"true"}),a.jsx("span",{"data-pyric-metric-label":"",children:o.label}),a.jsx("span",{"data-pyric-metric-value":"",children:r(o.total)})]});return i?a.jsxs("label",{"data-pyric-metric-card":"","data-pyric-metric-key":o.key,"data-pyric-series-index":l,"data-pyric-metric-hidden":c?void 0:"",children:[a.jsx("input",{type:"checkbox",checked:c,onChange:()=>n(o.key),"data-pyric-metric-checkbox":""}),u]},o.key):a.jsx("span",{"data-pyric-metric-card":"","data-pyric-metric-key":o.key,"data-pyric-series-index":l,children:u},o.key)})})}const Qb=e=>String(e),Zb=e=>new Date(e).toLocaleTimeString();function eg({points:e,series:t,visible:n,omitZeroSeries:r=!1,formatValue:s=Qb,formatTime:i=Zb,emptyState:o,className:l}){const[c,u]=f.useState(null);if(e.length===0)return a.jsx("div",{className:l,"data-pyric-ui":"traffic-line-chart","data-pyric-empty":"",children:o});const d=t.filter(b=>(!n||n.has(b.key))&&(!r||b.total>0));let p=0;for(const b of d)for(const v of b.values)v>p&&(p=v);const h=p===0?1:p,m=e.length,y=b=>m===1?50:b/(m-1)*100,g=b=>100-b/h*100,x=c!=null?e[c]:null;return a.jsx("div",{className:l,"data-pyric-ui":"traffic-line-chart",children:a.jsxs("div",{"data-pyric-chart-svg":"",children:[a.jsx("svg",{viewBox:"0 0 100 100",preserveAspectRatio:"none",role:"img","aria-label":"metrics over time",children:t.map(b=>{const v=t.indexOf(b);if(!((!n||n.has(b.key))&&(!r||b.total>0)))return null;const k=b.values.map((j,S)=>`${S===0?"M":"L"}${y(S)},${g(j)}`).join(" ");return a.jsx("path",{"data-pyric-chart-line":"","data-pyric-series-key":b.key,"data-pyric-series-index":v,d:k,fill:"none",vectorEffect:"non-scaling-stroke"},b.key)})}),a.jsx("div",{"data-pyric-chart-hits":"",children:e.map((b,v)=>a.jsx("button",{type:"button","data-pyric-chart-hit":"","data-pyric-point-index":v,onMouseEnter:()=>u(v),onFocus:()=>u(v),onMouseLeave:()=>u(w=>w===v?null:w),onBlur:()=>u(w=>w===v?null:w),"aria-label":`${i(b.start)} to ${i(b.end)}`},b.index))}),x&&a.jsxs("div",{"data-pyric-chart-tooltip":"",style:{"--pyric-hover-x":y(x.index)},children:[a.jsxs("div",{"data-pyric-tooltip-time":"",children:[i(x.start)," – ",i(x.end)]}),d.map(b=>a.jsxs("div",{"data-pyric-tooltip-row":"","data-pyric-series-key":b.key,"data-pyric-series-index":t.indexOf(b),children:[a.jsx("span",{"data-pyric-tooltip-label":"",children:b.label}),a.jsx("span",{"data-pyric-tooltip-value":"",children:s(b.values[x.index])})]},b.key))]})]})})}const tg={listUsers:he.listUsers,subscribeUsers:he.subscribeUsers,createUser:he.createUser,updateUser:he.updateUser,deleteUser:he.deleteUser,clearUsers:he.clearUsers,getAuthProviderConfig:he.getAuthProviderConfig,setAuthProviderConfig:he.setAuthProviderConfig,subscribeAuthProviderConfig:he.subscribeAuthProviderConfig},Go=f.createContext(tg);function ng(){return f.useContext(Go)}function Jo({value:e,children:t}){return f.createElement(Go.Provider,{value:e},t)}function rg(e,t){return[e.uid,e.email,e.displayName,e.phoneNumber].some(n=>n!=null&&n.toLowerCase().includes(t))}function hs(e){const{listUsers:t,subscribeUsers:n,createUser:r,updateUser:s,deleteUser:i,clearUsers:o}=ng(),[l,c]=f.useState([]),[u,d]=f.useState(!0),[p,h]=f.useState(void 0),[m,y]=f.useState("");f.useEffect(()=>{let j=!1;d(!0),h(void 0);const S=$=>{j||(c($),d(!1))},C=$=>{j||(c([]),h($ instanceof Error?$:new Error(String($))),d(!1))},O=()=>{try{const $=t(e);$&&typeof $.then=="function"?$.then(S).catch(C):S($)}catch($){C($)}};let I;try{O(),I=n(e,O)}catch($){C($)}return()=>{j=!0,I?.()}},[e,t,n]);const g=f.useMemo(()=>{const j=m.trim().toLowerCase();return j?l.filter(S=>rg(S,j)):l},[l,m]),x=f.useCallback(j=>r(e,j),[e,r]),b=f.useCallback((j,S)=>s(e,j,S),[e,s]),v=f.useCallback(j=>i(e,j),[e,i]),w=f.useCallback(()=>o(e),[e,o]),k=f.useCallback(()=>{const j=t(e);j&&typeof j.then=="function"?j.then(S=>c(S)).catch(()=>{}):c(j)},[e,t]);return{users:g,totalCount:l.length,isLoading:u,error:p,filter:m,setFilter:y,createUser:x,updateUser:b,deleteUser:v,clearUsers:w,refresh:k}}const sg=["iss","aud","sub","iat","exp","nbf","jti","nonce","azp","acr","amr","cnf","auth_time","firebase","at_hash","c_hash"],ig=1e3;function Yo(e){const t=e.trim();if(!t)return{ok:!0,claims:void 0};if(t.length>ig)return{ok:!1,message:"Custom claims length must not exceed 1000 characters"};let n;try{n=JSON.parse(t)}catch{return{ok:!1,message:"Custom claims must be a valid JSON object"}}if(typeof n!="object"||n===null||Array.isArray(n))return{ok:!1,message:"Custom claims must be a valid JSON object"};for(const r of sg)if(r in n)return{ok:!1,message:`Custom claims must not have forbidden key: ${r}`};return{ok:!0,claims:n}}const ag={email:"",password:"",displayName:"",phoneNumber:"",photoUrl:"",emailVerified:!1,disabled:!1,claimsText:"",providerIds:[]},og=new Set(["password","anonymous","phone"]),lg=/^[^@]+@[^@]+\.[^@]+$/,$i=6;function cg(e){return e?{email:e.email??"",password:"",displayName:e.displayName??"",phoneNumber:e.phoneNumber??"",photoUrl:e.photoUrl??"",emailVerified:e.emailVerified,disabled:e.disabled,claimsText:Object.keys(e.customClaims).length?JSON.stringify(e.customClaims,null,2):"",providerIds:e.providerUserInfo.map(t=>t.providerId).filter(t=>!og.has(t))}:{...ag}}function ug(e){const t=cg(e);return{fields:t,initial:{...t}}}function dg(e,t){switch(t.type){case"setField":return{...e,fields:{...e.fields,[t.field]:t.value}};case"reset":return{...e,fields:{...e.initial}}}}function fg(e){const t={},n=e.email.trim(),r=e.password;n&&!lg.test(n)&&(t.email="Invalid email"),r&&r.length<$i&&(t.password=`Password should be at least ${$i} characters`),r&&!n&&(t.password="Email is required for password authentication");const s=Yo(e.claimsText);return s.ok||(t.claims=s.message),t}function hg(e){const{fields:t,initial:n}=e;return Object.keys(t).some(r=>r==="providerIds"?!Xo(t.providerIds,n.providerIds):t[r]!==n[r])}function Xo(e,t){if(e.length!==t.length)return!1;const n=[...t].sort();return[...e].sort().every((r,s)=>r===n[s])}function Qo(e){const t=Yo(e.claimsText);return t.ok?t.claims:void 0}function pg(e){const t=e.fields,n={emailVerified:t.emailVerified,disabled:t.disabled};t.email.trim()&&(n.email=t.email.trim()),t.password&&(n.password=t.password),t.displayName.trim()&&(n.displayName=t.displayName.trim()),t.phoneNumber.trim()&&(n.phoneNumber=t.phoneNumber.trim()),t.photoUrl.trim()&&(n.photoUrl=t.photoUrl.trim());const r=Qo(t);return r&&(n.customClaims=r),t.providerIds.length&&(n.providerUserInfo=t.providerIds.map(s=>({providerId:s}))),n}function mg(e){const{fields:t,initial:n}=e,r={};return t.email.trim()!==n.email&&t.email.trim()&&(r.email=t.email.trim()),t.password&&t.password!==n.password&&(r.password=t.password),t.displayName.trim()!==n.displayName&&(r.displayName=t.displayName.trim()||null),t.emailVerified!==n.emailVerified&&(r.emailVerified=t.emailVerified),t.disabled!==n.disabled&&(r.disabled=t.disabled),t.claimsText!==n.claimsText&&(r.customClaims=Qo(t)??{}),Xo(t.providerIds,n.providerIds)||(r.providerUserInfo=t.providerIds.map(s=>({providerId:s}))),r}function Zo(e={}){const[t,n]=f.useReducer(dg,e.initial,ug),r=f.useMemo(()=>fg(t.fields),[t.fields]),s=f.useMemo(()=>hg(t),[t]),i=f.useCallback((l,c)=>n({type:"setField",field:l,value:c}),[]),o=f.useCallback(()=>n({type:"reset"}),[]);return{fields:t.fields,errors:r,isDirty:s,isValid:Object.keys(r).length===0,setField:i,reset:o,toCreateRequest:()=>pg(t),toUpdateRequest:()=>mg(t),dispatch:n}}const yg={"google.com":"Google","apple.com":"Apple","gc.apple.com":"Game Center","facebook.com":"Facebook","github.com":"GitHub","microsoft.com":"Microsoft","playgames.google.com":"Play Games","twitter.com":"Twitter","yahoo.com":"Yahoo",password:"Email/Password",phone:"Phone",anonymous:"Anonymous",oidc:"OIDC",saml:"SAML"};function wn(e){return yg[e]??e}function Pi(e){return e.email??e.phoneNumber??(e.isAnonymous?"anonymous":e.uid)}function bg(e){return e.isAnonymous&&e.providerUserInfo.length===0?a.jsx("span",{"data-pyric-provider-id":"anonymous",children:wn("anonymous")}):e.providerUserInfo.map(t=>a.jsx("span",{"data-pyric-provider-id":t.providerId,children:wn(t.providerId)},t.providerId))}function Oi(e){if(!e)return"—";const t=new Date(e);return Number.isNaN(t.getTime())?"—":t.toLocaleDateString()}function el({users:e,isLoading:t,error:n,filter:r,onSelect:s,renderIdentifier:i,renderProviders:o,renderSelection:l,renderSelectionHeader:c,renderActions:u,renderActionsHeader:d,formatCreatedAt:p=Oi,formatLastLoginAt:h=Oi,emptyState:m,noResultsState:y,className:g,virtualizeThreshold:x=100,rowHeight:b=44,virtualizedHeight:v="60vh"}){if(n)return a.jsx("div",{className:g,"data-pyric-ui":"auth-user-list","data-pyric-error":"",role:"alert",children:n.message});if(t&&e.length===0)return a.jsx("div",{className:g,"data-pyric-ui":"auth-user-list","data-pyric-loading":""});if(e.length===0){const j=!!r?.trim();return a.jsx("div",{className:g,"data-pyric-ui":"auth-user-list","data-pyric-empty":"","data-pyric-no-results":j?"":void 0,children:j?y??"No results":m??"No users for this project yet"})}const w=e.length>x,k=j=>a.jsxs("div",{role:"row","data-pyric-user-entry":!0,"data-pyric-user-uid":j.uid,"data-pyric-user-disabled":j.disabled?"":void 0,children:[l?a.jsx("span",{role:"cell","data-pyric-user-cell":"selection",children:l(j)}):null,a.jsx("span",{role:"cell","data-pyric-user-cell":"identifier",children:s?a.jsx("button",{type:"button","data-pyric-user-select":!0,onClick:()=>s(j),children:i?i(j):Pi(j)}):(i??Pi)(j)}),a.jsx("span",{role:"cell","data-pyric-user-cell":"providers",children:(o??bg)(j)}),a.jsx("span",{role:"cell","data-pyric-user-cell":"created",children:p(j.createdAt)}),a.jsx("span",{role:"cell","data-pyric-user-cell":"signed-in",children:h(j.lastLoginAt)}),a.jsx("span",{role:"cell","data-pyric-user-cell":"uid",children:j.uid}),u?a.jsx("span",{role:"cell","data-pyric-user-cell":"actions",children:u(j)}):null]},j.uid);return a.jsxs("div",{className:g,role:"table","aria-label":"Authentication users","data-pyric-ui":"auth-user-list","data-pyric-virtualized":w?"":void 0,"data-pyric-selection":l?"":void 0,"data-pyric-actions":u?"":void 0,children:[a.jsxs("div",{role:"row","data-pyric-user-header":!0,children:[l?a.jsx("span",{role:"columnheader","data-pyric-user-cell":"selection","aria-label":"Selection",children:c}):null,a.jsx("span",{role:"columnheader","data-pyric-user-cell":"identifier",children:"Identifier"}),a.jsx("span",{role:"columnheader","data-pyric-user-cell":"providers",children:"Provider"}),a.jsx("span",{role:"columnheader","data-pyric-user-cell":"created",children:"Created"}),a.jsx("span",{role:"columnheader","data-pyric-user-cell":"signed-in",children:"Signed In"}),a.jsx("span",{role:"columnheader","data-pyric-user-cell":"uid",children:"User UID"}),u?a.jsx("span",{role:"columnheader","data-pyric-user-cell":"actions","aria-label":"Actions",children:d}):null]}),w?a.jsx(fs,{items:e,estimateSize:b,height:v,getItemKey:j=>j.uid,renderItem:k}):a.jsx("div",{role:"rowgroup","data-pyric-user-rows":!0,children:e.map(k)})]})}function gg({value:e,onChange:t,error:n,hint:r,placeholder:s='{"role":"admin"}',className:i}){return a.jsxs("div",{className:i,"data-pyric-ui":"claims-field",children:[a.jsx("textarea",{"data-pyric-field":"claims","data-pyric-claims-invalid":n!=null?"":void 0,"aria-label":"Custom claims (optional)","aria-invalid":n!=null||void 0,placeholder:s,value:e,onChange:o=>t(o.target.value)}),n!=null&&a.jsx("p",{role:"alert","data-pyric-claims-error":!0,children:n}),r!=null&&a.jsx("p",{"data-pyric-claims-hint":!0,children:r})]})}function vg({selected:e,onChange:t}){return a.jsx("div",{"data-pyric-provider-checklist":!0,children:Co.map(n=>a.jsxs("label",{"data-pyric-provider-option":n,children:[a.jsx("input",{type:"checkbox",checked:e.includes(n),onChange:r=>t(r.target.checked?[...e,n]:e.filter(s=>s!==n))}),a.jsx("span",{"data-pyric-provider-option-label":!0,children:wn(n)}),a.jsx("span",{"data-pyric-provider-option-id":!0,children:n})]},n))})}function tl({initial:e,onSubmit:t,onCancel:n,submitLabel:r="Save",cancelLabel:s="Cancel",children:i,className:o,renderField:l}){const c=Zo({initial:e}),u=e?"edit":"create",d=c.isValid&&(u==="create"||c.isDirty),p=(y,g,x,b,v=null)=>({name:y,label:g,input:b,error:v,kind:x,defaultRender:()=>x==="checkbox"?a.jsxs("label",{"data-pyric-field-label":y,children:[b,a.jsx("span",{"data-pyric-label-text":!0,children:g})]},y):x==="group"?a.jsxs("fieldset",{"data-pyric-field-label":y,children:[a.jsx("legend",{"data-pyric-label-text":!0,children:g}),b]},y):a.jsxs("label",{"data-pyric-field-label":y,children:[a.jsx("span",{"data-pyric-label-text":!0,children:g}),b,v!=null&&a.jsx("p",{role:"alert","data-pyric-field-error":y,children:v})]},y)}),h=[p("email","Email","text",a.jsx("input",{type:"email","data-pyric-field":"email",placeholder:"email@example.com",value:c.fields.email,onChange:y=>c.setField("email",y.target.value)}),c.errors.email??null),p("password","Password","text",a.jsx("input",{type:"password","data-pyric-field":"password",placeholder:u==="edit"?"New password (unchanged if empty)":"Password",value:c.fields.password,onChange:y=>c.setField("password",y.target.value)}),c.errors.password??null),p("display-name","Display name","text",a.jsx("input",{type:"text","data-pyric-field":"display-name",placeholder:"Display name (optional)",value:c.fields.displayName,onChange:y=>c.setField("displayName",y.target.value)})),p("phone-number","Phone number","text",a.jsx("input",{type:"tel","data-pyric-field":"phone-number",placeholder:"+1 555 555 0100",value:c.fields.phoneNumber,onChange:y=>c.setField("phoneNumber",y.target.value)})),p("photo-url","Photo URL","text",a.jsx("input",{type:"url","data-pyric-field":"photo-url",placeholder:"https://example.com/avatar.png",value:c.fields.photoUrl,onChange:y=>c.setField("photoUrl",y.target.value)})),...u==="create"?[p("providers","Sign-in providers","group",a.jsx(vg,{selected:c.fields.providerIds,onChange:y=>c.setField("providerIds",y)}))]:[],p("email-verified","Verified email","checkbox",a.jsx("input",{type:"checkbox","data-pyric-field":"email-verified",checked:c.fields.emailVerified,onChange:y=>c.setField("emailVerified",y.target.checked)})),p("disabled","Disabled (sign-in attempts are rejected)","checkbox",a.jsx("input",{type:"checkbox","data-pyric-field":"disabled",checked:c.fields.disabled,onChange:y=>c.setField("disabled",y.target.checked)}))],m=y=>{y.preventDefault(),d&&t(u==="edit"?{mode:u,uid:e.uid,request:c.toUpdateRequest()}:{mode:u,request:c.toCreateRequest()})};return a.jsxs("form",{className:o,"data-pyric-ui":"auth-user-form","data-pyric-mode":u,"data-pyric-is-dirty":c.isDirty?"":void 0,"data-pyric-is-valid":c.isValid?"":void 0,onSubmit:m,children:[h.map(y=>l?a.jsx(f.Fragment,{children:l(y)},y.name):y.defaultRender()),a.jsx(gg,{value:c.fields.claimsText,onChange:y=>c.setField("claimsText",y),error:c.errors.claims}),i,a.jsxs("footer",{"data-pyric-form-actions":!0,children:[n?a.jsx("button",{type:"button","data-pyric-cancel":!0,onClick:n,children:s}):null,a.jsx("button",{type:"submit","data-pyric-submit":!0,disabled:!d,children:r})]})]})}function xg({open:e,onOpenChange:t,title:n,body:r,destructive:s,confirmLabel:i="Confirm",cancelLabel:o="Cancel",onConfirm:l,className:c}){const u=f.useRef(null),d=f.useRef(null);return f.useEffect(()=>{if(!e)return;const p=h=>{h.key==="Escape"&&(h.stopPropagation(),t(!1))};return window.addEventListener("keydown",p),()=>window.removeEventListener("keydown",p)},[e,t]),f.useEffect(()=>{if(e)return d.current=document.activeElement,u.current?.focus(),()=>{d.current?.focus?.()}},[e]),!e||typeof document>"u"?null:ds.createPortal(a.jsxs("div",{role:"presentation","data-pyric-ui":"confirm-portal",onClick:p=>{p.target===p.currentTarget&&t(!1)},children:[a.jsx("div",{"data-pyric-ui":"confirm-overlay","aria-hidden":"true"}),a.jsxs("div",{role:"dialog","aria-modal":"true","aria-labelledby":"pyric-confirm-title","aria-describedby":r?"pyric-confirm-body":void 0,className:c,"data-pyric-ui":"confirm-dialog","data-pyric-destructive":s?"":void 0,children:[a.jsx("div",{id:"pyric-confirm-title","data-pyric-confirm-title":!0,children:n}),r?a.jsx("div",{id:"pyric-confirm-body","data-pyric-confirm-body":!0,children:r}):null,a.jsxs("div",{"data-pyric-confirm-actions":!0,children:[a.jsx("button",{type:"button","data-pyric-confirm-cancel":!0,onClick:()=>t(!1),children:o}),a.jsx("button",{ref:u,type:"button","data-pyric-confirm-confirm":!0,"data-pyric-destructive":s?"":void 0,onClick:l,children:i})]})]})]}),document.body)}const nl=f.createContext(null);function vt(){const e=f.useContext(nl);if(!e)throw new Error("useConfirm: missing <ConfirmProvider> ancestor");return e}function ps({children:e,dialogClassName:t}){const[n,r]=f.useState(null),s=f.useRef(!1),i=f.useCallback(u=>new Promise(d=>{s.current=!1,r({options:u,resolve:d})}),[]),o=f.useCallback(()=>{n&&(s.current||(s.current=!0,n.resolve(!0),r(null)))},[n]),l=f.useCallback(u=>{u||n&&(s.current||(s.current=!0,n.resolve(!1),r(null)))},[n]),c=f.useMemo(()=>i,[i]);return a.jsxs(nl.Provider,{value:c,children:[e,n?a.jsx(xg,{open:!0,onOpenChange:l,title:n.options.title,body:n.options.body,destructive:n.options.destructive,confirmLabel:n.options.confirmLabel,cancelLabel:n.options.cancelLabel,onConfirm:o,className:t}):null]})}function wg(e){return e.email??e.phoneNumber??e.displayName??e.uid}function jg({user:e,onDelete:t,title:n="Delete user",body:r,confirmLabel:s="Delete",renderTrigger:i,className:o}){const l=vt(),c=async()=>{await l({title:n,body:r??`This will permanently delete ${wg(e)}.`,destructive:!0,confirmLabel:s})&&t(e.uid)};return i?a.jsx(a.Fragment,{children:i({onClick:c})}):a.jsx("button",{type:"button",className:o,"data-pyric-ui":"delete-user","data-pyric-destructive":!0,onClick:c,children:"Delete user"})}function kg(e){if(e instanceof Error)return e;if(typeof e=="string")return new Error(e);if(e&&typeof e=="object"){const t=e,n=typeof t.message=="string"?t.message:null,r=typeof t.code=="string"?t.code:null;if(n&&r)return new Error(`[${r}] ${n}`);if(n)return new Error(n);if(r)return new Error(r);try{return new Error(JSON.stringify(e))}catch{return new Error(Object.prototype.toString.call(e))}}return new Error(String(e))}const Sg={addDoc:Hr,collection:qe,deleteDoc:un,doc:pe,getDoc:Jr,getDocs:Rt,limit:hn,onSnapshot:Ru,query:Dt,setDoc:At,startAfter:Au},rl=f.createContext(Sg);function ms(){return f.useContext(rl)}function _g({value:e,children:t}){return f.createElement(rl.Provider,{value:e},t)}function Eg(e){const{onSnapshot:t}=ms(),[n,r]=f.useState(()=>({data:void 0,error:void 0,isLoading:e!=null}));return f.useEffect(()=>{if(!e){r({data:void 0,error:void 0,isLoading:!1});return}return r(i=>({data:i.data,error:void 0,isLoading:!0})),t(e,i=>r({data:i,error:void 0,isLoading:!1}),i=>r({data:void 0,error:kg(i),isLoading:!1}))},[t,e]),n}function Un(e){return e==null?"null":typeof e=="string"?"string":typeof e=="number"?"number":typeof e=="boolean"?"boolean":typeof e=="object"&&Ye(e)!==null?"vector":Array.isArray(e)?"array":e instanceof mt?"timestamp":e instanceof lt?"geopoint":e instanceof _n?"bytes":typeof e=="object"&&sl(e)?"timestamp":typeof e=="object"&&il(e)?"geopoint":typeof e=="object"&&Cg(e)?"reference":typeof e=="object"?"map":"null"}function sl(e){const t=e;return Object.keys(t).length!==2?!1:typeof t.seconds=="number"&&typeof t.nanoseconds=="number"||typeof t._seconds=="number"&&typeof t._nanoseconds=="number"}function il(e){const t=e;return Object.keys(t).length===2&&typeof t.latitude=="number"&&typeof t.longitude=="number"}function Cg(e){const t=e;if(typeof t.path!="string"||typeof t.id!="string")return!1;const n=typeof t.firestore=="object"&&t.firestore!==null,r=typeof t.env=="object"&&t.env!==null,s=t.type==="document";return n||r||s}function Ye(e){if(e===null||typeof e!="object")return null;const t=e;if(t.typeName==="vector"&&Zt(t.value)||t.__type__==="__vector__"&&Zt(t.value))return en(t.value);if(Zt(t._values))return en(t._values);if(typeof t.toArray=="function")try{const n=t.toArray();if(Zt(n))return en(n)}catch{}return null}function Zt(e){return Array.isArray(e)&&e.every(t=>typeof t=="number")}function en(e){const t=e.slice();return{values:t,dimension:t.length}}const Ui=4;function al(e){const t=e.values.slice(0,Ui).join(", "),n=e.values.length>Ui?", …":"";return`vector · ${e.dimension} [${t}${n}]`}function ft(e){const t=Ye(e);if(t)return al(t);if(Array.isArray(e))return e.map(ft);if(e&&typeof e=="object"){const n=Object.getPrototypeOf(e);if(n===Object.prototype||n===null){const r={};for(const[s,i]of Object.entries(e))r[s]=ft(i);return r}}return e}function ol(){return crypto.randomUUID()}function Ng(e){const t=ol(),n={rootId:t,nodes:{[t]:{id:t,parentId:null,key:null,type:"map",value:void 0}},childIds:{[t]:[]}};for(const[r,s]of Object.entries(e))$r(n,t,r,s);return n}function $r(e,t,n,r){const s=Un(r),i=ol(),o={id:i,parentId:t,key:n,type:s,value:Ag(s)?void 0:r};if(e.nodes[i]=o,e.childIds[i]=[],e.childIds[t].push(i),s==="map"&&r&&typeof r=="object")for(const[l,c]of Object.entries(r))$r(e,i,l,c);else if(s==="array"&&Array.isArray(r))for(const l of r)$r(e,i,null,l);return i}function Ag(e){return e==="map"||e==="array"}function ll(e){const t=e.nodes[e.rootId];if(!t||t.type!=="map")throw new Error("treeToData: tree root must be a map node");return Pr(e,e.rootId)}function Pr(e,t){const n=e.nodes[t];if(!n)throw new Error(`serializeNode: missing node ${t}`);switch(n.type){case"map":{const r={};for(const s of e.childIds[t]??[]){const i=e.nodes[s];i&&i.key!=null&&(r[i.key]=Pr(e,s))}return r}case"array":{const r=[];for(const s of e.childIds[t]??[])r.push(Pr(e,s));return r}default:return n.value}}function Or(e){const t={};for(const[r,s]of Object.entries(e.nodes))t[r]={...s};const n={};for(const[r,s]of Object.entries(e.childIds))n[r]=[...s];return{rootId:e.rootId,nodes:t,childIds:n}}function cl(e,t){const n=[t],r=[t];for(;r.length;){const s=r.shift();for(const i of e.childIds[s]??[])n.push(i),r.push(i)}return n}function ul(e,t){switch(e){case"string":return typeof t=="string"?void 0:"Expected a string";case"number":return typeof t!="number"?"Expected a number":Number.isFinite(t)?void 0:"Number must be finite";case"boolean":return typeof t=="boolean"?void 0:"Expected a boolean";case"null":return t==null?void 0:"Expected null";case"timestamp":return t instanceof mt?void 0:"Expected a Timestamp";case"geopoint":return t instanceof lt?t.latitude<-90||t.latitude>90?"Latitude must be between -90 and 90":t.longitude<-180||t.longitude>180?"Longitude must be between -180 and 180":void 0:"Expected a GeoPoint";case"reference":if(t===null||typeof t!="object")return"Expected a DocumentReference";const n=t;return typeof n.path!="string"?"Reference missing `path`":n.path?n.path.split("/").filter(Boolean).length%2!==0?"Reference path must have an even segment count":void 0:"Reference path is empty";case"bytes":return t instanceof _n?void 0:"Expected a Bytes value";case"vector":return Ye(t)!==null?void 0:"Expected a vector value";case"map":case"array":return}}function dl(e){const t={};let n=0;for(const[r,s]of Object.entries(e.nodes))t[r]={...s,error:void 0};for(const r of Object.values(t)){if(r.type==="map"||r.type==="array")continue;const s=ul(r.type,r.value);s&&(t[r.id].error=s,n++)}for(const[r,s]of Object.entries(t)){if(s.type!=="map")continue;const i=e.childIds[r]??[],o=new Map;for(const l of i){const c=t[l];if(!c)continue;const u=c.key??"";u||(c.error||n++,t[l].error=t[l].error??"Field name is required");const d=o.get(u)??[];d.push(l),o.set(u,d)}for(const[l,c]of o)if(l&&c.length>1)for(const u of c)t[u].error||n++,t[u].error=t[u].error??"Field name must be unique"}return{tree:{rootId:e.rootId,nodes:t,childIds:e.childIds},errorCount:n}}function ys(e){switch(e){case"string":return"";case"number":return 0;case"boolean":return!1;case"null":return null;case"timestamp":return mt.now();case"geopoint":return new lt(0,0);case"reference":return{path:"",id:"",firestore:{}};case"bytes":return _n.fromUint8Array(new Uint8Array);case"vector":return{__type__:"__vector__",value:[]};case"map":case"array":return}}function Ur(e){if(e===null||typeof e!="object"||Ye(e)!==null)return e;if(sl(e)){const n=e;return new mt(n.seconds??n._seconds??0,n.nanoseconds??n._nanoseconds??0)}if(il(e)){const n=e;return new lt(n.latitude,n.longitude)}if(Array.isArray(e))return e.map(Ur);const t=Object.getPrototypeOf(e);if(t===Object.prototype||t===null){const n={};for(const[r,s]of Object.entries(e))n[r]=Ur(s);return n}return e}function fl(e){const t=Ng(Ur(e)),{tree:n,errorCount:r}=dl(t);return{tree:n,initial:n,errorCount:r}}function Rg(e,t){switch(t.type){case"setValue":return et(e,n=>Ig(n,t.nodeId,t.value));case"setType":return et(e,n=>$g(n,t.nodeId,t.newType));case"setKey":return et(e,n=>Pg(n,t.nodeId,t.key));case"addMapEntry":return et(e,n=>Og(n,t.parentId,t.key,t.childType));case"addArrayEntry":return et(e,n=>Ug(n,t.parentId,t.childType));case"remove":return et(e,n=>Tg(n,t.nodeId));case"reset":return{tree:e.initial,initial:e.initial,errorCount:Dg(e.initial)};case"replaceData":return fl(t.data);case"touch":{const n=e.tree.nodes[t.nodeId];if(!n||n.touched)return e;const r=Or(e.tree);return r.nodes[t.nodeId]={...r.nodes[t.nodeId],touched:!0},{...e,tree:r}}case"touchAll":{const n=Or(e.tree);for(const r of Object.keys(n.nodes))n.nodes[r]={...n.nodes[r],touched:!0};return{...e,tree:n}}}}function et(e,t){const n=t(Or(e.tree)),{tree:r,errorCount:s}=dl(n);return{...e,tree:r,errorCount:s}}function Dg(e){let t=0;for(const n of Object.values(e.nodes))n.error&&t++;return t}function Ig(e,t,n){const r=e.nodes[t];return!r||r.type==="map"||r.type==="array"||(e.nodes[t]={...r,value:n}),e}function $g(e,t,n){const r=e.nodes[t];if(!r||r.id===e.rootId&&n!=="map"||r.type===n)return e;if(r.type==="map"||r.type==="array"){const i=(e.childIds[t]??[]).slice();for(const o of i)for(const l of cl(e,o))delete e.nodes[l],delete e.childIds[l];e.childIds[t]=[]}const s=n==="map"||n==="array"?void 0:ys(n);return e.nodes[t]={...r,type:n,value:s},e}function Pg(e,t,n){const r=e.nodes[t];if(!r||r.parentId==null)return e;const s=e.nodes[r.parentId];return!s||s.type!=="map"||(e.nodes[t]={...r,key:n}),e}function Og(e,t,n,r){const s=e.nodes[t];if(!s||s.type!=="map")return e;const i=crypto.randomUUID(),o=r==="map"||r==="array"?void 0:ys(r);return e.nodes[i]={id:i,parentId:t,key:n,type:r,value:o},e.childIds[i]=[],e.childIds[t]=[...e.childIds[t]??[],i],e}function Ug(e,t,n){const r=e.nodes[t];if(!r||r.type!=="array"||n==="array")return e;const s=crypto.randomUUID(),i=n==="map"?void 0:ys(n);return e.nodes[s]={id:s,parentId:t,key:null,type:n,value:i},e.childIds[s]=[],e.childIds[t]=[...e.childIds[t]??[],s],e}function Tg(e,t){const n=e.nodes[t];if(!n||n.id===e.rootId)return e;const r=cl(e,t);for(const s of r)delete e.nodes[s],delete e.childIds[s];return n.parentId!=null&&(e.childIds[n.parentId]=(e.childIds[n.parentId]??[]).filter(s=>s!==t)),e}function hl(e={}){const t=e.initial??{},n=f.useRef(null);n.current==null&&(n.current=fl(t));const[r,s]=f.useReducer(Rg,n.current),i=f.useCallback((v,w)=>s({type:"setValue",nodeId:v,value:w}),[]),o=f.useCallback((v,w)=>s({type:"setType",nodeId:v,newType:w}),[]),l=f.useCallback((v,w)=>s({type:"setKey",nodeId:v,key:w}),[]),c=f.useCallback((v,w,k)=>s({type:"addMapEntry",parentId:v,key:w,childType:k}),[]),u=f.useCallback((v,w)=>s({type:"addArrayEntry",parentId:v,childType:w}),[]),d=f.useCallback(v=>s({type:"remove",nodeId:v}),[]),p=f.useCallback(()=>s({type:"reset"}),[]),h=f.useCallback(v=>s({type:"replaceData",data:v}),[]),m=f.useCallback(v=>s({type:"touch",nodeId:v}),[]),y=f.useCallback(()=>s({type:"touchAll"}),[]),g=f.useCallback(()=>ll(r.tree),[r.tree]),x=r.tree!==r.initial,b=r.errorCount===0;return f.useMemo(()=>({...r,isDirty:x,isValid:b,dispatch:s,setValue:i,setType:o,setKey:l,addMapEntry:c,addArrayEntry:u,remove:d,reset:p,replaceData:h,touch:m,touchAll:y,toData:g}),[r,x,b,i,o,l,c,u,d,p,h,m,y,g])}function Mg({collection:e,query:t,pageSize:n=50,mode:r="paged"}){const[s,i]=f.useState([]),[o,l]=f.useState(!0),[c,u]=f.useState(void 0),[d,p]=f.useState(!1),[h,m]=f.useState(0),[y,g]=f.useState(n),x=f.useRef(0),[b,v]=f.useState(0),{addDoc:w,deleteDoc:k,doc:j,getDoc:S,getDocs:C,limit:O,onSnapshot:I,query:$,setDoc:N,startAfter:_}=ms();f.useEffect(()=>{g(n)},[e,r,n,t]),f.useEffect(()=>{let R=!1;r==="paged"&&i([]),p(!1),l(!0),u(void 0);const P=t??e,U=r==="live"?y:n,D=$(P,O(U)),J=ne=>{R||(i([...ne.docs]),p(ne.docs.length===U),l(!1))},se=ne=>{R||(u(ne instanceof Error?ne:new Error(String(ne))),l(!1))};if(r==="live"){const ne=++x.current,ac=I(D,oc=>{v(ne),J(oc)},se);return()=>{R=!0,ac()}}return C(D).then(ne=>{J(ne)}).catch(se),()=>{R=!0}},[e,C,O,r,I,n,t,$,y,h]);const E=f.useCallback(()=>{if(!d||o)return;if(r==="live"){l(!0),g(D=>D+n);return}const R=s[s.length-1];if(!R)return;l(!0);const U=$(t??e,_(R),O(n));C(U).then(D=>{i(J=>[...J,...D.docs]),p(D.docs.length===n),l(!1)}).catch(D=>{u(D instanceof Error?D:new Error(String(D))),l(!1)})},[e,s,C,d,o,O,r,n,t,$,_]),A=f.useCallback(async(R,P,U)=>{if(R==null){const J=await w(e,P);return r==="paged"&&m(se=>se+1),J}const D=j(e,R);if(U?.onExisting==="fail"){const J=await S(D);if(typeof J.exists=="function"?J.exists():!!J.exists){const ne=new Error(`Document "${R}" already exists.`);throw ne.code="already-exists",ne}}return await N(D,P),r==="paged"&&m(J=>J+1),D},[w,e,j,S,r,N]),q=f.useCallback(async R=>{await k(R),r==="paged"&&m(P=>P+1)},[k,r]),X=f.useCallback(()=>m(R=>R+1),[]);return{documents:s,isLoading:o,error:c,subscriptionGeneration:b,hasMore:d,loadMore:E,createDocument:A,deleteDocument:q,refresh:X}}function Lg({firestore:e,documentRef:t,listSubcollections:n}){const[r,s]=f.useState([]),[i,o]=f.useState(!1),[l,c]=f.useState(void 0),u=f.useRef(n);u.current=n;const d=t?.path;return f.useEffect(()=>{if(!t){s([]),o(!1),c(void 0);return}let p=!1;return o(!0),c(void 0),u.current(e,t).then(h=>{p||(s(h),o(!1))}).catch(h=>{p||(c(h instanceof Error?h:new Error(String(h))),o(!1))}),()=>{p=!0}},[e,d]),{subcollections:r,isLoading:i,error:l}}function Ti(e){return typeof e=="object"&&e!==null&&"isEqual"in e&&typeof e.isEqual=="function"}function Mi(e){if(typeof e!="object"||e===null||Array.isArray(e))return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function jn(e,t){if(Object.is(e,t))return!0;if(Ti(e))return e.isEqual(t);if(Ti(t))return t.isEqual(e);if(e instanceof Uint8Array||t instanceof Uint8Array)return!(e instanceof Uint8Array)||!(t instanceof Uint8Array)||e.length!==t.length?!1:e.every((s,i)=>s===t[i]);if(Array.isArray(e)||Array.isArray(t))return!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?!1:e.every((s,i)=>jn(s,t[i]));if(!Mi(e)||!Mi(t))return!1;const n=Object.keys(e),r=Object.keys(t);return n.length!==r.length?!1:n.every(s=>s in t&&jn(e[s],t[s]))}function Bg({value:e,path:t}){return a.jsx("span",{"data-pyric-field-type":"string","data-pyric-field-path":t,children:e})}function Fg({value:e,onChange:t,error:n,path:r}){return a.jsxs("label",{"data-pyric-field-type":"string","data-pyric-field-path":r,"data-pyric-error":n?"":void 0,children:[a.jsx("input",{type:"text",value:e,onChange:s=>t(s.target.value),"aria-invalid":n?"true":void 0}),n?a.jsx("span",{"data-pyric-error-message":!0,children:n}):null]})}const Vg={type:"string",Display:Bg,Edit:Fg};function qg({value:e,path:t}){return a.jsx("span",{"data-pyric-field-type":"number","data-pyric-field-path":t,children:String(e)})}function Wg({value:e,onChange:t,error:n,path:r}){return a.jsxs("label",{"data-pyric-field-type":"number","data-pyric-field-path":r,"data-pyric-error":n?"":void 0,children:[a.jsx("input",{type:"number",value:Number.isFinite(e)?e:"",onChange:s=>{const i=s.target.value,o=i===""?Number.NaN:parseFloat(i);t(o)},"aria-invalid":n?"true":void 0}),n?a.jsx("span",{"data-pyric-error-message":!0,children:n}):null]})}const zg={type:"number",Display:qg,Edit:Wg};function Kg({value:e,path:t}){return a.jsx("span",{"data-pyric-field-type":"boolean","data-pyric-field-path":t,"data-value":e?"true":"false",children:e?"true":"false"})}function Hg({value:e,onChange:t,path:n}){return a.jsx("span",{"data-pyric-field-type":"boolean","data-pyric-field-path":n,"data-value":e?"true":"false",children:a.jsxs("select",{value:e?"true":"false",onChange:r=>t(r.target.value==="true"),"aria-label":"Boolean value","data-pyric-boolean-select":!0,children:[a.jsx("option",{value:"true",children:"true"}),a.jsx("option",{value:"false",children:"false"})]})})}const Gg={type:"boolean",Display:Kg,Edit:Hg};function Jg({path:e}){return a.jsx("span",{"data-pyric-field-type":"null","data-pyric-field-path":e,children:"null"})}function Yg({path:e}){return a.jsx("span",{"data-pyric-field-type":"null","data-pyric-field-path":e,children:"null"})}const Xg={type:"null",Display:Jg,Edit:Yg};function pl(e){if(e instanceof mt)return e.toDate();const t=e,n=t?t.seconds??t._seconds:void 0,r=t?t.nanoseconds??t._nanoseconds??0:0;return typeof n=="number"?new Date(n*1e3+Math.floor(r/1e6)):new Date(NaN)}function Qg({value:e,path:t}){const n=pl(e),r=Number.isNaN(n.getTime())?"":n.toISOString();return a.jsx("time",{dateTime:r,"data-pyric-field-type":"timestamp","data-pyric-field-path":t,children:r})}function Zg({value:e,onChange:t,error:n,path:r}){const s=pl(e),i=new Date(s.getTime()-s.getTimezoneOffset()*6e4),o=Number.isNaN(i.getTime())?"":i.toISOString().slice(0,16);return a.jsxs("label",{"data-pyric-field-type":"timestamp","data-pyric-field-path":r,"data-pyric-error":n?"":void 0,children:[a.jsx("input",{type:"datetime-local",value:o,onChange:l=>{const c=l.target.value;if(!c)return;const u=new Date(c);t(mt.fromDate(u))},"aria-invalid":n?"true":void 0}),n?a.jsx("span",{"data-pyric-error-message":!0,children:n}):null]})}const ev={type:"timestamp",Display:Qg,Edit:Zg};function tv({value:e,path:t}){return a.jsxs("span",{"data-pyric-field-type":"geopoint","data-pyric-field-path":t,"data-lat":String(e.latitude),"data-lng":String(e.longitude),children:[e.latitude,", ",e.longitude]})}function nv({value:e,onChange:t,error:n,path:r}){return a.jsxs("span",{"data-pyric-field-type":"geopoint","data-pyric-field-path":r,"data-pyric-error":n?"":void 0,children:[a.jsx("label",{children:a.jsx("input",{type:"number",step:"any",min:-90,max:90,value:e.latitude,onChange:s=>{const i=parseFloat(s.target.value);try{t(new lt(i,e.longitude))}catch{}},"aria-label":"Latitude"})}),a.jsx("label",{children:a.jsx("input",{type:"number",step:"any",min:-180,max:180,value:e.longitude,onChange:s=>{const i=parseFloat(s.target.value);try{t(new lt(e.latitude,i))}catch{}},"aria-label":"Longitude"})}),n?a.jsx("span",{"data-pyric-error-message":!0,children:n}):null]})}const rv={type:"geopoint",Display:tv,Edit:nv},ml=f.createContext({});ml.Provider;function sv(){return f.useContext(ml)}function iv({value:e,path:t}){const{onReferenceClick:n}=sv();return n?a.jsx("button",{type:"button",onClick:()=>n(e),"data-pyric-field-type":"reference","data-pyric-field-path":t,"data-target-path":e.path,"data-pyric-clickable":"",children:e.path}):a.jsx("span",{"data-pyric-field-type":"reference","data-pyric-field-path":t,"data-target-path":e.path,children:e.path})}function av({value:e,onChange:t,error:n,path:r}){return a.jsxs("label",{"data-pyric-field-type":"reference","data-pyric-field-path":r,"data-pyric-error":n?"":void 0,children:[a.jsx("input",{type:"text",value:e.path,placeholder:"users/alice",onChange:s=>{const i=s.target.value,o=i.split("/").filter(Boolean),l=o[o.length-1]??"",c=e.firestore??{};t({path:i,id:l,firestore:c,type:"document"})},"aria-invalid":n?"true":void 0}),n?a.jsx("span",{"data-pyric-error-message":!0,children:n}):null]})}const ov={type:"reference",Display:iv,Edit:av};function lv({value:e,path:t}){const n=e.toBase64();return a.jsx("code",{"data-pyric-field-type":"bytes","data-pyric-field-path":t,"data-byte-length":String(e.toUint8Array().byteLength),children:n})}function cv({value:e,onChange:t,error:n,path:r}){return a.jsxs("label",{"data-pyric-field-type":"bytes","data-pyric-field-path":r,"data-pyric-error":n?"":void 0,children:[a.jsx("textarea",{value:e.toBase64(),onChange:s=>{try{t(_n.fromBase64String(s.target.value))}catch{}},"aria-invalid":n?"true":void 0}),n?a.jsx("span",{"data-pyric-error-message":!0,children:n}):null]})}const uv={type:"bytes",Display:lv,Edit:cv};function Tr({value:e,path:t,fieldEditors:n}){const r=Un(e),s=n[r];if(!s)return null;const{Display:i}=s;return a.jsx(i,{value:e,path:t,fieldEditors:n})}function yl({label:e,value:t,path:n,fieldEditors:r,kind:s}){const i=Un(t),o=i==="map"||i==="array",[l,c]=f.useState(!0),u=s==="key"?{"data-pyric-tree-key":""}:{"data-pyric-tree-index":""},d=s==="key"?{"data-field-name":e}:{"data-field-index":e};return o?a.jsxs("li",{"data-pyric-tree-entry":!0,"data-pyric-tree-nested":!0,...d,children:[a.jsxs("button",{type:"button","data-pyric-tree-toggle":!0,"aria-expanded":l,onClick:()=>c(p=>!p),children:[a.jsx("span",{"data-pyric-tree-chevron":!0,"aria-hidden":"true",children:"›"}),a.jsx("span",{...u,children:e})]}),l?a.jsx(Tr,{value:t,path:n,fieldEditors:r}):null]}):a.jsxs("li",{"data-pyric-tree-entry":!0,...d,children:[a.jsx("span",{"data-pyric-tree-chevron":!0,"data-pyric-tree-chevron-empty":!0,"aria-hidden":"true"}),a.jsx("span",{...u,children:e}),a.jsx(Tr,{value:t,path:n,fieldEditors:r})]})}function dv({value:e,path:t,fieldEditors:n}){const r=Object.entries(e).sort(([s],[i])=>s.localeCompare(i));return a.jsx("ul",{"data-pyric-field-type":"map","data-pyric-tree":!0,"data-pyric-field-path":t,children:r.map(([s,i])=>a.jsx(yl,{label:s,value:i,path:t?`${t}.${s}`:s,fieldEditors:n??{},kind:"key"},s))})}const fv={type:"map",Display:dv};function hv({value:e,path:t,fieldEditors:n}){return a.jsx("ul",{"data-pyric-field-type":"array","data-pyric-tree":!0,"data-pyric-field-path":t,children:e.map((r,s)=>a.jsx(yl,{label:String(s),value:r,path:t?`${t}[${s}]`:`[${s}]`,fieldEditors:n??{},kind:"index"},s))})}const pv={type:"array",Display:hv},Li=4;function mv(e){return e.length<=Li?`[${e.join(", ")}]`:`[${e.slice(0,Li).join(", ")}, …]`}function yv({value:e,path:t}){const n=Ye(e);return n?a.jsxs("span",{"data-pyric-field-type":"vector","data-pyric-field-path":t,"data-dimension":String(n.dimension),children:[a.jsx("span",{"data-pyric-vector-dims":!0,children:`vector · ${n.dimension}`}),a.jsx("span",{"data-pyric-vector-preview":!0,children:mv(n.values)})]}):a.jsx("span",{"data-pyric-field-type":"vector","data-pyric-field-path":t})}function bv(e){let t;try{t=JSON.parse(e)}catch{return{ok:!1,error:"Invalid JSON"}}return!Array.isArray(t)||!t.every(n=>typeof n=="number")?{ok:!1,error:"Expected a JSON array of numbers"}:{ok:!0,value:{__type__:"__vector__",value:t}}}function gv({value:e,onChange:t,error:n,path:r}){const s=Ye(e),i=s?JSON.stringify(s.values):"[]",[o,l]=f.useState(i),[c,u]=f.useState(void 0),d=m=>{l(m);const y=bv(m);if(!y.ok){u(y.error);return}u(void 0),t(y.value)},p=s?s.dimension:0,h=c??n;return a.jsxs("label",{"data-pyric-field-type":"vector","data-pyric-field-path":r,"data-dimension":String(p),"data-pyric-error":h?"":void 0,children:[a.jsx("span",{"data-pyric-vector-dims":!0,children:`vector · ${p}`}),a.jsx("span",{"data-pyric-vector-note":!0,children:"Replace whole. Paste a JSON number array."}),a.jsx("textarea",{"data-pyric-vector-raw":!0,value:o,onChange:m=>d(m.target.value),"aria-invalid":h?"true":void 0,"aria-label":"Vector value (JSON number array)"}),h?a.jsx("span",{"data-pyric-error-message":!0,children:h}):null]})}const vv={type:"vector",Display:yv,Edit:gv},Bi={string:Vg,number:zg,boolean:Gg,null:Xg,timestamp:ev,geopoint:rv,reference:ov,bytes:uv,map:fv,array:pv,vector:vv};function bl(e){return e?{...Bi,...e}:Bi}function Tn(e={}){const t=f.useRef(null),n=e.narrowBreakpoint??480,r=e.mediumBreakpoint??768,[s,i]=f.useState("wide");return f.useEffect(()=>{const o=t.current;if(!o||typeof ResizeObserver>"u")return;const l=new ResizeObserver(c=>{const u=c[0];if(!u)return;const d=u.contentRect.width;d<n?i("narrow"):d<r?i("medium"):i("wide")});return l.observe(o),()=>l.disconnect()},[n,r]),{ref:t,size:s}}const gl=f.createContext(null);function Ue(){const e=f.useContext(gl);if(!e)throw new Error("DocumentEditor.* components must render inside <DocumentEditor.Root>");return e}function xv({initial:e,fieldEditors:t,onChange:n,children:r,className:s}){const i=hl({initial:e}),o=bl(t),l=f.useRef(n);l.current=n,f.useEffect(()=>{l.current?.(i)},[i]);const{ref:c,size:u}=Tn();return a.jsx(gl.Provider,{value:{editor:i,fieldEditors:o},children:a.jsx("div",{ref:c,className:s,"data-pyric-ui":"document-editor","data-pyric-is-valid":i.isValid?"":void 0,"data-pyric-is-dirty":i.isDirty?"":void 0,"data-size":u,children:r})})}function wv(){const{editor:e}=Ue(),t=e.tree.childIds[e.tree.rootId]??[];return a.jsxs("div",{"data-pyric-editor-fields":!0,children:[t.map(n=>a.jsx(bs,{nodeId:n,path:jv(e,n)},n)),a.jsx(vl,{parentId:e.tree.rootId})]})}function jv(e,t){const n=[];let r=e.tree.nodes[t];for(;r&&r.parentId!=null;){const s=e.tree.nodes[r.parentId];if(!s)break;if(s.type==="array"){const i=(e.tree.childIds[s.id]??[]).indexOf(r.id);n.unshift(`[${i}]`)}else n.unshift(r.key??"");r=s}return n.reduce((s,i)=>i.startsWith("[")?`${s}${i}`:s?`${s}.${i}`:i,"")}function bs({nodeId:e,path:t}){const{editor:n,fieldEditors:r}=Ue(),s=n.tree.nodes[e];if(!s)return null;if(s.type==="map")return a.jsx(_v,{node:s,path:t});if(s.type==="array")return a.jsx(Ev,{node:s,path:t});const o=r[s.type]?.Edit;if(!o)return null;const l=s.touched?s.error:void 0;return a.jsxs("div",{"data-pyric-field-entry":!0,"data-field-name":s.key??void 0,"data-pyric-error":l?"":void 0,onBlur:()=>n.touch(s.id),children:[a.jsx(gs,{node:s,path:t}),a.jsx(o,{value:s.value,path:t,error:l,onChange:c=>n.setValue(s.id,c)})]})}function gs({node:e,path:t}){const{editor:n}=Ue(),s=(e.parentId!=null?n.tree.nodes[e.parentId]:null)?.type==="map";return e.id===n.tree.rootId?null:a.jsxs("div",{"data-pyric-field-chrome":!0,"data-pyric-field-path":t,children:[s?a.jsx("input",{type:"text",value:e.key??"",onChange:o=>n.setKey(e.id,o.target.value),"aria-label":"Field name","data-pyric-field-key-input":!0,"aria-invalid":e.touched&&e.error?"true":void 0}):null,a.jsx(Sv,{node:e}),a.jsx("button",{type:"button",onClick:()=>n.remove(e.id),"data-pyric-remove":!0,"aria-label":"Remove field",children:"×"})]})}const kv=["string","number","boolean","null","timestamp","geopoint","reference","bytes","vector","map","array"];function Sv({node:e}){const{editor:t}=Ue(),n=e.parentId!=null?t.tree.nodes[e.parentId]:null,r=kv.filter(s=>!(n?.type==="array"&&s==="array"));return a.jsx("select",{value:e.type,onChange:s=>t.setType(e.id,s.target.value),"aria-label":"Field type","data-pyric-field-type-select":!0,children:r.map(s=>a.jsx("option",{value:s,children:s},s))})}function _v({node:e,path:t}){const{editor:n}=Ue(),r=n.tree.childIds[e.id]??[];return a.jsxs("div",{"data-pyric-field-entry":!0,"data-pyric-field-type":"map","data-field-name":e.key??void 0,children:[e.id!==n.tree.rootId?a.jsx(gs,{node:e,path:t}):null,a.jsx("div",{"data-pyric-map-children":!0,children:r.map(s=>{const i=n.tree.nodes[s];if(!i)return null;const o=t?`${t}.${i.key??""}`:i.key??"";return a.jsx(bs,{nodeId:s,path:o},s)})}),a.jsx(vl,{parentId:e.id})]})}function Ev({node:e,path:t}){const{editor:n}=Ue(),r=n.tree.childIds[e.id]??[];return a.jsxs("div",{"data-pyric-field-entry":!0,"data-pyric-field-type":"array","data-field-name":e.key??void 0,children:[a.jsx(gs,{node:e,path:t}),a.jsx("ol",{"data-pyric-array-children":!0,children:r.map((s,i)=>{const o=t?`${t}[${i}]`:`[${i}]`;return a.jsx("li",{"data-field-index":String(i),children:a.jsx(bs,{nodeId:s,path:o})},s)})}),a.jsx(Cv,{parentId:e.id})]})}function vl({parentId:e}){const{editor:t}=Ue();return a.jsx("button",{type:"button","data-pyric-add-map-entry":!0,onClick:()=>t.addMapEntry(e,"","string"),children:"+ Add field"})}function Cv({parentId:e}){const{editor:t}=Ue();return a.jsx("button",{type:"button","data-pyric-add-array-entry":!0,onClick:()=>t.addArrayEntry(e,"string"),children:"+ Add item"})}const Fi={Root:xv,Fields:wv};function Nv({collections:e,isLoading:t,error:n,onSelect:r,emptyState:s,className:i}){return n?a.jsx("div",{className:i,"data-pyric-ui":"collection-list","data-pyric-error":"",role:"alert",children:n.message}):t&&e.length===0?a.jsx("div",{className:i,"data-pyric-ui":"collection-list","data-pyric-loading":""}):e.length===0?a.jsx("div",{className:i,"data-pyric-ui":"collection-list","data-pyric-empty":"",children:s}):a.jsx("ul",{className:i,"data-pyric-ui":"collection-list",children:e.map(o=>a.jsx("li",{"data-pyric-collection-entry":!0,"data-pyric-collection-id":o.id,children:a.jsx("button",{type:"button",onClick:()=>r?.(o),"data-pyric-collection-select":!0,children:o.id})},o.path))})}const _t=new Map;function vs({scope:e,entries:t,equals:n=Object.is,durationMs:r=1200,ready:s=!0}){const i=f.useRef(null),o=f.useRef(new Map),l=f.useRef(new Map),[c,u]=f.useState(_t);return f.useEffect(()=>{const d=i.current;if(!s){if(d&&d.scope!==e){i.current=null;for(const h of l.current.values())clearTimeout(h);l.current.clear(),o.current.clear(),u(_t)}return}if(!d||d.scope!==e){i.current={scope:e,entries:t};for(const h of l.current.values())clearTimeout(h);l.current.clear(),o.current.clear(),u(_t);return}const p=new Map;for(const[h,m]of t){const y=d.entries.has(h),g=d.entries.get(h);if(y&&n(g,m))continue;const x=o.current.get(h)===0?1:0;o.current.set(h,x),p.set(h,{kind:y?"modified":"added",cycle:x})}i.current={scope:e,entries:t},u(h=>{const m=new Map(h);let y=p.size>0;for(const g of h.keys())t.has(g)||(m.delete(g),y=!0);for(const[g,x]of p)m.set(g,x);return y?m.size===0?_t:m:h});for(const[h,m]of p){const y=l.current.get(h);y&&clearTimeout(y);const g=setTimeout(()=>{l.current.delete(h),u(x=>{if(x.get(h)?.cycle!==m.cycle)return x;const b=new Map(x);return b.delete(h),b.size===0?_t:b})},r);l.current.set(h,g)}},[r,t,n,s,e]),f.useEffect(()=>()=>{for(const d of l.current.values())clearTimeout(d);l.current.clear()},[]),c}function Et(e){return e.ref}function Av({documents:e,isLoading:t,error:n,hasMore:r,onSelect:s,onLoadMore:i,renderLabel:o,renderRowAction:l,emptyState:c,className:u,updateScope:d="document-list",virtualizeThreshold:p=100,rowHeight:h=36,virtualizedHeight:m="60vh"}){const y=f.useMemo(()=>new Map(e.map(b=>[Et(b).path,b.data()])),[e]),g=vs({scope:d,entries:y,equals:jn,ready:!t});if(n)return a.jsx("div",{className:u,"data-pyric-ui":"document-list","data-pyric-error":"",role:"alert",children:n.message});if(t&&e.length===0)return a.jsx("div",{className:u,"data-pyric-ui":"document-list","data-pyric-loading":""});if(e.length===0)return a.jsx("div",{className:u,"data-pyric-ui":"document-list","data-pyric-empty":"",children:c});const x=e.length>p;return a.jsxs("div",{className:u,"data-pyric-ui":"document-list","data-pyric-virtualized":x?"":void 0,children:[x?a.jsx(fs,{items:e,estimateSize:h,height:m,getItemKey:b=>Et(b).path,renderItem:b=>{const v=g.get(Et(b).path);return a.jsxs("div",{"data-pyric-document-entry":!0,"data-pyric-document-id":b.id,"data-pyric-update":v?.kind,"data-pyric-update-cycle":v?.cycle,children:[a.jsx("button",{type:"button",onClick:()=>s?.(Et(b)),"data-pyric-document-select":!0,"data-pyric-update":v?.kind,"data-pyric-update-cycle":v?.cycle,children:o?o(b):b.id}),l?a.jsx("span",{"data-pyric-document-action":!0,children:l(b)}):null]})}}):a.jsx("ul",{"data-pyric-document-list-items":!0,children:e.map(b=>{const v=Et(b),w=g.get(v.path);return a.jsxs("li",{"data-pyric-document-entry":!0,"data-pyric-document-id":b.id,"data-pyric-update":w?.kind,"data-pyric-update-cycle":w?.cycle,children:[a.jsx("button",{type:"button",onClick:()=>s?.(v),"data-pyric-document-select":!0,"data-pyric-update":w?.kind,"data-pyric-update-cycle":w?.cycle,children:o?o(b):b.id}),l?a.jsx("span",{"data-pyric-document-action":!0,children:l(b)}):null]},v.path)})}),r&&i?a.jsx("button",{type:"button",onClick:i,"data-pyric-load-more":!0,disabled:t,children:"Load more"}):null]})}const Rv=/^__.*__$/;function xl(e){if(e.length===0)return"Cannot be empty";if(e.includes("/"))return'Cannot contain "/"';if(e==="."||e==="..")return'Cannot be "." or ".."';if(Rv.test(e))return"Cannot match __.*__ (reserved)";if(Iv(e)>1500)return"Cannot exceed 1500 bytes"}function Dv(e){return xl(e)}function Iv(e){return new TextEncoder().encode(e).length}function $v(e){return xl(e)}const Vi="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Pv(){let e="";for(let t=0;t<20;t++)e+=Vi.charAt(Math.floor(Math.random()*Vi.length));return e}const Ov={ref:Ot,listAll:cs,getMetadata:Zm,getBlob:oy,uploadBytes:ny,deleteObject:Bo},wl=f.createContext(Ov);function Mn(){return f.useContext(wl)}function Uv({value:e,children:t}){return f.createElement(wl.Provider,{value:e},t)}function nr(e){return e.replace(/^\/+|\/+$/g,"")}function Mr(e,t){return e.fullPath<t.fullPath?-1:e.fullPath>t.fullPath?1:0}function rr(e,t){return e.some(n=>n.fullPath===t.fullPath)?e:[...e,t].sort(Mr)}function Tv(e,t){const{listAll:n,ref:r}=Mn(),s=nr(t),[i,o]=f.useState(()=>({status:e==null?"idle":"loading",items:[],prefixes:[],error:void 0})),[l,c]=f.useState(0),u=f.useRef(new Map);f.useEffect(()=>{if(u.current.clear(),e==null){o({status:"idle",items:[],prefixes:[],error:void 0});return}let y=!1;return o({status:"loading",items:[],prefixes:[],error:void 0}),n(r(e,s)).then(g=>{y||o({status:"success",items:[...g.items].sort(Mr),prefixes:[...g.prefixes].sort(Mr),error:void 0})}).catch(g=>{y||o({status:"error",items:[],prefixes:[],error:g instanceof Error?g:new Error(String(g))})}),()=>{y=!0}},[e,s,l]);const d=f.useCallback(()=>c(y=>y+1),[]),p=f.useCallback(y=>{if(e==null)return;const g=y.endsWith("/"),x=nr(y),b=s===""?"":`${s}/`;if(!x.startsWith(b)||x===s)return;const v=x.slice(b.length),w=v.indexOf("/");o(k=>{if(k.status==="idle")return k;if(w===-1)return g?(u.current.set(x,k.prefixes.some(S=>S.fullPath===x)?null:x),{...k,prefixes:rr(k.prefixes,r(e,x))}):(u.current.set(x,k.items.some(S=>S.fullPath===x)?null:x),{...k,items:rr(k.items,r(e,x))});const j=`${b}${v.slice(0,w)}`;return u.current.set(x,k.prefixes.some(S=>S.fullPath===j)?null:j),{...k,prefixes:rr(k.prefixes,r(e,j))}})},[e,s]),h=f.useCallback(y=>{const g=nr(y),x=u.current.get(g);if(u.current.delete(g),x===null)return;const b=x??g;o(v=>({...v,items:v.items.filter(w=>w.fullPath!==b),prefixes:v.prefixes.filter(w=>w.fullPath!==b)}))},[]),m=f.useMemo(()=>[...i.prefixes.map(y=>({kind:"folder",name:y.name,fullPath:y.fullPath,ref:y})),...i.items.map(y=>({kind:"object",name:y.name,fullPath:y.fullPath,ref:y}))],[i.prefixes,i.items]);return{status:i.status,items:i.items,prefixes:i.prefixes,entries:m,error:i.error,refresh:d,insertItem:p,removeItem:h}}function Y(e){return e.split("/").filter(Boolean).join("/")}function Mv(e={}){const{path:t,onPathChange:n,defaultPath:r=""}=e,s=t!==void 0,[i,o]=f.useState(()=>Y(r)),l=s?Y(t):i,c=f.useCallback(m=>{const y=Y(m);s||o(y),n?.(y)},[s,n]),u=f.useMemo(()=>l===""?[]:l.split("/"),[l]),d=f.useCallback(m=>{const y=Y(m);c(y.includes("/")||l===""?y:`${l}/${y}`)},[l,c]),p=f.useCallback(()=>{u.length!==0&&c(u.slice(0,-1).join("/"))},[u,c]),h=f.useCallback(m=>{c(m<0?"":u.slice(0,m+1).join("/"))},[u,c]);return{path:l,segments:u,setPath:c,enter:d,up:p,navigateToIndex:h}}const qi={status:"idle",blob:void 0,url:void 0,error:void 0};function Lv(e,t){const{getBlob:n,getMetadata:r,ref:s}=Mn(),i=t==null?null:Y(t),o=e!=null&&i!=null&&i!=="",[l,c]=f.useState(()=>({status:o?"loading":"idle",metadata:void 0,error:void 0})),[u,d]=f.useState(qi),[p,h]=f.useState(0),m=f.useRef(0);f.useEffect(()=>{if(m.current++,d(qi),!o){c({status:"idle",metadata:void 0,error:void 0});return}let b=!1;return c({status:"loading",metadata:void 0,error:void 0}),r(s(e,i)).then(v=>{b||c({status:"success",metadata:v,error:void 0})}).catch(v=>{b||c({status:"error",metadata:void 0,error:v instanceof Error?v:new Error(String(v))})}),()=>{b=!0}},[e,i,p]);const y=u.url;f.useEffect(()=>{if(y!==void 0)return()=>{URL.revokeObjectURL(y)}},[y]);const g=f.useCallback(()=>h(b=>b+1),[]),x=f.useCallback(()=>{if(e==null||i==null||i==="")return;const b=++m.current;d({status:"loading",blob:void 0,url:void 0,error:void 0}),n(s(e,i)).then(v=>{b===m.current&&d({status:"success",blob:v,url:URL.createObjectURL(v),error:void 0})}).catch(v=>{b===m.current&&d({status:"error",blob:void 0,url:void 0,error:v instanceof Error?v:new Error(String(v))})})},[e,i]);return{status:l.status,metadata:l.metadata,error:l.error,refresh:g,blobStatus:u.status,blob:u.blob,blobUrl:u.url,blobError:u.error,loadBlob:x}}function Bv(){const[e,t]=f.useState(()=>new Map),n=f.useCallback(u=>e.has(u),[e]),r=f.useCallback(u=>{t(d=>{if(d.has(u.fullPath))return d;const p=new Map(d);return p.set(u.fullPath,u),p})},[]),s=f.useCallback(u=>{t(d=>{if(!d.has(u))return d;const p=new Map(d);return p.delete(u),p})},[]),i=f.useCallback(u=>{t(d=>{const p=new Map(d);return p.has(u.fullPath)?p.delete(u.fullPath):p.set(u.fullPath,u),p})},[]),o=f.useCallback(u=>{t(new Map(u.map(d=>[d.fullPath,d])))},[]),l=f.useCallback(()=>t(new Map),[]);return{selected:f.useMemo(()=>[...e.values()],[e]),size:e.size,isSelected:n,toggle:i,select:r,deselect:s,selectAll:o,clear:l}}function Fv(e,t){const n=Ot(e,t);return{storage:e,bucket:n.bucket,fullPath:`${n.fullPath}/`,name:"",parent:n,root:n.root,toString:()=>`${n.toString()}/`}}function Vv(e){return{...e,fullPath:`${e.fullPath}/`,name:""}}function qv(e){return{async*start(t){const n=e??{listAll:cs,deleteObject:Bo};let r=0;const s=[t],i=[];for(;s.length>0;){const o=s.pop();i.push(o);const l=await n.listAll(o);s.push(...l.prefixes);for(const c of l.items)await n.deleteObject(c),r++,yield{deletedCount:r,done:!1}}for(const o of i)try{await n.deleteObject(Vv(o))}catch{}yield{deletedCount:r,done:!0}}}}function Wv(e,t={}){const n=Mn(),[r,s]=f.useState(0),[i,o]=f.useState(!1),[l,c]=f.useState(void 0),u=f.useRef(0),d=f.useRef(t);return d.current=t,{deleteEntries:f.useCallback(async h=>{const m=++u.current;s(0),c(void 0);const y={deleted:[],failed:[]};if(e==null||h.length===0)return y;o(!0);const g=d.current.impl??qv(n);let x=0;try{for(const b of h){d.current.list?.removeItem(b.fullPath);try{if(b.kind==="object")await n.deleteObject(n.ref(e,b.fullPath)),x++;else for await(const v of g.start(n.ref(e,b.fullPath))){if(m!==u.current)return y;if(s(x+v.deletedCount),v.done){x+=v.deletedCount;break}}y.deleted.push(b.fullPath),m===u.current&&s(x)}catch(v){const w=v instanceof Error?v:new Error(String(v));y.failed.push({fullPath:b.fullPath,error:w}),d.current.list?.insertItem(b.kind==="folder"?`${b.fullPath}/`:b.fullPath),m===u.current&&y.failed.length===1&&c(w)}}return y}finally{m===u.current&&o(!1)}},[n,e]),progress:r,isRunning:i,error:l}}const zv=Object.freeze({read:!0,write:!0,delete:!0,upload:!0,reasons:Object.freeze({read:[],write:[]})});function Kv(e,t={}){const{paths:n,rules:r,identity:s,writeResource:i}=t,o=e==null?null:e[In],[l,c]=f.useState(()=>({status:e==null?"idle":"loading",rules:null,source:"none",error:void 0}));f.useEffect(()=>{if(o==null){c({status:"idle",rules:null,source:"none",error:void 0});return}if(r!=null){try{const v=typeof r=="string"?Dr(r):r;c({status:"ready",rules:v,source:"option",error:void 0})}catch(v){c({status:"error",rules:null,source:"none",error:v instanceof Error?v:new Error(String(v))})}return}let b=!1;return c({status:"loading",rules:null,source:"none",error:void 0}),o.servicePromise.then(v=>{b||c({status:"ready",rules:v.rules,source:v.rules?"sandbox":"none",error:void 0})}).catch(v=>{b||c({status:"error",rules:null,source:"none",error:v instanceof Error?v:new Error(String(v))})}),()=>{b=!0}},[o,r]);const u=s!==void 0?s:o?.context.auth??null,{rules:d,status:p}=l,h=i?.size,m=i?.contentType,y=f.useCallback(b=>{if(d==null)return zv;const v=Y(b),w=o?.bucket??"pyric-default",k=v===""?`b/${w}/o`:`b/${w}/o/${v}`,j=$=>Mo(d,{request:{auth:u,method:$,path:k,...$==="create"&&h!==void 0?{resource:{size:h,contentType:m}}:{}},resource:null}),S=j("read"),C=j("create"),O=j("delete"),I=C;return{read:S.allowed,write:I.allowed,delete:O.allowed,upload:C.allowed,reasons:{read:S.allowed?[]:S.reasons,write:I.allowed?[]:I.reasons}}},[d,o?.bucket,u,h,m]),g=typeof n=="string"?n:(n??[]).join(`
107
- `),x=f.useMemo(()=>{const b=typeof n=="string"?[n]:n??[],v={};for(const w of b)v[Y(w)]=y(w);return v},[g,y]);return{status:p,source:l.source,advisory:!1,identity:u,verdicts:x,verdictFor:y,error:l.error}}function Wi(e,t){return e===""?t:t===""?e:`${e}/${t}`}function Hv(e){return e instanceof Blob?e.size:e.byteLength}function Gv(e){if(e instanceof Blob){const t=e;return{path:t.webkitRelativePath||t.name,data:t}}return e}function Jv(e,t={}){const{ref:n,uploadBytes:r}=Mn(),s=Y(t.path??""),[i,o]=f.useState([]),l=f.useRef(t);l.current=t;const c=f.useCallback(h=>{o(m=>m.map(y=>y.id===h.id?h:y))},[]),u=f.useCallback(async h=>{if(e==null)throw new Error("useObjectUpload: storage handle is null");const y=(Array.isArray(h)?h:[h]).map(g=>{const x=Gv(g);return{task:{id:crypto.randomUUID(),fullPath:Wi(s,Y(x.path)),status:"running",bytesTransferred:0,totalBytes:Hv(x.data)},entry:x}});o(g=>[...g,...y.map(x=>x.task)]);for(const{task:g}of y)l.current.list?.insertItem(g.fullPath),l.current.onProgress?.(g);return Promise.all(y.map(async({task:g,entry:x})=>{try{const b=await r(n(e,g.fullPath),x.data,x.metadata),v={...g,status:"success",bytesTransferred:g.totalBytes,metadata:b.metadata};return c(v),l.current.onProgress?.(v),l.current.onComplete?.(v),v}catch(b){const v={...g,status:"error",error:b instanceof Error?b:new Error(String(b))};return l.current.list?.removeItem(g.fullPath),c(v),l.current.onError?.(v),v}}))},[e,s,c,n,r]),d=f.useCallback(async h=>{if(e==null)throw new Error("useObjectUpload: storage handle is null");const m=Wi(s,Y(h));if(m==="")throw new Error("createFolder: folder name is empty");l.current.list?.insertItem(`${m}/`);try{await r(Fv(e,m),new Blob([]),{contentType:"text/plain"})}catch(y){throw l.current.list?.removeItem(m),y}},[e,s,r]),p=f.useCallback(()=>{o(h=>h.filter(m=>m.status==="running"))},[]);return{tasks:i,isUploading:i.some(h=>h.status==="running"),upload:u,createFolder:d,clearCompleted:p}}function Yv({path:e,onNavigate:t,rootLabel:n="/",separator:r="/",className:s}){const i=Y(e),o=i===""?[]:i.split("/");return a.jsx("nav",{className:s,"data-pyric-ui":"path-breadcrumb","aria-label":"Storage path",children:a.jsxs("ol",{"data-pyric-breadcrumb-list":!0,children:[a.jsx("li",{"data-pyric-breadcrumb-item":!0,children:a.jsx("button",{type:"button",onClick:()=>t?.(""),"data-pyric-breadcrumb-link":!0,"data-pyric-breadcrumb-root":!0,"data-pyric-current":o.length===0?"":void 0,"aria-current":o.length===0?"page":void 0,children:n})}),o.map((l,c)=>{const u=c===o.length-1,d=o.slice(0,c+1).join("/");return a.jsxs("li",{"data-pyric-breadcrumb-item":!0,children:[a.jsx("span",{"aria-hidden":!0,"data-pyric-breadcrumb-separator":!0,children:r}),a.jsx("button",{type:"button",onClick:()=>t?.(d),"data-pyric-breadcrumb-link":!0,"data-pyric-current":u?"":void 0,"aria-current":u?"page":void 0,children:l})]},d)})]})})}function Xv({entries:e,status:t="success",error:n,onNavigate:r,onSelect:s,selectedPath:i,gate:o,renderEntry:l,renderRowAction:c,emptyState:u,className:d,virtualizeThreshold:p=100,rowHeight:h=36,virtualizedHeight:m="60vh"}){const{ref:y,size:g}=Tn();if(n)return a.jsx("div",{className:d,"data-pyric-ui":"object-browser","data-pyric-error":"",role:"alert",children:n.message});if((t==="loading"||t==="idle")&&e.length===0)return a.jsx("div",{className:d,"data-pyric-ui":"object-browser","data-pyric-loading":t==="loading"?"":void 0,"data-pyric-idle":t==="idle"?"":void 0});if(e.length===0)return a.jsx("div",{className:d,"data-pyric-ui":"object-browser","data-pyric-empty":"",children:u});const x=w=>{if(!o)return{denied:!1};const k=o.verdictFor(w.fullPath);return k.read?{denied:!1}:{denied:!0,reason:k.reasons.read.join("; ")}},b=w=>{const k=w.kind==="object"&&w.fullPath===i;return a.jsxs(a.Fragment,{children:[a.jsx("button",{type:"button",onClick:()=>w.kind==="folder"?r?.(w.fullPath):s?.(w.ref),"data-pyric-entry-select":!0,"data-pyric-selected":k?"":void 0,"aria-selected":k||void 0,children:l?l(w):w.name}),c?a.jsx("span",{"data-pyric-storage-action":!0,children:c(w)}):null]})},v=e.length>p;return a.jsx("div",{ref:y,className:d,"data-pyric-ui":"object-browser","data-size":g,"data-pyric-virtualized":v?"":void 0,children:v?a.jsx(fs,{items:e,estimateSize:h,height:m,getItemKey:w=>`${w.kind}:${w.fullPath}`,renderItem:w=>{const k=x(w);return a.jsx("div",{"data-pyric-storage-entry":!0,"data-pyric-entry-kind":w.kind,"data-pyric-entry-path":w.fullPath,"data-pyric-denied":k.denied?"":void 0,"data-pyric-denied-reason":k.reason,children:b(w)})}}):a.jsx("ul",{"data-pyric-object-browser-items":!0,children:e.map(w=>{const k=x(w);return a.jsx("li",{"data-pyric-storage-entry":!0,"data-pyric-entry-kind":w.kind,"data-pyric-entry-path":w.fullPath,"data-pyric-denied":k.denied?"":void 0,"data-pyric-denied-reason":k.reason,children:b(w)},`${w.kind}:${w.fullPath}`)})})})}async function jl(e,t,n){const r=t===""?e.name:`${t}/${e.name}`;if(e.isFile){const s=await new Promise((i,o)=>e.file(i,o));n.push({file:s,relativePath:r});return}if(e.isDirectory){const s=e.createReader();for(;;){const i=await new Promise((o,l)=>s.readEntries(o,l));if(i.length===0)break;for(const o of i)await jl(o,r,n)}}}async function Qv(e){const t=[],n=e.items?Array.from(e.items):[];for(const r of n){if(r.kind!=="file")continue;const s=r.webkitGetAsEntry,i=typeof s=="function"?s.call(r):null;if(i)await jl(i,"",t);else{const o=r.getAsFile?.();o&&t.push({file:o,relativePath:o.name})}}if(t.length===0)for(const r of Array.from(e.files??[]))t.push({file:r,relativePath:r.name});return t}function Zv({onFiles:e,children:t,disabled:n,disabledReason:r,className:s}){const[i,o]=f.useState(!1),l=f.useRef(0),c=f.useCallback(h=>{h.preventDefault(),!n&&(l.current+=1,o(!0))},[n]),u=f.useCallback(h=>{h.preventDefault()},[]),d=f.useCallback(h=>{h.preventDefault(),!n&&(l.current=Math.max(0,l.current-1),l.current===0&&o(!1))},[n]),p=f.useCallback(h=>{if(h.preventDefault(),l.current=0,o(!1),n)return;const m=h.dataTransfer;m&&Qv(m).then(y=>{y.length>0&&e(y)})},[n,e]);return a.jsx("div",{className:s,"data-pyric-ui":"upload-dropzone","data-dragging":i?"":void 0,"data-disabled":n?"":void 0,"data-disabled-reason":n?r:void 0,"aria-disabled":n||void 0,onDragEnter:c,onDragOver:u,onDragLeave:d,onDrop:p,children:t})}function ex(e){const t=e.lastIndexOf(".");return t<=0||t===e.length-1?{stem:e,ext:""}:{stem:e.slice(0,t),ext:e.slice(t)}}function tx(e){const t=/^(.*) \((\d+)\)$/.exec(e);if(!t)return{base:e,counter:null};const n=Number(t[2]);return Number.isSafeInteger(n)?{base:t[1],counter:n}:{base:e,counter:null}}function zi(e,t){if(!t.has(e))return e;const{stem:n,ext:r}=ex(e),{base:s,counter:i}=tx(n);let o=i===null?1:i+1;for(;;){const l=`${s} (${o})${r}`;if(!t.has(l))return l;o+=1}}function nx(e,t){const n=new Set(t),r=new Map;return e.map(s=>{const i=s.indexOf("/");if(i===-1){const c=zi(s,n);return n.add(c),c}const o=s.slice(0,i);let l=r.get(o);return l===void 0&&(l=zi(o,n),n.add(l),r.set(o,l)),`${l}${s.slice(i)}`})}function Ki(e){const t=Y(e);if(t==="")return[];const n=t.split("/");return n.map((r,s)=>n.slice(0,s+1).join("/"))}const kl=[];function rx(e,t){switch(t.type){case"create":{const n=Ki(t.path).filter(r=>!e.includes(r));return n.length===0?e:[...e,...n].sort()}case"materialize":{const n=new Set(Ki(t.path));if(n.size===0)return e;const r=e.filter(s=>!n.has(s));return r.length===e.length?e:r}case"discard":{const n=Y(t.path);if(n==="")return e;const r=e.filter(s=>s!==n&&!s.startsWith(`${n}/`));return r.length===e.length?e:r}case"clear":return e.length===0?e:kl}}function sx(e,t){const n=Y(t),r=n===""?"":`${n}/`;return e.filter(s=>s.startsWith(r)&&s!==n&&!s.slice(r.length).includes("/")).map(s=>s.slice(r.length))}function Hi(e,t){return e.includes(Y(t))}function ix(e){const t=Y(e);return t===""?"Enter a folder name.":t.split("/").some(r=>r==="."||r==="..")?'Folder names may not be "." or "..".':null}const ax=256*1024;function Lr(e){return(e.contentType??"").split(";")[0].trim().toLowerCase()}const ox={id:"image",match:e=>Lr(e).startsWith("image/"),needsBlob:!0,render:({metadata:e,blobUrl:t})=>t?a.jsx("img",{"data-pyric-preview-image":!0,src:t,alt:e.name}):null};function lx({blob:e,isJson:t}){const[n,r]=f.useState(void 0);return f.useEffect(()=>{let s=!1;return e.text().then(i=>{if(!s){if(t)try{r(JSON.stringify(JSON.parse(i),null,2));return}catch{}r(i)}}),()=>{s=!0}},[e,t]),n===void 0?null:a.jsx("pre",{"data-pyric-preview-text":!0,children:n})}const cx={id:"text",match:e=>{const t=Lr(e);return t.startsWith("text/")||t==="application/json"},needsBlob:!0,maxBytes:ax,render:({metadata:e,blob:t})=>t?a.jsx(lx,{blob:t,isJson:Lr(e)==="application/json"}):null},ux=[ox,cx];function dx(e,t){for(const n of[...t??[],...ux])if(n.match(e))return n}const fx=[{key:"fullPath",label:"Path",value:e=>e.fullPath},{key:"size",label:"Size",value:e=>`${e.size}`},{key:"contentType",label:"Content type",value:e=>e.contentType},{key:"cacheControl",label:"Cache control",value:e=>e.cacheControl},{key:"timeCreated",label:"Created",value:e=>e.timeCreated},{key:"updated",label:"Updated",value:e=>e.updated}];function hx({metadata:e}){return a.jsxs("dl",{"data-pyric-object-metadata":!0,children:[fx.map(({key:t,label:n,value:r})=>{const s=r(e);return s===void 0?null:a.jsxs("div",{"data-pyric-metadata-field":t,children:[a.jsx("dt",{children:n}),a.jsx("dd",{children:s})]},t)}),Object.entries(e.customMetadata??{}).map(([t,n])=>a.jsxs("div",{"data-pyric-metadata-field":"customMetadata","data-pyric-metadata-key":t,children:[a.jsx("dt",{children:t}),a.jsx("dd",{children:n})]},`custom:${t}`))]})}function px({storage:e,path:t,previews:n,renderMetadata:r,children:s,className:i}){const{ref:o,size:l}=Tn(),c=Lv(e,t),{metadata:u,blobStatus:d,loadBlob:p}=c,h=u?dx(u,n):void 0,m=h?.maxBytes!==void 0&&u!==void 0&&u.size>h.maxBytes,y=h?.needsBlob===!0&&!m;if(f.useEffect(()=>{y&&d==="idle"&&p()},[y,d,p]),c.status==="idle")return a.jsx("div",{className:i,"data-pyric-ui":"object-inspector","data-pyric-idle":""});if(c.status==="loading")return a.jsx("div",{className:i,"data-pyric-ui":"object-inspector","data-pyric-loading":""});if(c.status==="error"||u===void 0)return a.jsx("div",{className:i,"data-pyric-ui":"object-inspector","data-pyric-error":"",role:"alert",children:c.error?.message});let g,x={};return h===void 0?x={"data-pyric-preview-none":""}:m?x={"data-pyric-preview-too-large":""}:y&&d==="loading"?x={"data-pyric-preview-loading":""}:y&&d==="error"?(x={"data-pyric-preview-error":""},g=c.blobError?.message):(!y||d==="success")&&(g=h.render({metadata:u,blob:c.blob,blobUrl:c.blobUrl})),a.jsxs("div",{ref:o,className:i,"data-pyric-ui":"object-inspector","data-size":l,children:[a.jsx("div",{"data-pyric-object-name":!0,children:u.name}),r?r(u):a.jsx(hx,{metadata:u}),a.jsx("div",{"data-pyric-object-preview":!0,"data-pyric-preview":h?.id,...x,children:g}),s]})}const Sl=f.createContext(null);function mx(){const e=f.useContext(Sl);if(!e)throw new Error("useToast: missing <ToastProvider> ancestor");return e}function yx({children:e,defaultDuration:t=5e3,className:n,regionLabel:r="Notifications"}){const[s,i]=f.useState([]),o=f.useCallback(u=>{i(d=>d.filter(p=>p.id!==u))},[]),l=f.useCallback(u=>{const d=crypto.randomUUID(),p=u.duration??t;return i(h=>[...h,{id:d,...u}]),p>0&&window.setTimeout(()=>{i(h=>h.filter(m=>m.id!==d))},p),d},[t]),c=f.useMemo(()=>({toast:l,dismiss:o,toasts:s}),[l,o,s]);return a.jsxs(Sl.Provider,{value:c,children:[e,a.jsx(bx,{toasts:s,dismiss:o,className:n,regionLabel:r})]})}function bx({toasts:e,dismiss:t,className:n,regionLabel:r}){const[s,i]=f.useState(!1);return f.useEffect(()=>i(!0),[]),!s||typeof document>"u"?null:ds.createPortal(a.jsx("ol",{"aria-label":r,"aria-live":"polite","data-pyric-ui":"toast-region",className:n,children:e.map(o=>a.jsxs("li",{"data-pyric-toast":!0,"data-pyric-toast-kind":o.kind??"info",role:o.kind==="error"?"alert":"status",children:[a.jsx("div",{"data-pyric-toast-title":!0,children:o.title}),o.body?a.jsx("div",{"data-pyric-toast-body":!0,children:o.body}):null,a.jsx("button",{type:"button","data-pyric-toast-dismiss":!0,"aria-label":"Dismiss",onClick:()=>t(o.id),children:"×"})]},o.id))}),document.body)}function gx({storage:e,entries:t,impl:n,list:r,gate:s,title:i,body:o,confirmLabel:l="Delete",onDeleted:c,onFailed:u,renderTrigger:d,className:p}){const h=vt(),{toast:m}=mx(),{deleteEntries:y,isRunning:g,progress:x}=Wv(e,{impl:n,list:r}),b=s?t.map(j=>({entry:j,verdict:s.verdictFor(j.fullPath)})).filter(j=>!j.verdict.delete):[],v=b.length===0?void 0:`Delete denied for ${b[0].entry.fullPath}${b.length>1?` (+${b.length-1} more)`:""}: ${b[0].verdict.reasons.write.join("; ")}`,w=g||t.length===0||e==null||b.length>0,k=async()=>{if(w||!await h({title:i??(t.length===1?`Delete ${t[0].fullPath}?`:`Delete ${t.length} items?`),body:o??a.jsx("ul",{"data-pyric-delete-selection-paths":!0,children:t.map(C=>a.jsxs("li",{"data-pyric-entry-kind":C.kind,children:[C.fullPath,C.kind==="folder"?"/":""]},C.fullPath))}),destructive:!0,confirmLabel:l}))return;const S=await y(t);S.failed.length===0?(m({title:`Deleted ${S.deleted.length} ${S.deleted.length===1?"item":"items"}`,kind:"success"}),c?.(S)):(m({title:`Delete failed for ${S.failed.length} of ${t.length}`,kind:"error",body:a.jsx("ul",{"data-pyric-delete-selection-failures":!0,children:S.failed.map(C=>a.jsxs("li",{children:[C.fullPath,":"," ",C.error.code??C.error.message]},C.fullPath))})}),u?.(S))};return d?a.jsx(a.Fragment,{children:d({onClick:k,isRunning:g,progress:x,disabled:w,deniedReason:v})}):a.jsx("button",{type:"button",onClick:k,className:p,disabled:w,title:v,"data-pyric-ui":"delete-selection","data-pyric-destructive":"","data-pyric-running":g?"":void 0,"data-pyric-denied":v?"":void 0,"data-pyric-denied-reason":v,children:g?`Deleting… (${x})`:l})}function kn(e){const t=e.split("/").filter(Boolean),n=[];let r="";return t.forEach((s,i)=>{r=r?`${r}/${s}`:s,n.push({kind:i%2===0?"collection":"document",id:s,path:r})}),n}function _l(e){const t=e.indexOf("?");return is(t===-1?e:e.slice(0,t),t===-1?"":e.slice(t))}function vx(e){const{tab:t,rest:n,query:r}=_l(e),s=n.join("/");return t==="firestore"?{view:"firestore",path:kn(s)}:t==="auth"?{view:"auth",uid:n[0]??null}:t==="storage"?s?{view:"storage",kind:r.kind==="prefix"?"prefix":"object",path:s}:{view:"storage",kind:"root"}:null}function xx(e){switch(e.view){case"firestore":{const t=e.path[e.path.length-1];return{tab:"firestore",rest:t?t.path.split("/").filter(Boolean):[]}}case"auth":return{tab:"auth",rest:e.uid?[e.uid]:[]};case"storage":return e.kind==="root"?{tab:"storage"}:{tab:"storage",rest:e.path.split("/").filter(Boolean),...e.kind==="prefix"?{query:{kind:"prefix"}}:{}}}}function El(e){const{tab:t,query:n}=_l(e),r=vx(e),s=t==="traffic"?n.inspect??null:null;return{target:r,selectedInspectId:s}}let Gi=null,Br=El("");function wx(){const e=jo();return e!==Gi&&(Gi=e,Br=El(e)),Br}function jx(){return Br}function tn(e){ce(xx(e))}function kx(e){ce({tab:"traffic",query:{inspect:e}})}function Ln(){const e=f.useSyncExternalStore(Ft,wx,jx),t=f.useCallback(s=>tn(s),[]),n=f.useCallback(s=>{switch(s.kind){case"user":tn({view:"auth",uid:s.uid});break;case"storage":tn({view:"storage",kind:"object",path:s.objectPath});break;case"document":tn({view:"firestore",path:kn(s.path)});break}},[]),r=f.useCallback(s=>kx(s),[]);return f.useMemo(()=>({target:e.target,navigate:t,navigateRef:n,selectedInspectId:e.selectedInspectId,navigateInspect:r}),[e,t,n,r])}const Sx={narrowBreakpoint:640,mediumBreakpoint:920};function _x(e){switch(e){case"narrow":return 1;case"medium":return 2;case"wide":return 3}}function Ex(e,t){const n=_x(t),r=Math.min(Math.max(e,1),n),s=Math.max(e-r,0),i=t==="narrow"?0:n-r;return{startIndex:s,visibleCount:r,emptySlots:i}}function sr({label:e,error:t,hint:n,children:r}){return a.jsxs("div",{className:"fs-modal__group",children:[a.jsx("span",{className:"fs-modal__label",children:e}),r,t?a.jsx("span",{className:"fs-modal__err",role:"alert",children:t}):n?a.jsx("span",{className:"fs-modal__hint",children:n}):null]})}function Cl({mode:e,parentPath:t,onCreate:n,onClose:r}){const[s,i]=f.useState(""),[o,l]=f.useState(()=>Pv()),[c,u]=f.useState(null),[d,p]=f.useState(null),[h,m]=f.useState(!1),y=f.useRef(null),g=e==="collection"&&s?Dv(s):void 0,x=o?$v(o):void 0,v=!(e==="collection"&&(!s||g))&&!!o&&!x&&!h;f.useEffect(()=>{const j=S=>{S.key==="Escape"&&!h&&r()};return document.addEventListener("keydown",j),()=>document.removeEventListener("keydown",j)},[h,r]);const w=async()=>{if(!(!v||!c)){if(!c.isValid){c.touchAll();return}m(!0),p(null);try{await n({collectionId:e==="collection"?s:null,docId:o,data:ll(c.tree)}),r()}catch(j){p(j instanceof Error?j:new Error(String(j))),m(!1)}}},k=e==="collection"?"Start a collection":"Add a document";return a.jsx("div",{className:"fs-modal-backdrop",onMouseDown:j=>{j.target===j.currentTarget&&!h&&r()},children:a.jsxs("div",{ref:y,className:"fs-modal",role:"dialog","aria-modal":"true","aria-label":k,"data-pyric-ui":"fs-create-modal","data-fs-create-mode":e,children:[a.jsx("h2",{className:"fs-modal__title",children:k}),a.jsx(sr,{label:"Parent path",children:a.jsx("span",{className:"fs-modal__path",children:t})}),e==="collection"?a.jsx(sr,{label:"Collection ID",error:g,children:a.jsx("input",{autoFocus:!0,type:"text",value:s,placeholder:"e.g. users",onChange:j=>i(j.target.value),"data-pyric-field":"collection-id","aria-invalid":g?"true":void 0})}):null,a.jsx(sr,{label:"Document ID",error:o?x:"Cannot be empty",hint:"Auto-generated — edit to set your own.",children:a.jsx("input",{autoFocus:e==="document",type:"text",value:o,onChange:j=>l(j.target.value),"data-pyric-field":"doc-id","aria-invalid":x||!o?"true":void 0})}),a.jsxs("div",{className:"fs-modal__group",children:[a.jsx("span",{className:"fs-modal__label",children:"Fields"}),a.jsx("div",{className:"fs-modal__fields",children:a.jsx(Fi.Root,{initial:{},onChange:u,children:a.jsx(Fi.Fields,{})})})]}),d?a.jsx("p",{className:"fs-modal__err",role:"alert",children:d.message}):null,a.jsxs("div",{className:"fs-modal__actions",children:[a.jsx("button",{type:"button",className:"fs-editor__cancel",disabled:h,onClick:r,children:"Cancel"}),a.jsx("button",{type:"button",className:"fs-editor__save",disabled:!v,onClick:()=>void w(),children:h?"Saving…":"Save"})]})]})})}function Nl({items:e,label:t="More actions"}){const[n,r]=f.useState(!1),[s,i]=f.useState(null),o=f.useRef(null),l=()=>{if(!n){const c=o.current?.getBoundingClientRect();c&&i({top:c.bottom+4,right:window.innerWidth-c.right})}r(c=>!c)};return f.useEffect(()=>{if(!n)return;const c=u=>{u.key==="Escape"&&(r(!1),o.current?.focus())};return document.addEventListener("keydown",c),()=>document.removeEventListener("keydown",c)},[n]),a.jsxs("span",{className:"fs-overflow","data-pyric-ui":"fs-overflow-menu",children:[a.jsx("button",{ref:o,type:"button",className:"fs-overflow__trigger","aria-haspopup":"menu","aria-expanded":n,"aria-label":t,onClick:l,children:a.jsx("span",{"aria-hidden":"true",children:"⋮"})}),n?a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"fs-overflow__backdrop",onMouseDown:()=>r(!1)}),a.jsx("div",{className:"fs-overflow__menu",role:"menu",style:s?{top:s.top,right:s.right}:void 0,children:e.map(c=>a.jsx("button",{type:"button",role:"menuitem",className:"fs-overflow__item","data-destructive":c.destructive?"":void 0,disabled:c.disabled,onClick:()=>{r(!1),c.onSelect()},children:c.label},c.label))})]}):null]})}function Al(e){return JSON.stringify(e)}function Cx(e,t){const n=new Map,r=(s,i)=>{const o=t(s),l=Al(i);if(o==="map"){const c=s,u=Object.keys(c).sort();n.set(l,[o,u]);for(const d of u)r(c[d],[...i,["field",d]]);return}if(o==="array"){const c=s;n.set(l,[o,c.map((u,d)=>String(d))]),c.forEach((u,d)=>r(u,[...i,["index",d]]));return}n.set(l,[o,s])};for(const[s,i]of Object.entries(e))r(i,[["field",s]]);return n}function Rl(e,t){const n=[];let r=e.nodes[t];for(;r&&r.parentId!=null;){const s=e.nodes[r.parentId];if(!s)break;s.type==="array"?n.unshift(["index",(e.childIds[s.id]??[]).indexOf(r.id)]):n.unshift(["field",r.key??""]),r=s}return Al(n)}function Nx(e,t){const n=[];let r=e.nodes[t];for(;r&&r.parentId!=null;){const s=e.nodes[r.parentId];if(!s)break;if(s.type==="array"){const i=(e.childIds[s.id]??[]).indexOf(r.id);n.unshift(`[${i}]`)}else n.unshift(r.key??"");r=s}return n.reduce((s,i)=>i.startsWith("[")?`${s}${i}`:s?`${s}.${i}`:i,"")}function Ax(e,t){const n=e.nodes[t],r=n?.parentId!=null?e.nodes[n.parentId]:null;if(r?.type==="array"){const s=(e.childIds[r.id]??[]).indexOf(t);return{label:String(s),isArrayChild:!0}}return{label:n?.key??"",isArrayChild:!1}}function Ji(e,t,n){switch(e.type){case"map":return"{…}";case"array":return"[…]";case"string":return JSON.stringify(e.value);case"null":return"null";case"vector":{const r=t(e.value);return r?n(r):"vector"}default:return String(e.value)}}const Rx=42;function Dx(e,t,n,r=Rx){const s=e.nodes[t],i=e.childIds[t]??[];let o;return s.type==="array"?o=`[${i.slice(0,3).map(c=>Ji(e.nodes[c],n.asVectorView,n.vectorPreview)).join(", ")}${i.length>3?", …":""}]`:o=`{${i.slice(0,2).map(c=>`"${e.nodes[c].key}": ${Ji(e.nodes[c],n.asVectorView,n.vectorPreview)}`).join(", ")}${i.length>2?", …":""}}`,o.length>r?`${o.slice(0,r-1)}…`:o}function Ix(e,t,n){return t.parentId==null?!1:(e.childIds[t.parentId]??[]).some(s=>s!==t.id&&e.nodes[s]?.key===n)}function $x(e){return e.shiftKey===!0}const Dl=["string","number","boolean","null","timestamp","geopoint","reference","bytes","vector"],Px=[...Dl,"map","array"];function Ox({snapshot:e,documentRef:t,onCommit:n,onDeleteDocument:r,onDeleteDocumentFields:s,fieldEditors:i,onReferenceClick:o,onStartCollection:l,firestore:c,listSubcollections:u,onSubcollectionClick:d}){const p=f.useMemo(()=>e?.data()??{},[e]),h=f.useMemo(()=>p,[]),m=hl({initial:h}),y=m.replaceData,g=f.useMemo(()=>bl(i),[i]),x=vt(),[b,v]=f.useState(()=>new Set),[w,k]=f.useState(null),j=f.useRef(e),S=f.useRef(new Set),C=f.useRef(!1),[O,I]=f.useState(null),$=f.useMemo(()=>Cx(p,Un),[p]),N=vs({scope:t.path,entries:$,equals:jn,ready:w===null});f.useEffect(()=>{C.current&&(C.current=!1,I(null),n(m.toData()).catch(D=>{I(D instanceof Error?D:new Error(String(D)))}))},[m.tree]),f.useEffect(()=>{!e||e===j.current||w!==null||(j.current=e,S.current.clear(),y(e.data()??{}))},[w,y,e]);const _=f.useCallback(D=>{v(J=>{const se=new Set(J);return se.has(D)?se.delete(D):se.add(D),se})},[]),[E,A]=f.useState(null),q=f.useCallback((D,J)=>{if(J==="map"?m.addMapEntry(D,"","string"):m.addArrayEntry(D,"string"),D!==m.tree.rootId){const se=Rl(m.tree,D);v(ne=>new Set(ne).add(se))}A(D)},[m]);f.useEffect(()=>{if(!E)return;const D=m.tree.childIds[E]??[],J=D[D.length-1];J&&!w&&(S.current.add(J),k(J),A(null))},[m.tree,E]);const X=f.useCallback(D=>{m.remove(D),S.current.delete(D),C.current=!0,w===D&&k(null)},[m,w]),R=f.useCallback(async(D,J,se)=>{if($x(se)){X(D.id);return}await x({title:`Delete field "${J}"?`,destructive:!0,confirmLabel:"Delete"})&&X(D.id)},[x,X]),P=t.id,U=m.tree.childIds[m.tree.rootId]??[];return a.jsxs("div",{"data-pyric-ui":"fs-doctree",className:"fs-doctree",children:[a.jsxs("div",{className:"fs-doctree__head",children:[a.jsx("span",{className:"fs-doctree__docid",children:P}),a.jsx(Nl,{items:[{label:"Delete document fields",onSelect:()=>{(async()=>await x({title:"Delete all fields?",body:"The document itself is kept, empty.",destructive:!0,confirmLabel:"Delete fields"})&&s())()},destructive:!0},{label:"Delete document",onSelect:r,destructive:!0}]})]}),O?a.jsx("p",{className:"fs-doctree__err",children:O.message}):null,a.jsxs("ul",{className:"fs-doctree__rows",children:[l?a.jsx("li",{className:"fs-doctree__action-row",children:a.jsxs("button",{type:"button",className:"fs-doctree__action",onClick:l,children:[a.jsx("span",{"aria-hidden":"true",children:"+"})," Start collection"]})}):null,a.jsx("li",{className:"fs-doctree__action-row",children:a.jsxs("button",{type:"button",className:"fs-doctree__action",onClick:()=>q(m.tree.rootId,"map"),children:[a.jsx("span",{"aria-hidden":"true",children:"+"})," Add field"]})}),U.map(D=>a.jsx(Il,{nodeId:D,depth:0,editor:m,registry:g,expanded:b,onToggle:_,editingId:w,setEditingId:k,newIdsRef:S,onAdd:q,onDelete:R,onCommitNeeded:()=>{C.current=!0},onReferenceClick:o,updates:N},D))]}),c&&u?a.jsx($l,{firestore:c,documentRef:t,listSubcollections:u,onSubcollectionClick:d}):null]})}function Il({nodeId:e,depth:t,editor:n,registry:r,expanded:s,onToggle:i,editingId:o,setEditingId:l,newIdsRef:c,onAdd:u,onDelete:d,onCommitNeeded:p,onReferenceClick:h,updates:m}){const{tree:y}=n,g=y.nodes[e];if(!g)return null;const{label:x,isArrayChild:b}=Ax(y,e),v=g.type==="map"||g.type==="array",w=Nx(y,e),k=Rl(y,e),j=m.get(k),S=s.has(k),C=o===e,O=c.current.has(e);return C?a.jsx("li",{className:"fs-doctree__row fs-doctree__row--editing","data-pyric-doctree-depth":t,style:{"--fs-depth":t},children:a.jsx(Ux,{node:g,isNew:O,isArrayChild:b,tree:y,editor:n,registry:r,path:w,onCommitNeeded:p,onDone:()=>{c.current.delete(e),l(null)},onCancelNew:()=>{n.remove(e),c.current.delete(e),l(null)}})}):a.jsxs("li",{className:"fs-doctree__row","data-pyric-doctree-depth":t,"data-pyric-doctree-nested":v?"":void 0,style:{"--fs-depth":t},children:[a.jsxs("div",{className:"fs-doctree__line","data-pyric-update":j?.kind,"data-pyric-update-cycle":j?.cycle,children:[v?a.jsx("button",{type:"button",className:"fs-doctree__caret","aria-expanded":S,onClick:()=>i(k),children:a.jsx("span",{"aria-hidden":"true",children:S?"▼":"▶"})}):a.jsx("span",{className:"fs-doctree__caret fs-doctree__caret--empty","aria-hidden":"true"}),b?a.jsx("span",{className:"fs-doctree__chip",children:x}):a.jsx("span",{className:"fs-doctree__key",children:x}),v?S?null:a.jsx("span",{className:"fs-doctree__preview",children:Dx(y,e,{asVectorView:Ye,vectorPreview:al})}):a.jsx("span",{className:"fs-doctree__value",children:a.jsx(Tr,{value:g.value,path:w,fieldEditors:r})}),a.jsxs("span",{className:"fs-doctree__hover",children:[a.jsxs("span",{className:"fs-doctree__typenote",children:["(",g.type,")"]}),v?a.jsx("button",{type:"button",className:"fs-doctree__icon",title:"Add field","aria-label":`Add field to ${x||"document"}`,onClick:()=>u(e,g.type==="array"?"array":"map"),children:"+"}):a.jsx("button",{type:"button",className:"fs-doctree__icon",title:"Edit","aria-label":`Edit ${x}`,onClick:()=>l(e),children:"✎"}),a.jsx("button",{type:"button",className:"fs-doctree__icon fs-doctree__icon--danger",title:"Delete (shift-click to skip confirmation)","aria-label":`Delete ${x||"field"} (shift-click to skip confirmation)`,onClick:I=>void d(g,x,{shiftKey:I.shiftKey}),children:"🗑"})]})]}),v&&S?a.jsxs("ul",{className:"fs-doctree__children",children:[(y.childIds[e]??[]).map(I=>a.jsx(Il,{nodeId:I,depth:t+1,editor:n,registry:r,expanded:s,onToggle:i,editingId:o,setEditingId:l,newIdsRef:c,onAdd:u,onDelete:d,onCommitNeeded:p,onReferenceClick:h,updates:m},I)),a.jsx("li",{className:"fs-doctree__action-row fs-doctree__action-row--nested",children:a.jsxs("button",{type:"button",className:"fs-doctree__action",onClick:()=>u(e,g.type==="array"?"array":"map"),children:[a.jsx("span",{"aria-hidden":"true",children:"+"})," ",g.type==="array"?"Add item":"Add field"]})})]}):null]})}function Ux({node:e,isNew:t,isArrayChild:n,tree:r,editor:s,registry:i,path:o,onCommitNeeded:l,onDone:c,onCancelNew:u}){const[d,p]=f.useState(e.key??""),[h,m]=f.useState(e.type),[y,g]=f.useState(e.value),[x,b]=f.useState(!1),v=n?void 0:d===""?"Field name is required":Ix(r,e,d)?"Field name must be unique":void 0,w=h==="map"||h==="array"?void 0:ul(h,y),k=!v&&!w,j=()=>{if(!k){b(!0);return}n||s.setKey(e.id,d),h!==e.type&&s.setType(e.id,h),h!=="map"&&h!=="array"&&s.setValue(e.id,y),l(),c()},S=()=>{t?u():c()},O=i[h]?.Edit,I=h!=="map"&&h!=="array"&&O?a.jsx(O,{value:y,path:o,error:x?w:void 0,onChange:_=>g(_)}):h==="map"||h==="array"?a.jsxs("span",{className:"fs-doctree__editnote",children:["Saves as an empty ",h," — add its children afterward."]}):null,$=a.jsxs("span",{className:"fs-doctree__editactions",children:[a.jsx("button",{type:"button",className:"fs-doctree__editsave",onClick:j,"aria-label":"Save field",children:"✓"}),a.jsx("button",{type:"button",className:"fs-doctree__editcancel",onClick:S,"aria-label":"Cancel edit",children:"✕"})]}),N=a.jsx("select",{className:"fs-doctree__edittype",value:h,onChange:_=>{const E=_.target.value;m(E),E!=="map"&&E!=="array"&&E!==h&&g(Tx(E))},"aria-label":"Field type",children:(t?Px:Dl).map(_=>a.jsx("option",{value:_,children:_},_))});return a.jsxs("div",{className:"fs-doctree__editrow",onKeyDown:_=>{_.key==="Enter"&&!_.target.matches("textarea")?(_.preventDefault(),j()):_.key==="Escape"&&(_.preventDefault(),S())},children:[n?null:a.jsxs("div",{className:"fs-doctree__editline",children:[a.jsx("input",{type:"text",className:"fs-doctree__editkey",value:d,placeholder:"Field name",autoFocus:t,onChange:_=>p(_.target.value),onBlur:()=>b(!0),"aria-label":"Field name","aria-invalid":x&&v?"true":void 0}),N]}),a.jsxs("div",{className:"fs-doctree__editline",children:[n?N:null,I,$]}),x&&v?a.jsx("span",{className:"fs-doctree__editerr",children:v}):null]})}function Tx(e){switch(e){case"string":return"";case"number":return 0;case"boolean":return!1;default:return null}}function $l({firestore:e,documentRef:t,listSubcollections:n,onSubcollectionClick:r}){const{subcollections:s,isLoading:i}=Lg({firestore:e,documentRef:t,listSubcollections:n});return!i&&s.length===0?null:a.jsxs("section",{"data-pyric-ui":"fs-doctree-subcollections","data-pyric-loading":i?"":void 0,children:[a.jsx("div",{className:"fs-doctree__subhead",children:"Subcollections"}),a.jsx("ul",{className:"fs-doctree__sublist",children:s.map(o=>a.jsx("li",{children:r?a.jsxs("button",{type:"button",className:"fs-doctree__subrow",onClick:()=>r(o),"aria-label":`Open subcollection ${o.id}`,children:[a.jsx("span",{children:o.id}),a.jsx("span",{className:"fs-doctree__subtype",children:"subcollection"}),a.jsx("span",{"aria-hidden":"true",children:"›"})]}):a.jsxs("div",{className:"fs-doctree__subrow",children:[a.jsx("span",{children:o.id}),a.jsx("span",{className:"fs-doctree__subtype",children:"subcollection"})]})},o.path))})]})}function Mx(e){return e.split("/").filter(Boolean).length%2===0}function Pl(e,t){async function*n(s,i,o=!1){const l=await t.listSubcollections(s.path);for(const c of l)yield*r(e.collection(s,c),i);o||(await e.deleteDoc(s),i.n++,yield{deletedCount:i.n,done:!1})}async function*r(s,i){const o=await t.listDocuments(s.path);for(const l of o){const c=l.path.split("/").pop();c&&(yield*n(e.doc(s,c),i,l.phantom===!0))}}return{async*start(s){const i={n:0};Mx(s.path)?yield*n(s,i):yield*r(s,i),yield{deletedCount:i.n,done:!0}}}}async function Ol(e,t){for await(const n of e.start(t))if(n.done)return}async function Ul({confirm:e,ref:t,api:n,recursiveImpl:r}){let s=!1;return await e({title:`Delete document "${t.id}"?`,body:a.jsxs("label",{className:"fs-delete-recursive",children:[a.jsx("input",{type:"checkbox",onChange:o=>{s=o.currentTarget.checked}}),a.jsx("span",{children:"Also delete subcollections recursively. Leave this off to keep nested data."})]}),destructive:!0,confirmLabel:"Delete document"})?(s?await Ol(r,t):await n.deleteDoc(t),!0):!1}function Lx(e){const t=e.exists;return typeof t=="function"?t.call(e):t}async function Bx(e,t,n,r){const s=e.doc(t,n),i=await e.getDoc(s);if(typeof i.exists=="function"?i.exists():!!i.exists)throw new Error(`Document "${n}" already exists here — choose a different ID.`);await e.setDoc(s,r)}function Fx(e){return{id:e.id,ref:e,data:()=>{},__pyricPhantom:!0}}function Yi(e){return e.__pyricPhantom===!0}function Vx(e,t,n){const r=n.split("/");if(r.length===1)return e.collection(t,n);const s=r[r.length-1],i=r.slice(0,-1).join("/");return e.collection(e.doc(t,i),s)}function qx({handles:e}){const{target:t,navigate:n}=Ln(),r=e.adminFirestore,s=ms(),i=f.useMemo(()=>t?.view==="firestore"?t.path:[],[t]),o=f.useCallback(k=>{const j=typeof k=="function"?k(i):k;n({view:"firestore",path:j})},[n,i]),l=(k,j)=>o(S=>[...S.slice(0,k+1),j]),[c,u]=f.useState(null),d=f.useCallback(async({collectionId:k,docId:j,data:S})=>{if(!c||!k)return;const C=c.parentDocPath,O=C?s.collection(s.doc(r,C),k):s.collection(r,k);await Bx(s,O,j,S);const I=C?`${C}/${k}`:k;n({view:"firestore",path:kn(`${I}/${j}`)})},[s,r,c,n]),p=[a.jsx(Kx,{api:s,firestore:r,collectionIds:e.listRootCollections(),onSelect:k=>o([{kind:"collection",id:k,path:k}]),onStartCollection:()=>u({parentDocPath:null})},"__root__"),...i.map((k,j)=>k.kind==="collection"?a.jsx(Hx,{api:s,firestore:r,handles:e,collectionPath:k.path,selectedId:i[j+1]?.id??null,onSelect:S=>l(j,{kind:"document",id:S.id,path:S.path}),onCollectionDeleted:()=>o(S=>S.slice(0,j))},k.path):a.jsx(Gx,{api:s,firestore:r,handles:e,docPath:k.path,onOpenSubcollection:S=>l(j,{kind:"collection",id:S.id,path:S.path}),onReferenceClick:S=>n({view:"firestore",path:kn(S.path)}),onStartCollection:()=>u({parentDocPath:k.path}),onDeleted:()=>o(S=>S.slice(0,j))},k.path))],{ref:h,size:m}=Tn(Sx),{startIndex:y,visibleCount:g,emptySlots:x}=Ex(p.length,m),b=p.slice(y,y+g),v=i.length===0?"Select a collection":i[i.length-1]?.kind==="collection"?"Select a document":null,w=[...b,...Array.from({length:x},(k,j)=>a.jsx(zx,{hint:j===0?v:null},`__empty_${j}__`))];return f.useEffect(()=>{if(m==="wide")return;const k=h.current;if(!k)return;const j=document.activeElement;if(j&&j!==document.body&&k.contains(j))return;const S=k.querySelector(".fs-columns > .fs-col:last-child");S&&(S.tabIndex=-1,S.focus({preventScroll:!0}))},[i.length,m]),a.jsx(ps,{children:a.jsxs("div",{ref:h,"data-pyric-ui":"fs-browser","data-fs-depth":i.length,"data-size":m,children:[a.jsx(Wx,{path:i,onHome:()=>o([]),onJump:k=>o(j=>j.slice(0,k+1))}),a.jsx("div",{className:"fs-columns",children:w}),c?a.jsx(Cl,{mode:"collection",parentPath:c.parentDocPath?`/${c.parentDocPath}`:"/",onCreate:d,onClose:()=>u(null)}):null]})})}function Wx({path:e,onHome:t,onJump:n}){return a.jsxs("nav",{"data-pyric-ui":"fs-breadcrumb","aria-label":"Firestore path",children:[a.jsx("button",{type:"button",className:"fs-crumb",onClick:t,children:"home"}),e.map((r,s)=>a.jsxs(f.Fragment,{children:[a.jsx("span",{className:"fs-crumb-sep","aria-hidden":!0,children:"›"}),s===e.length-1?a.jsx("span",{className:"fs-crumb fs-crumb--current",children:r.id}):a.jsx("button",{type:"button",className:"fs-crumb",onClick:()=>n(s),children:r.id})]},r.path))]})}function zx({hint:e}){return a.jsx("section",{"data-pyric-ui":"fs-empty-col",className:"fs-pane fs-col fs-col--empty","aria-hidden":e?void 0:!0,children:e?a.jsx("p",{className:"fs-empty",children:e}):null})}function Kx({api:e,firestore:t,collectionIds:n,onSelect:r,onStartCollection:s}){const i=f.useMemo(()=>n.map(o=>e.collection(t,o)),[e,t,n]);return a.jsxs("section",{"data-pyric-ui":"fs-collections",className:"fs-pane fs-col",children:[a.jsxs("div",{className:"fs-phead",children:[a.jsx("span",{className:"fs-phead-title",children:"Collections"}),a.jsx("button",{type:"button",className:"fs-add",onClick:s,children:"+ New"})]}),a.jsx(Nv,{collections:i,onSelect:o=>r(o.id),emptyState:a.jsx("p",{className:"fs-empty",children:"No collections yet. App or agent writes show up here."})})]})}function Hx({api:e,firestore:t,handles:n,collectionPath:r,selectedId:s,onSelect:i,onCollectionDeleted:o}){const l=f.useMemo(()=>Vx(e,t,r),[e,t,r]),{documents:c,isLoading:u,error:d,subscriptionGeneration:p,hasMore:h,loadMore:m,createDocument:y}=Mg({collection:l,mode:"live"}),[g,x]=f.useState([]);f.useEffect(()=>{let N=!1;return Promise.resolve(n.listDocuments(r)).then(_=>{N||x(_.filter(E=>E.phantom).map(E=>E.path.split("/").pop()??""))}).catch(()=>{N||x([])}),()=>{N=!0}},[n,r,c]);const b=f.useMemo(()=>{const N=new Set(c.map(_=>_.id));return[...c,...g.filter(_=>_.length>0&&!N.has(_)).map(_=>Fx(e.doc(t,`${r}/${_}`)))]},[c,g,e,t,r]),v=r.split("/").pop()??r,[w,k]=f.useState(null),[j,S]=f.useState(!1),C=vt(),O=f.useMemo(()=>Pl(e,n),[e,n]),I=f.useCallback(async N=>{k(null);try{await Ul({confirm:C,ref:N,api:e,recursiveImpl:O})}catch(_){k(_ instanceof Error?_:new Error(String(_)))}},[e,C,O]),$=f.useCallback(async()=>{if(await C({title:`Delete collection "${v}"?`,body:"This deletes every document in it (and their subcollections).",destructive:!0,confirmLabel:"Delete collection"})){k(null);try{await Ol(O,l),o()}catch(_){k(_ instanceof Error?_:new Error(String(_)))}}},[C,O,l,v,o]);return a.jsxs("section",{"data-pyric-ui":"fs-documents",className:"fs-pane fs-col",children:[a.jsxs("div",{className:"fs-phead",children:[a.jsx("span",{className:"fs-phead-title",children:v}),a.jsx("span",{className:"fs-phead-actions",children:a.jsx("button",{type:"button",className:"fs-add",onClick:()=>S(!0),children:"+ New"})}),a.jsx(Nl,{items:[{label:"Delete collection",onSelect:()=>void $(),destructive:!0}]})]}),j?a.jsx(Cl,{mode:"document",parentPath:`/${r}`,onCreate:async({docId:N,data:_})=>{const E=await y(N,_,{onExisting:"fail"});i(E)},onClose:()=>S(!1)}):null,a.jsx(Av,{documents:b,isLoading:u,error:d,updateScope:`${r}:${p}`,hasMore:h,onLoadMore:m,onSelect:i,renderLabel:N=>{const _=N.ref;return a.jsx("span",{"data-pyric-selected":s===_.id?"":void 0,style:{display:"contents"},children:Yi(N)?a.jsxs(a.Fragment,{children:[a.jsx("span",{className:"fs-doc-phantom",children:N.id}),a.jsx("span",{className:"fs-sub fs-doc-phantom-hint",children:"missing"})]}):N.id})},renderRowAction:N=>{if(Yi(N))return null;const _=N.ref;return a.jsx("button",{type:"button",className:"fs-doc-del",title:"Delete document","aria-label":`Delete ${_.id}`,onClick:E=>{E.stopPropagation(),I(_)},children:"×"})},emptyState:a.jsx("p",{className:"fs-empty",children:"No documents."})}),w?a.jsx("p",{className:"fs-empty fs-doc-del-err",children:w.message}):null]})}function Gx({api:e,firestore:t,handles:n,docPath:r,onOpenSubcollection:s,onReferenceClick:i,onStartCollection:o,onDeleted:l}){const c=f.useMemo(()=>e.doc(t,r),[e,t,r]),{data:u,error:d,isLoading:p}=Eg(c),h=f.useCallback(async(k,j)=>(await n.listSubcollections(j.path)).map(C=>e.collection(j,C)),[n,e]),m=vt(),y=f.useMemo(()=>Pl(e,n),[e,n]),[g,x]=f.useState(null),b=f.useCallback(async()=>{x(null);try{await Ul({confirm:m,ref:c,api:e,recursiveImpl:y})&&l()}catch(k){x(k instanceof Error?k:new Error(String(k)))}},[e,m,y,c,l]),v=f.useCallback(async()=>{await e.setDoc(c,{})},[e,c]),w=u!=null&&Lx(u);return a.jsxs("section",{"data-pyric-ui":"fs-document",className:"fs-pane fs-col doc",children:[w?null:a.jsxs("div",{className:"fs-phead",children:[a.jsx("span",{className:"fs-phead-title",children:c.id}),a.jsx("span",{className:"fs-phead-actions",children:a.jsx("button",{type:"button",className:"fs-add",onClick:o,children:"+ Collection"})})]}),u&&w?a.jsx(Ox,{snapshot:u,documentRef:c,firestore:t,listSubcollections:h,onReferenceClick:i,onSubcollectionClick:s,onStartCollection:o,onDeleteDocument:()=>void b(),onDeleteDocumentFields:v,onCommit:async k=>{await e.setDoc(c,k)}},r):d?a.jsx("p",{className:"fs-empty fs-doc-del-err",children:d.message}):p?a.jsx("p",{className:"fs-empty",children:"Loading document…"}):a.jsxs(a.Fragment,{children:[a.jsx("p",{className:"fs-empty",children:"This document does not exist."}),a.jsx($l,{firestore:t,documentRef:c,listSubcollections:h,onSubcollectionClick:s})]}),g?a.jsx("p",{className:"fs-empty fs-doc-del-err",children:g.message}):null]})}const Jx="block w-full text-sm text-soft-white";function Yx({auth:e,focusUid:t}){const{users:n,totalCount:r,isLoading:s,error:i,filter:o,setFilter:l,updateUser:c}=hs(e),[u,d]=f.useState(null);f.useEffect(()=>{t&&(d(t),l(t))},[t,l]);const p=n.find(h=>h.uid===u)??null;return a.jsxs("div",{className:"grid grid-cols-[1fr_320px] gap-4",children:[a.jsxs("section",{className:"min-w-0",children:[a.jsx("input",{value:o,onChange:h=>l(h.target.value),placeholder:"Filter users…",className:"mb-3 w-full rounded border border-border bg-content-bg px-3 py-1.5 text-sm text-soft-white placeholder:text-slate-gray"}),a.jsx(el,{users:n,isLoading:s,error:i,filter:o,onSelect:h=>d(h.uid),className:Jx,emptyState:a.jsx("p",{className:"py-6 text-sm text-slate-gray",children:"No users yet. Sign in from the app, or the agent seeds them, and they appear here."}),noResultsState:a.jsx("p",{className:"py-6 text-sm text-slate-gray",children:"No users match the filter."})}),a.jsxs("p",{className:"mt-2 text-xs text-slate-gray",children:[r," user(s) total"]})]}),a.jsx("section",{className:"min-w-0 border-l border-border pl-4",children:p?a.jsx(Xx,{user:p,onSave:h=>c(p.uid,h)},p.uid):a.jsx("p",{className:"py-6 text-sm text-slate-gray",children:"Select a user to view and edit."})})]})}function Xx({user:e,onSave:t}){const n=Zo({initial:e}),[r,s]=f.useState(null),[i,o]=f.useState(!1),l=()=>{s(null),o(!1);try{t(n.toUpdateRequest()),o(!0)}catch(c){s(c instanceof Error?c:new Error(String(c)))}};return a.jsxs("div",{"data-pyric-ui":"auth-editor",children:[a.jsx("h3",{className:"mb-3 truncate font-mono text-xs text-slate-gray",title:e.uid,children:e.uid}),a.jsxs("label",{className:"mb-3 block text-xs text-slate-gray",children:["Display name",a.jsx("input",{value:n.fields.displayName,onChange:c=>n.setField("displayName",c.target.value),className:"mt-1 w-full rounded border border-border bg-content-bg px-2 py-1 text-sm text-soft-white"})]}),a.jsxs("label",{className:"mb-3 block text-xs text-slate-gray",children:["Custom claims (JSON)",a.jsx("textarea",{value:n.fields.claimsText,onChange:c=>n.setField("claimsText",c.target.value),rows:6,spellCheck:!1,className:"mt-1 w-full rounded border border-border bg-content-bg p-2 font-mono text-xs text-soft-white"}),n.errors.claims?a.jsx("span",{className:"text-danger",children:n.errors.claims}):null]}),a.jsxs("label",{className:"mb-3 flex items-center gap-2 text-xs text-slate-gray",children:[a.jsx("input",{type:"checkbox",checked:n.fields.disabled,onChange:c=>n.setField("disabled",c.target.checked)}),"Disabled"]}),r?a.jsx("p",{className:"mb-2 text-xs text-danger",children:r.message}):null,i?a.jsx("p",{className:"mb-2 text-xs text-primary",children:"Saved."}):null,a.jsxs("div",{className:"flex gap-2",children:[a.jsx("button",{type:"button",onClick:l,disabled:!n.isValid||!n.isDirty,className:"rounded bg-primary/15 px-3 py-1 text-xs font-medium text-primary hover:bg-primary/25 disabled:opacity-40",children:"Save"}),a.jsx("button",{type:"button",onClick:n.reset,disabled:!n.isDirty,className:"rounded border border-border px-3 py-1 text-xs text-slate-gray hover:text-soft-white disabled:opacity-40",children:"Reset"})]})]})}function Xi(e){const t=Y(e),n=t.lastIndexOf("/");return n===-1?"":t.slice(0,n)}function Qi(e,t){return e===""?t:t===""?e:`${e}/${t}`}function Zi(e){const t=e.lastIndexOf("/");return t===-1?e:e.slice(t+1)}const Qx=[{key:"size",label:"size",value:e=>`${e.size} bytes`},{key:"contentType",label:"content type",value:e=>e.contentType},{key:"timeCreated",label:"created",value:e=>e.timeCreated},{key:"updated",label:"updated",value:e=>e.updated},{key:"md5Hash",label:"md5",value:e=>e.md5Hash},{key:"cacheControl",label:"cache control",value:e=>e.cacheControl},{key:"fullPath",label:"path",value:e=>`gs://${e.bucket}/${e.fullPath}`}];function Zx(e){const t=Object.entries(e.customMetadata??{});return a.jsxs("dl",{"data-pyric-object-metadata":!0,children:[a.jsx("div",{"data-storage-meta-group":!0,children:"Metadata"}),Qx.map(({key:n,label:r,value:s})=>{const i=s(e);return i===void 0?null:a.jsxs("div",{"data-pyric-metadata-field":n,children:[a.jsx("dt",{children:r}),a.jsx("dd",{children:i})]},n)}),t.length>0?a.jsx("div",{"data-storage-meta-group":!0,children:"Custom metadata"}):null,t.map(([n,r])=>a.jsxs("div",{"data-pyric-metadata-field":"customMetadata","data-pyric-metadata-key":n,children:[a.jsx("dt",{children:n}),a.jsx("dd",{children:r})]},`custom:${n}`))]})}function ew(){return a.jsx("svg",{"aria-hidden":!0,viewBox:"0 0 16 16",width:"13",height:"13",fill:"none",stroke:"currentColor",strokeWidth:"1.25",strokeLinejoin:"round",children:a.jsx("path",{d:"M1.75 4.25c0-.55.45-1 1-1h3.4l1.5 1.7h5.6c.55 0 1 .45 1 1v6.05c0 .55-.45 1-1 1H2.75c-.55 0-1-.45-1-1z"})})}function tw(){return a.jsxs("svg",{"aria-hidden":!0,viewBox:"0 0 16 16",width:"13",height:"13",fill:"none",stroke:"currentColor",strokeWidth:"1.25",strokeLinejoin:"round",children:[a.jsx("path",{d:"M4.25 1.75h5l3 3v9.5h-8z"}),a.jsx("path",{d:"M9.25 1.75v3h3"})]})}function nw(e){const t=e.kind==="folder";return a.jsxs(a.Fragment,{children:[a.jsxs("span",{className:"storage__cell-name",children:[a.jsx("span",{className:"storage__ic","aria-hidden":!0,children:t?a.jsx(ew,{}):a.jsx(tw,{})}),a.jsx("span",{className:"storage__nm",children:e.name}),t?a.jsx("span",{"aria-hidden":!0,className:"storage__chev",children:"›"}):null]}),a.jsx("span",{className:"storage__cell-type",children:t?"folder":"file"}),a.jsx("span",{className:"storage__cell-size"}),a.jsx("span",{className:"storage__cell-updated"})]})}function rw({storage:e,focusTarget:t}){const n=Ln(),r=t.kind==="object"?Y(t.path):null,s=t.kind==="prefix"?Y(t.path):r?Xi(r):"",i=f.useCallback(N=>{const _=Y(N);n.navigate(_?{view:"storage",kind:"prefix",path:_}:{view:"storage",kind:"root"})},[n.navigate]),o=Mv({path:s,onPathChange:i}),l=N=>{n.navigate({view:"storage",kind:"object",path:Y(N)})},c=Tv(e,o.path),u=Bv(),d=Kv(e),[p,h]=f.useReducer(rx,kl),m=Jv(e,{path:o.path,list:c,onComplete:N=>h({type:"materialize",path:Xi(N.fullPath)})});f.useEffect(()=>{if(c.status==="success")for(const N of c.entries)N.kind==="folder"&&Hi(p,N.fullPath)&&h({type:"materialize",path:N.fullPath})},[c.status,c.entries,p]);const[y,g]=f.useState(!1),[x,b]=f.useState(""),[v,w]=f.useState(null),k=f.useRef(null),j=f.useMemo(()=>{const N=sx(p,o.path).filter(A=>!c.entries.some(q=>q.kind==="folder"&&q.name===A));if(N.length===0)return c.entries;const _=N.map(A=>{const q=Qi(o.path,A);return{kind:"folder",name:A,fullPath:q,ref:{fullPath:q,name:A}}});return[...[...c.entries.filter(A=>A.kind==="folder"),..._].sort((A,q)=>A.name<q.name?-1:A.name>q.name?1:0),...c.entries.filter(A=>A.kind==="object")]},[c.entries,p,o.path]),S=j.length>0&&j.every(N=>u.isSelected(N.fullPath)),C=N=>{const _=new Set(j.map(A=>A.name)),E=nx(N.map(A=>A.relativePath),_);m.upload(N.map((A,q)=>({path:E[q],data:A.file})))},O=N=>{N.preventDefault();const _=ix(x);if(_){w(_);return}const E=Qi(o.path,Y(x));h({type:"create",path:E}),o.setPath(E),b(""),w(null),g(!1)};f.useEffect(()=>u.clear(),[o.path,u.clear]);const I=m.tasks.filter(N=>N.status==="error"),$=d.verdictFor(o.path);return a.jsx(yx,{children:a.jsx(ps,{children:a.jsxs("div",{className:"storage",children:[a.jsxs("div",{className:"storage__sub",children:[a.jsx(Yv,{path:o.path,rootLabel:"files",onNavigate:o.setPath}),a.jsx("div",{className:"storage__actions",children:u.size>0?a.jsxs(a.Fragment,{children:[a.jsxs("span",{className:"studio-selection-count",children:[u.size," selected"]}),a.jsx(gx,{storage:e,entries:u.selected,list:c,gate:d,className:"studio-selection-delete",onDeleted:N=>{for(const _ of u.selected)_.kind==="folder"&&N.deleted.includes(_.fullPath)&&h({type:"discard",path:_.fullPath});r&&u.selected.some(_=>_.kind==="object"?_.fullPath===r:r.startsWith(`${_.fullPath}/`))&&o.setPath(o.path),u.clear(),c.refresh()},onFailed:N=>{const _=new Set(N.failed.map(E=>E.fullPath));u.selectAll(u.selected.filter(E=>_.has(E.fullPath))),c.refresh()}}),a.jsx("button",{type:"button",className:"storage__action",onClick:u.clear,children:"Clear selection"})]}):a.jsxs(a.Fragment,{children:[a.jsx("button",{type:"button",className:"storage__action","aria-expanded":y,onClick:()=>{g(N=>!N),w(null)},children:"New folder"}),a.jsx("button",{type:"button",className:"storage__action storage__action--upload",onClick:()=>k.current?.click(),children:"Upload files"}),a.jsx("input",{ref:k,type:"file",multiple:!0,hidden:!0,onChange:N=>{const _=Array.from(N.currentTarget.files??[]);_.length>0&&C(_.map(E=>({file:E,relativePath:E.name}))),N.currentTarget.value=""}})]})})]}),y?a.jsxs("form",{className:"storage__newfolder",onSubmit:O,children:[a.jsx("input",{autoFocus:!0,className:"storage__newfolder-input",placeholder:"folder or nested/path/of/folders","aria-label":"New folder name",value:x,onChange:N=>{b(N.currentTarget.value),w(null)},onKeyDown:N=>{N.key==="Escape"&&g(!1)}}),a.jsx("button",{type:"submit",className:"storage__newfolder-btn",children:"Create"}),v?a.jsx("span",{className:"storage__newfolder-err",role:"alert",children:v}):a.jsx("span",{className:"storage__newfolder-note",children:"Nested paths create the whole chain. Empty folders last this session only — upload a file to keep one."})]}):null,I.length>0?a.jsxs("p",{className:"storage__upload-err",role:"alert",children:[I.length===1?`Upload failed: ${Zi(I[0].fullPath)} — ${I[0].error?.message??"error"}`:`${I.length} uploads failed: ${I.map(N=>Zi(N.fullPath)).join(", ")}`,a.jsx("button",{type:"button",className:"storage__upload-err-dismiss",onClick:m.clearCompleted,children:"Dismiss"})]}):null,a.jsxs("div",{className:"storage__body","data-storage-level":r?"inspector":"browser",children:[a.jsxs(Zv,{className:"storage__browser",onFiles:C,disabled:!$.upload,disabledReason:$.reasons.write.join("; "),children:[a.jsxs("div",{className:"storage__lhead",children:[a.jsx("label",{className:"storage__select-all",title:"Select all in this folder",children:a.jsx("input",{type:"checkbox","aria-label":"Select all in this folder",checked:S,onChange:N=>N.currentTarget.checked?u.selectAll(j):u.clear()})}),a.jsx("span",{children:"name"}),a.jsx("span",{children:"type"}),a.jsx("span",{children:"size"}),a.jsx("span",{children:"updated"})]}),a.jsx(Xv,{entries:j,status:c.status,error:c.error,gate:d,selectedPath:r??void 0,renderEntry:nw,renderRowAction:N=>a.jsx("label",{className:"storage__select-row",title:`Select ${N.name}`,children:a.jsx("input",{type:"checkbox","aria-label":`Select ${N.name}`,checked:u.isSelected(N.fullPath),onChange:()=>u.toggle(N)})}),onNavigate:o.enter,onSelect:N=>l(N.fullPath),emptyState:a.jsx("p",{className:"storage__empty",children:Hi(p,o.path)?"Empty folder — session-only until a file is uploaded here. Drop files anywhere in this pane, or use Upload files.":"No files yet. Drop files here or use Upload files; files your app uploads to Storage also appear here."})}),a.jsxs("div",{className:"storage__dropcue","aria-hidden":!0,children:["Drop to upload to /",o.path||""]})]}),a.jsx("div",{className:"storage__inspector",children:r?a.jsxs(a.Fragment,{children:[a.jsx("button",{type:"button",className:"storage__back",onClick:()=>o.setPath(o.path),"aria-label":"Back to files",children:"‹ Files"}),a.jsx(px,{storage:e,path:r,renderMetadata:Zx})]}):a.jsx("p",{className:"storage__inspector-hint",children:"Select an object to inspect its preview and metadata."})})]})]})})})}function sw({view:e}){const t=e==="firestore"?"Firestore":e==="auth"?"Auth":"Storage";return a.jsxs("div",{"data-pyric-ui":"data-pending",className:"flex flex-col items-center justify-center gap-2 py-16 text-center",children:[a.jsx("span",{className:"rounded-full border border-border px-3 py-1 text-xs uppercase tracking-wide text-slate-gray",children:"Local backend pending"}),a.jsxs("p",{className:"max-w-md text-sm leading-relaxed text-slate-gray",children:["The ",t," viewer mounts here. It goes live once the local sandbox backend is reachable (the served `pyric dev --ui` workspace)."]})]})}function Tl({view:e}){const{target:t}=Ln(),n=Oe(),r=n.status==="ready"?n.handles.auth:null;return a.jsx("div",{"data-pyric-ui":"data-feature",children:n.status!=="ready"||!r?a.jsx(sw,{view:e}):n.authApi?a.jsx(Jo,{value:n.authApi,children:a.jsx(ea,{view:e,handles:n.handles,auth:r,target:t,firestoreApi:n.firestoreApi,storageApi:n.storageApi})}):a.jsx(ea,{view:e,handles:n.handles,auth:r,target:t,firestoreApi:n.firestoreApi,storageApi:n.storageApi})})}function ea({view:e,handles:t,auth:n,target:r,firestoreApi:s,storageApi:i}){const{users:o}=hs(n),l=f.useMemo(()=>new Set(o.map(c=>c.uid)),[o]);switch(e){case"firestore":{const c=a.jsx(qx,{handles:t,knownUids:l});return s?a.jsx(_g,{value:s,children:c}):c}case"auth":return a.jsx(Yx,{auth:n,focusUid:r?.view==="auth"?r.uid:null});case"storage":{const c=a.jsx(rw,{storage:t.storage,focusTarget:r?.view==="storage"?r:{kind:"root"}});return i?a.jsx(Uv,{value:i,children:c}):c}}}function iw(){return a.jsx(Tl,{view:"firestore"})}function aw(){return a.jsx(Tl,{view:"storage"})}function ow(e,t){const n=new Set(t.map(r=>r.uid));return new Set([...e].filter(r=>n.has(r)))}async function lw(e,t){const n=[];for(const r of e)try{await t(r.uid)}catch{n.push(r.uid)}return n}function cw(e){const[t,n]=f.useState(()=>new Set);f.useEffect(()=>{n(s=>{const i=ow(s,e);return i.size===s.size&&[...i].every(o=>s.has(o))?s:i})},[e]);const r=f.useMemo(()=>e.filter(s=>t.has(s.uid)),[t,e]);return{selectedUsers:r,allVisibleSelected:e.length>0&&r.length===e.length,isSelected:s=>t.has(s),toggle(s){n(i=>{const o=new Set(i);return o.has(s)?o.delete(s):o.add(s),o})},selectAll(s){n(s?new Set(e.map(i=>i.uid)):new Set)},replace(s){n(new Set(s))},clear(){n(new Set)}}}function uw({users:e,filter:t,onDelete:n,onComplete:r}){const s=vt(),[i,o]=f.useState(!1),[l,c]=f.useState(null),u=async()=>{const d=t.trim().length>0;if(!await s({title:`Delete ${e.length} ${e.length===1?"user":"users"}?`,body:d?`Only the ${e.length} users shown by the current filter will be deleted.`:`This will permanently delete the ${e.length} selected users.`,destructive:!0,confirmLabel:"Delete users"}))return;o(!0),c(null);const h=await lw(e,n);o(!1),c(h.length>0?`Could not delete ${h.length} selected user(s).`:null),r(h)};return a.jsxs(a.Fragment,{children:[a.jsx("button",{type:"button",className:"studio-selection-delete",disabled:i,onClick:()=>void u(),children:i?"Deleting…":"Delete"}),l?a.jsx("span",{className:"auth-sub__error",children:l}):null]})}function Ml(e){if(!e)return"never";const t=new Date(e).getTime();if(Number.isNaN(t))return"never";const n=Math.max(0,Math.round((Date.now()-t)/1e3));if(n<45)return"just now";const r=Math.round(n/60);if(r<60)return`${r}m ago`;const s=Math.round(r/60);return s<24?`${s}h ago`:`${Math.round(s/24)}d ago`}function Ll(e){if(!e)return"unknown";const t=new Date(e);return Number.isNaN(t.getTime())?"unknown":t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}function dw(e){const t=e.isAnonymous&&!e.email,n=e.email??e.phoneNumber??(t?"anonymous":e.uid);return a.jsxs("span",{className:t?"auth-ident auth-ident--anon":"auth-ident",children:[a.jsx("span",{className:"auth-ident__primary",title:n,children:n}),a.jsx("span",{className:"auth-ident__uid",title:e.uid,children:e.uid})]})}function fw({auth:e}={}){const t=Ee(),n=Oe(),r=e??(n.status==="ready"?n.handles.auth:null),s=n.status==="ready"?n.authApi:void 0;if(!r)return a.jsx("div",{className:"auth-surface","data-pyric-ui":"auth-surface",children:a.jsx(bw,{status:t.status})});const i=a.jsx(ps,{children:a.jsx(hw,{auth:r})});return s?a.jsx(Jo,{value:s,children:i}):i}function hw({auth:e}){const{users:t,totalCount:n,isLoading:r,error:s,filter:i,setFilter:o,createUser:l,updateUser:c,deleteUser:u}=hs(e),d=Ln(),p=d.target?.view==="auth"?d.target.uid:null,h=b=>d.navigate({view:"auth",uid:b}),m=f.useMemo(()=>t.find(b=>b.uid===p)??null,[t,p]),[y,g]=f.useState(!1),x=cw(t);return a.jsxs("div",{className:"auth-surface","data-pyric-ui":"auth-surface",children:[a.jsxs("div",{className:"auth-sub",children:[a.jsxs("span",{className:"auth-sub__h",children:["users ",a.jsxs("span",{className:"auth-sub__n",children:["· ",n]})]}),a.jsx("input",{className:"auth-sub__filter",value:i,onChange:b=>o(b.target.value),placeholder:"filter users…","aria-label":"Filter users"}),a.jsx("div",{className:"auth-sub__right",children:x.selectedUsers.length>0?a.jsxs(a.Fragment,{children:[a.jsxs("span",{className:"studio-selection-count",children:[x.selectedUsers.length," selected"]}),a.jsx(uw,{users:x.selectedUsers,filter:i,onDelete:b=>Promise.resolve(u(b)),onComplete:b=>{x.replace(b),p&&!b.includes(p)&&h(null)}}),a.jsx("button",{type:"button",className:"auth-sub__clear",onClick:x.clear,children:"Clear selection"})]}):a.jsx("button",{type:"button",className:"auth-sub__add",onClick:()=>{g(!0),h(null)},children:"Add user"})})]}),a.jsxs("div",{className:"auth-body","data-auth-level":m||y?"detail":"list",children:[a.jsx("div",{className:"auth-list",children:a.jsx(el,{users:t,isLoading:r,error:s,filter:i,onSelect:b=>{g(!1),h(b.uid)},renderIdentifier:dw,formatCreatedAt:Ll,formatLastLoginAt:Ml,renderSelectionHeader:a.jsx("label",{className:"auth-select",title:"Select all shown users",children:a.jsx("input",{type:"checkbox","aria-label":"Select all shown users",checked:x.allVisibleSelected,onChange:b=>x.selectAll(b.currentTarget.checked)})}),renderSelection:b=>a.jsx("label",{className:"auth-select",title:`Select ${b.uid}`,children:a.jsx("input",{type:"checkbox","aria-label":`Select ${b.uid}`,checked:x.isSelected(b.uid),onChange:()=>x.toggle(b.uid)})}),emptyState:a.jsx("p",{className:"auth-zero",children:"No users yet. Sign-ins from the app, agent-seeded users, and “Add user” all land here."}),noResultsState:a.jsxs("p",{className:"auth-zero",children:["No users match “",i,"”."]})})}),a.jsx("div",{className:"auth-detail",children:y?a.jsx(pw,{onCancel:()=>g(!1),onCreate:async b=>{const v=await Promise.resolve(l(b));g(!1),h(v.uid)}}):m?a.jsxs(a.Fragment,{children:[a.jsx("button",{type:"button",className:"auth-back",onClick:()=>h(null),"aria-label":"Back to users",children:"‹ Users"}),a.jsx(yw,{user:m,onSave:b=>{b.mode==="edit"&&c(b.uid,b.request)},onProvidersChange:async b=>{await Promise.resolve(c(m.uid,{providerUserInfo:b}))},onDelete:()=>{u(m.uid),h(null)}},m.uid)]}):a.jsx("div",{className:"auth-detail__empty",children:a.jsx("p",{className:"auth-zero",children:"Select a user to view and edit."})})})]})]})}function pw({onCreate:e,onCancel:t}){const[n,r]=f.useState(null),s=i=>{i.mode==="create"&&(r(null),e(i.request).catch(o=>{r(o instanceof Error?o:new Error(String(o)))}))};return a.jsxs("div",{className:"auth-editor","data-pyric-ui":"auth-create-user",children:[a.jsxs("div",{className:"auth-editor__head",children:[a.jsx("div",{className:"auth-editor__who",children:"New user"}),a.jsx("div",{className:"auth-editor__meta",children:"Created without signing in — admin semantics, like the emulator’s add-user flow."})]}),a.jsx(tl,{onSubmit:s,onCancel:t,submitLabel:"Create user",children:n?a.jsx("p",{className:"auth-save auth-save--error",role:"alert",children:n.message}):null})]})}const ta=[...Co];function mw({user:e,onChange:t}){const[n,r]=f.useState(null),[s,i]=f.useState(""),o=e.providerUserInfo.map(m=>m.providerId),l=o.includes("password"),c=o.filter(m=>m!=="password"),u=c.filter(m=>!ta.includes(m)),d=m=>{r(null),t(m.map(y=>({providerId:y}))).catch(y=>{r(y instanceof Error?y:new Error(String(y)))})},p=(m,y)=>{d(y?[...c,m]:c.filter(g=>g!==m))},h=()=>{const m=s.trim();m&&(i(""),!c.includes(m)&&d([...c,m]))};return a.jsxs("section",{className:"auth-providers-editor","aria-label":"Sign-in providers",children:[a.jsx("div",{className:"auth-group",children:"Sign-in providers"}),a.jsx("div",{className:"auth-providers-editor__list",children:[...ta,...u].map(m=>a.jsxs("label",{className:"auth-provider-row","data-pyric-provider-id":m,children:[a.jsx("input",{type:"checkbox",checked:c.includes(m),onChange:y=>p(m,y.target.checked)}),a.jsx("span",{className:"auth-provider-row__label",children:wn(m)}),a.jsx("span",{className:"auth-provider-row__id",children:m})]},m))}),l||e.isAnonymous?a.jsx("p",{className:"auth-providers-editor__derived",children:l?"Password is linked by the password credential above.":"Anonymous — the provider lives on the token, not the record."}):null,a.jsx("div",{className:"auth-provider-custom",children:a.jsxs("label",{className:"auth-provider-custom__field",children:[a.jsx("span",{className:"auth-provider-custom__label",children:"Custom provider ID"}),a.jsxs("span",{className:"auth-provider-custom__row",children:[a.jsx("input",{type:"text",value:s,placeholder:"oidc.my-provider",onChange:m=>i(m.target.value),onKeyDown:m=>{m.key==="Enter"&&(m.preventDefault(),h())}}),a.jsx("button",{type:"button",onClick:h,disabled:!s.trim(),children:"Link"})]})]})}),n?a.jsx("p",{className:"auth-save auth-save--error",role:"alert",children:n.message}):null]})}function yw({user:e,onSave:t,onProvidersChange:n,onDelete:r}){const[s,i]=f.useState(null),[o,l]=f.useState(!1),c=p=>{i(null),l(!1);try{t(p),l(!0)}catch(h){i(h instanceof Error?h:new Error(String(h)))}},u=Ll(e.createdAt),d=Ml(e.lastLoginAt);return a.jsxs("div",{className:"auth-editor","data-pyric-user-disabled":e.disabled?"":void 0,children:[a.jsxs("div",{className:"auth-editor__head",children:[a.jsxs("div",{className:"auth-editor__who",children:[e.email??(e.isAnonymous?"anonymous":e.uid),e.disabled?a.jsx("span",{className:"auth-tag-off",children:"disabled"}):null]}),a.jsxs("div",{className:"auth-editor__uid",children:["uid · ",e.uid]}),a.jsxs("div",{className:"auth-editor__meta",children:["created ",u," · signed in ",d]})]}),a.jsx(mw,{user:e,onChange:n}),a.jsxs(tl,{initial:e,onSubmit:c,submitLabel:"Save",children:[s?a.jsx("p",{className:"auth-save auth-save--error",role:"alert",children:s.message}):null,o?a.jsx("p",{className:"auth-save auth-save--ok",children:"Saved."}):null]},e.uid),a.jsx("div",{className:"auth-editor__foot",children:a.jsx(jg,{user:e,onDelete:r,className:"auth-del"})})]})}function bw({status:e}){const t=e==="pending"?"Seeding the sandbox…":e==="error"?"The dev-seed failed. Check the console.":"No sandbox Auth handle. Run with the dev-seed (DEV) or a live env.";return a.jsx("div",{className:"auth-detail__empty","data-pyric-ui":"auth-surface-empty",children:a.jsx("p",{className:"auth-zero",children:t})})}function gw(e){return e.operationContext.source.kind==="studio"}function vw(e,t){return t?e.filter(n=>!gw(n)):[...e]}const xw=["all","allow","deny","bypassed"];function Bn(e){return e.rulesDisposition.kind==="bypassed"?"bypassed":e.rulesDisposition.kind==="evaluated"?e.rulesDisposition.verdict:null}function ww(e,t){return t==="all"?[...e]:e.filter(n=>Bn(n)===t)}function ir(e){return e.rulesDisposition.kind==="evaluated"}function na(e){const t=e.path;if(e.service==="storage"&&e.method==="list"&&(t===""||t==="/"))return{tab:"storage"};if(!t||t==="(service)")return null;const n=t.split("/").filter(Boolean);switch(e.service??"firestore"){case"firestore":return n.length?{tab:"firestore",rest:n}:null;case"rtdb":return{tab:"rtdb"};case"storage":return n.length?{tab:"storage",rest:n,...e.method==="list"?{query:{kind:"prefix"}}:{}}:null;case"auth":return t!=="*"?{tab:"auth",rest:[t]}:null;default:return null}}const Fr="inspect";function Bl(e){const t=e[Fr];return t||null}function Fl(e,t){const{[Fr]:n,...r}=e;return t?{...r,[Fr]:t}:r}function jw(e,t){return Fl(e,Bl(e)===t?null:t)}function kw(e){const t=Lc(e),n=t.warnings.map(r=>({rule:r.rule,severity:r.severity,message:r.message,...r.fix?{fix:r.fix}:{}}));return t.parseError?{parseable:!1,parseError:t.parseError.message,findings:n}:{parseable:!0,findings:n}}async function Sw(e,t,n,r){const s=kw(n);if(!s.parseable)return{result:{outcome:"error",code:"lint-parse-error",message:s.parseError??"The edited ruleset did not parse."},diff:[],lint:s};const i=Ma(e,n);try{const o=await Vl(i.sandbox,t),l=o.outcome==="allow"?wu(i,r):[];return{result:o,diff:l,lint:s}}finally{La(i)}}async function Vl(e,t){const n=Gr(e.withAuth(t.auth)),r=_w(t.resourceData);try{switch(t.method){case"get":await Jr(pe(n,t.path));break;case"list":case"listen":await Rt(Dt(qe(n,t.path)));break;case"create":case"set":await At(pe(n,t.path),r);break;case"update":await lr(pe(n,t.path),r);break;case"delete":await un(pe(n,t.path));break;default:await Hr(qe(n,Ew(t.path)),r)}return{outcome:"allow"}}catch(s){const i=s,o=typeof i?.code=="string"?i.code:"unknown",l=typeof i?.message=="string"?i.message:s instanceof Error?s.message:String(s);if(o==="permission-denied"){const c=i.denialContext?.reasons;return{outcome:"deny",code:o,message:l,...c?{reasons:c}:{}}}return{outcome:"error",code:o,message:l}}}function _w(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{}}function Ew(e){const t=e.lastIndexOf("/");return t<0?e:e.slice(0,t)}const Cw=f.lazy(()=>Ga(()=>import("./RulesCodeEditor.CzwHdCi9.js"),__vite__mapDeps([7,2,3])));function ql(e){return a.jsx(f.Suspense,{fallback:a.jsx(Nw,{value:e.value,minHeightRem:e.minHeightRem}),children:a.jsx(Cw,{...e})})}function Nw({value:e,minHeightRem:t=14}){return a.jsx("pre",{"data-pyric-ui":"rules-code-editor-loading",className:"overflow-auto rounded-md border border-border bg-content-bg p-3 font-mono text-xs text-slate-gray",style:{minHeight:`${t}rem`},children:e||"Loading editor…"})}function Wl({denial:e,editedRules:t,rulesSource:n,onEditedRulesChange:r,onRerunAsUser:s,onRerunAgainstRules:i}){const o=_y(e);return a.jsxs("div",{"data-pyric-ui":"denial-detail",className:"flex min-h-0 flex-col gap-4 overflow-auto rounded-lg border border-border bg-sidebar-bg p-5",children:[a.jsxs("section",{children:[a.jsxs("div",{className:"mb-2 flex items-center gap-2",children:[e.result==="allow"?a.jsx(ot,{kind:"allow",className:"rounded bg-primary/15 px-2 py-0.5 text-xs font-semibold uppercase text-primary",children:"allowed"}):a.jsx(ot,{kind:"deny",className:"rounded bg-danger/15 px-2 py-0.5 text-xs font-semibold uppercase text-danger",children:e.unsupported?"unsupported":"denied"}),a.jsxs("span",{className:"font-mono text-sm text-soft-white",children:[e.service!=="firestore"?`${e.service} · `:"",e.method," ",e.path]})]}),a.jsx("p",{className:"text-sm leading-relaxed text-soft-white",children:o.headline})]}),o.noEvaluation?a.jsx("p",{"data-pyric-ui":"rules-debug-no-evaluation",className:"rounded-md border border-border bg-content-bg px-3 py-2 text-xs text-slate-gray",children:"No matched rule, evaluation trace, or re-run is shown because this event carries no rules verdict to ground them in."}):a.jsxs(a.Fragment,{children:[a.jsx(Aw,{denial:e,exp:o,rulesSource:n}),a.jsx(Dw,{denial:e})]}),a.jsx($w,{denial:e}),o.noEvaluation?null:a.jsx(Tw,{denial:e,editedRules:t,onEditedRulesChange:r,onRerunAsUser:s,onRerunAgainstRules:i})]})}function Aw({denial:e,exp:t,rulesSource:n}){return t.engine==="rtdb"?a.jsx(Ow,{denial:e,exp:t}):t.engine==="storage"?a.jsx(Uw,{exp:t}):a.jsx(Rw,{denial:e,exp:t,rulesSource:n})}function Rw({denial:e,exp:t,rulesSource:n}){const r=e.evaluatedRule?.line,s=e.result==="allow",i=!!n&&n.trim().length>0;return a.jsx(Ie,{label:t.implicitDeny||!t.ruleNode?"matched rule":`matched rule — ${t.ruleNode}${r?` · line ${r}`:""}`,children:i?a.jsx(ql,{value:n,readOnly:!0,markLine:r,markKind:s?"allow":"deny",minHeightRem:12,ariaLabel:`Deployed firestore.rules — the ${s?"allowing":"denying"} rule is marked`}):a.jsx("pre",{className:"overflow-auto rounded-md border border-border bg-content-bg p-3 font-mono text-xs leading-relaxed text-slate-gray",children:[...t.ruleLines,...t.otherLines].join(`
108
- `)||"(no trace)"})})}function Dw({denial:e}){const t=Dy(e);return t.length===0?null:a.jsx(Ie,{label:"show the work — how the condition evaluated",children:a.jsx("div",{"data-pyric-ui":"rules-debug-trace",className:"flex flex-col gap-0.5 overflow-auto rounded-md border border-border bg-content-bg p-3",children:t.map((n,r)=>a.jsx(zl,{step:n},r))})})}const Iw={true:"✓",false:"✗",skipped:"⊘",error:"!",value:"·"};function zl({step:e}){const t=e.outcome==="true"?"text-diff-add":e.outcome==="false"||e.outcome==="error"?"text-danger":"text-slate-gray",n=e.outcome==="skipped"?"not evaluated (short-circuit)":e.outcome==="error"?e.error:`→ ${Kl(e.value)}`;return a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"flex items-baseline gap-2 font-mono text-xs",style:{paddingLeft:`${e.depth*.9}rem`},children:[a.jsx("span",{"aria-hidden":!0,className:`w-3 shrink-0 text-center font-bold ${t}`,children:Iw[e.outcome]}),a.jsxs("span",{className:e.outcome==="skipped"?"text-slate-gray line-through":"text-soft-white",children:[e.letBinding?`let ${e.letBinding} = `:"",e.source]}),a.jsx("span",{className:"text-slate-gray",children:n}),e.inlinedFrom?a.jsxs("span",{className:"text-[0.6rem] uppercase tracking-wide text-slate-gray",children:[e.inlinedFrom,"()"]}):null]}),e.children.map((r,s)=>a.jsx(zl,{step:r},s))]})}function Kl(e){if(e===void 0)return"undefined";try{return JSON.stringify(ft(e))}catch{return String(e)}}function $w({denial:e}){const t=Iy(e);return a.jsx(Ie,{label:"what the rule saw (request / resource)",children:a.jsx("div",{"data-pyric-ui":"rules-debug-variables",className:"flex flex-col gap-2 rounded-md border border-border bg-content-bg p-3",children:t.map(n=>a.jsx(Pw,{variable:n},n.name))})})}function Pw({variable:e}){return a.jsxs("div",{className:"flex flex-col gap-0.5",children:[a.jsx("span",{className:"font-mono text-[0.7rem] text-primary",children:e.name}),e.present?a.jsx(Hl,{value:e.value}):a.jsxs("span",{className:"font-mono text-xs italic text-slate-gray",children:["absent",e.absentNote?` — ${e.absentNote}`:""]})]})}function Hl({value:e,depth:t=0}){const[n,r]=f.useState(t<2),s=ft(e);if(s===null||typeof s!="object")return a.jsx("span",{className:"font-mono text-xs text-soft-white",children:Kl(s)});const i=Array.isArray(s)?s.map((o,l)=>[String(l),o]):Object.entries(s);return i.length===0?a.jsx("span",{className:"font-mono text-xs text-slate-gray",children:Array.isArray(s)?"[]":"{}"}):a.jsxs("div",{className:"flex flex-col",children:[a.jsxs("button",{type:"button",onClick:()=>r(o=>!o),"aria-expanded":n,className:"flex w-fit items-center gap-1 font-mono text-xs text-slate-gray hover:text-soft-white",children:[a.jsx("span",{"aria-hidden":!0,children:n?"▾":"▸"}),a.jsx("span",{children:Array.isArray(s)?`[${i.length}]`:`{${i.length}}`})]}),n?a.jsx("div",{className:"flex flex-col gap-0.5 border-l border-border pl-3",children:i.map(([o,l])=>a.jsxs("div",{className:"flex flex-wrap items-baseline gap-2",children:[a.jsxs("span",{className:"font-mono text-xs text-slate-gray",children:[o,":"]}),a.jsx(Hl,{value:l,depth:t+1})]},o))}):null]})}function Ow({denial:e,exp:t}){return a.jsxs(a.Fragment,{children:[a.jsx(Ie,{label:t.implicitDeny?"rule node":`rule node — ${t.ruleNode}`,children:a.jsxs("code",{className:"font-mono text-xs text-soft-white",children:[t.phase?`.${t.phase}`:"(no matching rule)",e.rules?.matchedPath?` at ${e.rules.matchedPath}`:""]})}),t.ruleExpression?a.jsx(Ie,{label:"rule expression",children:a.jsx("pre",{className:"overflow-auto rounded-md border border-border bg-content-bg p-3 font-mono text-xs text-slate-gray",children:t.ruleExpression})}):null,t.bindings?a.jsx(Ie,{label:"$variable bindings",children:a.jsx("code",{className:"font-mono text-xs text-soft-white",children:Object.entries(t.bindings).map(([n,r])=>`${n.startsWith("$")?n:`$${n}`} → ${r}`).join(", ")})}):null,e.rules?.reason?a.jsx(Ie,{label:"simulator reason",children:a.jsx("code",{className:"font-mono text-xs text-slate-gray",children:e.rules.reason})}):null]})}function Uw({exp:e}){return a.jsxs(Ie,{label:e.implicitDeny?"matched rule":"matched rule (match block)",children:[e.ruleNode?a.jsx("code",{className:"mb-2 block font-mono text-xs text-soft-white",children:e.ruleNode}):null,a.jsx("pre",{className:"overflow-auto rounded-md border border-border bg-content-bg p-3 font-mono text-xs leading-relaxed text-slate-gray",children:[...e.ruleLines,...e.otherLines].join(`
109
- `)||"(no trace)"})]})}function Ie({label:e,children:t}){return a.jsxs("div",{className:"flex flex-col gap-1",children:[a.jsx("span",{className:"text-[0.65rem] font-semibold uppercase tracking-wider text-slate-gray",children:e}),t]})}function Tw({denial:e,editedRules:t,onEditedRulesChange:n,onRerunAsUser:r,onRerunAgainstRules:s}){const[i,o]=f.useState(null),[l,c]=f.useState(null),u=by(e),d=u.impersonate.kind==="live"&&!!r&&!!e.auth?.uid,p=u.editedRuleset.kind==="live"&&!!s;async function h(){if(r){o("pending");try{o(await r(e))}catch(y){o({outcome:"error",code:"unknown",message:String(y)})}}}async function m(){if(s){c("pending");try{c(await s(e,t??""))}catch(y){c({result:{outcome:"error",code:"unknown",message:String(y)},diff:[],lint:{parseable:!0,findings:[]}})}}}return a.jsxs("section",{"data-pyric-ui":"rerun-panel",className:"mt-1 flex flex-col gap-4 border-t border-border pt-4",children:[Ay(e)?a.jsxs("div",{className:"flex flex-col gap-2",children:[a.jsxs("div",{className:"flex items-center justify-between gap-3",children:[a.jsx("span",{className:"text-sm font-medium text-soft-white",children:"Re-run as the attempting user"}),a.jsx("button",{type:"button",disabled:!d||i==="pending",onClick:h,className:"rounded-md border border-primary/40 px-3 py-1 text-xs font-medium text-primary transition-colors hover:bg-primary/10 disabled:cursor-not-allowed disabled:border-border disabled:text-slate-gray",children:i==="pending"?"Running…":u.impersonate.kind==="live"?`Impersonate ${e.auth?.uid??""}`:"Impersonation not available"})]}),a.jsx(ra,{support:u.impersonate,haveCallback:!!r}),i&&i!=="pending"?a.jsx(sa,{result:i}):null]}):null,a.jsxs("div",{className:"flex flex-col gap-2",children:[a.jsxs("div",{className:"flex items-center justify-between gap-3",children:[a.jsx("span",{className:"text-sm font-medium text-soft-white",children:"Re-run against an edited ruleset"}),a.jsx("button",{type:"button",disabled:!p||l==="pending",onClick:m,className:"rounded-md border border-primary/40 px-3 py-1 text-xs font-medium text-primary transition-colors hover:bg-primary/10 disabled:cursor-not-allowed disabled:border-border disabled:text-slate-gray",children:l==="pending"?"Linting + forking…":"Lint, then test on a branch"})]}),n&&u.editedRuleset.kind==="live"?a.jsx(ql,{value:t??"",onChange:n,markLine:e.evaluatedRule?.line,markKind:e.result==="allow"?"allow":"deny",minHeightRem:14,ariaLabel:"Edited firestore.rules to test the op against"}):null,a.jsx(ra,{support:u.editedRuleset,haveCallback:!!s}),l&&l!=="pending"?a.jsxs(a.Fragment,{children:[l.lint.findings.length>0||!l.lint.parseable?a.jsx(Mw,{lint:l.lint}):null,a.jsx(sa,{result:l.result}),l.diff.length>0?a.jsx(Bw,{diff:l.diff}):null]}):null]})]})}function ra({support:e,haveCallback:t}){if(e.kind==="pending"||e.kind==="absent"){const n=e.kind==="pending"?e.tool:e.missingTool;return a.jsxs("p",{"data-pyric-ui":"rerun-hint-gated",className:"rounded-md border border-border bg-content-bg px-3 py-2 text-xs text-slate-gray",children:[e.hint," ",a.jsx("code",{className:"font-mono text-[0.7rem] text-warning",children:n})]})}return t?null:a.jsx("p",{className:"rounded-md border border-border bg-content-bg px-3 py-2 text-xs text-slate-gray",children:"Wired to the live sandbox once the local backend is reachable. The denial, rule, and context above are already live."})}function Mw({lint:e}){return a.jsxs("div",{"data-pyric-ui":"rerun-lint",className:"flex flex-col gap-1 rounded-md border border-border bg-content-bg p-3",children:[a.jsx("span",{className:"text-[0.65rem] font-semibold uppercase tracking-wider text-slate-gray",children:"lint (firestore_lint_rules)"}),e.parseable?e.findings.map((t,n)=>a.jsxs("p",{className:"font-mono text-xs",children:[a.jsx("span",{className:t.severity==="error"?"text-danger":"text-warning",children:t.rule}),a.jsxs("span",{className:"text-slate-gray",children:[" — ",t.message]})]},`${t.rule}-${n}`)):a.jsx("p",{className:"font-mono text-xs text-danger",children:e.parseError})]})}function sa({result:e}){return e.outcome==="allow"?a.jsxs("p",{className:"flex items-center gap-2 text-xs",children:[a.jsx(ot,{kind:"allow",className:"rounded bg-primary/15 px-2 py-0.5 font-semibold uppercase text-primary",children:"allow"}),a.jsx("span",{className:"text-slate-gray",children:"The re-run is permitted under these rules."})]}):e.outcome==="deny"?a.jsxs("p",{className:"flex items-center gap-2 text-xs",children:[a.jsx(ot,{kind:"deny",className:"rounded bg-danger/15 px-2 py-0.5 font-semibold uppercase text-danger",children:"deny"}),a.jsxs("span",{className:"text-slate-gray",children:["Denied under these rules: ",e.message]})]}):a.jsxs("p",{className:"flex items-center gap-2 text-xs",children:[a.jsx(ot,{kind:"error",className:"rounded bg-warning/15 px-2 py-0.5 font-semibold uppercase text-warning",children:e.code}),a.jsx("span",{className:"text-slate-gray",children:e.message})]})}function Lw(e){return e.kind==="autoid-alias"?{path:e.originalPath,before:e.originalPath,after:e.replayedPath}:{path:e.path,..."field"in e&&e.field?{field:e.field}:{},before:e.before,after:e.after}}function Bw({diff:e}){return a.jsxs("div",{"data-pyric-ui":"rules-debug-diff",className:"flex flex-col gap-1 rounded-md border border-border bg-content-bg p-3",children:[a.jsx("span",{className:"text-[0.65rem] font-semibold uppercase tracking-wider text-slate-gray",children:"what the re-run changed (branch vs live)"}),e.map((t,n)=>{const r=Lw(t),s=r.field?`.${r.field}`:"",i=r.before===void 0&&r.after!==void 0,o=r.before!==void 0&&r.after===void 0;return a.jsxs("div",{className:"font-mono text-xs",children:[a.jsxs("span",{className:i?"text-diff-add":o?"text-diff-remove":"text-warning",children:[i?"+ ":o?"- ":"~ ",r.path,s]}),i?null:a.jsx("span",{className:"ml-2 text-slate-gray",children:JSON.stringify(ft(r.before))}),o?null:a.jsxs("span",{className:"ml-2 text-soft-white",children:["→ ",JSON.stringify(ft(r.after))]})]},`${r.path}-${n}`)})]})}function ia({eventId:e,onClose:t}){const n=My(),r=qy(),s=Hy(),i=n.find(p=>p.id===e),[o,l]=f.useState(""),c=o||s;if(!i)return a.jsxs("div",{"data-pyric-ui":"traffic-inspect-missing",className:"traffic__inspector",children:[a.jsx("p",{className:"traffic__inspector-missing",children:"This operation isn't in this session's traffic. It may be from an earlier session, or the event has aged out of the buffer."}),a.jsx("button",{type:"button",className:"traffic__inspector-close",onClick:t,children:"Back to the log"})]});const u=async p=>{const h=await r();if(!h)return{outcome:"error",code:"no-backend",message:"No sandbox snapshot to re-run against."};const m=Ma(h,s);try{return await Vl(m.sandbox,p)}finally{La(m)}},d=async(p,h)=>{const m=await r();return m?Sw(m,p,h,m):{result:{outcome:"error",code:"no-backend",message:"No sandbox snapshot to re-run against."},diff:[],lint:{parseable:!0,findings:[]}}};return a.jsxs("div",{"data-pyric-ui":"traffic-rules-inspector",className:"traffic__inspector",children:[a.jsxs("div",{className:"traffic__inspector-bar",children:[a.jsx("span",{className:"traffic__inspector-title",children:"rules inspector"}),a.jsx("button",{type:"button",className:"traffic__inspector-close",onClick:t,"aria-label":"Close rules inspector (Esc)",children:"close (esc)"})]}),a.jsx(Wl,{denial:i,editedRules:c,rulesSource:s,onEditedRulesChange:l,onRerunAsUser:u,onRerunAgainstRules:d})]})}const Fw=new Intl.NumberFormat,Vw={reads:"read operations",writes:"writes",deletes:"deletes"},qw={allows:"allowed requests",denies:"denied requests"};function aa(e){return e.length<=1?e[0]??"":e.length===2?`${e[0]} and ${e[1]}`:`${e.slice(0,-1).join(", ")}, and ${e.at(-1)}`}function oa(e){return e&&`${e[0].toUpperCase()}${e.slice(1)}`}function Gl(e,t){const n=e.reduce((u,d)=>u+d.total,0);if(n===0)return{total:n,headline:t.emptyHeadline,finding:t.emptyFinding};const r=Math.max(...e.map(u=>u.total)),s=e.filter(u=>u.total===r),i=`${Fw.format(n)} observed ${n===1?t.singular:t.plural}`,o=u=>t.labels[u.key]??u.label.toLowerCase();if(s.length>1){const u=s.map(o);return{total:n,headline:i,finding:s.length===e.length?`${t.evenSplitPrefix} ${aa(u)}.`:`${oa(aa(u))} tied for the largest share of ${t.subject} in this window.`}}const l=s[0],c=Math.round(l.total/n*100);return{total:n,headline:i,finding:`${oa(o(l))} accounted for ${c}% of ${t.subject} in this window.`}}function Ww(e){return Gl(e,{labels:Vw,singular:"billable operation",plural:"billable operations",subject:"activity",evenSplitPrefix:"Activity was split evenly across",emptyHeadline:"No billable activity observed",emptyFinding:"Successful reads, writes, and deletes will appear here as they happen."})}function zw(e){return Gl(e,{labels:qw,singular:"Rules evaluation",plural:"Rules evaluations",subject:"evaluations",evenSplitPrefix:"Evaluations were split evenly between",emptyHeadline:"No Rules evaluations observed",emptyFinding:"Allow and deny decisions will appear here as Rules evaluate requests."})}const Kw=new Intl.NumberFormat,Hw=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"2-digit"});function la(e){return Kw.format(e)}function Ct(e){return Hw.format(e)}function Gw(e){return Bn(e)==="bypassed"}function Jw(e){return e.every(t=>t.total===0)}function Jl({eyebrow:e,story:t,series:n,points:r,window:s,emptyLabel:i,evidenceTitle:o,source:l,methodology:c}){const[u,d]=f.useState(()=>new Set(n.map(h=>h.key))),p=f.useCallback(h=>{d(m=>{const y=new Set(m);return y.has(h)?y.delete(h):y.add(h),y})},[]);return a.jsxs("section",{className:"traffic__metric-panel traffic__metric-panel--journal","data-pyric-ui":"traffic-metric-panel",children:[a.jsxs("header",{className:"traffic__metric-story",children:[a.jsx("p",{className:"traffic__metric-eyebrow",children:e}),a.jsx("h3",{className:"traffic__metric-headline",children:t.headline}),a.jsx("p",{className:"traffic__metric-finding",children:t.finding})]}),a.jsx(Xb,{series:n,visible:u,onToggle:p,formatValue:la,className:`traffic__metric-cards traffic__metric-cards--journal traffic__metric-cards--${n.length}`}),Jw(n)?a.jsx("p",{className:"traffic__empty",children:i}):a.jsxs("div",{className:"traffic__metric-evidence",children:[a.jsxs("div",{className:"traffic__metric-evidence-header",children:[a.jsx("h4",{children:o}),a.jsxs("span",{children:[Ct(s.start),"–",Ct(s.end)]})]}),a.jsx(eg,{points:r,series:n,visible:u,omitZeroSeries:!0,formatValue:la,formatTime:Ct,className:"traffic__chart traffic__chart--journal"}),a.jsxs("div",{className:"traffic__metric-axis","aria-hidden":"true",children:[a.jsx("span",{children:Ct(s.start)}),a.jsx("span",{children:Ct(s.end)})]})]}),a.jsxs("footer",{className:"traffic__metric-footer",children:[a.jsx("p",{className:"traffic__metric-source",children:l}),a.jsxs("details",{className:"traffic__metric-methodology",children:[a.jsx("summary",{children:"How this is counted"}),a.jsx("div",{children:c})]})]})]})}function Yw({events:e,window:t}){const n=f.useMemo(()=>e.filter(i=>(i.service??"firestore")==="firestore"),[e]),r=Db({events:n,window:t,isAdmin:Gw}),s=f.useMemo(()=>Ww(r.series),[r.series]);return a.jsx("div",{className:"traffic__metrics","data-pyric-ui":"traffic-billable-view",children:a.jsx(Jl,{eyebrow:"Billable activity",story:s,series:r.series,points:r.points,window:t,emptyLabel:"No reads, writes, or deletes in this session yet.",evidenceTitle:"When the activity happened",source:"Source: Pyric Firestore sandbox events · Operation counts, not a Firebase invoice",methodology:a.jsxs(a.Fragment,{children:[a.jsxs("p",{children:["Counts successful Firestore sandbox ",a.jsx("code",{children:"get"}),"/",a.jsx("code",{children:"list"}),","," ",a.jsx("code",{children:"create"}),"/",a.jsx("code",{children:"update"}),"/",a.jsx("code",{children:"set"}),", and"," ",a.jsx("code",{children:"delete"}),"/",a.jsx("code",{children:"remove"})," operations in the displayed window. Rules-bypassed admin operations are included because they still execute."]}),a.jsxs("p",{children:[a.jsx("strong",{children:"Read ops are a proxy, not billed document reads."})," Each"," ",a.jsx("code",{children:"list"})," is counted once because the event does not report how many documents the query returned. This is observed sandbox activity, not a Firebase invoice."]})]})})})}function Xw({events:e,window:t}){const n=f.useMemo(()=>e.filter(o=>o.rulesDisposition.kind==="evaluated"),[e]),r=Ib({events:n,window:t}),s=f.useMemo(()=>r.series.filter(o=>o.key==="allows"||o.key==="denies"),[r.series]),i=f.useMemo(()=>zw(s),[s]);return a.jsx("div",{className:"traffic__metrics","data-pyric-ui":"traffic-rules-view",children:a.jsx(Jl,{eyebrow:"Rules decisions",story:i,series:s,points:r.points,window:t,emptyLabel:"No allow or deny decisions in this session yet.",evidenceTitle:"When Rules evaluated requests",source:"Source: Pyric sandbox events · Evaluated Rules dispositions only",methodology:a.jsxs(a.Fragment,{children:[a.jsxs("p",{children:["Counts only operations whose canonical Rules disposition is"," ",a.jsx("code",{children:"evaluated"}),", grouped by its ",a.jsx("code",{children:"allow"})," or ",a.jsx("code",{children:"deny"})," ","verdict."]}),a.jsxs("p",{children:[a.jsx("strong",{children:"Bypasses and runtime failures are not Rules decisions."})," Admin bypasses, services without Rules, unsupported operations, and runtime errors are excluded because Rules did not produce a verdict."]})]})})})}const Qw=[{id:"timeline",label:"Timeline"},{id:"billable",label:"Billable metrics"},{id:"rules",label:"Rules"}];function Zw(e){return e==="billable"?"billable":e==="rules"||e==="subscriptions"?"rules":"timeline"}function ej(e,t){return e===0?"No requests occurred in this interval.":e===1?t===1?"The request in this interval was denied.":"One request occurred in this interval; it was not denied.":t===0?`${e} requests occurred in this interval; none were denied.`:t===e?`All ${e} requests in this interval were denied.`:`${e} requests occurred in this interval; ${t} ${t===1?"was":"were"} denied.`}function tj(e,t){const n=e.filter(s=>s.at>=t.start&&s.at<t.end),r=n.reduce((s,i)=>s+(i.result==="deny"?1:0),0);return{window:t,events:n,total:n.length,denies:r,finding:ej(n.length,r)}}function nj(e,t){return e?.start===t.start&&e.end===t.end?null:t}function rj(){const{tab:e,query:t}=be();return e!=="traffic"?"timeline":Zw(t.view)}function sj(){const e=f.useSyncExternalStore(Ft,rj,()=>"timeline"),t=f.useCallback(n=>{const r={...be().query,view:n==="timeline"?void 0:n};r.view===void 0&&delete r.view,ce({tab:"traffic",query:r})},[]);return[e,t]}function ij(){const e=f.useSyncExternalStore(Ft,()=>be().query.hide==="studio",()=>!1),t=f.useCallback(()=>{const n={...be().query};n.hide==="studio"?delete n.hide:n.hide="studio",ce({tab:"traffic",query:n})},[]);return[e,t]}function aj(e,t){const n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return`${n}s ago`;const r=Math.round(n/60);return r<60?`${r}m ago`:`${Math.round(r/60)}h ago`}function ca(e){return`${Tt(e.start)}–${Tt(e.end)}`}function oj({event:e}){const t=Bn(e);return t?a.jsx("span",{className:"traffic__verdict","data-verdict":t,children:t}):null}function lj(){return f.useSyncExternalStore(Ft,()=>Bl(be().query),()=>null)}const ar=100;function cj(){const e=Ty(),[t,n]=sj(),[r,s]=ij(),i=f.useMemo(()=>vw(e,r),[e,r]),o=e.length-i.length,[l,c]=f.useState("all"),[u,d]=f.useState(null),p=lj(),[h,m]=f.useState(ar),y=E=>{ce({tab:"traffic",query:jw(be().query,E)})},g=()=>{ce({tab:"traffic",query:Fl(be().query,null)})};f.useEffect(()=>{if(!p)return;const E=A=>{A.key==="Escape"&&g()};return globalThis.addEventListener("keydown",E),()=>globalThis.removeEventListener("keydown",E)},[p]);const x=f.useMemo(()=>{const E=Date.now();if(i.length===0)return{start:E-15*6e4,end:E};let A=1/0;for(const q of i)q.at<A&&(A=q.at);return{start:Math.min(A,E-6e4),end:E+1e3}},[i]),b=x.end,v=f.useMemo(()=>u?tj(i,u):null,[i,u]),w=v?.events??i,k=f.useMemo(()=>ww(w,l).sort((E,A)=>A.at-E.at),[w,l]),{items:j}=bb({events:k}),S=j.slice(0,h),C=j.length-S.length,O=i.length>=vn,I=i.filter(E=>E.result==="deny").length,$=E=>a.jsx(oj,{event:E}),N=E=>{if(ir(E)){y(E.id);return}const A=na(E);A&&ce(A)},_=p!=null&&S.some(E=>E.type!=="group"&&E.event.id===p);return a.jsxs("section",{"data-pyric-ui":"traffic-surface",className:"traffic",children:[a.jsxs("div",{className:"traffic__tabs",role:"tablist","aria-label":"Traffic views",children:[Qw.map(E=>a.jsx("button",{type:"button",role:"tab",className:"traffic__tab","aria-selected":t===E.id,onClick:()=>n(E.id),children:E.label},E.id)),a.jsxs("button",{type:"button",className:"traffic__hide-studio","aria-pressed":r,onClick:s,title:"Hide ops issued by Pyric Studio's own viewers and editors",children:["Hide Studio traffic",r&&o>0?` (${o} hidden)`:""]})]}),t==="billable"?a.jsx(Yw,{events:i,window:x}):t==="rules"?a.jsx(Xw,{events:i,window:x}):a.jsxs(a.Fragment,{children:[a.jsx(Gb,{events:i,window:x,brush:u??void 0,onBrush:E=>{d(A=>nj(A,E)),p&&g()},liveAt:x.end,bucketCount:36,className:"traffic__timeline",header:a.jsxs("div",{className:"traffic__tl-header",children:[a.jsxs("span",{className:"traffic__tl-count",children:[i.length," requests",O?` (showing latest ${vn})`:""]}),I>0?a.jsxs("button",{type:"button",className:"traffic__tl-deny","aria-pressed":l==="deny",onClick:()=>c(E=>E==="deny"?"all":"deny"),title:"Filter the stream to denied requests",children:[I," denied"]}):null,a.jsx("span",{className:"traffic__tl-live",children:"live"})]}),axis:E=>a.jsxs("div",{className:"traffic__tl-axis",children:[a.jsx("span",{children:aj(E.start,b)}),a.jsx("span",{children:"now"})]}),renderBucketSummary:E=>a.jsxs("div",{className:"traffic__bucket-summary",children:[a.jsx("span",{children:ca(E)}),a.jsxs("strong",{children:[E.count," ",E.count===1?"request":"requests"]}),a.jsxs("span",{children:[E.denies," denied"]})]}),emptyState:a.jsx("p",{className:"traffic__empty",children:"No requests in this window yet."})}),v?a.jsxs("section",{className:"traffic__time-focus","aria-label":"Selected traffic interval","aria-live":"polite",children:[a.jsxs("div",{className:"traffic__time-focus-story",children:[a.jsx("p",{className:"traffic__time-focus-eyebrow",children:"Selected interval"}),a.jsx("h3",{children:ca(v.window)}),a.jsx("p",{children:v.finding})]}),a.jsx("button",{type:"button",onClick:()=>d(null),children:"Show all traffic"})]}):null,a.jsxs("div",{className:"traffic__filters",role:"group","aria-label":"Traffic filters",children:[a.jsx("span",{className:"traffic__filters-label","aria-hidden":"true",children:"verdict"}),xw.map(E=>a.jsx("button",{type:"button",className:"traffic__filter","aria-pressed":l===E,onClick:()=>c(E),children:E},E))]}),p&&!_?a.jsx(ia,{eventId:p,onClose:g},p):null,j.length===0?a.jsx("p",{className:"traffic__empty",children:v?l==="all"?"No requests occurred in the selected interval.":`No ${l} traffic occurred in the selected interval.`:l==="all"?"No requests yet. Reads, writes, and listeners against the sandbox stream in live.":`No ${l} traffic in this session.`}):a.jsxs("div",{className:"traffic__log","data-pyric-ui":"traffic-log","data-pyric-grouped":"","data-pyric-time-focused":v?"":void 0,children:[a.jsx("ul",{"data-pyric-traffic-log-items":"",children:S.map(E=>E.type==="group"?a.jsx("li",{"data-pyric-traffic-group-entry":"",children:a.jsx(Kb,{group:E,onSelect:A=>{const q=A;if(ir(q)){y(q.id);return}const X=na(q);X&&ce(X)},renderClassification:A=>$(A),formatTime:Tt})},E.key):a.jsxs("li",{"data-pyric-traffic-entry":"","data-pyric-traffic-id":E.event.id,"data-verdict":Bn(E.event)??void 0,children:[a.jsx(Ko,{event:E.event,selected:E.event.id===p,onSelect:A=>N(A),renderClassification:A=>$(A),formatTime:Tt}),E.event.id===p&&ir(E.event)?a.jsx(ia,{eventId:p,onClose:g},p):null]},E.event.id))}),C>0?a.jsxs("button",{type:"button",className:"traffic__show-more",onClick:()=>m(E=>E+ar),children:["Show ",Math.min(C,ar)," more (",C," hidden)"]}):null]})]})]})}const ua=["amber","teal","coral","slate","olive","plum","rust","indigo","mint","sand","ash","jade"],da=["fox","owl","lynx","crane","otter","wren","ibex","hare","newt","moth","seal","vole"];function xs(e){if(!e)return"";let t=0;for(let n=0;n<e.length;n++)t=Math.imul(t,31)+e.charCodeAt(n)>>>0;return`${ua[t%ua.length]}-${da[(t>>>4)%da.length]}`}function uj(e){const t=e.operationContext?.source??e.actor;if(t?.kind==="agent")return{provenance:"agent",identity:`agent:${t.name}`};if(t?.kind==="studio")return{provenance:"studio",identity:"studio"};if(t?.kind==="app-builder")return{provenance:"app-builder",identity:"builder"};const n="auth"in e&&e.auth&&typeof e.auth=="object"?e.auth.uid:void 0;return!t||t.kind==="unattributed"?{provenance:"unattributed",identity:n??"unattributed"}:{provenance:"app",identity:n??"app"}}function dj(e){return e?{tab:"firestore",rest:e.split("/").filter(Boolean)}:null}function fj(e){const{provenance:t,identity:n}=uj(e),r={id:e.id,at:e.at,provenance:t,identity:n};switch(e.kind){case"write":return{...r,denied:!1,summary:`${e.method} /${e.path}`,target:dj(e.path)};case"request":return e.result!=="deny"?null:{...r,denied:!0,summary:`denied ${e.method} /${e.path}`,target:{tab:"traffic",query:{inspect:e.id}}};case"operation":return e.result==="deny"?{...r,denied:!0,summary:`denied ${e.service} ${e.method}${e.path?` ${e.path}`:""}`,target:{tab:"traffic",query:{inspect:e.id}}}:null;case"service_mutation":{const s=e.path?` ${e.path}`:"",i=e.service==="auth"&&e.path&&e.path!=="*"?{tab:"auth",rest:[e.path]}:e.service==="storage"&&e.path?{tab:"storage",rest:e.path.split("/").filter(Boolean)}:e.service==="rtdb"?{tab:"rtdb"}:null;return{...r,denied:!1,summary:`${e.service} ${e.op}${s}`,target:i}}case"commit":return e.service!=="rtdb"||e.detail?.admin!==!0?null:{...r,denied:!1,summary:`rtdb ${e.method}${e.path?` ${e.path}`:""}`,target:{tab:"rtdb"}};case"session_boundary":return{...r,provenance:"system",identity:"sandbox",denied:!1,summary:`session ${e.phase}`,target:null};default:return null}}function hj(e,t=20){const n=[];for(let r=e.length-1;r>=0&&n.length<t;r--){const s=fj(e[r]);s&&n.push(s)}return n}const pj=20;function mj(e){ce(e)}function ht({target:e,className:t,children:n,title:r}){return a.jsx("a",{className:t,href:An(e),title:r,onClick:s=>{s.metaKey||s.ctrlKey||s.shiftKey||s.altKey||(s.preventDefault(),mj(e))},children:n})}function yj(){const e=Ee(),t=Pn(),n=us();if(t.status==="loading"||e.status==="pending")return a.jsxs("div",{className:"studio-home__status","aria-label":"Sandbox status",children:[a.jsx("span",{className:"studio-chip studio-home__skeleton-chip","aria-hidden":"true"}),a.jsx("span",{className:"studio-chip studio-home__skeleton-chip","aria-hidden":"true"})]});const s=[];if(e.status==="ready"&&t.status!=="ready"&&s.push(a.jsxs("span",{className:"studio-chip",title:"In-page seeded sandbox — no server. Data resets on reload.",children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),"dev seed · in-page"]},"seed")),t.status==="ready"){const i=t.payload;s.push(a.jsxs(ht,{className:"studio-chip",target:{tab:"settings"},title:"Persistence mode — manage in Settings.",children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),i.persist?"persisted to disk":"ephemeral"]},"persist")),i.rulesHash&&s.push(a.jsxs("span",{className:"studio-chip",title:"Hash of the rules this serve deployed to the sandbox.",children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),"rules ",i.rulesHash.slice(0,8)]},"rules"))}return n&&s.push(a.jsxs(ht,{className:"studio-chip",target:{tab:"settings"},title:`Sandbox instance ${n} — maintenance lives in Settings.`,children:[a.jsx("span",{className:"studio-chip__dot","aria-hidden":"true"}),xs(n)]},"instance")),a.jsx("div",{className:"studio-home__status","aria-label":"Sandbox status",children:s})}function bj(e){return new Date(e).toLocaleTimeString(void 0,{hour12:!1})}function gj(){const e=zt(),t=f.useMemo(()=>hj(e,pj),[e]);return a.jsxs("section",{className:"studio-panel studio-home__feed","aria-label":"Live activity",children:[a.jsxs("header",{className:"studio-home__feed-head",children:[a.jsx("h2",{className:"studio-panel__title studio-home__feed-title",children:"Activity"}),a.jsx(ht,{className:"studio-home__feed-all",target:{tab:"traffic"},children:"view all in Traffic →"})]}),t.length===0?a.jsx("p",{className:"studio-home__feed-empty",children:"No activity yet — writes, denials, and seeds show up here live."}):a.jsx("div",{className:"studio-home__feed-scroll",children:a.jsx("ol",{className:"studio-home__feed-list",children:t.map(n=>{const r=a.jsxs(a.Fragment,{children:[a.jsxs("span",{className:"studio-home__feed-ident","data-provenance":n.provenance,children:[a.jsx("span",{className:"studio-home__feed-dot","aria-hidden":"true"}),n.identity]}),a.jsx("span",{className:"studio-home__feed-summary","data-denied":n.denied?"true":void 0,children:n.summary}),a.jsx("time",{className:"studio-home__feed-time",dateTime:new Date(n.at).toISOString(),children:bj(n.at)})]});return a.jsx("li",{children:n.target?a.jsx(ht,{className:"studio-home__feed-row",target:n.target,children:r}):a.jsx("span",{className:"studio-home__feed-row",children:r})},n.id)})})})]})}const vj=["firestore","auth","rtdb","storage","traffic"];function xj(){const e=Oe(),t=zt(),n=f.useMemo(()=>{const r={};if(e.status==="ready"){const s=e.handles.listRootCollections().length;r.firestore=`${s} collection${s===1?"":"s"}`}return t.length&&(r.traffic=`${t.length} events`),r},[e,t]);return a.jsx("div",{className:"studio-home__tiles",children:vj.map(r=>{const s=Ke.find(i=>i.id===r);return s?a.jsxs(ht,{className:"studio-card studio-home__tile",target:{tab:r},children:[a.jsxs("span",{className:"studio-home__tile-top",children:[a.jsx("span",{className:"studio-home__tile-label",children:s.label}),n[r]?a.jsx("span",{className:"studio-badge",children:n[r]}):null]}),a.jsx("span",{className:"studio-home__tile-desc",children:s.description})]},r):null})})}function wj(){const e=Pn(),t=e.status==="ready",n=t&&!!e.payload.bridgeUrl,r=typeof window<"u"?window.location.origin:"",s=t?e.payload.rulesHash:null;return a.jsxs(a.Fragment,{children:[a.jsxs("section",{className:"studio-card studio-home__onboard","aria-label":"Connect your agent",children:[a.jsx("span",{className:"studio-home__tile-label",children:"Connect your agent"}),a.jsx("span",{className:"studio-home__tile-desc",children:"Point Claude Code, Cursor, or any MCP client at this sandbox and its writes show up in the feed, attributed."}),a.jsx("code",{className:"studio-home__snippet",children:n?`${r}/__pyric/mcp`:"pyric dev --bridge # then <url>/__pyric/mcp"})]}),a.jsxs("section",{className:"studio-card studio-home__onboard","aria-label":"Seed data",children:[a.jsx("span",{className:"studio-home__tile-label",children:"Seed data"}),a.jsx("span",{className:"studio-home__tile-desc",children:"Start from a fixture, or create documents by hand in the Firestore browser."}),a.jsx("code",{className:"studio-home__snippet",children:"pyric dev --seed seed.json"}),a.jsx(ht,{className:"studio-home__onboard-link",target:{tab:"firestore"},children:"open Firestore →"})]}),a.jsxs("section",{className:"studio-card studio-home__onboard","aria-label":"Bring your rules",children:[a.jsx("span",{className:"studio-home__tile-label",children:"Bring your rules"}),s?a.jsxs("span",{className:"studio-home__tile-desc",children:["Your repo rules are deployed to this sandbox (",s.slice(0,8),"). Denials will appear in the feed and in Traffic."]}):a.jsxs(a.Fragment,{children:[a.jsx("span",{className:"studio-home__tile-desc",children:"Serve your repo's rules file and every denial becomes a debuggable event."}),a.jsx("code",{className:"studio-home__snippet",children:"pyric dev --rules firestore.rules"})]})]})]})}function jj(){const e=Oe(),t=zt(),n=Ee(),r=e.status==="pending"||n.status==="pending",s=!r&&t.length===0&&(e.status!=="ready"||e.handles.listRootCollections().length===0);return a.jsxs("section",{className:"studio-surface studio-home","aria-label":"Home",children:[a.jsxs("div",{className:"studio-home__hero",children:[a.jsx("img",{className:"studio-home__hero-logo",src:"/__pyric/ui/pyric-logo.svg",alt:"","aria-hidden":"true"}),a.jsx("h1",{className:"studio-home__hero-title",children:"Firebase that runs in the browser"})]}),a.jsx(Wo,{exposeFocus:Ip}),a.jsx(yj,{}),a.jsx("div",{className:"studio-home__body",children:r?a.jsxs("section",{className:"studio-panel studio-home__feed studio-home__skeleton","aria-hidden":"true",children:[a.jsx("div",{className:"studio-home__skeleton-row"}),a.jsx("div",{className:"studio-home__skeleton-row"}),a.jsx("div",{className:"studio-home__skeleton-row"})]}):s?a.jsx(wj,{}):a.jsxs(a.Fragment,{children:[a.jsx(gj,{}),a.jsx(xj,{})]})})]})}function te(e){const t=e.split("/").filter(Boolean);return t.length===0?"/":`/${t.join("/")}`}function Ge(e){return te(e).split("/").filter(Boolean)}function Vr(e,t){return te([...Ge(e),...t.split("/").filter(Boolean)].join("/"))}function Yl(e,t){const n=Ge(e),r=Ge(t);if(r.length<n.length)return null;for(let i=0;i<n.length;i++)if(r[i]!==n[i])return null;const s=r.slice(n.length);return s.length===0?"/":`/${s.join("/")}`}function Xl(e){if(e==null)return null;if(typeof e!="object")return e;const t=e;let n=!1;const r={};for(const[s,i]of Object.entries(t)){const o=Xl(i);if(o===null){n=!0;continue}o!==i&&(n=!0),r[s]=o}return Object.keys(r).length===0?null:n?r:e}function kj(e){if(typeof e=="string")return JSON.stringify(e);if(e==null)return"null";if(typeof e=="object")try{return JSON.stringify(e)??"null"}catch{return"null"}return String(e)}function ws(e){return e===null||typeof e!="object"?!1:Object.keys(e).length>0}function Ql(e){return e===null||typeof e!="object"?[]:Object.entries(e).sort(([t],[n])=>t.localeCompare(n,void 0,{numeric:!0}))}function Zl(e,t){let n=e??null;for(const r of Ge(t)){if(n===null||typeof n!="object")return null;n=n[r]??null}return n}function Sj(e){return e==null?"null":Array.isArray(e)?"array":typeof e}function qr(e,t){if(Object.is(e,t))return!0;if(Array.isArray(e)||Array.isArray(t))return!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?!1:e.every((o,l)=>qr(o,t[l]));if(e===null||t===null||typeof e!="object"||typeof t!="object")return!1;const n=e,r=t,s=Object.keys(n),i=Object.keys(r);return s.length!==i.length?!1:s.every(o=>o in r&&qr(n[o],r[o]))}function _j(e,t){const n=new Map,r=(s,i)=>{if(!ws(s)){n.set(i,["leaf",s??null]);return}const o=Ql(s);n.set(i,["parent",o.map(([l])=>l)]);for(const[l,c]of o)r(c,Vr(i,l))};return r(e,te(t)),n}function Ej(e){let t=e.trim();if(t.length===0)return"/";const n=/^[a-z][a-z0-9+.-]*:\/\/[^/?#]+/i.exec(t);return n&&(t=t.slice(n[0].length)),t=t.replace(/[?#].*$/,""),te(t)}function Cj(e){const t=Ge(e);return t.map((n,r)=>({label:n,path:`/${t.slice(0,r+1).join("/")}`}))}const Nj=["string","number","boolean","json"];function fa(e){switch(typeof e){case"string":return"string";case"number":return"number";case"boolean":return"boolean";default:return"json"}}function Aj(e,t){return t==="json"?JSON.stringify(e??null):e==null?"":String(e)}function Rj(e){if(e.trim().length===0)return"Enter a key.";const t=e.match(/[.$#[\]/]/);return t?`Keys can't contain "${t[0]}".`:null}function Dj(e,t){switch(e){case"string":return{ok:!0,value:t};case"number":{const n=t.trim();if(n.length===0)return{ok:!1,error:"Enter a number."};const r=Number(n);return Number.isNaN(r)?{ok:!1,error:`"${t}" is not a number.`}:{ok:!0,value:r}}case"boolean":{const n=t.trim().toLowerCase();return n==="true"?{ok:!0,value:!0}:n==="false"?{ok:!0,value:!1}:{ok:!1,error:"Enter true or false."}}case"json":{const n=t.trim();if(n.length===0)return{ok:!0,value:null};try{return{ok:!0,value:JSON.parse(n)}}catch(r){return{ok:!1,error:r instanceof Error?r.message:"Invalid JSON."}}}}}function ec(e){return{path:te(e),status:"loading",value:null,error:null,expanded:{},pages:{}}}function tc(e,t){const n=Yl(e.path,t);return n===null?null:Zl(e.value,n)}function Ij(e,t){const n=te(t);return n===e.path||e.expanded[n]===!0}function $j(e,t,n){const r=Ql(tc(e,t)),s=Math.min(r.length,e.pages[te(t)]??n);return{entries:r.slice(0,s),total:r.length,hiddenCount:r.length-s}}function ha(e,t){const n={};let r=!1;for(const[s,i]of Object.entries(e)){const o=Yl(t.path,s);o!==null&&ws(Zl(t.value,o))?n[s]=i:r=!0}return r?n:e}function nc(e,t){switch(t.type){case"navigate":{const n=te(t.path);return n===e.path?e:ec(n)}case"value":{if(te(t.path)!==e.path)return e;const n={...e,status:"live",value:Xl(t.value),error:null};return n.expanded=ha(e.expanded,n),n.pages=ha(e.pages,n),n}case"error":return te(t.path)!==e.path?e:{...e,status:"error",error:t.message};case"expand":{const n=te(t.path);return n===e.path||e.expanded[n]?e:{...e,expanded:{...e.expanded,[n]:!0}}}case"collapse":{const n=te(t.path);if(!e.expanded[n])return e;const r={...e.expanded};return delete r[n],{...e,expanded:r}}case"toggle":{const n=te(t.path);return nc(e,{type:e.expanded[n]?"collapse":"expand",path:n})}case"show-more":{const n=te(t.path),r=e.pages[n]??t.pageSize;return{...e,pages:{...e.pages,[n]:r+t.pageSize}}}}}const Pj=50;function Oj(e,t,n={}){const r=n.pageSize??Pj,s=te(t),[i,o]=f.useReducer(nc,s,ec),l=f.useMemo(()=>_j(i.value,i.path),[i.path,i.value]),c=vs({scope:i.path,entries:l,equals:qr,ready:i.status==="live"});i.path!==s&&o({type:"navigate",path:s}),f.useEffect(()=>{let g=!1;const x=e.subscribeValue(s,b=>{g||o({type:"value",path:s,value:b})},b=>{g||o({type:"error",path:s,message:b instanceof Error?b.message:String(b)})});return()=>{g=!0,x()}},[e,s]);const u=f.useCallback(g=>tc(i,g),[i]),d=f.useCallback(g=>Ij(i,g),[i]),p=f.useCallback(g=>$j(i,g,r),[i,r]),h=f.useCallback(g=>o({type:"toggle",path:g}),[]),m=f.useCallback(g=>o({type:"show-more",path:g,pageSize:r}),[r]),y=f.useCallback(g=>c.get(te(g)),[c]);return f.useMemo(()=>({state:i,pageSize:r,valueAt:u,isExpanded:d,childrenAt:p,toggle:h,showMore:m,updateAt:y}),[i,r,u,d,p,h,m,y])}function Uj({path:e,onNavigate:t,rootLabel:n="/",inputPrefix:r,className:s}){const i=te(e),[o,l]=f.useState(!1),c=f.useRef(null);f.useEffect(()=>{o&&c.current?.select()},[o]);const u=h=>{h.preventDefault(),t(Ej(c.current?.value??"")),l(!1)},d=()=>l(!1),p=Cj(i);return a.jsx("nav",{className:s,"data-pyric-ui":"rtdb-path-bar","data-rtdb-editing":o?"":void 0,"aria-label":"Database path",children:o?a.jsxs("form",{"data-rtdb-path-form":!0,onSubmit:u,children:[r?a.jsx("span",{"data-rtdb-path-prefix":!0,children:r}):null,a.jsx("input",{ref:c,"data-rtdb-path-input":!0,"aria-label":"Database path",autoFocus:!0,defaultValue:i,onBlur:d,onKeyDown:h=>{h.key==="Escape"&&d()},spellCheck:!1})]}):a.jsxs(a.Fragment,{children:[a.jsxs("ol",{"data-rtdb-crumb-list":!0,children:[a.jsx("li",{"data-rtdb-crumb-item":!0,children:a.jsx("button",{type:"button","data-rtdb-crumb":!0,"data-rtdb-crumb-root":!0,"data-pyric-current":p.length===0?"":void 0,"aria-current":p.length===0?"page":void 0,onClick:()=>t("/"),children:n})}),p.map((h,m)=>{const y=m===p.length-1;return a.jsxs("li",{"data-rtdb-crumb-item":!0,children:[a.jsx("span",{"aria-hidden":!0,"data-rtdb-crumb-separator":!0,children:"/"}),a.jsx("button",{type:"button","data-rtdb-crumb":!0,"data-pyric-current":y?"":void 0,"aria-current":y?"page":void 0,onClick:()=>t(h.path),children:h.label})]},h.path)})]}),a.jsx("button",{type:"button","data-rtdb-path-edit":!0,"aria-label":"Edit path",title:"Edit path",onClick:()=>l(!0),children:a.jsx("svg",{"aria-hidden":!0,viewBox:"0 0 16 16",width:"12",height:"12",fill:"currentColor",children:a.jsx("path",{d:"M11.7 1.3a1 1 0 0 1 1.4 0l1.6 1.6a1 1 0 0 1 0 1.4l-8.5 8.5-3.4 1.1a.5.5 0 0 1-.63-.63l1.1-3.4 8.43-8.57ZM10.9 3.5l1.6 1.6 1.2-1.2-1.6-1.6-1.2 1.2Z"})})})]})})}function Tj({tree:e,api:t,onNavigate:n,rootLabel:r="/",className:s}){const{state:i}=e,o=Ge(i.path),l=o.length===0?r:o[o.length-1];return a.jsx("div",{className:s,"data-pyric-ui":"rtdb-tree",children:i.status==="loading"?a.jsx("p",{"data-rtdb-loading":!0,children:"Loading…"}):i.status==="error"?a.jsx("p",{role:"alert","data-rtdb-error":!0,children:i.error}):a.jsx(rc,{tree:e,api:t,onNavigate:n,path:i.path,label:l,isViewRoot:!0})})}function rc({tree:e,api:t,onNavigate:n,path:r,label:s,isViewRoot:i}){const o=e.valueAt(r),l=ws(o),c=e.isExpanded(r),u=e.updateAt(r),[d,p]=f.useState(!1),[h,m]=f.useState(!1),[y,g]=f.useState(!1),[x,b]=f.useState(null),v=async(j,S)=>{try{await j(),b(null),S()}catch(C){b(C instanceof Error?C.message:String(C))}},w=()=>{p(!0),g(!1),l&&!c&&e.toggle(r)},k=l&&c?e.childrenAt(r):null;return a.jsxs("div",{"data-rtdb-node":!0,"data-rtdb-kind":l?"parent":"leaf","data-rtdb-view-root":i?"":void 0,"data-rtdb-expanded":l&&c?"":void 0,children:[a.jsxs("div",{"data-rtdb-row":!0,"data-pyric-update":u?.kind,"data-pyric-update-cycle":u?.cycle,children:[l&&!i?a.jsx("button",{type:"button","data-rtdb-caret":!0,"aria-expanded":c,"aria-label":c?"Collapse":"Expand",onClick:()=>e.toggle(r),children:a.jsx("svg",{"aria-hidden":!0,viewBox:"0 0 8 8",width:"8",height:"8",fill:"currentColor",children:a.jsx("path",{d:"M1 0l6 4-6 4z"})})}):a.jsx("span",{"aria-hidden":!0,"data-rtdb-caret-spacer":!0}),a.jsx("button",{type:"button","data-rtdb-key":!0,"aria-label":"Key name",onClick:()=>n?.(r),children:s}),l?null:a.jsxs(a.Fragment,{children:[a.jsx("span",{"aria-hidden":!0,"data-rtdb-sep":!0,children:":"}),a.jsx("button",{type:"button","data-rtdb-value":!0,"data-rtdb-type":Sj(o),title:"Edit value",onClick:()=>{m(!0),g(!1)},children:kj(o)})]}),a.jsx("span",{"data-rtdb-actions":!0,children:y?a.jsxs("span",{"data-rtdb-confirm":!0,children:[a.jsxs("span",{"data-rtdb-confirm-label":!0,children:["Delete",l?" subtree":"","?"]}),a.jsx("button",{type:"button","data-rtdb-confirm-yes":!0,onClick:()=>void v(()=>t.remove(r),()=>g(!1)),children:"Delete"}),a.jsx("button",{type:"button","data-rtdb-confirm-no":!0,onClick:()=>g(!1),children:"Cancel"})]}):a.jsxs(a.Fragment,{children:[a.jsx("button",{type:"button","data-rtdb-action-add":!0,"aria-label":`Add child to ${pa(r)}`,title:"Add child",onClick:w,children:"+"}),a.jsx("button",{type:"button","data-rtdb-action-delete":!0,"aria-label":`Delete ${pa(r)}`,title:"Delete",onClick:()=>g(!0),children:"×"})]})})]}),x?a.jsx("p",{role:"alert","data-rtdb-error":!0,children:x}):null,h?a.jsx(ma,{initialType:fa(o),initialText:Aj(o,fa(o)),submitLabel:"Save",onCancel:()=>m(!1),onSubmit:j=>v(()=>t.set(r,j),()=>m(!1))}):null,d?a.jsx(ma,{withKey:!0,initialType:"string",initialText:"",submitLabel:"Add",onCancel:()=>p(!1),onSubmit:(j,S)=>v(()=>t.set(Vr(r,S),j),()=>p(!1))}):null,k?a.jsxs("ul",{"data-rtdb-children":!0,children:[k.entries.map(([j])=>a.jsx("li",{children:a.jsx(rc,{tree:e,api:t,onNavigate:n,path:Vr(r,j),label:j})},j)),k.hiddenCount>0?a.jsx("li",{"data-rtdb-show-more-item":!0,children:a.jsxs("button",{type:"button","data-rtdb-show-more":!0,onClick:()=>e.showMore(r),children:["Show more (",k.hiddenCount," hidden)"]})}):null]}):null]})}function pa(e){const t=Ge(e);return t.length===0?"root":t[t.length-1]}function ma({withKey:e,initialType:t,initialText:n,submitLabel:r,onSubmit:s,onCancel:i}){const o=f.useRef(null),l=f.useRef(null),[c,u]=f.useState(t),[d,p]=f.useState(null),h=y=>{y.preventDefault();const g=o.current?.value??"";if(e){const b=Rj(g);if(b){p(b);return}}const x=Dj(c,l.current?.value??"");if(!x.ok){p(x.error);return}p(null),s(x.value,e?g.trim():void 0)},m=y=>{y.key==="Escape"&&i()};return a.jsxs("form",{"data-rtdb-editor":!0,onSubmit:h,children:[e?a.jsx("input",{ref:o,"data-rtdb-editor-key":!0,"aria-label":"Child key",placeholder:"key",autoFocus:!0,onKeyDown:m,spellCheck:!1}):null,a.jsx("select",{"data-rtdb-editor-type":!0,"aria-label":"Value type",value:c,onChange:y=>u(y.currentTarget.value),onKeyDown:m,children:Nj.map(y=>a.jsx("option",{value:y,children:y},y))}),c==="boolean"?a.jsxs("select",{ref:l,"data-rtdb-editor-value":!0,"aria-label":"Value",defaultValue:n.trim().toLowerCase()==="true"?"true":"false",onKeyDown:m,children:[a.jsx("option",{value:"true",children:"true"}),a.jsx("option",{value:"false",children:"false"})]}):a.jsx("input",{ref:l,"data-rtdb-editor-value":!0,"aria-label":"Value",placeholder:c==="json"?'{ "key": "value" }':"value",autoFocus:!e,defaultValue:n,onKeyDown:m,spellCheck:!1}),a.jsx("button",{type:"submit","data-rtdb-editor-save":!0,children:r}),a.jsx("button",{type:"button","data-rtdb-editor-cancel":!0,onClick:i,children:"Cancel"}),d?a.jsx("span",{role:"alert","data-rtdb-editor-error":!0,children:d}):null]})}function Mj(){const e=fe(),t=e.status==="ready"?e.env.live:void 0;return a.jsxs("section",{className:"studio-surface grid gap-4","aria-labelledby":"rtdb-title",children:[a.jsxs("div",{className:"studio-surface__intro",children:[a.jsx("p",{className:"studio-surface__eyebrow",children:"RTDB"}),a.jsx("h1",{id:"rtdb-title",className:"studio-surface__title",children:"RTDB"}),a.jsx("p",{className:"studio-surface__copy",children:"Browse and edit RTDB data in the shared sandbox."})]}),t?a.jsx(Bj,{live:t}):a.jsx(Lj,{})]})}function Lj(){return a.jsxs("div",{className:"rounded-md border border-dashed border-line bg-panel p-8 text-center",children:[a.jsx("span",{className:"rounded-full border border-line px-3 py-1 text-xs uppercase tracking-wide text-muted",children:"Shared worker pending"}),a.jsx("p",{className:"mx-auto mt-3 max-w-md text-sm leading-relaxed text-muted",children:"The RTDB viewer goes live once Studio connects to the shared sandbox worker."})]})}function Bj({live:e}){const[t,n]=f.useState("/"),r=xs(us()),s=r?`${r}-sandbox`:"sandbox",i=f.useMemo(()=>({set:(l,c)=>e.setRtdbValue(l,c),remove:l=>e.deleteRtdbValue(l),subscribeValue:(l,c,u)=>e.subscribeRtdbValue(l,c,u)}),[e]),o=Oj(i,t);return a.jsxs("div",{className:"rtdb",children:[a.jsx(Uj,{className:"rtdb__pathbar",path:t,onNavigate:n,rootLabel:s,inputPrefix:s}),a.jsx(Tj,{className:"rtdb__tree",tree:o,api:i,onNavigate:n,rootLabel:s})]})}function Fj(e){if(e===null)return null;const t={collections:0,users:0,objects:0,rtdbKeys:0};for(const n of e)n.kind==="collection"?t.collections++:n.kind==="user"?t.users++:n.kind==="object"?t.objects++:n.kind==="rtdb-key"&&t.rtdbKeys++;return t}function nn(e,t,n=`${t}s`){return`${e} ${e===1?t:n}`}function Vj(e){if(e===null)return"measuring…";const t=[];return e.collections&&t.push(nn(e.collections,"collection")),e.users&&t.push(nn(e.users,"user")),e.objects&&t.push(nn(e.objects,"file")),e.rtdbKeys&&t.push(nn(e.rtdbKeys,"RTDB key")),t.length?t.join(" · "):"empty — no data yet"}function Fn(){return{width:15,height:15,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.7,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0}}function qj(){return a.jsxs("svg",{...Fn(),children:[a.jsx("path",{d:"M12 4v10"}),a.jsx("path",{d:"M8 10l4 4 4-4"}),a.jsx("path",{d:"M4 19h16"})]})}function Wj(){return a.jsxs("svg",{...Fn(),children:[a.jsx("path",{d:"M12 14V4"}),a.jsx("path",{d:"M8 8l4-4 4 4"}),a.jsx("path",{d:"M4 19h16"})]})}function zj(){return a.jsxs("svg",{...Fn(),children:[a.jsx("circle",{cx:"7",cy:"6",r:"2.4"}),a.jsx("circle",{cx:"7",cy:"18",r:"2.4"}),a.jsx("circle",{cx:"17",cy:"8",r:"2.4"}),a.jsx("path",{d:"M7 8.4v7.2"}),a.jsx("path",{d:"M17 10.4c0 3-4 3.6-7 4.4"})]})}function Kj(){return a.jsxs("svg",{...Fn(),children:[a.jsx("path",{d:"M4 5v5h5"}),a.jsx("path",{d:"M4.6 10a8 8 0 1 0 1.7-5.3"})]})}function rn({glyph:e,name:t,caption:n,disabled:r,danger:s,onClick:i}){return a.jsxs("button",{type:"button",className:"studio-sandbox__action","data-danger":s?"true":void 0,disabled:r,onClick:i,children:[a.jsxs("span",{className:"studio-sandbox__action-top",children:[e,a.jsx("span",{className:"studio-sandbox__action-name",children:t})]}),a.jsx("span",{className:"studio-sandbox__action-caption",children:n})]})}function Hj(){const e=Vy(),t=Wy(),n=zy(),r=Ky(),s=Pn(),i=f.useRef(null),o=xs(us()),[l,c]=f.useState(!1),[u,d]=f.useState(!1),[p,h]=f.useState(!1),[m,y]=f.useState(!1),[g,x]=f.useState(""),b=qo(),{ensure:v}=b;f.useEffect(()=>v(),[v]);const w=Fj(b.entries),k=Vj(w),j=s.status==="ready"?s.payload.persist?"persisted to disk":"ephemeral":"in-page · resets on reload",S=async()=>{const _=await t();if(!_||typeof document>"u")return;const E=URL.createObjectURL(new Blob([_],{type:"application/json"})),A=document.createElement("a");A.href=E,A.download=`pyric-sandbox-${o||"export"}.json`,A.click(),URL.revokeObjectURL(E)},C=async _=>{const E=_.target.files?.[0];if(_.target.value="",!!E&&!(typeof window<"u"&&!window.confirm("Import replaces all data in this sandbox. This cannot be undone. Continue?"))){d(!0);try{await n(await E.text())}finally{d(!1)}}},O=async()=>{h(!1),c(!0);try{await e()}finally{c(!1)}},I=async()=>{const _=g.trim();_&&(await r.save(_),x(""),y(!1))},$=async _=>{typeof window<"u"&&!window.confirm(`Switch to branch "${_}"? This replaces the current sandbox state.`)||await r.switchTo(_)},N=async _=>{typeof window<"u"&&!window.confirm(`Delete branch "${_}"?`)||await r.remove(_)};return a.jsxs("section",{className:"studio-surface studio-settings","aria-labelledby":"settings-title",children:[a.jsxs("div",{className:"studio-surface__intro",children:[a.jsx("p",{className:"studio-surface__eyebrow",children:"Settings"}),a.jsx("h1",{id:"settings-title",className:"studio-surface__title",children:"Configuration and maintenance."}),a.jsx("p",{className:"studio-surface__copy",children:"Global controls live here so service surfaces can stay focused on their primary work."})]}),a.jsx("div",{className:"studio-settings__grid",children:a.jsxs("section",{className:"studio-panel studio-settings__panel","aria-labelledby":"settings-sandbox-title",children:[a.jsx("h2",{id:"settings-sandbox-title",className:"studio-panel__title",children:"Sandbox"}),a.jsxs("div",{className:"studio-sandbox__live","aria-label":"Sandbox contents",children:[a.jsx("span",{className:"studio-sandbox__instance mono",children:o||"local"}),a.jsx("span",{className:"studio-sandbox__inventory",children:k}),a.jsx("span",{className:"studio-sandbox__persist",children:j})]}),a.jsxs("div",{className:"studio-sandbox__actions",children:[a.jsx(rn,{glyph:a.jsx(qj,{}),name:"Export",caption:"Downloads all of this as one file.",onClick:()=>void S()}),a.jsx(rn,{glyph:a.jsx(Wj,{}),name:u?"Importing…":"Import",caption:"A chosen file replaces everything here.",disabled:u,onClick:()=>i.current?.click()}),a.jsx(rn,{glyph:a.jsx(zj,{}),name:"Save branch",caption:"Keeps a copy you can return to.",onClick:()=>y(_=>!_)}),a.jsx(rn,{glyph:a.jsx(Kj,{}),name:l?"Resetting…":"Reset session",caption:"Everything returns to the seeded start.",disabled:l,danger:!0,onClick:()=>h(!0)})]}),a.jsx("input",{ref:i,type:"file",accept:"application/json,.json",className:"studio-settings__file",onChange:C}),m?a.jsxs("form",{className:"studio-sandbox__name-row",onSubmit:_=>{_.preventDefault(),I()},children:[a.jsx("input",{className:"studio-sandbox__name-input",type:"text",value:g,placeholder:"branch name","aria-label":"Branch name",autoFocus:!0,onChange:_=>x(_.target.value),onKeyDown:_=>{_.key==="Escape"&&(y(!1),x(""))}}),a.jsx("button",{type:"submit",className:"studio-button",disabled:!g.trim(),children:"Save"}),a.jsx("button",{type:"button",className:"studio-button",onClick:()=>{y(!1),x("")},children:"Cancel"})]}):null,p?a.jsxs("div",{className:"studio-sandbox__confirm",role:"alert",children:[a.jsx("span",{className:"studio-sandbox__confirm-copy",children:w&&k!=="empty — no data yet"?`This erases ${k}.`:"This erases everything in this sandbox."}),a.jsxs("span",{className:"studio-sandbox__confirm-actions",children:[a.jsx("button",{type:"button",className:"studio-button studio-button--danger",onClick:()=>void O(),children:"Erase and reseed"}),a.jsx("button",{type:"button",className:"studio-button",onClick:()=>h(!1),children:"Keep"})]})]}):null,r.branches.length>0?a.jsx("div",{className:"studio-settings__branches",children:r.branches.map(_=>a.jsxs("div",{className:"studio-settings__branch",children:[a.jsx("span",{className:"mono",children:_}),a.jsxs("span",{className:"studio-settings__branch-actions",children:[a.jsx("button",{type:"button",className:"studio-button",onClick:()=>void $(_),children:"Switch"}),a.jsx("button",{type:"button",className:"studio-button",onClick:()=>void N(_),children:"Delete"})]})]},_))}):a.jsx("p",{className:"studio-sandbox__branches-empty",children:"No branches yet — Save branch keeps this exact state to come back to."})]})})]})}function sn(e){return e===null?"absent":e===void 0?"unknown":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):JSON.stringify(e)}function Gj(e){const t=e.stateDiff;if(!t)return"No state evidence";if(!t.changed)return e.mutation.output!==void 0?"Read result captured":"No state change";if(t.before&&t.after&&typeof t.before=="object"&&typeof t.after=="object"&&!Array.isArray(t.before)&&!Array.isArray(t.after)){const n=t.before,r=t.after,i=[...new Set([...Object.keys(n),...Object.keys(r)])].filter(o=>JSON.stringify(n[o])!==JSON.stringify(r[o]));if(i.length>0&&i.length<=3)return i.map(o=>`${o}: ${sn(n[o])} -> ${sn(r[o])}`).join(", ")}return`${sn(t.before)} -> ${sn(t.after)}`}function Jj(e){return e.results.map(t=>({id:t.probeId,service:t.control.operation.service,operation:`${t.mutation.operation.method} ${t.mutation.operation.path}`,actor:t.actorEvidence.uid??(t.actorEvidence.acquisition==="anonymous-request"?"anonymous":t.actorEvidence.actorId),expected:t.invariant.expected,observed:t.mutation.decision,classification:t.classification,impact:Gj(t),supported:t.qualification.supported}))}function Yj(e){const t=e.mutation.events.find(o=>o.result==="allow"||o.result==="deny"||o.result==="unsupported");if(!t)return null;const n=t.result,r={id:t.id??`${e.probeId}-decision`,at:t.at??0,result:n,method:t.method??t.op??e.mutation.operation.method,service:t.service??e.mutation.operation.service,path:t.path??e.mutation.operation.path,auth:t.auth??null,reasons:t.reasons??[],origin:t.origin??"user",unsupported:n==="unsupported"};t.matchedRule&&(r.matchedRule=t.matchedRule),t.evaluatedRule&&(r.evaluatedRule=t.evaluatedRule),t.rules&&(r.rules=t.rules),t.resourceBefore&&(r.resourceBefore=t.resourceBefore);const s=t.request,i=s?.resourceData??s?.data;return i!==void 0&&(r.resourceData=i),r}const Xj="pyric:assurance-campaign",Qj="pyric-assurance-v1",Wr=new Set;let ya=!1,ba;function ga(e){for(const t of Wr)t(e)}function va(e){return!!e&&typeof e=="object"&&e.schema==="pyric.assurance.visualization.v1"&&typeof e.campaignId=="string"}function Zj(){if(!(ya||typeof document>"u")){ya=!0,globalThis.addEventListener(Xj,e=>{const t=e.detail;va(t)&&ga(t)});try{ba=new BroadcastChannel(Qj),ba.onmessage=e=>{va(e.data)&&ga(e.data)}}catch{}}}function ek(e){return Zj(),Wr.add(e),()=>Wr.delete(e)}function or(e){return{campaignId:"collaboration-local-v1",probeId:e.id,targetHash:"fnv1a32-7f4c911a",actorEvidence:{actorId:"member-b",acquisition:"password",reachability:"reachable",uid:"mallory"},invariant:{id:`${e.id}-invariant`,service:e.service,statement:e.statement,expected:"DENY",source:"declared",confidence:"authoritative"},mutationSpec:{dimension:e.service==="firestore"?"payload":"path",description:e.description,operation:e.mutation},control:{operation:e.control,decision:"ALLOW",events:[]},mutation:{operation:e.mutation,decision:"ALLOW",events:e.service==="firestore"?[{id:"req-firestore-owner-transfer",at:100,kind:"request",service:"firestore",method:"update",path:"rooms/r1",result:"allow",auth:{uid:"mallory",token:{}},reasons:["Rule #1 (update) -> ALLOW"],origin:"user",request:{resourceData:{ownerId:"mallory"}},resourceBefore:{exists:!0,data:e.before},matchedRule:{ruleIndex:0,operations:["update"]}}]:[]},stateDiff:{changed:!0,before:e.before,after:e.after},qualification:{engine:"pyric-local-sandboxes",supported:!0,requirements:[{id:`${e.service}.local-supported-subset`,supported:!0,reason:"This probe stays within the supported local evaluator subset."}]},classification:"local-counterexample"}}const tk=[or({id:"firestore-owner-transfer",service:"firestore",control:{service:"firestore",method:"update",path:"rooms/r1",data:{title:"Edited"}},mutation:{service:"firestore",method:"update",path:"rooms/r1",data:{ownerId:"mallory"}},statement:"A non-owner room member must not change ownerId.",description:"Changed only the updated field from title to ownerId.",before:{ownerId:"alice",title:"Original title"},after:{ownerId:"mallory",title:"Original title"}}),or({id:"rtdb-other-role",service:"rtdb",control:{service:"rtdb",method:"set",path:"/rooms/r1/members/mallory/status",data:"online"},mutation:{service:"rtdb",method:"set",path:"/rooms/r1/members/alice/role",data:"online"},statement:"A member must not change another member's role.",description:"Changed only the target path from own status to another member role.",before:"owner",after:"online"}),or({id:"storage-overwrite-owner",service:"storage",control:{service:"storage",method:"upload",path:"b/pyric-default/o/rooms/r1/mallory/note.json",dataBase64:"bWFsbG9yeQ==",customMetadata:{owner:"mallory"}},mutation:{service:"storage",method:"upload",path:"b/pyric-default/o/rooms/r1/alice/private.json",dataBase64:"bWFsbG9yeQ==",customMetadata:{owner:"mallory"}},statement:"A member must not overwrite an object owned by another actor.",description:"Changed only the target from a new own object to an existing other-owned object.",before:{text:"alice-secret",customMetadata:{owner:"alice"}},after:{text:"mallory",customMetadata:{owner:"mallory"}}})],kk=tk.map(e=>({...e,campaignId:"collaboration-local-v1-fixed",targetHash:"fnv1a32-a9f18f23",mutation:{...e.mutation,decision:"DENY",events:[]},stateDiff:void 0,classification:"no-counterexample"}));const zr="pyric:assurance:campaigns",sc="pyric:assurance:campaign:";function nk(e){return!!e&&typeof e=="object"&&e.schema==="pyric.assurance.visualization.v1"&&typeof e.campaignId=="string"}function rk(){if(typeof sessionStorage>"u")return[];try{const e=JSON.parse(sessionStorage.getItem(zr)??"[]");if(!Array.isArray(e))return[];const t=e.map(n=>sessionStorage.getItem(`${sc}${String(n)}`)).filter(n=>!!n).map(n=>JSON.parse(n)).filter(nk);return t.length,t}catch{return[]}}function sk(e){if(!(typeof sessionStorage>"u"))try{const t=JSON.parse(sessionStorage.getItem(zr)??"[]"),n=Array.isArray(t)?t.map(String):[];n.includes(e.campaignId)||n.push(e.campaignId),sessionStorage.setItem(zr,JSON.stringify(n)),sessionStorage.setItem(`${sc}${e.campaignId}`,JSON.stringify(e))}catch{}}function ik(e,t){const n=e.findIndex(s=>s.campaignId===t.campaignId);if(n===-1)return[...e,t];const r=[...e];return r[n]=t,r}function ak(){const[e,t]=f.useState(rk);return f.useEffect(()=>{const r=ek(s=>{sk(s),t(i=>ik(i,s))});return()=>{r()}},[]),e}function ok(e,t){return e!==t?"assurance-verdict--mismatch":t==="ALLOW"?"assurance-verdict--allow":"assurance-verdict--deny"}function lk(e){return e.replaceAll("-"," ")}function xa({value:e}){return a.jsx("pre",{className:"assurance-evidence__json",children:JSON.stringify(e,null,2)})}function ck(){return a.jsxs("section",{className:"assurance-empty","aria-labelledby":"assurance-empty-title",children:[a.jsx("p",{className:"assurance-surface__eyebrow",children:"Local authorization assurance"}),a.jsx("h1",{id:"assurance-empty-title",children:"No campaign in this Studio session"}),a.jsx("p",{children:"Campaigns appear here as the local assurance tools map actors, run controls, and test explicit security invariants."}),a.jsx("span",{className:"assurance-local-state",children:"Pyric sandboxes only | network off"})]})}function wa({attachment:e}){return e?a.jsxs("div",{className:"assurance-attachment","aria-label":"Attached sandbox inventory",children:[a.jsxs("span",{children:[a.jsx("strong",{children:e.source.origin}),"read-only clone"]}),a.jsxs("span",{children:[a.jsx("strong",{children:e.inventory.firestoreDocuments}),"Firestore docs"]}),a.jsxs("span",{children:[a.jsx("strong",{children:e.inventory.authUsers}),"Auth users"]}),a.jsxs("span",{children:[a.jsx("strong",{children:e.inventory.rtdbPresent?"present":"empty"}),"RTDB"]})]}):null}function uk({campaigns:e}){const t=ak(),n=e??t,r=be().query,[s,i]=f.useState(r.campaign??n.find(w=>w.report)?.campaignId??n[0]?.campaignId??""),o=n.find(w=>w.campaignId===s)??n[0],l=f.useMemo(()=>o?.report?Jj(o.report):[],[o]),[c,u]=f.useState(r.probe??l[0]?.id??"");if(f.useEffect(()=>{!s&&n[0]&&i(n[0].campaignId)},[s,n]),f.useEffect(()=>{l.some(w=>w.id===c)||u(l[0]?.id??"")},[l,c]),!o)return a.jsx(ck,{});const d=o.context?.attachment,p=o.report;if(!p)return a.jsxs("section",{className:"assurance-empty","aria-labelledby":"assurance-mapped-title",children:[a.jsx("p",{className:"assurance-surface__eyebrow",children:o.campaignId}),a.jsx("h1",{id:"assurance-mapped-title",children:"Campaign mapped, awaiting its first run"}),a.jsxs("p",{children:[o.observations.length," known-good operation(s) and"," ",o.probes.length," probe(s) are available."]}),a.jsx(wa,{attachment:d}),d?.coverageGaps.length?a.jsx("ul",{className:"assurance-coverage-gaps","aria-label":"Attachment coverage gaps",children:d.coverageGaps.map(w=>a.jsxs("li",{children:[a.jsx("code",{children:w.service}),w.reason]},w.code))}):null,a.jsx("span",{className:"assurance-local-state",children:"Pyric sandboxes only | network off"})]});const h=l.find(w=>w.id===c)??l[0],m=p.results.find(w=>w.probeId===h?.id),y=m?Yj(m):null,g=o.verifications?.at(-1),x=g!==void 0&&g.summary.controlsPassed===g.summary.probes&&g.summary.noCounterexamples===g.summary.probes&&g.summary.localCounterexamples===0&&g.summary.engineGaps===0&&g.summary.invalidProbes===0;function b(w){i(w);const j=n.find(S=>S.campaignId===w)?.report?.results[0]?.probeId??"";u(j),bn({tab:"assurance",query:{campaign:w,probe:j||void 0}})}function v(w){u(w.id),bn({tab:"assurance",query:{campaign:o.campaignId,probe:w.id}})}return a.jsxs("section",{className:"assurance-surface","aria-labelledby":"assurance-title",children:[a.jsxs("header",{className:"assurance-surface__header",children:[a.jsxs("div",{children:[a.jsx("p",{className:"assurance-surface__eyebrow",children:"Local authorization assurance"}),a.jsx("h1",{id:"assurance-title",children:o.campaignId})]}),a.jsxs("div",{className:"assurance-surface__controls",children:[n.length>1?a.jsxs("label",{children:[a.jsx("span",{children:"Campaign"}),a.jsx("select",{value:o.campaignId,onChange:w=>b(w.target.value),children:n.map(w=>a.jsx("option",{value:w.campaignId,children:w.campaignId},w.campaignId))})]}):null,a.jsx("span",{className:"assurance-local-state",children:"Pyric sandboxes only | network off"})]})]}),a.jsx(wa,{attachment:d}),a.jsxs("div",{className:"assurance-summary","aria-label":"Campaign summary",children:[a.jsxs("div",{children:[a.jsx("span",{children:"Controls"}),a.jsxs("strong",{children:[p.summary.controlsPassed,"/",p.summary.probes]})]}),a.jsxs("div",{children:[a.jsx("span",{children:"Counterexamples"}),a.jsx("strong",{children:p.summary.localCounterexamples})]}),a.jsxs("div",{children:[a.jsx("span",{children:"Candidate signals"}),a.jsx("strong",{children:p.summary.candidateSignals})]}),a.jsxs("div",{children:[a.jsx("span",{children:"Engine gaps"}),a.jsx("strong",{children:p.summary.engineGaps})]}),a.jsxs("div",{children:[a.jsx("span",{children:"Coverage gaps"}),a.jsx("strong",{children:d?.coverageGaps.length??0})]})]}),g?a.jsxs("div",{className:`assurance-verification-band assurance-verification-band--${x?"passed":"failed"}`,role:"status",children:[a.jsx("strong",{children:x?"Candidate rules verified":"Candidate rules need review"}),a.jsxs("span",{children:[g.summary.controlsPassed,"/",g.summary.probes," ","controls preserved"," | ",g.summary.noCounterexamples,"/",g.summary.probes," negative cases denied"]}),a.jsx("code",{children:g.campaignId})]}):null,d?.coverageGaps.length?a.jsxs("div",{className:"assurance-coverage-band",children:[a.jsxs("strong",{children:[d.coverageGaps.length," attachment gap(s)"]}),a.jsx("span",{children:d.coverageGaps.map(w=>`${w.service}: ${w.reason}`).join(" ")})]}):null,a.jsxs("div",{className:"assurance-workspace",children:[a.jsxs("section",{className:"assurance-matrix","aria-labelledby":"assurance-matrix-title",children:[a.jsxs("div",{className:"assurance-section-heading",children:[a.jsx("h2",{id:"assurance-matrix-title",children:"Expected and observed access"}),a.jsx("span",{children:p.targetHash})]}),a.jsxs("div",{className:"assurance-table",role:"table",children:[a.jsxs("div",{className:"assurance-table__header",role:"row",children:[a.jsx("span",{role:"columnheader",children:"Operation"}),a.jsx("span",{role:"columnheader",children:"Actor"}),a.jsx("span",{role:"columnheader",children:"Expected"}),a.jsx("span",{role:"columnheader",children:"Observed"}),a.jsx("span",{role:"columnheader",children:"Impact"})]}),l.map(w=>a.jsxs("button",{type:"button",className:"assurance-table__row","aria-pressed":w.id===h?.id,onClick:()=>v(w),role:"row",children:[a.jsxs("span",{role:"cell",children:[a.jsx("small",{children:w.service}),w.operation]}),a.jsx("span",{role:"cell",children:w.actor}),a.jsx("span",{role:"cell",className:`assurance-verdict ${w.expected==="ALLOW"?"assurance-verdict--allow":"assurance-verdict--deny"}`,children:w.expected}),a.jsx("span",{role:"cell",className:`assurance-verdict ${ok(w.expected,w.observed)}`,children:w.observed}),a.jsx("span",{role:"cell",children:w.impact})]},w.id))]})]}),m?a.jsxs("aside",{className:"assurance-inspector","aria-labelledby":"assurance-inspector-title",children:[a.jsxs("div",{className:"assurance-section-heading",children:[a.jsxs("div",{children:[a.jsx("span",{className:`assurance-classification assurance-classification--${m.classification}`,children:lk(m.classification)}),a.jsx("h2",{id:"assurance-inspector-title",children:m.probeId})]}),a.jsx("span",{children:m.actorEvidence.reachability})]}),a.jsxs("dl",{className:"assurance-facts",children:[a.jsxs("div",{children:[a.jsx("dt",{children:"Invariant"}),a.jsx("dd",{children:m.invariant.statement})]}),a.jsxs("div",{children:[a.jsx("dt",{children:"Mutation"}),a.jsx("dd",{children:m.mutationSpec.description})]}),a.jsxs("div",{children:[a.jsx("dt",{children:"Actor"}),a.jsxs("dd",{children:[m.actorEvidence.uid??m.actorEvidence.actorId," ","via ",m.actorEvidence.acquisition]})]}),a.jsxs("div",{children:[a.jsx("dt",{children:"Fidelity"}),a.jsx("dd",{children:m.qualification.supported?"Supported for this probe":"Engine gap"})]})]}),m.qualification.requirements.some(w=>!w.supported)?a.jsx("ul",{className:"assurance-gaps",children:m.qualification.requirements.filter(w=>!w.supported).map(w=>a.jsxs("li",{children:[a.jsx("code",{children:w.id}),w.reason]},w.id))}):null,m.stateDiff?a.jsxs("section",{className:"assurance-evidence","aria-labelledby":"assurance-state-title",children:[a.jsx("h3",{id:"assurance-state-title",children:"State evidence"}),a.jsxs("div",{className:"assurance-evidence__diff",children:[a.jsxs("div",{children:[a.jsx("span",{children:"Before"}),a.jsx(xa,{value:m.stateDiff.before})]}),a.jsxs("div",{children:[a.jsx("span",{children:"After"}),a.jsx(xa,{value:m.stateDiff.after})]})]})]}):null,y?a.jsxs("section",{className:"assurance-rule-decision","aria-labelledby":"assurance-rule-title",children:[a.jsx("h3",{id:"assurance-rule-title",children:"Rule decision"}),a.jsx(Wl,{denial:y})]}):a.jsx("p",{className:"assurance-no-decision",children:"This service recorded operation and state evidence but no canonical rule-decision event."})]}):null]})]})}function ic(){const e="/__pyric/ui/";return`${e.endsWith("/")?e:`${e}/`}docs`}function dk(){const[e,t]=f.useState(!1);return f.useEffect(()=>{let n=!0;return fetch(`${ic()}/index.json`,{method:"HEAD"}).then(r=>{const s=r.headers.get("content-type")??"";n&&r.ok&&s.includes("json")&&t(!0)}).catch(()=>{}),()=>{n=!1}},[]),e}function fk({id:e}){const t=Mp(e),n=Ee(),r=[`route #${t.id}`];return n.status==="ready"?(r.push(`events: ${n.events.length}`),r.push("dev-seed: ready")):n.status==="pending"?r.push("dev-seed: seeding…"):n.status==="error"?r.push("dev-seed: error"):r.push("dev-seed: off"),a.jsxs("section",{className:"studio__placeholder","aria-labelledby":`route-${t.id}`,children:[a.jsx("p",{className:"studio__placeholder-eyebrow",children:"Surface"}),a.jsx("h2",{id:`route-${t.id}`,className:"studio__placeholder-title",children:t.label}),a.jsx("p",{className:"studio__placeholder-blurb",children:t.description}),a.jsx("div",{className:"studio__placeholder-meta",children:r.map(s=>a.jsx("span",{children:s},s))})]})}function hk({id:e}){switch(e){case"home":return a.jsx(jj,{});case"firestore":return a.jsx(iw,{});case"auth":return a.jsx(fw,{});case"storage":return a.jsx(aw,{});case"rtdb":return a.jsx(Mj,{});case"traffic":return a.jsx(cj,{});case"assurance":return a.jsx(uk,{});case"settings":return a.jsx(Hj,{});default:return a.jsx(fk,{id:e})}}function pk(){const[e,t]=Dp(Tp,"home"),n=l=>t(l),[r,s]=f.useState(!1),i=dk(),o=e==="home";return f.useEffect(()=>{const l=c=>{if(Pp(c)){if(r){c.preventDefault(),s(!1);return}if(o){$p()&&c.preventDefault();return}c.preventDefault(),s(!0)}};return window.addEventListener("keydown",l),()=>window.removeEventListener("keydown",l)},[o,r]),f.useEffect(()=>{o&&s(!1)},[o]),f.useEffect(()=>{document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"})},[e]),a.jsxs("div",{className:"studio","data-surface":e,children:[a.jsx("header",{className:"studio__bar",children:a.jsxs("div",{className:"studio__bar-inner",children:[a.jsx("span",{className:"studio__brand","aria-label":"Pyric Studio",children:"Pyric"}),a.jsxs("nav",{className:"studio__nav","aria-label":"Studio tabs",children:[Ke.map(l=>a.jsx("button",{type:"button",className:"studio__nav-tab","aria-current":l.id===e?"page":void 0,onClick:()=>n(l.id),children:l.label},l.id)),i?a.jsx("a",{className:"studio__nav-tab",href:ic(),children:"Docs"}):null]}),a.jsx(mb,{})]})}),a.jsx("main",{className:"studio__content","data-surface":e,children:a.jsx("div",{className:"studio__surface-slot","data-active":"true",children:a.jsx(hk,{id:e})})}),r?a.jsx(eb,{onClose:()=>s(!1)}):null]})}function mk(){return a.jsx(Ep,{children:a.jsx(Bu,{children:a.jsx(wp,{mode:"local",children:a.jsx(pk,{})})})})}function Sk(){return a.jsx(f.StrictMode,{children:a.jsx(mk,{})})}export{Sk as S,jk as a,dm as b,Ot as r,he as s,ny as u};