@pyric/cli 0.1.0-alpha.30.1 → 0.1.0-alpha.31
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.
- package/dist/assurance/.generated/conformance-verdicts.d.ts +111 -40
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +111 -40
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/assurance/capabilities.d.ts.map +1 -1
- package/dist/assurance/capabilities.js +12 -14
- package/dist/assurance/capabilities.js.map +1 -1
- package/dist/bounded-request.d.ts +27 -5
- package/dist/bounded-request.d.ts.map +1 -1
- package/dist/bounded-request.js +48 -4
- package/dist/bounded-request.js.map +1 -1
- package/dist/bridge/client/bridge-url.d.ts +5 -1
- package/dist/bridge/client/bridge-url.d.ts.map +1 -1
- package/dist/bridge/client/bridge-url.js +5 -1
- package/dist/bridge/client/bridge-url.js.map +1 -1
- package/dist/bridge/client/bridge.d.ts +9 -3
- package/dist/bridge/client/bridge.d.ts.map +1 -1
- package/dist/bridge/client/bridge.js +17 -3
- package/dist/bridge/client/bridge.js.map +1 -1
- package/dist/bridge/frame-output.d.ts.map +1 -1
- package/dist/bridge/frame-output.js +46 -0
- package/dist/bridge/frame-output.js.map +1 -1
- package/dist/bridge/protocol.d.ts +10 -0
- package/dist/bridge/protocol.d.ts.map +1 -1
- package/dist/bridge/protocol.js +10 -0
- package/dist/bridge/protocol.js.map +1 -1
- package/dist/bridge/server/in-process.d.ts +16 -7
- package/dist/bridge/server/in-process.d.ts.map +1 -1
- package/dist/bridge/server/in-process.js +51 -17
- package/dist/bridge/server/in-process.js.map +1 -1
- package/dist/bridge/server/peer.d.ts +18 -0
- package/dist/bridge/server/peer.d.ts.map +1 -1
- package/dist/bridge/server/peer.js +56 -1
- package/dist/bridge/server/peer.js.map +1 -1
- package/dist/bridge/server/standalone.d.ts +7 -2
- package/dist/bridge/server/standalone.d.ts.map +1 -1
- package/dist/bridge/server/standalone.js +27 -99
- package/dist/bridge/server/standalone.js.map +1 -1
- package/dist/bridge/surface/arguments/firestore.d.ts +6 -6
- package/dist/bridge/surface/arguments/sandbox.d.ts +0 -47
- package/dist/bridge/surface/arguments/sandbox.d.ts.map +1 -1
- package/dist/bridge/surface/arguments/sandbox.js +2 -59
- package/dist/bridge/surface/arguments/sandbox.js.map +1 -1
- package/dist/bridge/surface/arguments/seed.d.ts +61 -0
- package/dist/bridge/surface/arguments/seed.d.ts.map +1 -0
- package/dist/bridge/surface/arguments/seed.js +67 -0
- package/dist/bridge/surface/arguments/seed.js.map +1 -0
- package/dist/bridge/surface/arguments/storage.d.ts +2 -2
- package/dist/bridge/surface/context.d.ts +5 -10
- package/dist/bridge/surface/context.d.ts.map +1 -1
- package/dist/bridge/surface/context.js +11 -23
- package/dist/bridge/surface/context.js.map +1 -1
- package/dist/bridge/surface/database-instance-catalog.d.ts +0 -3
- package/dist/bridge/surface/database-instance-catalog.d.ts.map +1 -1
- package/dist/bridge/surface/database-instance-catalog.js +4 -27
- package/dist/bridge/surface/database-instance-catalog.js.map +1 -1
- package/dist/bridge/surface/database-instance-project.d.ts +5 -0
- package/dist/bridge/surface/database-instance-project.d.ts.map +1 -0
- package/dist/bridge/surface/database-instance-project.js +32 -0
- package/dist/bridge/surface/database-instance-project.js.map +1 -0
- package/dist/bridge/surface/database-instance.d.ts +3 -3
- package/dist/bridge/surface/database-instance.d.ts.map +1 -1
- package/dist/bridge/surface/database-instance.js +1 -2
- package/dist/bridge/surface/database-instance.js.map +1 -1
- package/dist/bridge/surface/functions-runtime.d.ts +2 -2
- package/dist/bridge/surface/functions-runtime.js +5 -5
- package/dist/bridge/surface/functions-runtime.js.map +1 -1
- package/dist/bridge/surface/held-identity.d.ts +4 -4
- package/dist/bridge/surface/held-identity.d.ts.map +1 -1
- package/dist/bridge/surface/held-identity.js.map +1 -1
- package/dist/bridge/surface/manifest.sandbox.generated.d.ts +3 -0
- package/dist/bridge/surface/manifest.sandbox.generated.d.ts.map +1 -0
- package/dist/bridge/surface/manifest.sandbox.generated.js +135 -0
- package/dist/bridge/surface/manifest.sandbox.generated.js.map +1 -0
- package/dist/bridge/surface/method-types.d.ts +48 -7
- package/dist/bridge/surface/method-types.d.ts.map +1 -1
- package/dist/bridge/surface/method-types.js +15 -0
- package/dist/bridge/surface/method-types.js.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/clearScripts.d.ts +2 -1
- package/dist/bridge/surface/methods/ai_logic/clearScripts.d.ts.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/clearScripts.js +2 -1
- package/dist/bridge/surface/methods/ai_logic/clearScripts.js.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/script.d.ts +2 -1
- package/dist/bridge/surface/methods/ai_logic/script.d.ts.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/script.js +2 -1
- package/dist/bridge/surface/methods/ai_logic/script.js.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/scripts.d.ts +2 -1
- package/dist/bridge/surface/methods/ai_logic/scripts.d.ts.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/scripts.js +2 -1
- package/dist/bridge/surface/methods/ai_logic/scripts.js.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/status.d.ts +2 -1
- package/dist/bridge/surface/methods/ai_logic/status.d.ts.map +1 -1
- package/dist/bridge/surface/methods/ai_logic/status.js +1 -0
- package/dist/bridge/surface/methods/ai_logic/status.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/attach.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/attach.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/attach.js +1 -0
- package/dist/bridge/surface/methods/assurance/attach.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/canIUse.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/canIUse.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/canIUse.js +1 -0
- package/dist/bridge/surface/methods/assurance/canIUse.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/define.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/define.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/define.js +1 -0
- package/dist/bridge/surface/methods/assurance/define.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/export.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/export.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/export.js +1 -0
- package/dist/bridge/surface/methods/assurance/export.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/inspect.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/inspect.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/inspect.js +1 -0
- package/dist/bridge/surface/methods/assurance/inspect.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/map.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/map.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/map.js +1 -0
- package/dist/bridge/surface/methods/assurance/map.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/minimize.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/minimize.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/minimize.js +1 -0
- package/dist/bridge/surface/methods/assurance/minimize.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/propose.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/propose.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/propose.js +1 -0
- package/dist/bridge/surface/methods/assurance/propose.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/replaySession.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/replaySession.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/replaySession.js +1 -0
- package/dist/bridge/surface/methods/assurance/replaySession.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/run.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/run.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/run.js +1 -0
- package/dist/bridge/surface/methods/assurance/run.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/start.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/start.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/start.js +1 -0
- package/dist/bridge/surface/methods/assurance/start.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/testRulesHosted.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/testRulesHosted.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/testRulesHosted.js +1 -0
- package/dist/bridge/surface/methods/assurance/testRulesHosted.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/verify.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/verify.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/verify.js +1 -0
- package/dist/bridge/surface/methods/assurance/verify.js.map +1 -1
- package/dist/bridge/surface/methods/assurance/verifyCases.d.ts +1 -0
- package/dist/bridge/surface/methods/assurance/verifyCases.d.ts.map +1 -1
- package/dist/bridge/surface/methods/assurance/verifyCases.js +1 -0
- package/dist/bridge/surface/methods/assurance/verifyCases.js.map +1 -1
- package/dist/bridge/surface/methods/auth/actAsAdmin.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/actAsAdmin.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/actAsAdmin.js +1 -0
- package/dist/bridge/surface/methods/auth/actAsAdmin.js.map +1 -1
- package/dist/bridge/surface/methods/auth/actAsAnonymous.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/actAsAnonymous.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/actAsAnonymous.js +1 -0
- package/dist/bridge/surface/methods/auth/actAsAnonymous.js.map +1 -1
- package/dist/bridge/surface/methods/auth/createCustomToken.d.ts +1 -0
- package/dist/bridge/surface/methods/auth/createCustomToken.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/createCustomToken.js +1 -0
- package/dist/bridge/surface/methods/auth/createCustomToken.js.map +1 -1
- package/dist/bridge/surface/methods/auth/createUser.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/createUser.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/createUser.js +2 -1
- package/dist/bridge/surface/methods/auth/createUser.js.map +1 -1
- package/dist/bridge/surface/methods/auth/deleteUser.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/deleteUser.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/deleteUser.js +2 -1
- package/dist/bridge/surface/methods/auth/deleteUser.js.map +1 -1
- package/dist/bridge/surface/methods/auth/getUser.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/getUser.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/getUser.js +2 -1
- package/dist/bridge/surface/methods/auth/getUser.js.map +1 -1
- package/dist/bridge/surface/methods/auth/getUserByEmail.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/getUserByEmail.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/getUserByEmail.js +2 -1
- package/dist/bridge/surface/methods/auth/getUserByEmail.js.map +1 -1
- package/dist/bridge/surface/methods/auth/impersonate.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/impersonate.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/impersonate.js +1 -0
- package/dist/bridge/surface/methods/auth/impersonate.js.map +1 -1
- package/dist/bridge/surface/methods/auth/importUsers.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/importUsers.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/importUsers.js +3 -2
- package/dist/bridge/surface/methods/auth/importUsers.js.map +1 -1
- package/dist/bridge/surface/methods/auth/listUsers.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/listUsers.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/listUsers.js +2 -1
- package/dist/bridge/surface/methods/auth/listUsers.js.map +1 -1
- package/dist/bridge/surface/methods/auth/sessions.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/sessions.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/sessions.js +1 -0
- package/dist/bridge/surface/methods/auth/sessions.js.map +1 -1
- package/dist/bridge/surface/methods/auth/setCustomUserClaims.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/setCustomUserClaims.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/setCustomUserClaims.js +2 -1
- package/dist/bridge/surface/methods/auth/setCustomUserClaims.js.map +1 -1
- package/dist/bridge/surface/methods/auth/signInAnonymously.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/signInAnonymously.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/signInAnonymously.js +1 -0
- package/dist/bridge/surface/methods/auth/signInAnonymously.js.map +1 -1
- package/dist/bridge/surface/methods/auth/signInWithCredential.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/signInWithCredential.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/signInWithCredential.js +1 -0
- package/dist/bridge/surface/methods/auth/signInWithCredential.js.map +1 -1
- package/dist/bridge/surface/methods/auth/signInWithCustomToken.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/signInWithCustomToken.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/signInWithCustomToken.js +1 -0
- package/dist/bridge/surface/methods/auth/signInWithCustomToken.js.map +1 -1
- package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.js +1 -0
- package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.js.map +1 -1
- package/dist/bridge/surface/methods/auth/signOut.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/signOut.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/signOut.js +1 -0
- package/dist/bridge/surface/methods/auth/signOut.js.map +1 -1
- package/dist/bridge/surface/methods/auth/takeAuthMail.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/takeAuthMail.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/takeAuthMail.js +1 -0
- package/dist/bridge/surface/methods/auth/takeAuthMail.js.map +1 -1
- package/dist/bridge/surface/methods/auth/updateUser.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/updateUser.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/updateUser.js +2 -1
- package/dist/bridge/surface/methods/auth/updateUser.js.map +1 -1
- package/dist/bridge/surface/methods/auth/useAppSession.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/useAppSession.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/useAppSession.js +1 -0
- package/dist/bridge/surface/methods/auth/useAppSession.js.map +1 -1
- package/dist/bridge/surface/methods/auth/whoami.d.ts +2 -1
- package/dist/bridge/surface/methods/auth/whoami.d.ts.map +1 -1
- package/dist/bridge/surface/methods/auth/whoami.js +1 -0
- package/dist/bridge/surface/methods/auth/whoami.js.map +1 -1
- package/dist/bridge/surface/methods/database/crawl.d.ts +2 -1
- package/dist/bridge/surface/methods/database/crawl.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/crawl.js +1 -0
- package/dist/bridge/surface/methods/database/crawl.js.map +1 -1
- package/dist/bridge/surface/methods/database/get.d.ts +2 -1
- package/dist/bridge/surface/methods/database/get.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/get.js +1 -0
- package/dist/bridge/surface/methods/database/get.js.map +1 -1
- package/dist/bridge/surface/methods/database/push.d.ts +2 -1
- package/dist/bridge/surface/methods/database/push.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/push.js +1 -0
- package/dist/bridge/surface/methods/database/push.js.map +1 -1
- package/dist/bridge/surface/methods/database/query.d.ts +2 -1
- package/dist/bridge/surface/methods/database/query.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/query.js +1 -0
- package/dist/bridge/surface/methods/database/query.js.map +1 -1
- package/dist/bridge/surface/methods/database/remove.d.ts +2 -1
- package/dist/bridge/surface/methods/database/remove.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/remove.js +1 -0
- package/dist/bridge/surface/methods/database/remove.js.map +1 -1
- package/dist/bridge/surface/methods/database/set.d.ts +2 -1
- package/dist/bridge/surface/methods/database/set.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/set.js +1 -0
- package/dist/bridge/surface/methods/database/set.js.map +1 -1
- package/dist/bridge/surface/methods/database/update.d.ts +2 -1
- package/dist/bridge/surface/methods/database/update.d.ts.map +1 -1
- package/dist/bridge/surface/methods/database/update.js +1 -0
- package/dist/bridge/surface/methods/database/update.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/addDoc.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/addDoc.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/addDoc.js +2 -1
- package/dist/bridge/surface/methods/firestore/addDoc.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/deleteDoc.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/deleteDoc.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/deleteDoc.js +2 -1
- package/dist/bridge/surface/methods/firestore/deleteDoc.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/discoverPaths.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/discoverPaths.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/discoverPaths.js +1 -0
- package/dist/bridge/surface/methods/firestore/discoverPaths.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/extractIndexes.d.ts +7 -6
- package/dist/bridge/surface/methods/firestore/extractIndexes.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/extractIndexes.js +1 -0
- package/dist/bridge/surface/methods/firestore/extractIndexes.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/findCollectionGroup.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/findCollectionGroup.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/findCollectionGroup.js +1 -0
- package/dist/bridge/surface/methods/firestore/findCollectionGroup.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/getAggregateFromServer.d.ts +6 -5
- package/dist/bridge/surface/methods/firestore/getAggregateFromServer.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/getAggregateFromServer.js +1 -0
- package/dist/bridge/surface/methods/firestore/getAggregateFromServer.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/getCountFromServer.d.ts +6 -5
- package/dist/bridge/surface/methods/firestore/getCountFromServer.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/getCountFromServer.js +1 -0
- package/dist/bridge/surface/methods/firestore/getCountFromServer.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/getDoc.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/getDoc.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/getDoc.js +2 -1
- package/dist/bridge/surface/methods/firestore/getDoc.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/getDocs.d.ts +6 -5
- package/dist/bridge/surface/methods/firestore/getDocs.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/getDocs.js +2 -1
- package/dist/bridge/surface/methods/firestore/getDocs.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/setDoc.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/setDoc.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/setDoc.js +2 -1
- package/dist/bridge/surface/methods/firestore/setDoc.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/updateDoc.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/updateDoc.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/updateDoc.js +2 -1
- package/dist/bridge/surface/methods/firestore/updateDoc.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/writeBatch.d.ts +2 -1
- package/dist/bridge/surface/methods/firestore/writeBatch.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/writeBatch.js +2 -1
- package/dist/bridge/surface/methods/firestore/writeBatch.js.map +1 -1
- package/dist/bridge/surface/methods/firestore/writeIndexes.d.ts +1 -0
- package/dist/bridge/surface/methods/firestore/writeIndexes.d.ts.map +1 -1
- package/dist/bridge/surface/methods/firestore/writeIndexes.js +1 -0
- package/dist/bridge/surface/methods/firestore/writeIndexes.js.map +1 -1
- package/dist/bridge/surface/methods/functions/executions.d.ts +3 -2
- package/dist/bridge/surface/methods/functions/executions.d.ts.map +1 -1
- package/dist/bridge/surface/methods/functions/executions.js +2 -1
- package/dist/bridge/surface/methods/functions/executions.js.map +1 -1
- package/dist/bridge/surface/methods/functions/fire.d.ts +1 -0
- package/dist/bridge/surface/methods/functions/fire.d.ts.map +1 -1
- package/dist/bridge/surface/methods/functions/fire.js +6 -5
- package/dist/bridge/surface/methods/functions/fire.js.map +1 -1
- package/dist/bridge/surface/methods/functions/listTriggers.d.ts +2 -1
- package/dist/bridge/surface/methods/functions/listTriggers.d.ts.map +1 -1
- package/dist/bridge/surface/methods/functions/listTriggers.js +1 -0
- package/dist/bridge/surface/methods/functions/listTriggers.js.map +1 -1
- package/dist/bridge/surface/methods/messaging/deliveries.d.ts +2 -1
- package/dist/bridge/surface/methods/messaging/deliveries.d.ts.map +1 -1
- package/dist/bridge/surface/methods/messaging/deliveries.js +1 -0
- package/dist/bridge/surface/methods/messaging/deliveries.js.map +1 -1
- package/dist/bridge/surface/methods/messaging/send.d.ts +2 -1
- package/dist/bridge/surface/methods/messaging/send.d.ts.map +1 -1
- package/dist/bridge/surface/methods/messaging/send.js +2 -1
- package/dist/bridge/surface/methods/messaging/send.js.map +1 -1
- package/dist/bridge/surface/methods/messaging/subscribeToTopic.d.ts +2 -1
- package/dist/bridge/surface/methods/messaging/subscribeToTopic.d.ts.map +1 -1
- package/dist/bridge/surface/methods/messaging/subscribeToTopic.js +1 -0
- package/dist/bridge/surface/methods/messaging/subscribeToTopic.js.map +1 -1
- package/dist/bridge/surface/methods/messaging/tokens.d.ts +2 -1
- package/dist/bridge/surface/methods/messaging/tokens.d.ts.map +1 -1
- package/dist/bridge/surface/methods/messaging/tokens.js +1 -0
- package/dist/bridge/surface/methods/messaging/tokens.js.map +1 -1
- package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.d.ts +2 -1
- package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.d.ts.map +1 -1
- package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.js +1 -0
- package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.js.map +1 -1
- package/dist/bridge/surface/methods/registry.d.ts.map +1 -1
- package/dist/bridge/surface/methods/registry.js +2 -8
- package/dist/bridge/surface/methods/registry.js.map +1 -1
- package/dist/bridge/surface/methods/rules/explainDenial.d.ts +1 -0
- package/dist/bridge/surface/methods/rules/explainDenial.d.ts.map +1 -1
- package/dist/bridge/surface/methods/rules/explainDenial.js +1 -0
- package/dist/bridge/surface/methods/rules/explainDenial.js.map +1 -1
- package/dist/bridge/surface/methods/rules/getStdlib.d.ts +1 -0
- package/dist/bridge/surface/methods/rules/getStdlib.d.ts.map +1 -1
- package/dist/bridge/surface/methods/rules/getStdlib.js +1 -0
- package/dist/bridge/surface/methods/rules/getStdlib.js.map +1 -1
- package/dist/bridge/surface/methods/rules/lint.d.ts +1 -0
- package/dist/bridge/surface/methods/rules/lint.d.ts.map +1 -1
- package/dist/bridge/surface/methods/rules/lint.js +1 -0
- package/dist/bridge/surface/methods/rules/lint.js.map +1 -1
- package/dist/bridge/surface/methods/rules/listStdlib.d.ts +1 -0
- package/dist/bridge/surface/methods/rules/listStdlib.d.ts.map +1 -1
- package/dist/bridge/surface/methods/rules/listStdlib.js +1 -0
- package/dist/bridge/surface/methods/rules/listStdlib.js.map +1 -1
- package/dist/bridge/surface/methods/rules/set.d.ts +1 -0
- package/dist/bridge/surface/methods/rules/set.d.ts.map +1 -1
- package/dist/bridge/surface/methods/rules/set.js +1 -0
- package/dist/bridge/surface/methods/rules/set.js.map +1 -1
- package/dist/bridge/surface/methods/rules/simulate.d.ts +1 -0
- package/dist/bridge/surface/methods/rules/simulate.d.ts.map +1 -1
- package/dist/bridge/surface/methods/rules/simulate.js +1 -0
- package/dist/bridge/surface/methods/rules/simulate.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/activity.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/activity.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/activity.js +2 -1
- package/dist/bridge/surface/methods/sandbox/activity.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/advanceClock.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/advanceClock.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/advanceClock.js +1 -0
- package/dist/bridge/surface/methods/sandbox/advanceClock.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/apply.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/apply.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/apply.js +1 -0
- package/dist/bridge/surface/methods/sandbox/apply.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/checkpoint.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/checkpoint.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/checkpoint.js +1 -0
- package/dist/bridge/surface/methods/sandbox/checkpoint.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/deleteCapture.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/deleteCapture.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/deleteCapture.js +1 -1
- package/dist/bridge/surface/methods/sandbox/deleteCapture.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.js +1 -0
- package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/diff.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/diff.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/diff.js +1 -0
- package/dist/bridge/surface/methods/sandbox/diff.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/discard.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/discard.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/discard.js +1 -0
- package/dist/bridge/surface/methods/sandbox/discard.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/events.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/events.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/events.js +2 -1
- package/dist/bridge/surface/methods/sandbox/events.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/exportFixture.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/exportFixture.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/exportFixture.js +1 -0
- package/dist/bridge/surface/methods/sandbox/exportFixture.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/fork.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/fork.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/fork.js +1 -0
- package/dist/bridge/surface/methods/sandbox/fork.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/inspect.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/inspect.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/inspect.js +2 -1
- package/dist/bridge/surface/methods/sandbox/inspect.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listBranches.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/listBranches.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listBranches.js +1 -0
- package/dist/bridge/surface/methods/sandbox/listBranches.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listCaptures.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/listCaptures.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listCaptures.js +1 -1
- package/dist/bridge/surface/methods/sandbox/listCaptures.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listCheckpoints.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/listCheckpoints.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listCheckpoints.js +1 -0
- package/dist/bridge/surface/methods/sandbox/listCheckpoints.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listeners.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/listeners.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/listeners.js +1 -0
- package/dist/bridge/surface/methods/sandbox/listeners.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/openCapture.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/openCapture.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/openCapture.js +1 -1
- package/dist/bridge/surface/methods/sandbox/openCapture.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/promote.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/promote.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/promote.js +1 -0
- package/dist/bridge/surface/methods/sandbox/promote.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/renameCapture.d.ts +3 -2
- package/dist/bridge/surface/methods/sandbox/renameCapture.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/renameCapture.js +1 -1
- package/dist/bridge/surface/methods/sandbox/renameCapture.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/reset.d.ts +3 -2
- package/dist/bridge/surface/methods/sandbox/reset.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/reset.js +1 -0
- package/dist/bridge/surface/methods/sandbox/reset.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/resetClock.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/resetClock.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/resetClock.js +1 -0
- package/dist/bridge/surface/methods/sandbox/resetClock.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/restore.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/restore.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/restore.js +1 -0
- package/dist/bridge/surface/methods/sandbox/restore.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/saveCapture.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/saveCapture.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/saveCapture.js +1 -1
- package/dist/bridge/surface/methods/sandbox/saveCapture.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/seed.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/seed.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/seed.js +3 -2
- package/dist/bridge/surface/methods/sandbox/seed.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/seedFromFixture.d.ts +1 -0
- package/dist/bridge/surface/methods/sandbox/seedFromFixture.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/seedFromFixture.js +1 -0
- package/dist/bridge/surface/methods/sandbox/seedFromFixture.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox/setClock.d.ts +2 -1
- package/dist/bridge/surface/methods/sandbox/setClock.d.ts.map +1 -1
- package/dist/bridge/surface/methods/sandbox/setClock.js +1 -0
- package/dist/bridge/surface/methods/sandbox/setClock.js.map +1 -1
- package/dist/bridge/surface/methods/sandbox-registry.d.ts +6 -0
- package/dist/bridge/surface/methods/sandbox-registry.d.ts.map +1 -0
- package/dist/bridge/surface/methods/sandbox-registry.js +21 -0
- package/dist/bridge/surface/methods/sandbox-registry.js.map +1 -0
- package/dist/bridge/surface/methods/storage/deleteObject.d.ts +2 -1
- package/dist/bridge/surface/methods/storage/deleteObject.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/deleteObject.js +1 -0
- package/dist/bridge/surface/methods/storage/deleteObject.js.map +1 -1
- package/dist/bridge/surface/methods/storage/getBytes.d.ts +2 -1
- package/dist/bridge/surface/methods/storage/getBytes.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/getBytes.js +1 -0
- package/dist/bridge/surface/methods/storage/getBytes.js.map +1 -1
- package/dist/bridge/surface/methods/storage/getDownloadURL.d.ts +2 -1
- package/dist/bridge/surface/methods/storage/getDownloadURL.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/getDownloadURL.js +1 -0
- package/dist/bridge/surface/methods/storage/getDownloadURL.js.map +1 -1
- package/dist/bridge/surface/methods/storage/getMetadata.d.ts +2 -1
- package/dist/bridge/surface/methods/storage/getMetadata.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/getMetadata.js +1 -0
- package/dist/bridge/surface/methods/storage/getMetadata.js.map +1 -1
- package/dist/bridge/surface/methods/storage/listAll.d.ts +2 -1
- package/dist/bridge/surface/methods/storage/listAll.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/listAll.js +1 -0
- package/dist/bridge/surface/methods/storage/listAll.js.map +1 -1
- package/dist/bridge/surface/methods/storage/provision.d.ts +1 -0
- package/dist/bridge/surface/methods/storage/provision.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/provision.js +1 -0
- package/dist/bridge/surface/methods/storage/provision.js.map +1 -1
- package/dist/bridge/surface/methods/storage/setCrossServiceIam.d.ts +2 -1
- package/dist/bridge/surface/methods/storage/setCrossServiceIam.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/setCrossServiceIam.js +1 -0
- package/dist/bridge/surface/methods/storage/setCrossServiceIam.js.map +1 -1
- package/dist/bridge/surface/methods/storage/status.d.ts +1 -0
- package/dist/bridge/surface/methods/storage/status.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/status.js +1 -0
- package/dist/bridge/surface/methods/storage/status.js.map +1 -1
- package/dist/bridge/surface/methods/storage/updateMetadata.d.ts +6 -5
- package/dist/bridge/surface/methods/storage/updateMetadata.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/updateMetadata.js +1 -0
- package/dist/bridge/surface/methods/storage/updateMetadata.js.map +1 -1
- package/dist/bridge/surface/methods/storage/uploadBytes.d.ts +1 -0
- package/dist/bridge/surface/methods/storage/uploadBytes.d.ts.map +1 -1
- package/dist/bridge/surface/methods/storage/uploadBytes.js +1 -0
- package/dist/bridge/surface/methods/storage/uploadBytes.js.map +1 -1
- package/dist/bridge/surface/render/discriminator-schemas.d.ts +2 -2
- package/dist/bridge/surface/request-instant.d.ts +2 -2
- package/dist/bridge/surface/request-instant.d.ts.map +1 -1
- package/dist/bridge/surface/request-instant.js.map +1 -1
- package/dist/bridge/surface/rules-engines/database.d.ts.map +1 -1
- package/dist/bridge/surface/rules-engines/database.js +1 -2
- package/dist/bridge/surface/rules-engines/database.js.map +1 -1
- package/dist/bridge/surface/rules-engines/storage-request-resource.d.ts +38 -0
- package/dist/bridge/surface/rules-engines/storage-request-resource.d.ts.map +1 -0
- package/dist/bridge/surface/rules-engines/storage-request-resource.js +246 -0
- package/dist/bridge/surface/rules-engines/storage-request-resource.js.map +1 -0
- package/dist/bridge/surface/rules-engines/storage.d.ts.map +1 -1
- package/dist/bridge/surface/rules-engines/storage.js +44 -65
- package/dist/bridge/surface/rules-engines/storage.js.map +1 -1
- package/dist/bridge/surface/sandbox-context.d.ts +25 -0
- package/dist/bridge/surface/sandbox-context.d.ts.map +1 -0
- package/dist/bridge/surface/sandbox-context.js +29 -0
- package/dist/bridge/surface/sandbox-context.js.map +1 -0
- package/dist/bridge/surface/service-handles.d.ts +6 -6
- package/dist/bridge/surface/service-handles.d.ts.map +1 -1
- package/dist/bridge/surface/service-handles.js +7 -4
- package/dist/bridge/surface/service-handles.js.map +1 -1
- package/dist/bridge/surface/sign-in.d.ts +2 -2
- package/dist/bridge/surface/sign-in.d.ts.map +1 -1
- package/dist/bridge/surface/sign-in.js +1 -1
- package/dist/bridge/surface/sign-in.js.map +1 -1
- package/dist/bridge/surface/storage-rules.d.ts +2 -9
- package/dist/bridge/surface/storage-rules.d.ts.map +1 -1
- package/dist/bridge/surface/storage-rules.js +0 -10
- package/dist/bridge/surface/storage-rules.js.map +1 -1
- package/dist/bridge/surface/stored-identity.d.ts +3 -3
- package/dist/bridge/surface/stored-identity.d.ts.map +1 -1
- package/dist/bridge/surface/stored-identity.js.map +1 -1
- package/dist/bridge/surface/types.d.ts +29 -8
- package/dist/bridge/surface/types.d.ts.map +1 -1
- package/dist/cli/firebase-json.d.ts +35 -7
- package/dist/cli/firebase-json.d.ts.map +1 -1
- package/dist/cli/firebase-json.js +13 -0
- package/dist/cli/firebase-json.js.map +1 -1
- package/dist/cli/firestore-indexes.d.ts.map +1 -1
- package/dist/cli/firestore-indexes.js +2 -1
- package/dist/cli/firestore-indexes.js.map +1 -1
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +44 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/public-dir-hint.d.ts +8 -0
- package/dist/cli/public-dir-hint.d.ts.map +1 -0
- package/dist/cli/public-dir-hint.js +30 -0
- package/dist/cli/public-dir-hint.js.map +1 -0
- package/dist/cli/run.d.ts +8 -2
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +28 -5
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/sandbox-runner.d.ts.map +1 -1
- package/dist/cli/sandbox-runner.js +11 -2
- package/dist/cli/sandbox-runner.js.map +1 -1
- package/dist/cli/serve-diagnostics.d.ts.map +1 -1
- package/dist/cli/serve-diagnostics.js +11 -1
- package/dist/cli/serve-diagnostics.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +25 -24
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/snapshot.d.ts.map +1 -1
- package/dist/cli/snapshot.js +13 -5
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/cli/surface-method-runner.js +1 -1
- package/dist/cli/surface-method-runner.js.map +1 -1
- package/dist/cli/verify.d.ts.map +1 -1
- package/dist/cli/verify.js +10 -1
- package/dist/cli/verify.js.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js +19 -3
- package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
- package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use.js +1 -1
- package/dist/conformance/.generated/can-i-use.js.map +1 -1
- package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
- package/dist/conformance/.generated/conformance-docs.js +1 -1
- package/dist/conformance/.generated/conformance-docs.js.map +1 -1
- package/dist/conformance/.generated/served-availability.d.ts.map +1 -1
- package/dist/conformance/.generated/served-availability.js +1 -1
- package/dist/conformance/.generated/served-availability.js.map +1 -1
- package/dist/discover/merge.d.ts.map +1 -1
- package/dist/discover/merge.js +11 -3
- package/dist/discover/merge.js.map +1 -1
- package/dist/functions/child-protocol.d.ts +43 -0
- package/dist/functions/child-protocol.d.ts.map +1 -0
- package/dist/functions/child-protocol.js +14 -0
- package/dist/functions/child-protocol.js.map +1 -0
- package/dist/functions/child.d.ts +2 -0
- package/dist/functions/child.d.ts.map +1 -0
- package/dist/functions/child.js +92 -0
- package/dist/functions/child.js.map +1 -0
- package/dist/{functions-rtdb → functions}/development-runtime.d.ts +5 -4
- package/dist/functions/development-runtime.d.ts.map +1 -0
- package/dist/{functions-rtdb → functions}/development-runtime.js +2 -2
- package/dist/functions/development-runtime.js.map +1 -0
- package/dist/functions/endpoints.d.ts +39 -0
- package/dist/functions/endpoints.d.ts.map +1 -0
- package/dist/functions/endpoints.js +48 -0
- package/dist/functions/endpoints.js.map +1 -0
- package/dist/functions/events.d.ts.map +1 -0
- package/dist/functions/events.js.map +1 -0
- package/dist/functions/execution-log.d.ts.map +1 -0
- package/dist/functions/execution-log.js.map +1 -0
- package/dist/functions/module-loader.d.ts.map +1 -0
- package/dist/functions/module-loader.js.map +1 -0
- package/dist/functions/project.d.ts +7 -0
- package/dist/functions/project.d.ts.map +1 -0
- package/dist/{functions-rtdb → functions}/project.js +1 -1
- package/dist/functions/project.js.map +1 -0
- package/dist/functions/rtdb/child-runtime.d.ts +23 -0
- package/dist/functions/rtdb/child-runtime.d.ts.map +1 -0
- package/dist/functions/rtdb/child-runtime.js +102 -0
- package/dist/functions/rtdb/child-runtime.js.map +1 -0
- package/dist/functions/rtdb/delivery.d.ts.map +1 -0
- package/dist/functions/rtdb/delivery.js.map +1 -0
- package/dist/{functions-rtdb → functions/rtdb}/discovery.d.ts +3 -20
- package/dist/functions/rtdb/discovery.d.ts.map +1 -0
- package/dist/{functions-rtdb → functions/rtdb}/discovery.js +6 -21
- package/dist/functions/rtdb/discovery.js.map +1 -0
- package/dist/functions/rtdb/event.d.ts.map +1 -0
- package/dist/functions/rtdb/event.js.map +1 -0
- package/dist/functions/rtdb/execution.d.ts.map +1 -0
- package/dist/functions/rtdb/execution.js.map +1 -0
- package/dist/functions/rtdb/in-memory-delivery.d.ts.map +1 -0
- package/dist/functions/rtdb/in-memory-delivery.js.map +1 -0
- package/dist/functions/rtdb/projection.d.ts.map +1 -0
- package/dist/functions/rtdb/projection.js.map +1 -0
- package/dist/functions/rtdb/reference-pattern.d.ts.map +1 -0
- package/dist/functions/rtdb/reference-pattern.js.map +1 -0
- package/dist/{functions-rtdb → functions/rtdb}/remote-delivery.d.ts +1 -1
- package/dist/functions/rtdb/remote-delivery.d.ts.map +1 -0
- package/dist/functions/rtdb/remote-delivery.js.map +1 -0
- package/dist/{functions-rtdb/child.d.ts → functions/spawn.d.ts} +16 -38
- package/dist/functions/spawn.d.ts.map +1 -0
- package/dist/functions/spawn.js +166 -0
- package/dist/functions/spawn.js.map +1 -0
- package/dist/functions/unsupported.d.ts +23 -0
- package/dist/functions/unsupported.d.ts.map +1 -0
- package/dist/functions/unsupported.js +25 -0
- package/dist/functions/unsupported.js.map +1 -0
- package/dist/google-endpoints.d.ts +9 -2
- package/dist/google-endpoints.d.ts.map +1 -1
- package/dist/google-endpoints.js +72 -3
- package/dist/google-endpoints.js.map +1 -1
- package/dist/next/bridge-import-loader.d.ts +9 -0
- package/dist/next/bridge-import-loader.d.ts.map +1 -0
- package/dist/next/bridge-import-loader.js +45 -0
- package/dist/next/bridge-import-loader.js.map +1 -0
- package/dist/next/bridge-imports.d.ts +26 -0
- package/dist/next/bridge-imports.d.ts.map +1 -0
- package/dist/next/bridge-imports.js +90 -0
- package/dist/next/bridge-imports.js.map +1 -0
- package/dist/next/client-aliases.d.ts +13 -5
- package/dist/next/client-aliases.d.ts.map +1 -1
- package/dist/next/client-aliases.js +14 -27
- package/dist/next/client-aliases.js.map +1 -1
- package/dist/next/guard.d.ts +3 -2
- package/dist/next/guard.d.ts.map +1 -1
- package/dist/next/guard.js +28 -10
- package/dist/next/guard.js.map +1 -1
- package/dist/next/turbopack-config.d.ts +9 -0
- package/dist/next/turbopack-config.d.ts.map +1 -1
- package/dist/next/turbopack-config.js +21 -0
- package/dist/next/turbopack-config.js.map +1 -1
- package/dist/next/webpack-config.d.ts +9 -0
- package/dist/next/webpack-config.d.ts.map +1 -1
- package/dist/next/webpack-config.js +18 -0
- package/dist/next/webpack-config.js.map +1 -1
- package/dist/next/with-pyric.d.ts +1 -0
- package/dist/next/with-pyric.d.ts.map +1 -1
- package/dist/next/with-pyric.js +25 -0
- package/dist/next/with-pyric.js.map +1 -1
- package/dist/register/activation.d.ts +16 -0
- package/dist/register/activation.d.ts.map +1 -0
- package/dist/register/activation.js +22 -0
- package/dist/register/activation.js.map +1 -0
- package/dist/register/app-bridge-admin-app-check.d.ts.map +1 -1
- package/dist/register/app-bridge-admin-app-check.js +3 -1
- package/dist/register/app-bridge-admin-app-check.js.map +1 -1
- package/dist/register/child-process-guard.d.ts +43 -0
- package/dist/register/child-process-guard.d.ts.map +1 -0
- package/dist/register/child-process-guard.js +165 -0
- package/dist/register/child-process-guard.js.map +1 -0
- package/dist/register/client/bootstrap.js +6 -1
- package/dist/register/client/bootstrap.js.map +1 -1
- package/dist/register/connect-prototypes.d.ts +9 -0
- package/dist/register/connect-prototypes.d.ts.map +1 -1
- package/dist/register/connect-prototypes.js +11 -0
- package/dist/register/connect-prototypes.js.map +1 -1
- package/dist/register/hooks.d.ts +7 -1
- package/dist/register/hooks.d.ts.map +1 -1
- package/dist/register/hooks.js +44 -2
- package/dist/register/hooks.js.map +1 -1
- package/dist/register/index.d.ts.map +1 -1
- package/dist/register/index.js +93 -23
- package/dist/register/index.js.map +1 -1
- package/dist/register/mapping.d.ts +33 -0
- package/dist/register/mapping.d.ts.map +1 -1
- package/dist/register/mapping.js +45 -3
- package/dist/register/mapping.js.map +1 -1
- package/dist/register/net-guard.d.ts +17 -0
- package/dist/register/net-guard.d.ts.map +1 -1
- package/dist/register/net-guard.js +118 -41
- package/dist/register/net-guard.js.map +1 -1
- package/dist/register/package-identity.d.ts +16 -0
- package/dist/register/package-identity.d.ts.map +1 -0
- package/dist/register/package-identity.js +97 -0
- package/dist/register/package-identity.js.map +1 -0
- package/dist/register/swap-or-stop.d.ts +27 -0
- package/dist/register/swap-or-stop.d.ts.map +1 -0
- package/dist/register/swap-or-stop.js +170 -0
- package/dist/register/swap-or-stop.js.map +1 -0
- package/dist/register/worker-guard.d.ts +20 -0
- package/dist/register/worker-guard.d.ts.map +1 -0
- package/dist/register/worker-guard.js +77 -0
- package/dist/register/worker-guard.js.map +1 -0
- package/dist/remote/resolve-host.d.ts +9 -0
- package/dist/remote/resolve-host.d.ts.map +1 -1
- package/dist/remote/resolve-host.js +13 -2
- package/dist/remote/resolve-host.js.map +1 -1
- package/dist/serve/ai-diagnostics-relay.d.ts +4 -1
- package/dist/serve/ai-diagnostics-relay.d.ts.map +1 -1
- package/dist/serve/ai-diagnostics-relay.js +3 -0
- package/dist/serve/ai-diagnostics-relay.js.map +1 -1
- package/dist/serve/ai-proxy.d.ts +23 -1
- package/dist/serve/ai-proxy.d.ts.map +1 -1
- package/dist/serve/ai-proxy.js +70 -20
- package/dist/serve/ai-proxy.js.map +1 -1
- package/dist/serve/ai-terminal-blocks.d.ts +6 -4
- package/dist/serve/ai-terminal-blocks.d.ts.map +1 -1
- package/dist/serve/ai-terminal-blocks.js +7 -4
- package/dist/serve/ai-terminal-blocks.js.map +1 -1
- package/dist/serve/ai-terminal-text.d.ts +8 -0
- package/dist/serve/ai-terminal-text.d.ts.map +1 -1
- package/dist/serve/ai-terminal-text.js +10 -0
- package/dist/serve/ai-terminal-text.js.map +1 -1
- package/dist/serve/app-ports.d.ts +48 -0
- package/dist/serve/app-ports.d.ts.map +1 -0
- package/dist/serve/app-ports.js +82 -0
- package/dist/serve/app-ports.js.map +1 -0
- package/dist/serve/bridge-mount.d.ts +13 -0
- package/dist/serve/bridge-mount.d.ts.map +1 -1
- package/dist/serve/bridge-mount.js +28 -8
- package/dist/serve/bridge-mount.js.map +1 -1
- package/dist/serve/bundler.d.ts +6 -0
- package/dist/serve/bundler.d.ts.map +1 -1
- package/dist/serve/bundler.js +78 -26
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/discovery.d.ts +17 -3
- package/dist/serve/discovery.d.ts.map +1 -1
- package/dist/serve/discovery.js +199 -63
- package/dist/serve/discovery.js.map +1 -1
- package/dist/serve/entries/ai.d.ts.map +1 -1
- package/dist/serve/entries/ai.js +28 -26
- package/dist/serve/entries/ai.js.map +1 -1
- package/dist/serve/entries/auth.d.ts.map +1 -1
- package/dist/serve/entries/auth.js +19 -1
- package/dist/serve/entries/auth.js.map +1 -1
- package/dist/serve/entries/firestore-surface.d.ts +1 -0
- package/dist/serve/entries/firestore-surface.d.ts.map +1 -1
- package/dist/serve/entries/firestore-surface.js +1 -0
- package/dist/serve/entries/firestore-surface.js.map +1 -1
- package/dist/serve/entries/init-payload.d.ts +9 -2
- package/dist/serve/entries/init-payload.d.ts.map +1 -1
- package/dist/serve/entries/init-payload.js +25 -5
- package/dist/serve/entries/init-payload.js.map +1 -1
- package/dist/serve/entries/moved-host.d.ts +18 -0
- package/dist/serve/entries/moved-host.d.ts.map +1 -0
- package/dist/serve/entries/moved-host.js +14 -0
- package/dist/serve/entries/moved-host.js.map +1 -0
- package/dist/serve/entries/runtime-origin.d.ts +6 -0
- package/dist/serve/entries/runtime-origin.d.ts.map +1 -1
- package/dist/serve/entries/runtime-origin.js.map +1 -1
- package/dist/serve/entries/unsupported/firestore.d.ts +0 -1
- package/dist/serve/entries/unsupported/firestore.d.ts.map +1 -1
- package/dist/serve/entries/unsupported/firestore.js +0 -1
- package/dist/serve/entries/unsupported/firestore.js.map +1 -1
- package/dist/serve/entries/worker-runtime.d.ts.map +1 -1
- package/dist/serve/entries/worker-runtime.js +19 -7
- package/dist/serve/entries/worker-runtime.js.map +1 -1
- package/dist/serve/firebase-module-swap.d.ts +19 -2
- package/dist/serve/firebase-module-swap.d.ts.map +1 -1
- package/dist/serve/firebase-module-swap.js +92 -16
- package/dist/serve/firebase-module-swap.js.map +1 -1
- package/dist/serve/gemini-proxy.d.ts +40 -0
- package/dist/serve/gemini-proxy.d.ts.map +1 -0
- package/dist/serve/gemini-proxy.js +105 -0
- package/dist/serve/gemini-proxy.js.map +1 -0
- package/dist/serve/hosted/runtime.d.ts.map +1 -1
- package/dist/serve/hosted/runtime.js +10 -3
- package/dist/serve/hosted/runtime.js.map +1 -1
- package/dist/serve/namespace.d.ts +16 -0
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +87 -27
- package/dist/serve/namespace.js.map +1 -1
- package/dist/serve/repro/compare.d.ts +2 -1
- package/dist/serve/repro/compare.d.ts.map +1 -1
- package/dist/serve/repro/compare.js +9 -1
- package/dist/serve/repro/compare.js.map +1 -1
- package/dist/serve/rules-fixture-check.d.ts.map +1 -1
- package/dist/serve/rules-fixture-check.js +22 -10
- package/dist/serve/rules-fixture-check.js.map +1 -1
- package/dist/serve/rules.d.ts +35 -9
- package/dist/serve/rules.d.ts.map +1 -1
- package/dist/serve/rules.js +72 -21
- package/dist/serve/rules.js.map +1 -1
- package/dist/serve/sandbox-session.d.ts +6 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +11 -3
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/server.d.ts +10 -2
- package/dist/serve/server.d.ts.map +1 -1
- package/dist/serve/server.js +24 -4
- package/dist/serve/server.js.map +1 -1
- package/dist/serve/site-ui/_astro/{RulesCodeEditor.Cp_-FK3b.js → RulesCodeEditor.D-eQLCvu.js} +1 -1
- package/dist/serve/site-ui/_astro/app.BjQiEBOY.js +1 -0
- package/dist/serve/site-ui/_astro/app.C84Qr10v.js +151 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.CVhCNUi_.js → chess-showcase.CsH1s4g7.js} +1 -1
- package/dist/serve/site-ui/_astro/{example-runtime.zC1l-Yka.js → example-runtime.CTp8mh7I.js} +1 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.DI8MTU3L.js +1725 -0
- package/dist/serve/site-ui/_astro/{seed.B4vza_Bv.js → seed.BvtbLu-q.js} +1 -1
- package/dist/serve/site-ui/_astro/writes.D8gcuovU.js +1 -0
- package/dist/serve/site-ui/auth/index.html +1 -1
- package/dist/serve/site-ui/docs/ai-compat/index.html +66 -8
- package/dist/serve/site-ui/docs/ai-compat.md +73 -7
- package/dist/serve/site-ui/docs/app-check-compat/index.html +102 -26
- package/dist/serve/site-ui/docs/app-check-compat.md +107 -25
- package/dist/serve/site-ui/docs/auth-compat/index.html +33 -21
- package/dist/serve/site-ui/docs/auth-compat.md +35 -20
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +29 -6
- package/dist/serve/site-ui/docs/build/ai-logic.md +30 -3
- package/dist/serve/site-ui/docs/conformance-scores/index.html +2 -2
- package/dist/serve/site-ui/docs/conformance-scores.md +2 -2
- package/dist/serve/site-ui/docs/database-compat/index.html +113 -49
- package/dist/serve/site-ui/docs/database-compat.md +118 -48
- package/dist/serve/site-ui/docs/firestore-compat/index.html +144 -37
- package/dist/serve/site-ui/docs/firestore-compat.md +149 -36
- package/dist/serve/site-ui/docs/firestore-swift-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/firestore-swift-compat.md +1 -1
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +12 -12
- package/dist/serve/site-ui/docs/functions-rtdb-compat.md +12 -12
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works.md +1 -1
- package/dist/serve/site-ui/docs/get-started/node-host/index.html +1 -0
- package/dist/serve/site-ui/docs/get-started/node-host.md +2 -0
- package/dist/serve/site-ui/docs/index.json +55 -5
- package/dist/serve/site-ui/docs/messaging-compat/index.html +2 -2
- package/dist/serve/site-ui/docs/messaging-compat.md +2 -2
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +3 -1
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api.md +2 -0
- package/dist/serve/site-ui/docs/pyric-app-check-reference-api/index.html +11 -3
- package/dist/serve/site-ui/docs/pyric-app-check-reference-api.md +13 -3
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +1 -0
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +1 -0
- package/dist/serve/site-ui/docs/pyric-cli-register-client-firestore-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-register-client-firestore-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +17 -9
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +13 -11
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +8 -4
- package/dist/serve/site-ui/docs/pyric-database-reference-api.md +9 -4
- package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +15 -4
- package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +21 -4
- package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +7 -1
- package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +1 -0
- package/dist/serve/site-ui/docs/reference/cli/index.html +4 -3
- package/dist/serve/site-ui/docs/reference/cli.md +5 -3
- package/dist/serve/site-ui/docs/rules-compat/index.html +150 -49
- package/dist/serve/site-ui/docs/rules-compat.md +149 -51
- package/dist/serve/site-ui/docs/storage-compat/index.html +20 -20
- package/dist/serve/site-ui/docs/storage-compat.md +20 -20
- package/dist/serve/site-ui/docs/tutorial/index.html +12 -1
- package/dist/serve/site-ui/docs/tutorial.md +13 -1
- package/dist/serve/site-ui/examples/chess/index.html +1 -1
- package/dist/serve/site-ui/firestore/index.html +1 -1
- package/dist/serve/site-ui/rtdb/index.html +1 -1
- package/dist/serve/site-ui/settings/index.html +1 -1
- package/dist/serve/site-ui/storage/index.html +1 -1
- package/dist/serve/site-ui/studio/index.html +1 -1
- package/dist/serve/site-ui/traffic/index.html +1 -1
- package/dist/serve/vite-ai-config.d.ts +8 -0
- package/dist/serve/vite-ai-config.d.ts.map +1 -1
- package/dist/serve/vite-ai-config.js +16 -1
- package/dist/serve/vite-ai-config.js.map +1 -1
- package/dist/serve/vite-functions-development.d.ts +3 -3
- package/dist/serve/vite-functions-development.d.ts.map +1 -1
- package/dist/serve/vite-functions-development.js +1 -1
- package/dist/serve/vite-functions-development.js.map +1 -1
- package/dist/serve/vite-generation-bridge.d.ts +2 -2
- package/dist/serve/vite-generation-bridge.d.ts.map +1 -1
- package/dist/serve/vite-generation-functions.d.ts +3 -3
- package/dist/serve/vite-generation-functions.d.ts.map +1 -1
- package/dist/serve/vite-generation-functions.js +1 -1
- package/dist/serve/vite-generation-functions.js.map +1 -1
- package/dist/serve/vite-generation-middleware.d.ts +1 -1
- package/dist/serve/vite-generation-middleware.d.ts.map +1 -1
- package/dist/serve/vite-generation-middleware.js +36 -1
- package/dist/serve/vite-generation-middleware.js.map +1 -1
- package/dist/serve/vite-module-swap.d.ts.map +1 -1
- package/dist/serve/vite-module-swap.js +8 -0
- package/dist/serve/vite-module-swap.js.map +1 -1
- package/dist/serve/vite-page-runtime.d.ts.map +1 -1
- package/dist/serve/vite-page-runtime.js +7 -1
- package/dist/serve/vite-page-runtime.js.map +1 -1
- package/dist/serve/vite-rules-source.d.ts +1 -1
- package/dist/serve/vite-rules-source.d.ts.map +1 -1
- package/dist/serve/vite-rules-source.js +2 -4
- package/dist/serve/vite-rules-source.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts +2 -2
- package/dist/serve/vite-sandbox-generation.d.ts.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +4 -2
- package/dist/serve/vite-sandbox-generation.js.map +1 -1
- package/dist/serve/worker/ai-proxy-paths.d.ts +32 -0
- package/dist/serve/worker/ai-proxy-paths.d.ts.map +1 -0
- package/dist/serve/worker/ai-proxy-paths.js +20 -0
- package/dist/serve/worker/ai-proxy-paths.js.map +1 -0
- package/dist/serve/worker/client/ai.d.ts +3 -1
- package/dist/serve/worker/client/ai.d.ts.map +1 -1
- package/dist/serve/worker/client/ai.js +3 -0
- package/dist/serve/worker/client/ai.js.map +1 -1
- package/dist/serve/worker/client/auth.d.ts +29 -5
- package/dist/serve/worker/client/auth.d.ts.map +1 -1
- package/dist/serve/worker/client/auth.js +61 -11
- package/dist/serve/worker/client/auth.js.map +1 -1
- package/dist/serve/worker/client/clock.d.ts +0 -16
- package/dist/serve/worker/client/clock.d.ts.map +1 -1
- package/dist/serve/worker/client/clock.js +23 -10
- package/dist/serve/worker/client/clock.js.map +1 -1
- package/dist/serve/worker/client/firestore-reads.d.ts +12 -5
- package/dist/serve/worker/client/firestore-reads.d.ts.map +1 -1
- package/dist/serve/worker/client/firestore-reads.js +47 -16
- package/dist/serve/worker/client/firestore-reads.js.map +1 -1
- package/dist/serve/worker/client/firestore-refs.d.ts.map +1 -1
- package/dist/serve/worker/client/firestore-refs.js +4 -14
- package/dist/serve/worker/client/firestore-refs.js.map +1 -1
- package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -1
- package/dist/serve/worker/client/rtdb-connection-lifecycle.js +5 -0
- package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -1
- package/dist/serve/worker/client/rtdb-snapshots.d.ts +7 -0
- package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -1
- package/dist/serve/worker/client/rtdb-snapshots.js +25 -1
- package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -1
- package/dist/serve/worker/client/rtdb-value-validation.d.ts +21 -0
- package/dist/serve/worker/client/rtdb-value-validation.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb-value-validation.js +183 -0
- package/dist/serve/worker/client/rtdb-value-validation.js.map +1 -0
- package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -1
- package/dist/serve/worker/client/rtdb-writes.js +7 -0
- package/dist/serve/worker/client/rtdb-writes.js.map +1 -1
- package/dist/serve/worker/client/snapshots.d.ts +2 -0
- package/dist/serve/worker/client/snapshots.d.ts.map +1 -1
- package/dist/serve/worker/client/snapshots.js +13 -7
- package/dist/serve/worker/client/snapshots.js.map +1 -1
- package/dist/serve/worker/client/websocket-connection.d.ts +6 -0
- package/dist/serve/worker/client/websocket-connection.d.ts.map +1 -1
- package/dist/serve/worker/client/websocket-connection.js +32 -3
- package/dist/serve/worker/client/websocket-connection.js.map +1 -1
- package/dist/serve/worker/entry.js +2 -0
- package/dist/serve/worker/entry.js.map +1 -1
- package/dist/serve/worker/host/auth-credential-sign-in.d.ts +33 -0
- package/dist/serve/worker/host/auth-credential-sign-in.d.ts.map +1 -0
- package/dist/serve/worker/host/auth-credential-sign-in.js +70 -0
- package/dist/serve/worker/host/auth-credential-sign-in.js.map +1 -0
- package/dist/serve/worker/host/auth-reauthentication.js +3 -3
- package/dist/serve/worker/host/auth-reauthentication.js.map +1 -1
- package/dist/serve/worker/host/rules.d.ts +15 -1
- package/dist/serve/worker/host/rules.d.ts.map +1 -1
- package/dist/serve/worker/host/rules.js +43 -34
- package/dist/serve/worker/host/rules.js.map +1 -1
- package/dist/serve/worker/host/staged-sign-in-results.d.ts +24 -0
- package/dist/serve/worker/host/staged-sign-in-results.d.ts.map +1 -0
- package/dist/serve/worker/host/staged-sign-in-results.js +40 -0
- package/dist/serve/worker/host/staged-sign-in-results.js.map +1 -0
- package/dist/serve/worker/host/storage.d.ts.map +1 -1
- package/dist/serve/worker/host/storage.js +20 -12
- package/dist/serve/worker/host/storage.js.map +1 -1
- package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
- package/dist/serve/worker/host/subscriptions.js +6 -2
- package/dist/serve/worker/host/subscriptions.js.map +1 -1
- package/dist/serve/worker/host-ai.d.ts +4 -5
- package/dist/serve/worker/host-ai.d.ts.map +1 -1
- package/dist/serve/worker/host-ai.js +19 -23
- package/dist/serve/worker/host-ai.js.map +1 -1
- package/dist/serve/worker/host-auth.d.ts +3 -0
- package/dist/serve/worker/host-auth.d.ts.map +1 -1
- package/dist/serve/worker/host-auth.js +32 -13
- package/dist/serve/worker/host-auth.js.map +1 -1
- package/dist/serve/worker/host-context.d.ts +13 -4
- package/dist/serve/worker/host-context.d.ts.map +1 -1
- package/dist/serve/worker/host-context.js.map +1 -1
- package/dist/serve/worker/inbound-validation/operation-arguments.d.ts.map +1 -1
- package/dist/serve/worker/inbound-validation/operation-arguments.js +38 -14
- package/dist/serve/worker/inbound-validation/operation-arguments.js.map +1 -1
- package/dist/serve/worker/operation-persistence.d.ts +1 -0
- package/dist/serve/worker/operation-persistence.d.ts.map +1 -1
- package/dist/serve/worker/operation-persistence.js +1 -0
- package/dist/serve/worker/operation-persistence.js.map +1 -1
- package/dist/serve/worker/protocol.d.ts +22 -1
- package/dist/serve/worker/protocol.d.ts.map +1 -1
- package/dist/serve/worker/protocol.js.map +1 -1
- package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -1
- package/dist/serve/worker/rtdb-value-equality.js +3 -1
- package/dist/serve/worker/rtdb-value-equality.js.map +1 -1
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +3 -9
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/serve/worker-build-lock.d.ts +23 -0
- package/dist/serve/worker-build-lock.d.ts.map +1 -0
- package/dist/serve/worker-build-lock.js +179 -0
- package/dist/serve/worker-build-lock.js.map +1 -0
- package/dist/serve/worker-bundle-cache.d.ts +17 -0
- package/dist/serve/worker-bundle-cache.d.ts.map +1 -0
- package/dist/serve/worker-bundle-cache.js +89 -0
- package/dist/serve/worker-bundle-cache.js.map +1 -0
- package/dist/verify/cases.js +7 -3
- package/dist/verify/cases.js.map +1 -1
- package/dist/verify/index.d.ts.map +1 -1
- package/dist/verify/index.js +11 -5
- package/dist/verify/index.js.map +1 -1
- package/package.json +10 -4
- package/src/assurance/.generated/conformance-verdicts.ts +111 -40
- package/src/assurance/capabilities.ts +11 -15
- package/src/bounded-request.ts +66 -7
- package/src/bridge/client/bridge-url.ts +5 -1
- package/src/bridge/client/bridge.ts +19 -3
- package/src/bridge/frame-output.ts +45 -0
- package/src/bridge/protocol.ts +13 -0
- package/src/bridge/server/in-process.ts +57 -17
- package/src/bridge/server/peer.ts +60 -1
- package/src/bridge/server/standalone.ts +29 -107
- package/src/bridge/surface/arguments/sandbox.ts +2 -69
- package/src/bridge/surface/arguments/seed.ts +78 -0
- package/src/bridge/surface/context.ts +26 -37
- package/src/bridge/surface/database-instance-catalog.ts +4 -32
- package/src/bridge/surface/database-instance-project.ts +40 -0
- package/src/bridge/surface/database-instance.ts +4 -4
- package/src/bridge/surface/functions-runtime.ts +5 -5
- package/src/bridge/surface/held-identity.ts +4 -4
- package/src/bridge/surface/manifest.sandbox.generated.ts +137 -0
- package/src/bridge/surface/method-types.ts +61 -7
- package/src/bridge/surface/methods/ai_logic/clearScripts.ts +2 -1
- package/src/bridge/surface/methods/ai_logic/script.ts +2 -1
- package/src/bridge/surface/methods/ai_logic/scripts.ts +2 -1
- package/src/bridge/surface/methods/ai_logic/status.ts +1 -0
- package/src/bridge/surface/methods/assurance/attach.ts +1 -0
- package/src/bridge/surface/methods/assurance/canIUse.ts +1 -0
- package/src/bridge/surface/methods/assurance/define.ts +1 -0
- package/src/bridge/surface/methods/assurance/export.ts +1 -0
- package/src/bridge/surface/methods/assurance/inspect.ts +1 -0
- package/src/bridge/surface/methods/assurance/map.ts +1 -0
- package/src/bridge/surface/methods/assurance/minimize.ts +1 -0
- package/src/bridge/surface/methods/assurance/propose.ts +1 -0
- package/src/bridge/surface/methods/assurance/replaySession.ts +1 -0
- package/src/bridge/surface/methods/assurance/run.ts +1 -0
- package/src/bridge/surface/methods/assurance/start.ts +1 -0
- package/src/bridge/surface/methods/assurance/testRulesHosted.ts +1 -0
- package/src/bridge/surface/methods/assurance/verify.ts +1 -0
- package/src/bridge/surface/methods/assurance/verifyCases.ts +1 -0
- package/src/bridge/surface/methods/auth/actAsAdmin.ts +1 -0
- package/src/bridge/surface/methods/auth/actAsAnonymous.ts +1 -0
- package/src/bridge/surface/methods/auth/createCustomToken.ts +1 -0
- package/src/bridge/surface/methods/auth/createUser.ts +2 -1
- package/src/bridge/surface/methods/auth/deleteUser.ts +2 -1
- package/src/bridge/surface/methods/auth/getUser.ts +2 -1
- package/src/bridge/surface/methods/auth/getUserByEmail.ts +2 -1
- package/src/bridge/surface/methods/auth/impersonate.ts +1 -0
- package/src/bridge/surface/methods/auth/importUsers.ts +3 -2
- package/src/bridge/surface/methods/auth/listUsers.ts +2 -1
- package/src/bridge/surface/methods/auth/sessions.ts +1 -0
- package/src/bridge/surface/methods/auth/setCustomUserClaims.ts +2 -1
- package/src/bridge/surface/methods/auth/signInAnonymously.ts +1 -0
- package/src/bridge/surface/methods/auth/signInWithCredential.ts +1 -0
- package/src/bridge/surface/methods/auth/signInWithCustomToken.ts +1 -0
- package/src/bridge/surface/methods/auth/signInWithEmailAndPassword.ts +1 -0
- package/src/bridge/surface/methods/auth/signOut.ts +1 -0
- package/src/bridge/surface/methods/auth/takeAuthMail.ts +1 -0
- package/src/bridge/surface/methods/auth/updateUser.ts +2 -1
- package/src/bridge/surface/methods/auth/useAppSession.ts +1 -0
- package/src/bridge/surface/methods/auth/whoami.ts +1 -0
- package/src/bridge/surface/methods/database/crawl.ts +1 -0
- package/src/bridge/surface/methods/database/get.ts +1 -0
- package/src/bridge/surface/methods/database/push.ts +1 -0
- package/src/bridge/surface/methods/database/query.ts +1 -0
- package/src/bridge/surface/methods/database/remove.ts +1 -0
- package/src/bridge/surface/methods/database/set.ts +1 -0
- package/src/bridge/surface/methods/database/update.ts +1 -0
- package/src/bridge/surface/methods/firestore/addDoc.ts +2 -1
- package/src/bridge/surface/methods/firestore/deleteDoc.ts +2 -1
- package/src/bridge/surface/methods/firestore/discoverPaths.ts +1 -0
- package/src/bridge/surface/methods/firestore/extractIndexes.ts +1 -0
- package/src/bridge/surface/methods/firestore/findCollectionGroup.ts +1 -0
- package/src/bridge/surface/methods/firestore/getAggregateFromServer.ts +1 -0
- package/src/bridge/surface/methods/firestore/getCountFromServer.ts +1 -0
- package/src/bridge/surface/methods/firestore/getDoc.ts +2 -1
- package/src/bridge/surface/methods/firestore/getDocs.ts +2 -1
- package/src/bridge/surface/methods/firestore/setDoc.ts +2 -1
- package/src/bridge/surface/methods/firestore/updateDoc.ts +2 -1
- package/src/bridge/surface/methods/firestore/writeBatch.ts +2 -1
- package/src/bridge/surface/methods/firestore/writeIndexes.ts +1 -0
- package/src/bridge/surface/methods/functions/executions.ts +2 -1
- package/src/bridge/surface/methods/functions/fire.ts +7 -6
- package/src/bridge/surface/methods/functions/listTriggers.ts +1 -0
- package/src/bridge/surface/methods/messaging/deliveries.ts +1 -0
- package/src/bridge/surface/methods/messaging/send.ts +2 -1
- package/src/bridge/surface/methods/messaging/subscribeToTopic.ts +1 -0
- package/src/bridge/surface/methods/messaging/tokens.ts +1 -0
- package/src/bridge/surface/methods/messaging/unsubscribeFromTopic.ts +1 -0
- package/src/bridge/surface/methods/registry.ts +2 -12
- package/src/bridge/surface/methods/rules/explainDenial.ts +1 -0
- package/src/bridge/surface/methods/rules/getStdlib.ts +1 -0
- package/src/bridge/surface/methods/rules/lint.ts +1 -0
- package/src/bridge/surface/methods/rules/listStdlib.ts +1 -0
- package/src/bridge/surface/methods/rules/set.ts +1 -0
- package/src/bridge/surface/methods/rules/simulate.ts +1 -0
- package/src/bridge/surface/methods/sandbox/activity.ts +2 -1
- package/src/bridge/surface/methods/sandbox/advanceClock.ts +1 -0
- package/src/bridge/surface/methods/sandbox/apply.ts +1 -0
- package/src/bridge/surface/methods/sandbox/checkpoint.ts +1 -0
- package/src/bridge/surface/methods/sandbox/deleteCapture.ts +1 -1
- package/src/bridge/surface/methods/sandbox/deleteCheckpoint.ts +1 -0
- package/src/bridge/surface/methods/sandbox/diff.ts +1 -0
- package/src/bridge/surface/methods/sandbox/discard.ts +1 -0
- package/src/bridge/surface/methods/sandbox/events.ts +2 -1
- package/src/bridge/surface/methods/sandbox/exportFixture.ts +1 -0
- package/src/bridge/surface/methods/sandbox/fork.ts +1 -0
- package/src/bridge/surface/methods/sandbox/inspect.ts +2 -1
- package/src/bridge/surface/methods/sandbox/listBranches.ts +1 -0
- package/src/bridge/surface/methods/sandbox/listCaptures.ts +1 -1
- package/src/bridge/surface/methods/sandbox/listCheckpoints.ts +1 -0
- package/src/bridge/surface/methods/sandbox/listeners.ts +1 -0
- package/src/bridge/surface/methods/sandbox/openCapture.ts +1 -1
- package/src/bridge/surface/methods/sandbox/promote.ts +1 -0
- package/src/bridge/surface/methods/sandbox/renameCapture.ts +1 -1
- package/src/bridge/surface/methods/sandbox/reset.ts +3 -2
- package/src/bridge/surface/methods/sandbox/resetClock.ts +1 -0
- package/src/bridge/surface/methods/sandbox/restore.ts +1 -0
- package/src/bridge/surface/methods/sandbox/saveCapture.ts +1 -1
- package/src/bridge/surface/methods/sandbox/seed.ts +3 -2
- package/src/bridge/surface/methods/sandbox/seedFromFixture.ts +1 -0
- package/src/bridge/surface/methods/sandbox/setClock.ts +1 -0
- package/src/bridge/surface/methods/sandbox-registry.ts +24 -0
- package/src/bridge/surface/methods/storage/deleteObject.ts +1 -0
- package/src/bridge/surface/methods/storage/getBytes.ts +1 -0
- package/src/bridge/surface/methods/storage/getDownloadURL.ts +1 -0
- package/src/bridge/surface/methods/storage/getMetadata.ts +1 -0
- package/src/bridge/surface/methods/storage/listAll.ts +1 -0
- package/src/bridge/surface/methods/storage/provision.ts +1 -0
- package/src/bridge/surface/methods/storage/setCrossServiceIam.ts +1 -0
- package/src/bridge/surface/methods/storage/status.ts +1 -0
- package/src/bridge/surface/methods/storage/updateMetadata.ts +1 -0
- package/src/bridge/surface/methods/storage/uploadBytes.ts +1 -0
- package/src/bridge/surface/request-instant.ts +2 -2
- package/src/bridge/surface/rules-engines/database.ts +1 -2
- package/src/bridge/surface/rules-engines/storage-request-resource.ts +275 -0
- package/src/bridge/surface/rules-engines/storage.ts +54 -81
- package/src/bridge/surface/sandbox-context.ts +49 -0
- package/src/bridge/surface/service-handles.ts +13 -9
- package/src/bridge/surface/sign-in.ts +3 -3
- package/src/bridge/surface/storage-rules.ts +2 -14
- package/src/bridge/surface/stored-identity.ts +3 -3
- package/src/bridge/surface/types.ts +30 -8
- package/src/cli/firebase-json.ts +45 -7
- package/src/cli/firestore-indexes.ts +2 -1
- package/src/cli/index.ts +46 -11
- package/src/cli/public-dir-hint.ts +35 -0
- package/src/cli/run.ts +35 -7
- package/src/cli/sandbox-runner.ts +10 -2
- package/src/cli/serve-diagnostics.ts +12 -1
- package/src/cli/serve.ts +27 -26
- package/src/cli/service-commands.test.ts +7 -0
- package/src/cli/snapshot.ts +15 -6
- package/src/cli/surface-method-runner.ts +1 -1
- package/src/cli/verify.ts +11 -1
- package/src/conformance/.generated/can-i-use-browser.ts +22 -3
- package/src/conformance/.generated/can-i-use.ts +1 -1
- package/src/conformance/.generated/conformance-docs.ts +1 -1
- package/src/conformance/.generated/served-availability.ts +1 -1
- package/src/discover/merge.ts +12 -3
- package/src/functions/child-protocol.ts +59 -0
- package/src/functions/child.ts +107 -0
- package/src/{functions-rtdb → functions}/development-runtime.ts +13 -14
- package/src/functions/endpoints.ts +80 -0
- package/src/{functions-rtdb → functions}/project.ts +2 -2
- package/src/functions/rtdb/child-runtime.ts +139 -0
- package/src/{functions-rtdb → functions/rtdb}/discovery.ts +9 -43
- package/src/{functions-rtdb → functions/rtdb}/remote-delivery.ts +1 -1
- package/src/functions/spawn.ts +212 -0
- package/src/functions/unsupported.ts +42 -0
- package/src/google-endpoints.ts +74 -3
- package/src/next/bridge-import-loader.ts +56 -0
- package/src/next/bridge-imports.ts +108 -0
- package/src/next/client-aliases.ts +14 -27
- package/src/next/guard.ts +33 -11
- package/src/next/turbopack-config.ts +26 -0
- package/src/next/webpack-config.ts +26 -0
- package/src/next/with-pyric.ts +26 -0
- package/src/register/activation.ts +26 -0
- package/src/register/app-bridge-admin-app-check.ts +3 -1
- package/src/register/child-process-guard.ts +189 -0
- package/src/register/client/bootstrap.ts +7 -1
- package/src/register/connect-prototypes.ts +12 -0
- package/src/register/hooks.ts +56 -3
- package/src/register/index.ts +92 -20
- package/src/register/mapping.ts +57 -3
- package/src/register/net-guard.ts +149 -39
- package/src/register/package-identity.ts +98 -0
- package/src/register/swap-or-stop.ts +194 -0
- package/src/register/worker-guard.ts +90 -0
- package/src/remote/resolve-host.ts +14 -2
- package/src/serve/ai-diagnostics-relay.ts +6 -1
- package/src/serve/ai-proxy.ts +77 -20
- package/src/serve/ai-terminal-blocks.ts +8 -4
- package/src/serve/ai-terminal-text.ts +11 -0
- package/src/serve/app-ports.ts +119 -0
- package/src/serve/bridge-mount.ts +36 -8
- package/src/serve/bundler.ts +87 -29
- package/src/serve/discovery.ts +244 -67
- package/src/serve/entries/ai.ts +28 -27
- package/src/serve/entries/auth.ts +22 -1
- package/src/serve/entries/firestore-surface.ts +1 -0
- package/src/serve/entries/init-payload.ts +28 -5
- package/src/serve/entries/moved-host.ts +28 -0
- package/src/serve/entries/runtime-origin.ts +6 -0
- package/src/serve/entries/unsupported/firestore.ts +0 -1
- package/src/serve/entries/worker-runtime.ts +19 -6
- package/src/serve/firebase-module-swap.ts +98 -15
- package/src/serve/gemini-proxy.ts +140 -0
- package/src/serve/hosted/runtime.ts +10 -2
- package/src/serve/namespace.ts +99 -32
- package/src/serve/repro/compare.ts +9 -1
- package/src/serve/rules-fixture-check.ts +34 -9
- package/src/serve/rules.ts +104 -20
- package/src/serve/sandbox-session.ts +15 -3
- package/src/serve/server.ts +29 -2
- package/src/serve/vite-ai-config.ts +19 -1
- package/src/serve/vite-functions-development.ts +3 -3
- package/src/serve/vite-generation-bridge.ts +2 -2
- package/src/serve/vite-generation-functions.ts +5 -5
- package/src/serve/vite-generation-middleware.ts +38 -2
- package/src/serve/vite-module-swap.ts +8 -0
- package/src/serve/vite-page-runtime.ts +6 -0
- package/src/serve/vite-rules-source.ts +2 -5
- package/src/serve/vite-sandbox-generation.ts +7 -5
- package/src/serve/worker/__tests__/auth-credential-sign-in.test.ts +343 -0
- package/src/serve/worker/__tests__/auth-m2-parity.test.ts +45 -1
- package/src/serve/worker/__tests__/staged-sign-in-results.test.ts +139 -0
- package/src/serve/worker/ai-proxy-paths.ts +35 -0
- package/src/serve/worker/client/ai.ts +6 -1
- package/src/serve/worker/client/auth.ts +97 -21
- package/src/serve/worker/client/clock.ts +10 -12
- package/src/serve/worker/client/firestore-reads.ts +70 -21
- package/src/serve/worker/client/firestore-refs.ts +4 -14
- package/src/serve/worker/client/rtdb-connection-lifecycle.ts +5 -0
- package/src/serve/worker/client/rtdb-snapshots.ts +24 -2
- package/src/serve/worker/client/rtdb-value-validation.ts +198 -0
- package/src/serve/worker/client/rtdb-writes.ts +7 -0
- package/src/serve/worker/client/snapshots.ts +15 -6
- package/src/serve/worker/client/websocket-connection.ts +39 -3
- package/src/serve/worker/entry.ts +2 -0
- package/src/serve/worker/host/auth-credential-sign-in.ts +97 -0
- package/src/serve/worker/host/auth-reauthentication.ts +3 -3
- package/src/serve/worker/host/rules.ts +53 -34
- package/src/serve/worker/host/staged-sign-in-results.ts +53 -0
- package/src/serve/worker/host/storage.ts +26 -11
- package/src/serve/worker/host/subscriptions.ts +7 -4
- package/src/serve/worker/host-ai.ts +23 -23
- package/src/serve/worker/host-auth.ts +33 -15
- package/src/serve/worker/host-context.ts +13 -3
- package/src/serve/worker/inbound-validation/operation-arguments.ts +38 -14
- package/src/serve/worker/operation-persistence.ts +1 -0
- package/src/serve/worker/protocol.ts +21 -3
- package/src/serve/worker/rtdb-value-equality.ts +3 -1
- package/src/serve/worker/serve-init.ts +3 -9
- package/src/serve/worker-build-lock.ts +207 -0
- package/src/serve/worker-bundle-cache.ts +90 -0
- package/src/verify/cases.ts +6 -3
- package/src/verify/index.ts +16 -4
- package/dist/functions-rtdb/child.d.ts.map +0 -1
- package/dist/functions-rtdb/child.js +0 -386
- package/dist/functions-rtdb/child.js.map +0 -1
- package/dist/functions-rtdb/delivery.d.ts.map +0 -1
- package/dist/functions-rtdb/delivery.js.map +0 -1
- package/dist/functions-rtdb/development-runtime.d.ts.map +0 -1
- package/dist/functions-rtdb/development-runtime.js.map +0 -1
- package/dist/functions-rtdb/discovery.d.ts.map +0 -1
- package/dist/functions-rtdb/discovery.js.map +0 -1
- package/dist/functions-rtdb/event.d.ts.map +0 -1
- package/dist/functions-rtdb/event.js.map +0 -1
- package/dist/functions-rtdb/events.d.ts.map +0 -1
- package/dist/functions-rtdb/events.js.map +0 -1
- package/dist/functions-rtdb/execution-log.d.ts.map +0 -1
- package/dist/functions-rtdb/execution-log.js.map +0 -1
- package/dist/functions-rtdb/execution.d.ts.map +0 -1
- package/dist/functions-rtdb/execution.js.map +0 -1
- package/dist/functions-rtdb/in-memory-delivery.d.ts.map +0 -1
- package/dist/functions-rtdb/in-memory-delivery.js.map +0 -1
- package/dist/functions-rtdb/module-loader.d.ts.map +0 -1
- package/dist/functions-rtdb/module-loader.js.map +0 -1
- package/dist/functions-rtdb/project.d.ts +0 -7
- package/dist/functions-rtdb/project.d.ts.map +0 -1
- package/dist/functions-rtdb/project.js.map +0 -1
- package/dist/functions-rtdb/projection.d.ts.map +0 -1
- package/dist/functions-rtdb/projection.js.map +0 -1
- package/dist/functions-rtdb/reference-pattern.d.ts.map +0 -1
- package/dist/functions-rtdb/reference-pattern.js.map +0 -1
- package/dist/functions-rtdb/remote-delivery.d.ts.map +0 -1
- package/dist/functions-rtdb/remote-delivery.js.map +0 -1
- package/dist/serve/site-ui/_astro/app.C--T2qDK.js +0 -151
- package/dist/serve/site-ui/_astro/app.DqyhRyrU.js +0 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.Bv6lfpIe.js +0 -1725
- package/dist/serve/site-ui/_astro/writes.Bg0YEEA7.js +0 -1
- package/src/functions-rtdb/child.ts +0 -512
- /package/dist/{functions-rtdb → functions}/events.d.ts +0 -0
- /package/dist/{functions-rtdb → functions}/events.js +0 -0
- /package/dist/{functions-rtdb → functions}/execution-log.d.ts +0 -0
- /package/dist/{functions-rtdb → functions}/execution-log.js +0 -0
- /package/dist/{functions-rtdb → functions}/module-loader.d.ts +0 -0
- /package/dist/{functions-rtdb → functions}/module-loader.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/delivery.d.ts +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/delivery.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/event.d.ts +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/event.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/execution.d.ts +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/execution.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/in-memory-delivery.d.ts +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/in-memory-delivery.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/projection.d.ts +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/projection.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/reference-pattern.d.ts +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/reference-pattern.js +0 -0
- /package/dist/{functions-rtdb → functions/rtdb}/remote-delivery.js +0 -0
- /package/src/{functions-rtdb → functions}/events.ts +0 -0
- /package/src/{functions-rtdb → functions}/execution-log.ts +0 -0
- /package/src/{functions-rtdb → functions}/module-loader.ts +0 -0
- /package/src/{functions-rtdb → functions/rtdb}/delivery.ts +0 -0
- /package/src/{functions-rtdb → functions/rtdb}/event.ts +0 -0
- /package/src/{functions-rtdb → functions/rtdb}/execution.ts +0 -0
- /package/src/{functions-rtdb → functions/rtdb}/in-memory-delivery.ts +0 -0
- /package/src/{functions-rtdb → functions/rtdb}/projection.ts +0 -0
- /package/src/{functions-rtdb → functions/rtdb}/reference-pattern.ts +0 -0
|
@@ -0,0 +1,1725 @@
|
|
|
1
|
+
var ei={exports:{}},zn={};/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-jsx-runtime.production.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/var wa;function Pf(){if(wa)return zn;wa=1;var t=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function n(s,r,i){var o=null;if(i!==void 0&&(o=""+i),r.key!==void 0&&(o=""+r.key),"key"in r){i={};for(var a in r)a!=="key"&&(i[a]=r[a])}else i=r;return r=i.ref,{$$typeof:t,type:s,key:o,ref:r!==void 0?r:null,props:i}}return zn.Fragment=e,zn.jsx=n,zn.jsxs=n,zn}var Sa;function Ff(){return Sa||(Sa=1,ei.exports=Pf()),ei.exports}var pk=Ff();function Ue(t){const e=t||"";return function(){throw new Error("this method "+e+" is abstract! (it has no implementation in class "+this.constructor.name+")")}}function nn(t,e){if(!t)throw new Error(e||"Assertion failed")}function _i(t,e,n){let s;Object.defineProperty(t,e,{get(){return s||(s=n.call(this)),s}})}function Vu(t,e){const n=[];for(;e-- >0;)n.push(t());return n}function Gu(t,e){return new Array(e+1).join(t)}function Lr(t,e){return Vu(()=>t,e)}function xi(t){const e=[];for(let n=0;n<t.length;n++){const s=t[n];t.lastIndexOf(s)!==n&&e.indexOf(s)<0&&e.push(s)}return e}function Hu(t){const e=[];return t.forEach(n=>{e.indexOf(n)<0&&e.push(n)}),e}function an(t){const e=t[0];return e===e.toUpperCase()}function Ku(t){return!an(t)}function Zu(t,e,n){return t.length<e?Gu(" ",e-t.length)+t:t}function bn(){this.strings=[]}bn.prototype.append=function(t){this.strings.push(t)};bn.prototype.contents=function(){return this.strings.join("")};const ti=t=>String.fromCodePoint(parseInt(t,16));function Ju(t){if(t.charAt(0)==="\\")switch(t.charAt(1)){case"b":return"\b";case"f":return"\f";case"n":return`
|
|
10
|
+
`;case"r":return"\r";case"t":return" ";case"v":return"\v";case"x":return ti(t.slice(2,4));case"u":return t.charAt(2)==="{"?ti(t.slice(3,-1)):ti(t.slice(2,6));default:return t.charAt(1)}else return t}function Ao(t){if(t==null)return String(t);const e=Object.prototype.toString.call(t);try{let n;return t.constructor&&t.constructor.name?n=t.constructor.name:e.indexOf("[object ")===0?n=e.slice(8,-1):n=typeof t,n+": "+JSON.stringify(String(t))}catch{return e}}function Qu(t,e="unexpected null value"){if(t==null)throw new Error(e);return t}const jf=Object.freeze(Object.defineProperty({__proto__:null,StringBuffer:bn,abstract:Ue,assert:nn,checkNotNull:Qu,copyWithoutDuplicates:Hu,defineLazyProperty:_i,getDuplicates:xi,isLexical:Ku,isSyntactic:an,padLeft:Zu,repeat:Lr,repeatFn:Vu,repeatStr:Gu,unescapeCodePoint:Ju,unexpectedObjToString:Ao},Symbol.toStringTag,{value:"Module"})),Yu=t=>new RegExp(String.raw`\p{${t}}`,"u"),Ci=Object.fromEntries(["Cc","Cf","Cn","Co","Cs","Ll","Lm","Lo","Lt","Lu","Mc","Me","Mn","Nd","Nl","No","Pc","Pd","Pe","Pf","Pi","Po","Ps","Sc","Sk","Sm","So","Zl","Zp","Zs"].map(t=>[t,Yu(t)]));Ci.Ltmo=/\p{Lt}|\p{Lm}|\p{Lo}/u;const Aa=Object.fromEntries(["XID_Start","XID_Continue","White_Space"].map(t=>[t,Yu(t)]));class B{constructor(){if(this.constructor===B)throw new Error("PExpr cannot be instantiated -- it's abstract")}withSource(e){return e&&(this.source=e.trimmed()),this}}const De=Object.create(B.prototype),$e=Object.create(B.prototype);class Ne extends B{constructor(e){super(),this.obj=e}}class Pe extends B{constructor(e,n){super(),this.from=e,this.to=n,this.matchCodePoint=e.length>1||n.length>1}}class Fe extends B{constructor(e){super(),this.index=e}}class Ee extends B{constructor(e){super(),this.terms=e}}class Mr extends Ee{constructor(e,n,s){const r=e.rules[n].body;super([s,r]),this.superGrammar=e,this.name=n,this.body=s}}class Dr extends Ee{constructor(e,n,s,r){const i=e.rules[n].body;super([...s,i,...r]),this.superGrammar=e,this.ruleName=n,this.expansionPos=s.length}}class xe extends B{constructor(e){super(),this.factors=e}}class Be extends B{constructor(e){super(),this.expr=e}}class vn extends Be{}class Pn extends Be{}class $t extends Be{}vn.prototype.operator="*";Pn.prototype.operator="+";$t.prototype.operator="?";vn.prototype.minNumMatches=0;Pn.prototype.minNumMatches=1;$t.prototype.minNumMatches=0;vn.prototype.maxNumMatches=Number.POSITIVE_INFINITY;Pn.prototype.maxNumMatches=Number.POSITIVE_INFINITY;$t.prototype.maxNumMatches=1;class Te extends B{constructor(e){super(),this.expr=e}}class ze extends B{constructor(e){super(),this.expr=e}}class Ze extends B{constructor(e){super(),this.expr=e}}class X extends B{constructor(e,n=[]){super(),this.ruleName=e,this.args=n}isSyntactic(){return an(this.ruleName)}toMemoKey(){return this._memoKey||Object.defineProperty(this,"_memoKey",{value:this.toString()}),this._memoKey}}class Re extends B{constructor(e){if(super(),this.categoryOrProp=e,e in Ci)this.pattern=Ci[e];else if(e in Aa)this.pattern=Aa[e];else throw new Error(`Invalid Unicode category or property name: ${JSON.stringify(e)}`)}}function ge(t,e){let n;return e?(n=new Error(e.getLineAndColumnMessage()+t),n.shortMessage=t,n.interval=e):n=new Error(t),n}function Oi(){return ge("Interval sources don't match")}function qf(t){const e=new Error;return Object.defineProperty(e,"message",{enumerable:!0,get(){return t.message}}),Object.defineProperty(e,"shortMessage",{enumerable:!0,get(){return"Expected "+t.getExpectedText()}}),e.interval=t.getInterval(),e}function Uf(t,e,n){const s=e?`Grammar ${t} is not declared in namespace '${e}'`:"Undeclared grammar "+t;return ge(s,n)}function Bf(t,e){return ge("Grammar "+t.name+" is already declared in this namespace")}function zf(t){return ge(`Grammar '${t.name}' does not support incremental parsing`)}function Xu(t,e,n){return ge("Rule "+t+" is not declared in grammar "+e,n)}function Wf(t,e,n){return ge("Cannot override rule "+t+" because it is not declared in "+e,n)}function Vf(t,e,n){return ge("Cannot extend rule "+t+" because it is not declared in "+e,n)}function ka(t,e,n,s){let r="Duplicate declaration for rule '"+t+"' in grammar '"+e+"'";return e!==n&&(r+=" (originally declared in '"+n+"')"),ge(r,s)}function el(t,e,n,s){return ge("Wrong number of parameters for rule "+t+" (expected "+e+", got "+n+")",s)}function Gf(t,e,n,s){return ge("Wrong number of arguments for rule "+t+" (expected "+e+", got "+n+")",s)}function Ea(t,e,n){return ge("Duplicate parameter names in rule "+t+": "+e.join(", "),n)}function Hf(t,e){return ge("Invalid parameter to rule "+t+": "+e+" has arity "+e.getArity()+", but parameter expressions must have arity 1",e.source)}const Kf="NOTE: A _syntactic rule_ is a rule whose name begins with a capital letter. See https://ohmjs.org/d/svl for more details.";function Zf(t,e){return ge("Cannot apply syntactic rule "+t+" from here (inside a lexical context)",e.source)}function Jf(t){const{ruleName:e}=t;return ge(`applySyntactic is for syntactic rules, but '${e}' is a lexical rule. `+Kf,t.source)}function Qf(t){return ge("applySyntactic is not required here (in a syntactic context)",t.source)}function Ia(t,e){return ge("Incorrect argument type: expected "+t,e.source)}function Yf(t){return ge("'...' can appear at most once in a rule body",t.source)}function Xf(t){const e=t._node;nn(e&&e.isNonterminal()&&e.ctorName==="escapeChar_unicodeCodePoint");const n=t.children.slice(1,-1).map(r=>r.source),s=n[0].coverageWith(...n.slice(1));return ge(`U+${s.contents} is not a valid Unicode code point`,s)}function tl(t,e){const n=e.length>0?e[e.length-1].args:[];let r="Nullable expression "+t.expr.substituteParams(n)+" is not allowed inside '"+t.operator+"' (possible infinite loop)";if(e.length>0){const i=e.map(o=>new X(o.ruleName,o.args)).join(`
|
|
11
|
+
`);r+=`
|
|
12
|
+
Application stack (most recent application last):
|
|
13
|
+
`+i}return ge(r,t.expr.source)}function nl(t,e,n,s){return ge("Rule "+t+" involves an alternation which has inconsistent arity (expected "+e+", got "+n+")",s.source)}function eh(t){const e=t.map(n=>n.message);return ge(["Errors:"].concat(e).join(`
|
|
14
|
+
- `),t[0].interval)}function th(t,e,n,s){let r=s.slice(0,-1).map(c=>{const u=" "+c[0].name+" > "+c[1];return c.length===3?u+" for '"+c[2]+"'":u}).join(`
|
|
15
|
+
`);r+=`
|
|
16
|
+
`+e+" > "+t;let i="";t==="_iter"&&(i=[`
|
|
17
|
+
NOTE: as of Ohm v16, there is no default action for iteration nodes — see `," https://ohmjs.org/d/dsa for details."].join(`
|
|
18
|
+
`));const o=[`Missing semantic action for '${t}' in ${n} '${e}'.${i}`,"Action stack (most recent call last):",r].join(`
|
|
19
|
+
`),a=ge(o);return a.name="missingSemanticAction",a}function nh(t){if(t.length===1)throw t[0];if(t.length>1)throw eh(t)}function sh(t){let e=0;return t.map(s=>{const r=s.toString();return e=Math.max(e,r.length),r}).map(s=>Zu(s,e))}function _a(t,e,n){const s=t.length,r=t.slice(0,n),i=t.slice(n+e.length);return(r+e+i).substr(0,s)}function rh(...t){const e=this,{offset:n}=e,{repeatStr:s}=jf,r=new bn;r.append("Line "+e.lineNum+", col "+e.colNum+`:
|
|
20
|
+
`);const i=sh([e.prevLine==null?0:e.lineNum-1,e.lineNum,e.nextLine==null?0:e.lineNum+1]),o=(l,d,f)=>{r.append(f+i[l]+" | "+d+`
|
|
21
|
+
`)};e.prevLine!=null&&o(0,e.prevLine," "),o(1,e.line,"> ");const a=e.line.length;let c=s(" ",a+1);for(let l=0;l<t.length;++l){let d=t[l][0],f=t[l][1];nn(d>=0&&d<=f,"range start must be >= 0 and <= end");const p=n-e.colNum+1;d=Math.max(0,d-p),f=Math.min(f-p,a),c=_a(c,s("~",f-d),d)}const u=2+i[1].length+3;return r.append(s(" ",u)),c=_a(c,"^",e.colNum-1),r.append(c.replace(/ +$/,"")+`
|
|
22
|
+
`),e.nextLine!=null&&o(2,e.nextLine," "),r.contents()}let Ti=[];function sl(t){Ti.push(t)}function ih(t){Ti.forEach(e=>{e(t)}),Ti=null}function ko(t,e){let n=1,s=1,r=0,i=0,o=null,a=null,c=-1;for(;r<e;){const d=t.charAt(r++);d===`
|
|
23
|
+
`?(n++,s=1,c=i,i=r):d!=="\r"&&s++}let u=t.indexOf(`
|
|
24
|
+
`,i);if(u===-1)u=t.length;else{const d=t.indexOf(`
|
|
25
|
+
`,u+1);o=d===-1?t.slice(u):t.slice(u,d),o=o.replace(/^\r?\n/,"").replace(/\r$/,"")}c>=0&&(a=t.slice(c,i).replace(/\r?\n$/,""));const l=t.slice(i,u).replace(/\r$/,"");return{offset:e,lineNum:n,colNum:s,line:l,prevLine:a,nextLine:o,toString:rh}}function Eo(t,e,...n){return ko(t,e).toString(...n)}const xa=(()=>{let t=0;return e=>""+e+t++})();class Me{constructor(e,n,s){Object.defineProperty(this,"_sourceString",{value:e,configurable:!1,enumerable:!1,writable:!1}),this.startIdx=n,this.endIdx=s}get sourceString(){return this._sourceString}get contents(){return this._contents===void 0&&(this._contents=this.sourceString.slice(this.startIdx,this.endIdx)),this._contents}get length(){return this.endIdx-this.startIdx}coverageWith(...e){return Me.coverage(...e,this)}collapsedLeft(){return new Me(this.sourceString,this.startIdx,this.startIdx)}collapsedRight(){return new Me(this.sourceString,this.endIdx,this.endIdx)}getLineAndColumn(){return ko(this.sourceString,this.startIdx)}getLineAndColumnMessage(){const e=[this.startIdx,this.endIdx];return Eo(this.sourceString,this.startIdx,e)}minus(e){if(this.sourceString!==e.sourceString)throw Oi();return this.startIdx===e.startIdx&&this.endIdx===e.endIdx?[]:this.startIdx<e.startIdx&&e.endIdx<this.endIdx?[new Me(this.sourceString,this.startIdx,e.startIdx),new Me(this.sourceString,e.endIdx,this.endIdx)]:this.startIdx<e.endIdx&&e.endIdx<this.endIdx?[new Me(this.sourceString,e.endIdx,this.endIdx)]:this.startIdx<e.startIdx&&e.startIdx<this.endIdx?[new Me(this.sourceString,this.startIdx,e.startIdx)]:[this]}relativeTo(e){if(this.sourceString!==e.sourceString)throw Oi();return nn(this.startIdx>=e.startIdx&&this.endIdx<=e.endIdx,"other interval does not cover this one"),new Me(this.sourceString,this.startIdx-e.startIdx,this.endIdx-e.startIdx)}trimmed(){const{contents:e}=this,n=this.startIdx+e.match(/^\s*/)[0].length,s=this.endIdx-e.match(/\s*$/)[0].length;return new Me(this.sourceString,n,s)}subInterval(e,n){const s=this.startIdx+e;return new Me(this.sourceString,s,s+n)}}Me.coverage=function(t,...e){let{startIdx:n,endIdx:s}=t;for(const r of e){if(r.sourceString!==t.sourceString)throw Oi();n=Math.min(n,r.startIdx),s=Math.max(s,r.endIdx)}return new Me(t.sourceString,n,s)};const oh=65535,ah=1114111;class $r{constructor(e){this.source=e,this.pos=0,this.examinedLength=0}atEnd(){const e=this.pos>=this.source.length;return this.examinedLength=Math.max(this.examinedLength,this.pos+1),e}next(){const e=this.source[this.pos++];return this.examinedLength=Math.max(this.examinedLength,this.pos),e}nextCharCode(){const e=this.next();return e&&e.charCodeAt(0)}nextCodePoint(){const e=this.source.slice(this.pos++).codePointAt(0);return e>oh&&(this.pos+=1),this.examinedLength=Math.max(this.examinedLength,this.pos),e}matchString(e,n){let s;if(n){for(s=0;s<e.length;s++){const r=this.next(),i=e[s];if(r==null||r.toUpperCase()!==i.toUpperCase())return!1}return!0}for(s=0;s<e.length;s++)if(this.next()!==e[s])return!1;return!0}sourceSlice(e,n){return this.source.slice(e,n)}interval(e,n){return new Me(this.source,e,n||this.pos)}}class rl{constructor(e,n,s,r,i,o,a){this.matcher=e,this.input=n,this.startExpr=s,this._cst=r,this._cstOffset=i,this._rightmostFailurePosition=o,this._rightmostFailures=a,this.failed()&&(_i(this,"message",function(){const c="Expected "+this.getExpectedText();return Eo(this.input,this.getRightmostFailurePosition())+c}),_i(this,"shortMessage",function(){const c="expected "+this.getExpectedText(),u=ko(this.input,this.getRightmostFailurePosition());return"Line "+u.lineNum+", col "+u.colNum+": "+c}))}succeeded(){return!!this._cst}failed(){return!this.succeeded()}getRightmostFailurePosition(){return this._rightmostFailurePosition}getRightmostFailures(){if(!this._rightmostFailures){this.matcher.setInput(this.input);const e=this.matcher._match(this.startExpr,{tracing:!1,positionToRecordFailures:this.getRightmostFailurePosition()});this._rightmostFailures=e.getRightmostFailures()}return this._rightmostFailures}toString(){return this.succeeded()?"[match succeeded]":"[match failed at position "+this.getRightmostFailurePosition()+"]"}getExpectedText(){if(this.succeeded())throw new Error("cannot get expected text of a successful MatchResult");const e=new bn;let n=this.getRightmostFailures();n=n.filter(s=>!s.isFluffy());for(let s=0;s<n.length;s++)s>0&&(s===n.length-1?e.append(n.length>2?", or ":" or "):e.append(", ")),e.append(n[s].toString());return e.contents()}getInterval(){const e=this.getRightmostFailurePosition();return new Me(this.input,e,e)}}class ch{constructor(){this.applicationMemoKeyStack=[],this.memo={},this.maxExaminedLength=0,this.maxRightmostFailureOffset=-1,this.currentLeftRecursion=void 0}isActive(e){return this.applicationMemoKeyStack.indexOf(e.toMemoKey())>=0}enter(e){this.applicationMemoKeyStack.push(e.toMemoKey())}exit(){this.applicationMemoKeyStack.pop()}startLeftRecursion(e,n){n.isLeftRecursion=!0,n.headApplication=e,n.nextLeftRecursion=this.currentLeftRecursion,this.currentLeftRecursion=n;const{applicationMemoKeyStack:s}=this,r=s.indexOf(e.toMemoKey())+1,i=s.slice(r);n.isInvolved=function(o){return i.indexOf(o)>=0},n.updateInvolvedApplicationMemoKeys=function(){for(let o=r;o<s.length;o++){const a=s[o];this.isInvolved(a)||i.push(a)}}}endLeftRecursion(){this.currentLeftRecursion=this.currentLeftRecursion.nextLeftRecursion}shouldUseMemoizedResult(e){if(!e.isLeftRecursion)return!0;const{applicationMemoKeyStack:n}=this;for(let s=0;s<n.length;s++){const r=n[s];if(e.isInvolved(r))return!1}return!0}memoize(e,n){return this.memo[e]=n,this.maxExaminedLength=Math.max(this.maxExaminedLength,n.examinedLength),this.maxRightmostFailureOffset=Math.max(this.maxRightmostFailureOffset,n.rightmostFailureOffset),n}clearObsoleteEntries(e,n){if(e+this.maxExaminedLength<=n)return;const{memo:s}=this;this.maxExaminedLength=0,this.maxRightmostFailureOffset=-1,Object.keys(s).forEach(r=>{const i=s[r];e+i.examinedLength>n?delete s[r]:(this.maxExaminedLength=Math.max(this.maxExaminedLength,i.examinedLength),this.maxRightmostFailureOffset=Math.max(this.maxRightmostFailureOffset,i.rightmostFailureOffset))})}}const uh="✗",lh="✓",dh="⋅",fh="⇒",hh="␉",ph="␊",mh="␍",Ri={succeeded:1,isRootNode:2,isImplicitSpaces:4,isMemoized:8,isHeadOfLeftRecursion:16,terminatesLR:32};function gh(t){return Lr(" ",t).join("")}function yh(t,e,n){const s=il(t.slice(e,e+n));return s.length<n?s+Lr(" ",n-s.length).join(""):s}function il(t){return typeof t=="string"?t.replace(/ /g,dh).replace(/\t/g,hh).replace(/\n/g,ph).replace(/\r/g,mh):String(t)}class Kt{constructor(e,n,s,r,i,o,a){this.input=e,this.pos=this.pos1=n,this.pos2=s,this.source=new Me(e,n,s),this.expr=r,this.bindings=o,this.children=a||[],this.terminatingLREntry=null,this._flags=i?Ri.succeeded:0}get displayString(){return this.expr.toDisplayString()}clone(){return this.cloneWithExpr(this.expr)}cloneWithExpr(e){const n=new Kt(this.input,this.pos,this.pos2,e,this.succeeded,this.bindings,this.children);return n.isHeadOfLeftRecursion=this.isHeadOfLeftRecursion,n.isImplicitSpaces=this.isImplicitSpaces,n.isMemoized=this.isMemoized,n.isRootNode=this.isRootNode,n.terminatesLR=this.terminatesLR,n.terminatingLREntry=this.terminatingLREntry,n}recordLRTermination(e,n){this.terminatingLREntry=new Kt(this.input,this.pos,this.pos2,this.expr,!1,[n],[e]),this.terminatingLREntry.terminatesLR=!0}walk(e,n){let s=e;typeof s=="function"&&(s={enter:s});function r(i,o,a){let c=!0;s.enter&&s.enter.call(n,i,o,a)===Kt.prototype.SKIP&&(c=!1),c&&(i.children.forEach(u=>{r(u,i,a+1)}),s.exit&&s.exit.call(n,i,o,a))}this.isRootNode?this.children.forEach(i=>{r(i,null,0)}):r(this,null,0)}toString(){const e=new bn;return this.walk((n,s,r)=>{if(!n)return this.SKIP;if(n.expr.constructor.name!=="Alt"){if(e.append(yh(n.input,n.pos,10)+gh(r*2+1)),e.append((n.succeeded?lh:uh)+" "+n.displayString),n.isHeadOfLeftRecursion&&e.append(" (LR)"),n.succeeded){const o=il(n.source.contents);e.append(" "+fh+" "),e.append(typeof o=="string"?'"'+o+'"':o)}e.append(`
|
|
26
|
+
`)}}),e.contents()}}Kt.prototype.SKIP={};Object.keys(Ri).forEach(t=>{const e=Ri[t];Object.defineProperty(Kt.prototype,t,{get(){return(this._flags&e)!==0},set(n){n?this._flags|=e:this._flags&=~e}})});B.prototype.allowsSkippingPrecedingSpace=Ue("allowsSkippingPrecedingSpace");De.allowsSkippingPrecedingSpace=$e.allowsSkippingPrecedingSpace=X.prototype.allowsSkippingPrecedingSpace=Ne.prototype.allowsSkippingPrecedingSpace=Pe.prototype.allowsSkippingPrecedingSpace=Re.prototype.allowsSkippingPrecedingSpace=function(){return!0};Ee.prototype.allowsSkippingPrecedingSpace=Be.prototype.allowsSkippingPrecedingSpace=Ze.prototype.allowsSkippingPrecedingSpace=ze.prototype.allowsSkippingPrecedingSpace=Te.prototype.allowsSkippingPrecedingSpace=Fe.prototype.allowsSkippingPrecedingSpace=xe.prototype.allowsSkippingPrecedingSpace=function(){return!1};let Qn;sl(t=>{Qn=t});let Ys;B.prototype.assertAllApplicationsAreValid=function(t,e){Ys=0,this._assertAllApplicationsAreValid(t,e)};B.prototype._assertAllApplicationsAreValid=Ue("_assertAllApplicationsAreValid");De._assertAllApplicationsAreValid=$e._assertAllApplicationsAreValid=Ne.prototype._assertAllApplicationsAreValid=Pe.prototype._assertAllApplicationsAreValid=Fe.prototype._assertAllApplicationsAreValid=Re.prototype._assertAllApplicationsAreValid=function(t,e){};Ze.prototype._assertAllApplicationsAreValid=function(t,e){Ys++,this.expr._assertAllApplicationsAreValid(t,e),Ys--};Ee.prototype._assertAllApplicationsAreValid=function(t,e){for(let n=0;n<this.terms.length;n++)this.terms[n]._assertAllApplicationsAreValid(t,e)};xe.prototype._assertAllApplicationsAreValid=function(t,e){for(let n=0;n<this.factors.length;n++)this.factors[n]._assertAllApplicationsAreValid(t,e)};Be.prototype._assertAllApplicationsAreValid=Te.prototype._assertAllApplicationsAreValid=ze.prototype._assertAllApplicationsAreValid=function(t,e){this.expr._assertAllApplicationsAreValid(t,e)};X.prototype._assertAllApplicationsAreValid=function(t,e,n=!1){const s=e.rules[this.ruleName],r=an(t)&&Ys===0;if(!s)throw Xu(this.ruleName,e.name,this.source);if(!n&&an(this.ruleName)&&!r)throw Zf(this.ruleName,this);const i=this.args.length,o=s.formals.length;if(i!==o)throw Gf(this.ruleName,o,i,this.source);const a=Qn&&s===Qn.rules.applySyntactic;if(Qn&&s===Qn.rules.caseInsensitive&&!(this.args[0]instanceof Ne))throw Ia('a Terminal (e.g. "abc")',this.args[0]);if(a){const u=this.args[0];if(!(u instanceof X))throw Ia("a syntactic rule application",u);if(!an(u.ruleName))throw Jf(u);if(r)throw Qf(this)}this.args.forEach(u=>{if(u._assertAllApplicationsAreValid(t,e,a),u.getArity()!==1)throw Hf(this.ruleName,u)})};B.prototype.assertChoicesHaveUniformArity=Ue("assertChoicesHaveUniformArity");De.assertChoicesHaveUniformArity=$e.assertChoicesHaveUniformArity=Ne.prototype.assertChoicesHaveUniformArity=Pe.prototype.assertChoicesHaveUniformArity=Fe.prototype.assertChoicesHaveUniformArity=Ze.prototype.assertChoicesHaveUniformArity=Re.prototype.assertChoicesHaveUniformArity=function(t){};Ee.prototype.assertChoicesHaveUniformArity=function(t){if(this.terms.length===0)return;const e=this.terms[0].getArity();for(let n=0;n<this.terms.length;n++){const s=this.terms[n];s.assertChoicesHaveUniformArity();const r=s.getArity();if(e!==r)throw nl(t,e,r,s)}};Mr.prototype.assertChoicesHaveUniformArity=function(t){const e=this.terms[0].getArity(),n=this.terms[1].getArity();if(e!==n)throw nl(t,n,e,this.terms[0])};xe.prototype.assertChoicesHaveUniformArity=function(t){for(let e=0;e<this.factors.length;e++)this.factors[e].assertChoicesHaveUniformArity(t)};Be.prototype.assertChoicesHaveUniformArity=function(t){this.expr.assertChoicesHaveUniformArity(t)};Te.prototype.assertChoicesHaveUniformArity=function(t){};ze.prototype.assertChoicesHaveUniformArity=function(t){this.expr.assertChoicesHaveUniformArity(t)};X.prototype.assertChoicesHaveUniformArity=function(t){};B.prototype.assertIteratedExprsAreNotNullable=Ue("assertIteratedExprsAreNotNullable");De.assertIteratedExprsAreNotNullable=$e.assertIteratedExprsAreNotNullable=Ne.prototype.assertIteratedExprsAreNotNullable=Pe.prototype.assertIteratedExprsAreNotNullable=Fe.prototype.assertIteratedExprsAreNotNullable=Re.prototype.assertIteratedExprsAreNotNullable=function(t){};Ee.prototype.assertIteratedExprsAreNotNullable=function(t){for(let e=0;e<this.terms.length;e++)this.terms[e].assertIteratedExprsAreNotNullable(t)};xe.prototype.assertIteratedExprsAreNotNullable=function(t){for(let e=0;e<this.factors.length;e++)this.factors[e].assertIteratedExprsAreNotNullable(t)};Be.prototype.assertIteratedExprsAreNotNullable=function(t){if(this.expr.assertIteratedExprsAreNotNullable(t),this.expr.isNullable(t))throw tl(this,[])};$t.prototype.assertIteratedExprsAreNotNullable=Te.prototype.assertIteratedExprsAreNotNullable=ze.prototype.assertIteratedExprsAreNotNullable=Ze.prototype.assertIteratedExprsAreNotNullable=function(t){this.expr.assertIteratedExprsAreNotNullable(t)};X.prototype.assertIteratedExprsAreNotNullable=function(t){this.args.forEach(e=>{e.assertIteratedExprsAreNotNullable(t)})};class Io{constructor(e){this.matchLength=e}get ctorName(){throw new Error("subclass responsibility")}numChildren(){return this.children?this.children.length:0}childAt(e){if(this.children)return this.children[e]}indexOfChild(e){return this.children.indexOf(e)}hasChildren(){return this.numChildren()>0}hasNoChildren(){return!this.hasChildren()}onlyChild(){if(this.numChildren()!==1)throw new Error("cannot get only child of a node of type "+this.ctorName+" (it has "+this.numChildren()+" children)");return this.firstChild()}firstChild(){if(this.hasNoChildren())throw new Error("cannot get first child of a "+this.ctorName+" node, which has no children");return this.childAt(0)}lastChild(){if(this.hasNoChildren())throw new Error("cannot get last child of a "+this.ctorName+" node, which has no children");return this.childAt(this.numChildren()-1)}childBefore(e){const n=this.indexOfChild(e);if(n<0)throw new Error("Node.childBefore() called w/ an argument that is not a child");if(n===0)throw new Error("cannot get child before first child");return this.childAt(n-1)}childAfter(e){const n=this.indexOfChild(e);if(n<0)throw new Error("Node.childAfter() called w/ an argument that is not a child");if(n===this.numChildren()-1)throw new Error("cannot get child after last child");return this.childAt(n+1)}isTerminal(){return!1}isNonterminal(){return!1}isIteration(){return!1}isOptional(){return!1}}class wn extends Io{get ctorName(){return"_terminal"}isTerminal(){return!0}get primitiveValue(){throw new Error("The `primitiveValue` property was removed in Ohm v17.")}}class bh extends Io{constructor(e,n,s,r){super(r),this.ruleName=e,this.children=n,this.childOffsets=s}get ctorName(){return this.ruleName}isNonterminal(){return!0}isLexical(){return Ku(this.ctorName)}isSyntactic(){return an(this.ctorName)}}class ol extends Io{constructor(e,n,s,r){super(s),this.children=e,this.childOffsets=n,this.optional=r}get ctorName(){return"_iter"}isIteration(){return!0}isOptional(){return this.optional}}B.prototype.eval=Ue("eval");De.eval=function(t){const{inputStream:e}=t,n=e.pos,s=e.nextCodePoint();return s!==void 0?(t.pushBinding(new wn(String.fromCodePoint(s).length),n),!0):(t.processFailure(n,this),!1)};$e.eval=function(t){const{inputStream:e}=t,n=e.pos;return e.atEnd()?(t.pushBinding(new wn(0),n),!0):(t.processFailure(n,this),!1)};Ne.prototype.eval=function(t){const{inputStream:e}=t,n=e.pos;return e.matchString(this.obj)?(t.pushBinding(new wn(this.obj.length),n),!0):(t.processFailure(n,this),!1)};Pe.prototype.eval=function(t){const{inputStream:e}=t,n=e.pos,s=this.matchCodePoint?e.nextCodePoint():e.nextCharCode();return s!==void 0&&this.from.codePointAt(0)<=s&&s<=this.to.codePointAt(0)?(t.pushBinding(new wn(String.fromCodePoint(s).length),n),!0):(t.processFailure(n,this),!1)};Fe.prototype.eval=function(t){return t.eval(t.currentApplication().args[this.index])};Ze.prototype.eval=function(t){t.enterLexifiedContext();const e=t.eval(this.expr);return t.exitLexifiedContext(),e};Ee.prototype.eval=function(t){for(let e=0;e<this.terms.length;e++)if(t.eval(this.terms[e]))return!0;return!1};xe.prototype.eval=function(t){for(let e=0;e<this.factors.length;e++){const n=this.factors[e];if(!t.eval(n))return!1}return!0};Be.prototype.eval=function(t){const{inputStream:e}=t,n=e.pos,s=this.getArity(),r=[],i=[];for(;r.length<s;)r.push([]),i.push([]);let o=0,a=n,c;for(;o<this.maxNumMatches&&t.eval(this.expr);){if(e.pos===a)throw tl(this,t._applicationStack);a=e.pos,o++;const f=t._bindings.splice(t._bindings.length-s,s),p=t._bindingOffsets.splice(t._bindingOffsets.length-s,s);for(c=0;c<f.length;c++)r[c].push(f[c]),i[c].push(p[c])}if(o<this.minNumMatches)return!1;let u=t.posToOffset(n),l=0;if(o>0){const f=r[s-1],p=i[s-1],h=p[p.length-1]+f[f.length-1].matchLength;u=i[0][0],l=h-u}const d=this instanceof $t;for(c=0;c<r.length;c++)t._bindings.push(new ol(r[c],i[c],l,d)),t._bindingOffsets.push(u);return!0};Te.prototype.eval=function(t){const{inputStream:e}=t,n=e.pos;t.pushFailuresInfo();const s=t.eval(this.expr);return t.popFailuresInfo(),s?(t.processFailure(n,this),!1):(e.pos=n,!0)};ze.prototype.eval=function(t){const{inputStream:e}=t,n=e.pos;return t.eval(this.expr)?(e.pos=n,!0):!1};X.prototype.eval=function(t){const e=t.currentApplication(),n=e?e.args:[],s=this.substituteParams(n),r=t.getCurrentPosInfo();if(r.isActive(s))return s.handleCycle(t);const i=s.toMemoKey(),o=r.memo[i];if(o&&r.shouldUseMemoizedResult(o)){if(t.hasNecessaryInfo(o))return t.useMemoizedResult(t.inputStream.pos,o);delete r.memo[i]}return s.reallyEval(t)};X.prototype.handleCycle=function(t){const e=t.getCurrentPosInfo(),{currentLeftRecursion:n}=e,s=this.toMemoKey();let r=e.memo[s];return n&&n.headApplication.toMemoKey()===s?r.updateInvolvedApplicationMemoKeys():r||(r=e.memoize(s,{matchLength:0,examinedLength:0,value:!1,rightmostFailureOffset:-1}),e.startLeftRecursion(this,r)),t.useMemoizedResult(t.inputStream.pos,r)};X.prototype.reallyEval=function(t){const{inputStream:e}=t,n=e.pos,s=t.getCurrentPosInfo(),r=t.grammar.rules[this.ruleName],{body:i}=r,{description:o}=r;t.enterApplication(s,this),o&&t.pushFailuresInfo();const a=e.examinedLength;e.examinedLength=0;let c=this.evalOnce(i,t);const u=s.currentLeftRecursion,l=this.toMemoKey(),d=u&&u.headApplication.toMemoKey()===l;let f;t.doNotMemoize?t.doNotMemoize=!1:d?(c=this.growSeedResult(i,t,n,u,c),s.endLeftRecursion(),f=u,f.examinedLength=e.examinedLength-n,f.rightmostFailureOffset=t._getRightmostFailureOffset(),s.memoize(l,f)):(!u||!u.isInvolved(l))&&(f=s.memoize(l,{matchLength:e.pos-n,examinedLength:e.examinedLength-n,value:c,failuresAtRightmostPosition:t.cloneRecordedFailures(),rightmostFailureOffset:t._getRightmostFailureOffset()}));const p=!!c;if(o&&(t.popFailuresInfo(),p||t.processFailure(n,this),f&&(f.failuresAtRightmostPosition=t.cloneRecordedFailures(),f.rightmostFailureOffset=t._getRightmostFailureOffset())),t.isTracing()&&f){const h=t.getTraceEntry(n,this,p,p?[c]:[]);d&&(nn(h.terminatingLREntry!=null||!p),h.isHeadOfLeftRecursion=!0),f.traceEntry=h}return e.examinedLength=Math.max(e.examinedLength,a),t.exitApplication(s,c),p};X.prototype.evalOnce=function(t,e){const{inputStream:n}=e,s=n.pos;if(e.eval(t)){const r=t.getArity(),i=e._bindings.splice(e._bindings.length-r,r),o=e._bindingOffsets.splice(e._bindingOffsets.length-r,r),a=n.pos-s;return new bh(this.ruleName,i,o,a)}else return!1};X.prototype.growSeedResult=function(t,e,n,s,r){if(!r)return!1;const{inputStream:i}=e;for(;;){if(s.matchLength=i.pos-n,s.value=r,s.failuresAtRightmostPosition=e.cloneRecordedFailures(),e.isTracing()){const o=e.trace[e.trace.length-1];s.traceEntry=new Kt(e.input,n,i.pos,this,!0,[r],[o.clone()])}if(i.pos=n,r=this.evalOnce(t,e),i.pos-n<=s.matchLength)break;e.isTracing()&&e.trace.splice(-2,1)}return e.isTracing()&&s.traceEntry.recordLRTermination(e.trace.pop(),r),i.pos=n+s.matchLength,s.value};Re.prototype.eval=function(t){const{inputStream:e}=t,n=e.pos,s=e.nextCodePoint();if(s!==void 0&&s<=ah){const r=String.fromCodePoint(s);if(this.pattern.test(r))return t.pushBinding(new wn(r.length),n),!0}return t.processFailure(n,this),!1};B.prototype.getArity=Ue("getArity");De.getArity=$e.getArity=Ne.prototype.getArity=Pe.prototype.getArity=Fe.prototype.getArity=X.prototype.getArity=Re.prototype.getArity=function(){return 1};Ee.prototype.getArity=function(){return this.terms.length===0?0:this.terms[0].getArity()};xe.prototype.getArity=function(){let t=0;for(let e=0;e<this.factors.length;e++)t+=this.factors[e].getArity();return t};Be.prototype.getArity=function(){return this.expr.getArity()};Te.prototype.getArity=function(){return 0};ze.prototype.getArity=Ze.prototype.getArity=function(){return this.expr.getArity()};function dt(t,e){const n={};if(t.source&&e){const s=t.source.relativeTo(e);n.sourceInterval=[s.startIdx,s.endIdx]}return n}B.prototype.outputRecipe=Ue("outputRecipe");De.outputRecipe=function(t,e){return["any",dt(this,e)]};$e.outputRecipe=function(t,e){return["end",dt(this,e)]};Ne.prototype.outputRecipe=function(t,e){return["terminal",dt(this,e),this.obj]};Pe.prototype.outputRecipe=function(t,e){return["range",dt(this,e),this.from,this.to]};Fe.prototype.outputRecipe=function(t,e){return["param",dt(this,e),this.index]};Ee.prototype.outputRecipe=function(t,e){return["alt",dt(this,e)].concat(this.terms.map(n=>n.outputRecipe(t,e)))};Mr.prototype.outputRecipe=function(t,e){return this.terms[0].outputRecipe(t,e)};Dr.prototype.outputRecipe=function(t,e){const n=this.terms.slice(0,this.expansionPos),s=this.terms.slice(this.expansionPos+1);return["splice",dt(this,e),n.map(r=>r.outputRecipe(t,e)),s.map(r=>r.outputRecipe(t,e))]};xe.prototype.outputRecipe=function(t,e){return["seq",dt(this,e)].concat(this.factors.map(n=>n.outputRecipe(t,e)))};vn.prototype.outputRecipe=Pn.prototype.outputRecipe=$t.prototype.outputRecipe=Te.prototype.outputRecipe=ze.prototype.outputRecipe=Ze.prototype.outputRecipe=function(t,e){return[this.constructor.name.toLowerCase(),dt(this,e),this.expr.outputRecipe(t,e)]};X.prototype.outputRecipe=function(t,e){return["app",dt(this,e),this.ruleName,this.args.map(n=>n.outputRecipe(t,e))]};Re.prototype.outputRecipe=function(t,e){return["unicodeChar",dt(this,e),this.categoryOrProp]};B.prototype.introduceParams=Ue("introduceParams");De.introduceParams=$e.introduceParams=Ne.prototype.introduceParams=Pe.prototype.introduceParams=Fe.prototype.introduceParams=Re.prototype.introduceParams=function(t){return this};Ee.prototype.introduceParams=function(t){return this.terms.forEach((e,n,s)=>{s[n]=e.introduceParams(t)}),this};xe.prototype.introduceParams=function(t){return this.factors.forEach((e,n,s)=>{s[n]=e.introduceParams(t)}),this};Be.prototype.introduceParams=Te.prototype.introduceParams=ze.prototype.introduceParams=Ze.prototype.introduceParams=function(t){return this.expr=this.expr.introduceParams(t),this};X.prototype.introduceParams=function(t){const e=t.indexOf(this.ruleName);if(e>=0){if(this.args.length>0)throw new Error("Parameterized rules cannot be passed as arguments to another rule.");return new Fe(e).withSource(this.source)}else return this.args.forEach((n,s,r)=>{r[s]=n.introduceParams(t)}),this};B.prototype.isNullable=function(t){return this._isNullable(t,Object.create(null))};B.prototype._isNullable=Ue("_isNullable");De._isNullable=Pe.prototype._isNullable=Fe.prototype._isNullable=Pn.prototype._isNullable=Re.prototype._isNullable=function(t,e){return!1};$e._isNullable=function(t,e){return!0};Ne.prototype._isNullable=function(t,e){return typeof this.obj=="string"?this.obj==="":!1};Ee.prototype._isNullable=function(t,e){return this.terms.length===0||this.terms.some(n=>n._isNullable(t,e))};xe.prototype._isNullable=function(t,e){return this.factors.every(n=>n._isNullable(t,e))};vn.prototype._isNullable=$t.prototype._isNullable=Te.prototype._isNullable=ze.prototype._isNullable=function(t,e){return!0};Ze.prototype._isNullable=function(t,e){return this.expr._isNullable(t,e)};X.prototype._isNullable=function(t,e){const n=this.toMemoKey();if(!Object.prototype.hasOwnProperty.call(e,n)){const{body:s}=t.rules[this.ruleName],r=s.substituteParams(this.args);e[n]=!1,e[n]=r._isNullable(t,e)}return e[n]};B.prototype.substituteParams=Ue("substituteParams");De.substituteParams=$e.substituteParams=Ne.prototype.substituteParams=Pe.prototype.substituteParams=Re.prototype.substituteParams=function(t){return this};Fe.prototype.substituteParams=function(t){return Qu(t[this.index])};Ee.prototype.substituteParams=function(t){return new Ee(this.terms.map(e=>e.substituteParams(t)))};xe.prototype.substituteParams=function(t){return new xe(this.factors.map(e=>e.substituteParams(t)))};Be.prototype.substituteParams=Te.prototype.substituteParams=ze.prototype.substituteParams=Ze.prototype.substituteParams=function(t){return new this.constructor(this.expr.substituteParams(t))};X.prototype.substituteParams=function(t){if(this.args.length===0)return this;{const e=this.args.map(n=>n.substituteParams(t));return new X(this.ruleName,e)}};function Ca(t){return/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(t)}function _o(t){const e=Object.create(null);t.forEach(n=>{e[n]=(e[n]||0)+1}),Object.keys(e).forEach(n=>{if(e[n]<=1)return;let s=1;t.forEach((r,i)=>{r===n&&(t[i]=r+"_"+s++)})})}B.prototype.toArgumentNameList=Ue("toArgumentNameList");De.toArgumentNameList=function(t,e){return["any"]};$e.toArgumentNameList=function(t,e){return["end"]};Ne.prototype.toArgumentNameList=function(t,e){return typeof this.obj=="string"&&/^[_a-zA-Z0-9]+$/.test(this.obj)?["_"+this.obj]:["$"+t]};Pe.prototype.toArgumentNameList=function(t,e){let n=this.from+"_to_"+this.to;return Ca(n)||(n="_"+n),Ca(n)||(n="$"+t),[n]};Ee.prototype.toArgumentNameList=function(t,e){const n=this.terms.map(i=>i.toArgumentNameList(t,!0)),s=[],r=n[0].length;for(let i=0;i<r;i++){const o=[];for(let c=0;c<this.terms.length;c++)o.push(n[c][i]);const a=Hu(o);s.push(a.join("_or_"))}return e||_o(s),s};xe.prototype.toArgumentNameList=function(t,e){let n=[];return this.factors.forEach(s=>{const r=s.toArgumentNameList(t,!0);n=n.concat(r),t+=r.length}),e||_o(n),n};Be.prototype.toArgumentNameList=function(t,e){const n=this.expr.toArgumentNameList(t,e).map(s=>s[s.length-1]==="s"?s+"es":s+"s");return e||_o(n),n};$t.prototype.toArgumentNameList=function(t,e){return this.expr.toArgumentNameList(t,e).map(n=>"opt"+n[0].toUpperCase()+n.slice(1))};Te.prototype.toArgumentNameList=function(t,e){return[]};ze.prototype.toArgumentNameList=Ze.prototype.toArgumentNameList=function(t,e){return this.expr.toArgumentNameList(t,e)};X.prototype.toArgumentNameList=function(t,e){return[this.ruleName]};Re.prototype.toArgumentNameList=function(t,e){return["$"+t]};Fe.prototype.toArgumentNameList=function(t,e){return["param"+this.index]};B.prototype.toDisplayString=Ue("toDisplayString");Ee.prototype.toDisplayString=xe.prototype.toDisplayString=function(){return this.source?this.source.trimmed().contents:"["+this.constructor.name+"]"};De.toDisplayString=$e.toDisplayString=Be.prototype.toDisplayString=Te.prototype.toDisplayString=ze.prototype.toDisplayString=Ze.prototype.toDisplayString=Ne.prototype.toDisplayString=Pe.prototype.toDisplayString=Fe.prototype.toDisplayString=function(){return this.toString()};X.prototype.toDisplayString=function(){if(this.args.length>0){const t=this.args.map(e=>e.toDisplayString());return this.ruleName+"<"+t.join(",")+">"}else return this.ruleName};Re.prototype.toDisplayString=function(){return"Unicode ["+this.categoryOrProp+"] character"};function vh(t){return t==="description"||t==="string"||t==="code"}class Je{constructor(e,n,s){if(!vh(s))throw new Error("invalid Failure type: "+s);this.pexpr=e,this.text=n,this.type=s,this.fluffy=!1}getPExpr(){return this.pexpr}getText(){return this.text}getType(){return this.type}isDescription(){return this.type==="description"}isStringTerminal(){return this.type==="string"}isCode(){return this.type==="code"}isFluffy(){return this.fluffy}makeFluffy(){this.fluffy=!0}clearFluffy(){this.fluffy=!1}subsumes(e){return this.getText()===e.getText()&&this.type===e.type&&(!this.isFluffy()||this.isFluffy()&&e.isFluffy())}toString(){return this.type==="string"?JSON.stringify(this.getText()):this.getText()}clone(){const e=new Je(this.pexpr,this.text,this.type);return this.isFluffy()&&e.makeFluffy(),e}toKey(){return this.toString()+"#"+this.type}}B.prototype.toFailure=Ue("toFailure");De.toFailure=function(t){return new Je(this,"any object","description")};$e.toFailure=function(t){return new Je(this,"end of input","description")};Ne.prototype.toFailure=function(t){return new Je(this,this.obj,"string")};Pe.prototype.toFailure=function(t){return new Je(this,JSON.stringify(this.from)+".."+JSON.stringify(this.to),"code")};Te.prototype.toFailure=function(t){const e=this.expr===De?"nothing":"not "+this.expr.toFailure(t);return new Je(this,e,"description")};ze.prototype.toFailure=function(t){return this.expr.toFailure(t)};X.prototype.toFailure=function(t){let{description:e}=t.rules[this.ruleName];return e||(e=(/^[aeiouAEIOU]/.test(this.ruleName)?"an":"a")+" "+this.ruleName),new Je(this,e,"description")};Re.prototype.toFailure=function(t){return new Je(this,"a Unicode ["+this.categoryOrProp+"] character","description")};Ee.prototype.toFailure=function(t){const n="("+this.terms.map(s=>s.toFailure(t)).join(" or ")+")";return new Je(this,n,"description")};xe.prototype.toFailure=function(t){const n="("+this.factors.map(s=>s.toFailure(t)).join(" ")+")";return new Je(this,n,"description")};Be.prototype.toFailure=function(t){const e="("+this.expr.toFailure(t)+this.operator+")";return new Je(this,e,"description")};B.prototype.toString=Ue("toString");De.toString=function(){return"any"};$e.toString=function(){return"end"};Ne.prototype.toString=function(){return JSON.stringify(this.obj)};Pe.prototype.toString=function(){return JSON.stringify(this.from)+".."+JSON.stringify(this.to)};Fe.prototype.toString=function(){return"$"+this.index};Ze.prototype.toString=function(){return"#("+this.expr.toString()+")"};Ee.prototype.toString=function(){return this.terms.length===1?this.terms[0].toString():"("+this.terms.map(t=>t.toString()).join(" | ")+")"};xe.prototype.toString=function(){return this.factors.length===1?this.factors[0].toString():"("+this.factors.map(t=>t.toString()).join(" ")+")"};Be.prototype.toString=function(){return this.expr+this.operator};Te.prototype.toString=function(){return"~"+this.expr};ze.prototype.toString=function(){return"&"+this.expr};X.prototype.toString=function(){if(this.args.length>0){const t=this.args.map(e=>e.toString());return this.ruleName+"<"+t.join(",")+">"}else return this.ruleName};Re.prototype.toString=function(){return"\\p{"+this.categoryOrProp+"}"};class xo extends B{constructor(e){super(),this.obj=e}_getString(e){const n=e.currentApplication().args[this.obj.index];return nn(n instanceof Ne,"expected a Terminal expression"),n.obj}allowsSkippingPrecedingSpace(){return!0}eval(e){const{inputStream:n}=e,s=n.pos,r=this._getString(e);return n.matchString(r,!0)?(e.pushBinding(new wn(r.length),s),!0):(e.processFailure(s,this),!1)}getArity(){return 1}substituteParams(e){return new xo(this.obj.substituteParams(e))}toDisplayString(){return this.obj.toDisplayString()+" (case-insensitive)"}toFailure(e){return new Je(this,this.obj.toFailure(e)+" (case-insensitive)","description")}_isNullable(e,n){return this.obj._isNullable(e,n)}}let al;sl(t=>{al=t.rules.applySyntactic.body});const ni=new X("spaces");class wh{constructor(e,n,s){this.matcher=e,this.startExpr=n,this.grammar=e.grammar,this.input=e.getInput(),this.inputStream=new $r(this.input),this.memoTable=e._memoTable,this.userData=void 0,this.doNotMemoize=!1,this._bindings=[],this._bindingOffsets=[],this._applicationStack=[],this._posStack=[0],this.inLexifiedContextStack=[!1],this.rightmostFailurePosition=-1,this._rightmostFailurePositionStack=[],this._recordedFailuresStack=[],s!==void 0&&(this.positionToRecordFailures=s,this.recordedFailures=Object.create(null))}posToOffset(e){return e-this._posStack[this._posStack.length-1]}enterApplication(e,n){this._posStack.push(this.inputStream.pos),this._applicationStack.push(n),this.inLexifiedContextStack.push(!1),e.enter(n),this._rightmostFailurePositionStack.push(this.rightmostFailurePosition),this.rightmostFailurePosition=-1}exitApplication(e,n){const s=this._posStack.pop();this._applicationStack.pop(),this.inLexifiedContextStack.pop(),e.exit(),this.rightmostFailurePosition=Math.max(this.rightmostFailurePosition,this._rightmostFailurePositionStack.pop()),n&&this.pushBinding(n,s)}enterLexifiedContext(){this.inLexifiedContextStack.push(!0)}exitLexifiedContext(){this.inLexifiedContextStack.pop()}currentApplication(){return this._applicationStack[this._applicationStack.length-1]}inSyntacticContext(){const e=this.currentApplication();return e?e.isSyntactic()&&!this.inLexifiedContext():this.startExpr.factors[0].isSyntactic()}inLexifiedContext(){return this.inLexifiedContextStack[this.inLexifiedContextStack.length-1]}skipSpaces(){return this.pushFailuresInfo(),this.eval(ni),this.popBinding(),this.popFailuresInfo(),this.inputStream.pos}skipSpacesIfInSyntacticContext(){return this.inSyntacticContext()?this.skipSpaces():this.inputStream.pos}maybeSkipSpacesBefore(e){return e.allowsSkippingPrecedingSpace()&&e!==ni?this.skipSpacesIfInSyntacticContext():this.inputStream.pos}pushBinding(e,n){this._bindings.push(e),this._bindingOffsets.push(this.posToOffset(n))}popBinding(){this._bindings.pop(),this._bindingOffsets.pop()}numBindings(){return this._bindings.length}truncateBindings(e){for(;this._bindings.length>e;)this.popBinding()}getCurrentPosInfo(){return this.getPosInfo(this.inputStream.pos)}getPosInfo(e){let n=this.memoTable[e];return n||(n=this.memoTable[e]=new ch),n}processFailure(e,n){if(this.rightmostFailurePosition=Math.max(this.rightmostFailurePosition,e),this.recordedFailures&&e===this.positionToRecordFailures){const s=this.currentApplication();s&&(n=n.substituteParams(s.args)),this.recordFailure(n.toFailure(this.grammar),!1)}}recordFailure(e,n){const s=e.toKey();this.recordedFailures[s]?this.recordedFailures[s].isFluffy()&&!e.isFluffy()&&this.recordedFailures[s].clearFluffy():this.recordedFailures[s]=n?e.clone():e}recordFailures(e,n){Object.keys(e).forEach(s=>{this.recordFailure(e[s],n)})}cloneRecordedFailures(){if(!this.recordedFailures)return;const e=Object.create(null);return Object.keys(this.recordedFailures).forEach(n=>{e[n]=this.recordedFailures[n].clone()}),e}getRightmostFailurePosition(){return this.rightmostFailurePosition}_getRightmostFailureOffset(){return this.rightmostFailurePosition>=0?this.posToOffset(this.rightmostFailurePosition):-1}getMemoizedTraceEntry(e,n){const s=this.memoTable[e];if(s&&n instanceof X){const r=s.memo[n.toMemoKey()];if(r&&r.traceEntry){const i=r.traceEntry.cloneWithExpr(n);return i.isMemoized=!0,i}}return null}getTraceEntry(e,n,s,r){if(n instanceof X){const i=this.currentApplication(),o=i?i.args:[];n=n.substituteParams(o)}return this.getMemoizedTraceEntry(e,n)||new Kt(this.input,e,this.inputStream.pos,n,s,r,this.trace)}isTracing(){return!!this.trace}hasNecessaryInfo(e){return this.trace&&!e.traceEntry?!1:this.recordedFailures&&this.inputStream.pos+e.rightmostFailureOffset===this.positionToRecordFailures?!!e.failuresAtRightmostPosition:!0}useMemoizedResult(e,n){this.trace&&this.trace.push(n.traceEntry);const s=this.inputStream.pos+n.rightmostFailureOffset;return this.rightmostFailurePosition=Math.max(this.rightmostFailurePosition,s),this.recordedFailures&&this.positionToRecordFailures===s&&n.failuresAtRightmostPosition&&this.recordFailures(n.failuresAtRightmostPosition,!0),this.inputStream.examinedLength=Math.max(this.inputStream.examinedLength,n.examinedLength+e),n.value?(this.inputStream.pos+=n.matchLength,this.pushBinding(n.value,e),!0):!1}eval(e){const{inputStream:n}=this,s=this._bindings.length,r=this.userData;let i;this.recordedFailures&&(i=this.recordedFailures,this.recordedFailures=Object.create(null));const o=n.pos,a=this.maybeSkipSpacesBefore(e);let c;this.trace&&(c=this.trace,this.trace=[]);const u=e.eval(this);if(this.trace){const l=this._bindings.slice(s),d=this.getTraceEntry(a,e,u,l);d.isImplicitSpaces=e===ni,d.isRootNode=e===this.startExpr,c.push(d),this.trace=c}return u?this.recordedFailures&&n.pos===this.positionToRecordFailures&&Object.keys(this.recordedFailures).forEach(l=>{this.recordedFailures[l].makeFluffy()}):(n.pos=o,this.truncateBindings(s),this.userData=r),this.recordedFailures&&this.recordFailures(i,!1),e===al&&this.skipSpaces(),u}getMatchResult(){this.grammar._setUpMatchState(this),this.eval(this.startExpr);let e;this.recordedFailures&&(e=Object.keys(this.recordedFailures).map(s=>this.recordedFailures[s]));const n=this._bindings[0];return n&&(n.grammar=this.grammar),new rl(this.matcher,this.input,this.startExpr,n,this._bindingOffsets[0],this.rightmostFailurePosition,e)}getTrace(){this.trace=[];const e=this.getMatchResult(),n=this.trace[this.trace.length-1];return n.result=e,n}pushFailuresInfo(){this._rightmostFailurePositionStack.push(this.rightmostFailurePosition),this._recordedFailuresStack.push(this.recordedFailures)}popFailuresInfo(){this.rightmostFailurePosition=this._rightmostFailurePositionStack.pop(),this.recordedFailures=this._recordedFailuresStack.pop()}}class Sh{constructor(e){this.grammar=e,this._memoTable=[],this._input="",this._isMemoTableStale=!1}_resetMemoTable(){this._memoTable=[],this._isMemoTableStale=!1}getInput(){return this._input}setInput(e){return this._input!==e&&this.replaceInputRange(0,this._input.length,e),this}replaceInputRange(e,n,s){const r=this._input,i=this._memoTable;if(e<0||e>r.length||n<0||n>r.length||e>n)throw new Error("Invalid indices: "+e+" and "+n);this._input=r.slice(0,e)+s+r.slice(n),this._input!==r&&i.length>0&&(this._isMemoTableStale=!0);const o=i.slice(n);i.length=e;for(let a=0;a<s.length;a++)i.push(void 0);for(const a of o)i.push(a);for(let a=0;a<e;a++){const c=i[a];c&&c.clearObsoleteEntries(a,e)}return this}match(e,n={incremental:!0}){return this._match(this._getStartExpr(e),{incremental:n.incremental,tracing:!1})}trace(e,n={incremental:!0}){return this._match(this._getStartExpr(e),{incremental:n.incremental,tracing:!0})}_match(e,n={}){const s={tracing:!1,incremental:!0,positionToRecordFailures:void 0,...n};if(!s.incremental)this._resetMemoTable();else if(this._isMemoTableStale&&!this.grammar.supportsIncrementalParsing)throw zf(this.grammar);const r=new wh(this,e,s.positionToRecordFailures);return s.tracing?r.getTrace():r.getMatchResult()}_getStartExpr(e){const n=e||this.grammar.defaultStartRule;if(!n)throw new Error("Missing start rule argument -- the grammar has no default start rule.");const s=this.grammar.parseApplication(n);return new xe([s,$e])}}const Yn=[],Ni=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);class Oa{constructor(e,n,s){this._node=e,this.source=n,this._baseInterval=s,e.isNonterminal()&&nn(n===s),this._childWrappers=[]}_forgetMemoizedResultFor(e){delete this._node[this._semantics.attributeKeys[e]],this.children.forEach(n=>{n._forgetMemoizedResultFor(e)})}child(e){if(!(0<=e&&e<this._node.numChildren()))return;let n=this._childWrappers[e];if(!n){const s=this._node.childAt(e),r=this._node.childOffsets[e],i=this._baseInterval.subInterval(r,s.matchLength),o=s.isNonterminal()?i:this._baseInterval;n=this._childWrappers[e]=this._semantics.wrap(s,i,o)}return n}_children(){for(let e=0;e<this._node.numChildren();e++)this.child(e);return this._childWrappers}isIteration(){return this._node.isIteration()}isTerminal(){return this._node.isTerminal()}isNonterminal(){return this._node.isNonterminal()}isSyntactic(){return this.isNonterminal()&&this._node.isSyntactic()}isLexical(){return this.isNonterminal()&&this._node.isLexical()}isOptional(){return this._node.isOptional()}iteration(e){const n=e||[],s=n.map(o=>o._node),r=new ol(s,[],-1,!1),i=this._semantics.wrap(r,null,null);return i._childWrappers=n,i}get children(){return this._children()}get ctorName(){return this._node.ctorName}get numChildren(){return this._node.numChildren()}get sourceString(){return this.source.contents}}class Ke{constructor(e,n){const s=this;if(this.grammar=e,this.checkedActionDicts=!1,this.Wrapper=class extends(n?n.Wrapper:Oa){constructor(r,i,o){super(r,i,o),s.checkActionDictsIfHaventAlready(),this._semantics=s}toString(){return"[semantics wrapper for "+s.grammar.name+"]"}},this.super=n,n){if(!(e.equals(this.super.grammar)||e._inheritsFrom(this.super.grammar)))throw new Error("Cannot extend a semantics for grammar '"+this.super.grammar.name+"' for use with grammar '"+e.name+"' (not a sub-grammar)");this.operations=Object.create(this.super.operations),this.attributes=Object.create(this.super.attributes),this.attributeKeys=Object.create(null);for(const r in this.attributes)Object.defineProperty(this.attributeKeys,r,{value:xa(r)})}else this.operations=Object.create(null),this.attributes=Object.create(null),this.attributeKeys=Object.create(null)}toString(){return"[semantics for "+this.grammar.name+"]"}checkActionDictsIfHaventAlready(){this.checkedActionDicts||(this.checkActionDicts(),this.checkedActionDicts=!0)}checkActionDicts(){let e;for(e in this.operations)this.operations[e].checkActionDict(this.grammar);for(e in this.attributes)this.attributes[e].checkActionDict(this.grammar)}toRecipe(e){function n(r){return r.super!==Ke.BuiltInSemantics._getSemantics()}let s=`(function(g) {
|
|
27
|
+
`;if(n(this)){s+=" var semantics = "+this.super.toRecipe(!0)+"(g";const r=this.super.grammar;let i=this.grammar;for(;i!==r;)s+=".superGrammar",i=i.superGrammar;s+=`);
|
|
28
|
+
`,s+=" return g.extendSemantics(semantics)"}else s+=" return g.createSemantics()";return["Operation","Attribute"].forEach(r=>{const i=this[r.toLowerCase()+"s"];Object.keys(i).forEach(o=>{const{actionDict:a,formals:c,builtInDefault:u}=i[o];let l=o;c.length>0&&(l+="("+c.join(", ")+")");let d;n(this)&&this.super[r.toLowerCase()+"s"][o]?d="extend"+r:d="add"+r,s+=`
|
|
29
|
+
.`+d+"("+JSON.stringify(l)+", {";const f=[];Object.keys(a).forEach(p=>{if(a[p]!==u){let h=a[p].toString().trim();h=h.replace(/^.*\(/,"function("),f.push(`
|
|
30
|
+
`+JSON.stringify(p)+": "+h)}}),s+=f.join(",")+`
|
|
31
|
+
})`})}),s+=`;
|
|
32
|
+
})`,e||(s=`(function() {
|
|
33
|
+
var grammar = this.fromRecipe(`+this.grammar.toRecipe()+`);
|
|
34
|
+
var semantics = `+s+`(grammar);
|
|
35
|
+
return semantics;
|
|
36
|
+
});
|
|
37
|
+
`),s}addOperationOrAttribute(e,n,s){const r=e+"s",i=Ta(n,e),{name:o}=i,{formals:a}=i;this.assertNewName(o,e);const c=Ah(e,o,d),u={_default:c};Object.keys(s).forEach(f=>{u[f]=s[f]});const l=e==="operation"?new us(o,a,u,c):new Li(o,u,c);l.checkActionDict(this.grammar),this[r][o]=l;function d(...f){const p=this._semantics[r][o];if(arguments.length!==p.formals.length)throw new Error("Invalid number of arguments passed to "+o+" "+e+" (expected "+p.formals.length+", got "+arguments.length+")");const h=Object.create(null);for(const[y,b]of Object.entries(f)){const v=p.formals[y];h[v]=b}const m=this.args;this.args=h;const g=p.execute(this._semantics,this);return this.args=m,g}e==="operation"?(this.Wrapper.prototype[o]=d,this.Wrapper.prototype[o].toString=function(){return"["+o+" operation]"}):(Object.defineProperty(this.Wrapper.prototype,o,{get:d,configurable:!0}),Object.defineProperty(this.attributeKeys,o,{value:xa(o)}))}extendOperationOrAttribute(e,n,s){const r=e+"s";if(Ta(n,"attribute"),!(this.super&&n in this.super[r]))throw new Error("Cannot extend "+e+" '"+n+"': did not inherit an "+e+" with that name");if(Ni(this[r],n))throw new Error("Cannot extend "+e+" '"+n+"' again");const i=this[r][n].formals,o=this[r][n].actionDict,a=Object.create(o);Object.keys(s).forEach(c=>{a[c]=s[c]}),this[r][n]=e==="operation"?new us(n,i,a):new Li(n,a),this[r][n].checkActionDict(this.grammar)}assertNewName(e,n){if(Ni(Oa.prototype,e))throw new Error("Cannot add "+n+" '"+e+"': that's a reserved name");if(e in this.operations)throw new Error("Cannot add "+n+" '"+e+"': an operation with that name already exists");if(e in this.attributes)throw new Error("Cannot add "+n+" '"+e+"': an attribute with that name already exists")}wrap(e,n,s){const r=s||n;return e instanceof this.Wrapper?e:new this.Wrapper(e,n,r)}}function Ta(t,e){if(!Ke.prototypeGrammar)return nn(t.indexOf("(")===-1),{name:t,formals:[]};const n=Ke.prototypeGrammar.match(t,e==="operation"?"OperationSignature":"AttributeSignature");if(n.failed())throw new Error(n.message);return Ke.prototypeGrammarSemantics(n).parse()}function Ah(t,e,n){return function(...s){const i=(this._semantics.operations[e]||this._semantics.attributes[e]).formals.map(o=>this.args[o]);if(!this.isIteration()&&s.length===1)return n.apply(s[0],i);throw th(this.ctorName,e,t,Yn)}}Ke.createSemantics=function(t,e){const n=new Ke(t,e!==void 0?e:Ke.BuiltInSemantics._getSemantics()),s=function(i){if(!(i instanceof rl))throw new TypeError("Semantics expected a MatchResult, but got "+Ao(i));if(i.failed())throw new TypeError("cannot apply Semantics to "+i.toString());const o=i._cst;if(o.grammar!==t)throw new Error("Cannot use a MatchResult from grammar '"+o.grammar.name+"' with a semantics for '"+t.name+"'");const a=new $r(i.input);return n.wrap(o,a.interval(i._cstOffset,i.input.length))};return s.addOperation=function(r,i){return n.addOperationOrAttribute("operation",r,i),s},s.extendOperation=function(r,i){return n.extendOperationOrAttribute("operation",r,i),s},s.addAttribute=function(r,i){return n.addOperationOrAttribute("attribute",r,i),s},s.extendAttribute=function(r,i){return n.extendOperationOrAttribute("attribute",r,i),s},s._getActionDict=function(r){const i=n.operations[r]||n.attributes[r];if(!i)throw new Error('"'+r+'" is not a valid operation or attribute name in this semantics for "'+t.name+'"');return i.actionDict},s._remove=function(r){let i;return r in n.operations?(i=n.operations[r],delete n.operations[r]):r in n.attributes&&(i=n.attributes[r],delete n.attributes[r]),delete n.Wrapper.prototype[r],i},s.getOperationNames=function(){return Object.keys(n.operations)},s.getAttributeNames=function(){return Object.keys(n.attributes)},s.getGrammar=function(){return n.grammar},s.toRecipe=function(r){return n.toRecipe(r)},s.toString=n.toString.bind(n),s._getSemantics=function(){return n},s};class us{constructor(e,n,s,r){this.name=e,this.formals=n,this.actionDict=s,this.builtInDefault=r}checkActionDict(e){e._checkTopDownActionDict(this.typeName,this.name,this.actionDict)}execute(e,n){try{const{ctorName:s}=n._node;let r=this.actionDict[s];return r?(Yn.push([this,s]),r.apply(n,n._children())):n.isNonterminal()&&(r=this.actionDict._nonterminal,r)?(Yn.push([this,"_nonterminal",s]),r.apply(n,n._children())):(Yn.push([this,"default action",s]),this.actionDict._default.apply(n,n._children()))}finally{Yn.pop()}}}us.prototype.typeName="operation";class Li extends us{constructor(e,n,s){super(e,[],n,s)}execute(e,n){const s=n._node,r=e.attributeKeys[this.name];return Ni(s,r)||(s[r]=us.prototype.execute.call(this,e,n)),s[r]}}Li.prototype.typeName="attribute";const Ra=["_iter","_terminal","_nonterminal","_default"];function Na(t){return Object.keys(t.rules).sort().map(e=>t.rules[e])}const kh=t=>t.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029");let cl,ul;class je{constructor(e,n,s,r){if(this.name=e,this.superGrammar=n,this.rules=s,r){if(!(r in s))throw new Error("Invalid start rule: '"+r+"' is not a rule in grammar '"+e+"'");this.defaultStartRule=r}this._matchStateInitializer=void 0,this.supportsIncrementalParsing=!0}matcher(){return new Sh(this)}isBuiltIn(){return this===je.ProtoBuiltInRules||this===je.BuiltInRules}equals(e){if(this===e)return!0;if(e==null||this.name!==e.name||this.defaultStartRule!==e.defaultStartRule||!(this.superGrammar===e.superGrammar||this.superGrammar.equals(e.superGrammar)))return!1;const n=Na(this),s=Na(e);return n.length===s.length&&n.every((r,i)=>r.description===s[i].description&&r.formals.join(",")===s[i].formals.join(",")&&r.body.toString()===s[i].body.toString())}match(e,n){const s=this.matcher();return s.replaceInputRange(0,0,e),s.match(n)}trace(e,n){const s=this.matcher();return s.replaceInputRange(0,0,e),s.trace(n)}createSemantics(){return Ke.createSemantics(this)}extendSemantics(e){return Ke.createSemantics(this,e._getSemantics())}_checkTopDownActionDict(e,n,s){const r=[];for(const i in s){const o=s[i];if(!Ra.includes(i)&&!(i in this.rules)){r.push(`'${i}' is not a valid semantic action for '${this.name}'`);continue}if(typeof o!="function"){r.push(`'${i}' must be a function in an action dictionary for '${this.name}'`);continue}const c=o.length,u=this._topDownActionArity(i);if(c!==u){let l;i==="_iter"||i==="_nonterminal"?l=`it should use a rest parameter, e.g. \`${i}(...children) {}\`. NOTE: this is new in Ohm v16 — see https://ohmjs.org/d/ati for details.`:l=`expected ${u}, got ${c}`,r.push(`Semantic action '${i}' has the wrong arity: ${l}`)}}if(r.length>0){const i=r.map(a=>"- "+a),o=new Error([`Found errors in the action dictionary of the '${n}' ${e}:`,...i].join(`
|
|
38
|
+
`));throw o.problems=r,o}}_topDownActionArity(e){return Ra.includes(e)?0:this.rules[e].body.getArity()}_inheritsFrom(e){let n=this.superGrammar;for(;n;){if(n.equals(e,!0))return!0;n=n.superGrammar}return!1}toRecipe(e=void 0){const n={};this.source&&(n.source=this.source.contents);let s=null;this.defaultStartRule&&(s=this.defaultStartRule);const r={};Object.keys(this.rules).forEach(a=>{const c=this.rules[a],{body:u}=c,l=!this.superGrammar||!this.superGrammar.rules[a];let d;l?d="define":d=u instanceof Mr?"extend":"override";const f={};if(c.source&&this.source){const m=c.source.relativeTo(this.source);f.sourceInterval=[m.startIdx,m.endIdx]}const p=l?c.description:null,h=u.outputRecipe(c.formals,this.source);r[a]=[d,f,p,c.formals,h]});let i="null";e?i=e:this.superGrammar&&!this.superGrammar.isBuiltIn()&&(i=this.superGrammar.toRecipe());const o=[...["grammar",n,this.name].map(JSON.stringify),i,...[s,r].map(JSON.stringify)];return kh(`[${o.join(",")}]`)}toOperationActionDictionaryTemplate(){return this._toOperationOrAttributeActionDictionaryTemplate()}toAttributeActionDictionaryTemplate(){return this._toOperationOrAttributeActionDictionaryTemplate()}_toOperationOrAttributeActionDictionaryTemplate(){const e=new bn;e.append("{");let n=!0;for(const s in this.rules){const{body:r}=this.rules[s];n?n=!1:e.append(","),e.append(`
|
|
39
|
+
`),e.append(" "),this.addSemanticActionTemplate(s,r,e)}return e.append(`
|
|
40
|
+
}`),e.contents()}addSemanticActionTemplate(e,n,s){s.append(e),s.append(": function(");const r=this._topDownActionArity(e);s.append(Lr("_",r).join(", ")),s.append(`) {
|
|
41
|
+
`),s.append(" }")}parseApplication(e){let n;if(e.indexOf("<")===-1)n=new X(e);else{const r=cl.match(e,"Base_application");n=ul(r,{})}if(!(n.ruleName in this.rules))throw Xu(n.ruleName,this.name);const{formals:s}=this.rules[n.ruleName];if(s.length!==n.args.length){const{source:r}=this.rules[n.ruleName];throw el(n.ruleName,s.length,n.args.length,r)}return n}_setUpMatchState(e){this._matchStateInitializer&&this._matchStateInitializer(e)}}je.ProtoBuiltInRules=new je("ProtoBuiltInRules",void 0,{any:{body:De,formals:[],description:"any character",primitive:!0},end:{body:$e,formals:[],description:"end of input",primitive:!0},caseInsensitive:{body:new xo(new Fe(0)),formals:["str"],primitive:!0},lower:{body:new Re("Ll"),formals:[],description:"a lowercase letter",primitive:!0},upper:{body:new Re("Lu"),formals:[],description:"an uppercase letter",primitive:!0},unicodeLtmo:{body:new Re("Ltmo"),formals:[],description:"a Unicode character in Lt, Lm, or Lo",primitive:!0},spaces:{body:new vn(new X("space")),formals:[]},space:{body:new Pe("\0"," "),formals:[],description:"a space"}});je.initApplicationParser=function(t,e){cl=t,ul=e};class La{constructor(e){this.name=e}sourceInterval(e,n){return this.source.subInterval(e,n-e)}ensureSuperGrammar(){return this.superGrammar||this.withSuperGrammar(this.name==="BuiltInRules"?je.ProtoBuiltInRules:je.BuiltInRules),this.superGrammar}ensureSuperGrammarRuleForOverriding(e,n){const s=this.ensureSuperGrammar().rules[e];if(!s)throw Wf(e,this.superGrammar.name,n);return s}installOverriddenOrExtendedRule(e,n,s,r){const i=xi(n);if(i.length>0)throw Ea(e,i,r);const o=this.ensureSuperGrammar().rules[e],a=o.formals,c=a?a.length:0;if(n.length!==c)throw el(e,c,n.length,r);return this.install(e,n,s,o.description,r)}install(e,n,s,r,i,o=!1){return this.rules[e]={body:s.introduceParams(n),formals:n,description:r,source:i,primitive:o},this}withSuperGrammar(e){if(this.superGrammar)throw new Error("the super grammar of a GrammarDecl cannot be set more than once");return this.superGrammar=e,this.rules=Object.create(e.rules),e.isBuiltIn()||(this.defaultStartRule=e.defaultStartRule),this}withDefaultStartRule(e){return this.defaultStartRule=e,this}withSource(e){return this.source=new $r(e).interval(0,e.length),this}build(){const e=new je(this.name,this.ensureSuperGrammar(),this.rules,this.defaultStartRule);e._matchStateInitializer=e.superGrammar._matchStateInitializer,e.supportsIncrementalParsing=e.superGrammar.supportsIncrementalParsing;const n=[];let s=!1;return Object.keys(e.rules).forEach(r=>{const{body:i}=e.rules[r];try{i.assertChoicesHaveUniformArity(r)}catch(o){n.push(o)}try{i.assertAllApplicationsAreValid(r,e)}catch(o){n.push(o),s=!0}}),s||Object.keys(e.rules).forEach(r=>{const{body:i}=e.rules[r];try{i.assertIteratedExprsAreNotNullable(e,[])}catch(o){n.push(o)}}),n.length>0&&nh(n),this.source&&(e.source=this.source),e}define(e,n,s,r,i,o){if(this.ensureSuperGrammar(),this.superGrammar.rules[e])throw ka(e,this.name,this.superGrammar.name,i);if(this.rules[e])throw ka(e,this.name,this.name,i);const a=xi(n);if(a.length>0)throw Ea(e,a,i);return this.install(e,n,s,r,i,o)}override(e,n,s,r,i){return this.ensureSuperGrammarRuleForOverriding(e,i),this.installOverriddenOrExtendedRule(e,n,s,i),this}extend(e,n,s,r,i){if(!this.ensureSuperGrammar().rules[e])throw Vf(e,this.superGrammar.name,i);const a=new Mr(this.superGrammar,e,s);return a.source=s.source,this.installOverriddenOrExtendedRule(e,n,a,i),this}}class Xs{constructor(e){this.currentDecl=null,this.currentRuleName=null,this.options=e||{}}newGrammar(e){return new La(e)}grammar(e,n,s,r,i){const o=new La(n);return s&&o.withSuperGrammar(s instanceof je?s:this.fromRecipe(s)),r&&o.withDefaultStartRule(r),e&&e.source&&o.withSource(e.source),this.currentDecl=o,Object.keys(i).forEach(a=>{this.currentRuleName=a;const c=i[a],u=c[0],l=c[1],d=c[2],f=c[3],p=this.fromRecipe(c[4]);let h;o.source&&l&&l.sourceInterval&&(h=o.source.subInterval(l.sourceInterval[0],l.sourceInterval[1]-l.sourceInterval[0])),o[u](a,f,p,d,h)}),this.currentRuleName=this.currentDecl=null,o.build()}terminal(e){return new Ne(e)}range(e,n){return new Pe(e,n)}param(e){return new Fe(e)}alt(...e){let n=[];for(let s of e)s instanceof B||(s=this.fromRecipe(s)),s instanceof Ee?n=n.concat(s.terms):n.push(s);return n.length===1?n[0]:new Ee(n)}seq(...e){let n=[];for(let s of e)s instanceof B||(s=this.fromRecipe(s)),s instanceof xe?n=n.concat(s.factors):n.push(s);return n.length===1?n[0]:new xe(n)}star(e){return e instanceof B||(e=this.fromRecipe(e)),new vn(e)}plus(e){return e instanceof B||(e=this.fromRecipe(e)),new Pn(e)}opt(e){return e instanceof B||(e=this.fromRecipe(e)),new $t(e)}not(e){return e instanceof B||(e=this.fromRecipe(e)),new Te(e)}lookahead(e){return e instanceof B||(e=this.fromRecipe(e)),this.options.eliminateLookaheads?new Te(new Te(e)):new ze(e)}lex(e){return e instanceof B||(e=this.fromRecipe(e)),new Ze(e)}app(e,n){return n&&n.length>0&&(n=n.map(function(s){return s instanceof B?s:this.fromRecipe(s)},this)),new X(e,n)}splice(e,n){return new Dr(this.currentDecl.superGrammar,this.currentRuleName,e.map(s=>this.fromRecipe(s)),n.map(s=>this.fromRecipe(s)))}fromRecipe(e){const n=e[0]==="grammar"?e.slice(1):e.slice(2),s=this[e[0]](...n),r=e[1];return r&&r.sourceInterval&&this.currentDecl&&s.withSource(this.currentDecl.sourceInterval(...r.sourceInterval)),s}}function Co(t){return typeof t=="function"?t.call(new Xs):(typeof t=="string"&&(t=JSON.parse(t)),new Xs().fromRecipe(t))}const Oo=Co(["grammar",{source:`BuiltInRules {
|
|
42
|
+
|
|
43
|
+
alnum (an alpha-numeric character)
|
|
44
|
+
= letter
|
|
45
|
+
| digit
|
|
46
|
+
|
|
47
|
+
letter (a letter)
|
|
48
|
+
= lower
|
|
49
|
+
| upper
|
|
50
|
+
| unicodeLtmo
|
|
51
|
+
|
|
52
|
+
digit (a digit)
|
|
53
|
+
= "0".."9"
|
|
54
|
+
|
|
55
|
+
hexDigit (a hexadecimal digit)
|
|
56
|
+
= digit
|
|
57
|
+
| "a".."f"
|
|
58
|
+
| "A".."F"
|
|
59
|
+
|
|
60
|
+
ListOf<elem, sep>
|
|
61
|
+
= NonemptyListOf<elem, sep>
|
|
62
|
+
| EmptyListOf<elem, sep>
|
|
63
|
+
|
|
64
|
+
NonemptyListOf<elem, sep>
|
|
65
|
+
= elem (sep elem)*
|
|
66
|
+
|
|
67
|
+
EmptyListOf<elem, sep>
|
|
68
|
+
= /* nothing */
|
|
69
|
+
|
|
70
|
+
listOf<elem, sep>
|
|
71
|
+
= nonemptyListOf<elem, sep>
|
|
72
|
+
| emptyListOf<elem, sep>
|
|
73
|
+
|
|
74
|
+
nonemptyListOf<elem, sep>
|
|
75
|
+
= elem (sep elem)*
|
|
76
|
+
|
|
77
|
+
emptyListOf<elem, sep>
|
|
78
|
+
= /* nothing */
|
|
79
|
+
|
|
80
|
+
// Allows a syntactic rule application within a lexical context.
|
|
81
|
+
applySyntactic<app> = app
|
|
82
|
+
}`},"BuiltInRules",null,null,{alnum:["define",{sourceInterval:[18,78]},"an alpha-numeric character",[],["alt",{sourceInterval:[60,78]},["app",{sourceInterval:[60,66]},"letter",[]],["app",{sourceInterval:[73,78]},"digit",[]]]],letter:["define",{sourceInterval:[82,142]},"a letter",[],["alt",{sourceInterval:[107,142]},["app",{sourceInterval:[107,112]},"lower",[]],["app",{sourceInterval:[119,124]},"upper",[]],["app",{sourceInterval:[131,142]},"unicodeLtmo",[]]]],digit:["define",{sourceInterval:[146,177]},"a digit",[],["range",{sourceInterval:[169,177]},"0","9"]],hexDigit:["define",{sourceInterval:[181,254]},"a hexadecimal digit",[],["alt",{sourceInterval:[219,254]},["app",{sourceInterval:[219,224]},"digit",[]],["range",{sourceInterval:[231,239]},"a","f"],["range",{sourceInterval:[246,254]},"A","F"]]],ListOf:["define",{sourceInterval:[258,336]},null,["elem","sep"],["alt",{sourceInterval:[282,336]},["app",{sourceInterval:[282,307]},"NonemptyListOf",[["param",{sourceInterval:[297,301]},0],["param",{sourceInterval:[303,306]},1]]],["app",{sourceInterval:[314,336]},"EmptyListOf",[["param",{sourceInterval:[326,330]},0],["param",{sourceInterval:[332,335]},1]]]]],NonemptyListOf:["define",{sourceInterval:[340,388]},null,["elem","sep"],["seq",{sourceInterval:[372,388]},["param",{sourceInterval:[372,376]},0],["star",{sourceInterval:[377,388]},["seq",{sourceInterval:[378,386]},["param",{sourceInterval:[378,381]},1],["param",{sourceInterval:[382,386]},0]]]]],EmptyListOf:["define",{sourceInterval:[392,434]},null,["elem","sep"],["seq",{sourceInterval:[438,438]}]],listOf:["define",{sourceInterval:[438,516]},null,["elem","sep"],["alt",{sourceInterval:[462,516]},["app",{sourceInterval:[462,487]},"nonemptyListOf",[["param",{sourceInterval:[477,481]},0],["param",{sourceInterval:[483,486]},1]]],["app",{sourceInterval:[494,516]},"emptyListOf",[["param",{sourceInterval:[506,510]},0],["param",{sourceInterval:[512,515]},1]]]]],nonemptyListOf:["define",{sourceInterval:[520,568]},null,["elem","sep"],["seq",{sourceInterval:[552,568]},["param",{sourceInterval:[552,556]},0],["star",{sourceInterval:[557,568]},["seq",{sourceInterval:[558,566]},["param",{sourceInterval:[558,561]},1],["param",{sourceInterval:[562,566]},0]]]]],emptyListOf:["define",{sourceInterval:[572,682]},null,["elem","sep"],["seq",{sourceInterval:[685,685]}]],applySyntactic:["define",{sourceInterval:[685,710]},null,["app"],["param",{sourceInterval:[707,710]},0]]}]);je.BuiltInRules=Oo;ih(je.BuiltInRules);const To=Co(["grammar",{source:`Ohm {
|
|
83
|
+
|
|
84
|
+
Grammars
|
|
85
|
+
= Grammar*
|
|
86
|
+
|
|
87
|
+
Grammar
|
|
88
|
+
= ident SuperGrammar? "{" Rule* "}"
|
|
89
|
+
|
|
90
|
+
SuperGrammar
|
|
91
|
+
= "<:" ident
|
|
92
|
+
|
|
93
|
+
Rule
|
|
94
|
+
= ident Formals? ruleDescr? "=" RuleBody -- define
|
|
95
|
+
| ident Formals? ":=" OverrideRuleBody -- override
|
|
96
|
+
| ident Formals? "+=" RuleBody -- extend
|
|
97
|
+
|
|
98
|
+
RuleBody
|
|
99
|
+
= "|"? NonemptyListOf<TopLevelTerm, "|">
|
|
100
|
+
|
|
101
|
+
TopLevelTerm
|
|
102
|
+
= Seq caseName -- inline
|
|
103
|
+
| Seq
|
|
104
|
+
|
|
105
|
+
OverrideRuleBody
|
|
106
|
+
= "|"? NonemptyListOf<OverrideTopLevelTerm, "|">
|
|
107
|
+
|
|
108
|
+
OverrideTopLevelTerm
|
|
109
|
+
= "..." -- superSplice
|
|
110
|
+
| TopLevelTerm
|
|
111
|
+
|
|
112
|
+
Formals
|
|
113
|
+
= "<" ListOf<ident, ","> ">"
|
|
114
|
+
|
|
115
|
+
Params
|
|
116
|
+
= "<" ListOf<Seq, ","> ">"
|
|
117
|
+
|
|
118
|
+
Alt
|
|
119
|
+
= NonemptyListOf<Seq, "|">
|
|
120
|
+
|
|
121
|
+
Seq
|
|
122
|
+
= Iter*
|
|
123
|
+
|
|
124
|
+
Iter
|
|
125
|
+
= Pred "*" -- star
|
|
126
|
+
| Pred "+" -- plus
|
|
127
|
+
| Pred "?" -- opt
|
|
128
|
+
| Pred
|
|
129
|
+
|
|
130
|
+
Pred
|
|
131
|
+
= "~" Lex -- not
|
|
132
|
+
| "&" Lex -- lookahead
|
|
133
|
+
| Lex
|
|
134
|
+
|
|
135
|
+
Lex
|
|
136
|
+
= "#" Base -- lex
|
|
137
|
+
| Base
|
|
138
|
+
|
|
139
|
+
Base
|
|
140
|
+
= ident Params? ~(ruleDescr? "=" | ":=" | "+=") -- application
|
|
141
|
+
| oneCharTerminal ".." oneCharTerminal -- range
|
|
142
|
+
| terminal -- terminal
|
|
143
|
+
| "(" Alt ")" -- paren
|
|
144
|
+
|
|
145
|
+
ruleDescr (a rule description)
|
|
146
|
+
= "(" ruleDescrText ")"
|
|
147
|
+
|
|
148
|
+
ruleDescrText
|
|
149
|
+
= (~")" any)*
|
|
150
|
+
|
|
151
|
+
caseName
|
|
152
|
+
= "--" (~"\\n" space)* name (~"\\n" space)* ("\\n" | &"}")
|
|
153
|
+
|
|
154
|
+
name (a name)
|
|
155
|
+
= nameFirst nameRest*
|
|
156
|
+
|
|
157
|
+
nameFirst
|
|
158
|
+
= "_"
|
|
159
|
+
| letter
|
|
160
|
+
|
|
161
|
+
nameRest
|
|
162
|
+
= "_"
|
|
163
|
+
| alnum
|
|
164
|
+
|
|
165
|
+
ident (an identifier)
|
|
166
|
+
= name
|
|
167
|
+
|
|
168
|
+
terminal
|
|
169
|
+
= "\\"" terminalChar* "\\""
|
|
170
|
+
|
|
171
|
+
oneCharTerminal
|
|
172
|
+
= "\\"" terminalChar "\\""
|
|
173
|
+
|
|
174
|
+
terminalChar
|
|
175
|
+
= escapeChar
|
|
176
|
+
| ~"\\\\" ~"\\"" ~"\\n" "\\u{0}".."\\u{10FFFF}"
|
|
177
|
+
|
|
178
|
+
escapeChar (an escape sequence)
|
|
179
|
+
= "\\\\\\\\" -- backslash
|
|
180
|
+
| "\\\\\\"" -- doubleQuote
|
|
181
|
+
| "\\\\\\'" -- singleQuote
|
|
182
|
+
| "\\\\b" -- backspace
|
|
183
|
+
| "\\\\n" -- lineFeed
|
|
184
|
+
| "\\\\r" -- carriageReturn
|
|
185
|
+
| "\\\\t" -- tab
|
|
186
|
+
| "\\\\u{" hexDigit hexDigit? hexDigit?
|
|
187
|
+
hexDigit? hexDigit? hexDigit? "}" -- unicodeCodePoint
|
|
188
|
+
| "\\\\u" hexDigit hexDigit hexDigit hexDigit -- unicodeEscape
|
|
189
|
+
| "\\\\x" hexDigit hexDigit -- hexEscape
|
|
190
|
+
|
|
191
|
+
space
|
|
192
|
+
+= comment
|
|
193
|
+
|
|
194
|
+
comment
|
|
195
|
+
= "//" (~"\\n" any)* &("\\n" | end) -- singleLine
|
|
196
|
+
| "/*" (~"*/" any)* "*/" -- multiLine
|
|
197
|
+
|
|
198
|
+
tokens = token*
|
|
199
|
+
|
|
200
|
+
token = caseName | comment | ident | operator | punctuation | terminal | any
|
|
201
|
+
|
|
202
|
+
operator = "<:" | "=" | ":=" | "+=" | "*" | "+" | "?" | "~" | "&"
|
|
203
|
+
|
|
204
|
+
punctuation = "<" | ">" | "," | "--"
|
|
205
|
+
}`},"Ohm",null,"Grammars",{Grammars:["define",{sourceInterval:[9,32]},null,[],["star",{sourceInterval:[24,32]},["app",{sourceInterval:[24,31]},"Grammar",[]]]],Grammar:["define",{sourceInterval:[36,83]},null,[],["seq",{sourceInterval:[50,83]},["app",{sourceInterval:[50,55]},"ident",[]],["opt",{sourceInterval:[56,69]},["app",{sourceInterval:[56,68]},"SuperGrammar",[]]],["terminal",{sourceInterval:[70,73]},"{"],["star",{sourceInterval:[74,79]},["app",{sourceInterval:[74,78]},"Rule",[]]],["terminal",{sourceInterval:[80,83]},"}"]]],SuperGrammar:["define",{sourceInterval:[87,116]},null,[],["seq",{sourceInterval:[106,116]},["terminal",{sourceInterval:[106,110]},"<:"],["app",{sourceInterval:[111,116]},"ident",[]]]],Rule_define:["define",{sourceInterval:[131,181]},null,[],["seq",{sourceInterval:[131,170]},["app",{sourceInterval:[131,136]},"ident",[]],["opt",{sourceInterval:[137,145]},["app",{sourceInterval:[137,144]},"Formals",[]]],["opt",{sourceInterval:[146,156]},["app",{sourceInterval:[146,155]},"ruleDescr",[]]],["terminal",{sourceInterval:[157,160]},"="],["app",{sourceInterval:[162,170]},"RuleBody",[]]]],Rule_override:["define",{sourceInterval:[188,248]},null,[],["seq",{sourceInterval:[188,235]},["app",{sourceInterval:[188,193]},"ident",[]],["opt",{sourceInterval:[194,202]},["app",{sourceInterval:[194,201]},"Formals",[]]],["terminal",{sourceInterval:[214,218]},":="],["app",{sourceInterval:[219,235]},"OverrideRuleBody",[]]]],Rule_extend:["define",{sourceInterval:[255,305]},null,[],["seq",{sourceInterval:[255,294]},["app",{sourceInterval:[255,260]},"ident",[]],["opt",{sourceInterval:[261,269]},["app",{sourceInterval:[261,268]},"Formals",[]]],["terminal",{sourceInterval:[281,285]},"+="],["app",{sourceInterval:[286,294]},"RuleBody",[]]]],Rule:["define",{sourceInterval:[120,305]},null,[],["alt",{sourceInterval:[131,305]},["app",{sourceInterval:[131,170]},"Rule_define",[]],["app",{sourceInterval:[188,235]},"Rule_override",[]],["app",{sourceInterval:[255,294]},"Rule_extend",[]]]],RuleBody:["define",{sourceInterval:[309,362]},null,[],["seq",{sourceInterval:[324,362]},["opt",{sourceInterval:[324,328]},["terminal",{sourceInterval:[324,327]},"|"]],["app",{sourceInterval:[329,362]},"NonemptyListOf",[["app",{sourceInterval:[344,356]},"TopLevelTerm",[]],["terminal",{sourceInterval:[358,361]},"|"]]]]],TopLevelTerm_inline:["define",{sourceInterval:[385,408]},null,[],["seq",{sourceInterval:[385,397]},["app",{sourceInterval:[385,388]},"Seq",[]],["app",{sourceInterval:[389,397]},"caseName",[]]]],TopLevelTerm:["define",{sourceInterval:[366,418]},null,[],["alt",{sourceInterval:[385,418]},["app",{sourceInterval:[385,397]},"TopLevelTerm_inline",[]],["app",{sourceInterval:[415,418]},"Seq",[]]]],OverrideRuleBody:["define",{sourceInterval:[422,491]},null,[],["seq",{sourceInterval:[445,491]},["opt",{sourceInterval:[445,449]},["terminal",{sourceInterval:[445,448]},"|"]],["app",{sourceInterval:[450,491]},"NonemptyListOf",[["app",{sourceInterval:[465,485]},"OverrideTopLevelTerm",[]],["terminal",{sourceInterval:[487,490]},"|"]]]]],OverrideTopLevelTerm_superSplice:["define",{sourceInterval:[522,543]},null,[],["terminal",{sourceInterval:[522,527]},"..."]],OverrideTopLevelTerm:["define",{sourceInterval:[495,562]},null,[],["alt",{sourceInterval:[522,562]},["app",{sourceInterval:[522,527]},"OverrideTopLevelTerm_superSplice",[]],["app",{sourceInterval:[550,562]},"TopLevelTerm",[]]]],Formals:["define",{sourceInterval:[566,606]},null,[],["seq",{sourceInterval:[580,606]},["terminal",{sourceInterval:[580,583]},"<"],["app",{sourceInterval:[584,602]},"ListOf",[["app",{sourceInterval:[591,596]},"ident",[]],["terminal",{sourceInterval:[598,601]},","]]],["terminal",{sourceInterval:[603,606]},">"]]],Params:["define",{sourceInterval:[610,647]},null,[],["seq",{sourceInterval:[623,647]},["terminal",{sourceInterval:[623,626]},"<"],["app",{sourceInterval:[627,643]},"ListOf",[["app",{sourceInterval:[634,637]},"Seq",[]],["terminal",{sourceInterval:[639,642]},","]]],["terminal",{sourceInterval:[644,647]},">"]]],Alt:["define",{sourceInterval:[651,685]},null,[],["app",{sourceInterval:[661,685]},"NonemptyListOf",[["app",{sourceInterval:[676,679]},"Seq",[]],["terminal",{sourceInterval:[681,684]},"|"]]]],Seq:["define",{sourceInterval:[689,704]},null,[],["star",{sourceInterval:[699,704]},["app",{sourceInterval:[699,703]},"Iter",[]]]],Iter_star:["define",{sourceInterval:[719,736]},null,[],["seq",{sourceInterval:[719,727]},["app",{sourceInterval:[719,723]},"Pred",[]],["terminal",{sourceInterval:[724,727]},"*"]]],Iter_plus:["define",{sourceInterval:[743,760]},null,[],["seq",{sourceInterval:[743,751]},["app",{sourceInterval:[743,747]},"Pred",[]],["terminal",{sourceInterval:[748,751]},"+"]]],Iter_opt:["define",{sourceInterval:[767,783]},null,[],["seq",{sourceInterval:[767,775]},["app",{sourceInterval:[767,771]},"Pred",[]],["terminal",{sourceInterval:[772,775]},"?"]]],Iter:["define",{sourceInterval:[708,794]},null,[],["alt",{sourceInterval:[719,794]},["app",{sourceInterval:[719,727]},"Iter_star",[]],["app",{sourceInterval:[743,751]},"Iter_plus",[]],["app",{sourceInterval:[767,775]},"Iter_opt",[]],["app",{sourceInterval:[790,794]},"Pred",[]]]],Pred_not:["define",{sourceInterval:[809,824]},null,[],["seq",{sourceInterval:[809,816]},["terminal",{sourceInterval:[809,812]},"~"],["app",{sourceInterval:[813,816]},"Lex",[]]]],Pred_lookahead:["define",{sourceInterval:[831,852]},null,[],["seq",{sourceInterval:[831,838]},["terminal",{sourceInterval:[831,834]},"&"],["app",{sourceInterval:[835,838]},"Lex",[]]]],Pred:["define",{sourceInterval:[798,862]},null,[],["alt",{sourceInterval:[809,862]},["app",{sourceInterval:[809,816]},"Pred_not",[]],["app",{sourceInterval:[831,838]},"Pred_lookahead",[]],["app",{sourceInterval:[859,862]},"Lex",[]]]],Lex_lex:["define",{sourceInterval:[876,892]},null,[],["seq",{sourceInterval:[876,884]},["terminal",{sourceInterval:[876,879]},"#"],["app",{sourceInterval:[880,884]},"Base",[]]]],Lex:["define",{sourceInterval:[866,903]},null,[],["alt",{sourceInterval:[876,903]},["app",{sourceInterval:[876,884]},"Lex_lex",[]],["app",{sourceInterval:[899,903]},"Base",[]]]],Base_application:["define",{sourceInterval:[918,979]},null,[],["seq",{sourceInterval:[918,963]},["app",{sourceInterval:[918,923]},"ident",[]],["opt",{sourceInterval:[924,931]},["app",{sourceInterval:[924,930]},"Params",[]]],["not",{sourceInterval:[932,963]},["alt",{sourceInterval:[934,962]},["seq",{sourceInterval:[934,948]},["opt",{sourceInterval:[934,944]},["app",{sourceInterval:[934,943]},"ruleDescr",[]]],["terminal",{sourceInterval:[945,948]},"="]],["terminal",{sourceInterval:[951,955]},":="],["terminal",{sourceInterval:[958,962]},"+="]]]]],Base_range:["define",{sourceInterval:[986,1041]},null,[],["seq",{sourceInterval:[986,1022]},["app",{sourceInterval:[986,1001]},"oneCharTerminal",[]],["terminal",{sourceInterval:[1002,1006]},".."],["app",{sourceInterval:[1007,1022]},"oneCharTerminal",[]]]],Base_terminal:["define",{sourceInterval:[1048,1106]},null,[],["app",{sourceInterval:[1048,1056]},"terminal",[]]],Base_paren:["define",{sourceInterval:[1113,1168]},null,[],["seq",{sourceInterval:[1113,1124]},["terminal",{sourceInterval:[1113,1116]},"("],["app",{sourceInterval:[1117,1120]},"Alt",[]],["terminal",{sourceInterval:[1121,1124]},")"]]],Base:["define",{sourceInterval:[907,1168]},null,[],["alt",{sourceInterval:[918,1168]},["app",{sourceInterval:[918,963]},"Base_application",[]],["app",{sourceInterval:[986,1022]},"Base_range",[]],["app",{sourceInterval:[1048,1056]},"Base_terminal",[]],["app",{sourceInterval:[1113,1124]},"Base_paren",[]]]],ruleDescr:["define",{sourceInterval:[1172,1231]},"a rule description",[],["seq",{sourceInterval:[1210,1231]},["terminal",{sourceInterval:[1210,1213]},"("],["app",{sourceInterval:[1214,1227]},"ruleDescrText",[]],["terminal",{sourceInterval:[1228,1231]},")"]]],ruleDescrText:["define",{sourceInterval:[1235,1266]},null,[],["star",{sourceInterval:[1255,1266]},["seq",{sourceInterval:[1256,1264]},["not",{sourceInterval:[1256,1260]},["terminal",{sourceInterval:[1257,1260]},")"]],["app",{sourceInterval:[1261,1264]},"any",[]]]]],caseName:["define",{sourceInterval:[1270,1338]},null,[],["seq",{sourceInterval:[1285,1338]},["terminal",{sourceInterval:[1285,1289]},"--"],["star",{sourceInterval:[1290,1304]},["seq",{sourceInterval:[1291,1302]},["not",{sourceInterval:[1291,1296]},["terminal",{sourceInterval:[1292,1296]},`
|
|
206
|
+
`]],["app",{sourceInterval:[1297,1302]},"space",[]]]],["app",{sourceInterval:[1305,1309]},"name",[]],["star",{sourceInterval:[1310,1324]},["seq",{sourceInterval:[1311,1322]},["not",{sourceInterval:[1311,1316]},["terminal",{sourceInterval:[1312,1316]},`
|
|
207
|
+
`]],["app",{sourceInterval:[1317,1322]},"space",[]]]],["alt",{sourceInterval:[1326,1337]},["terminal",{sourceInterval:[1326,1330]},`
|
|
208
|
+
`],["lookahead",{sourceInterval:[1333,1337]},["terminal",{sourceInterval:[1334,1337]},"}"]]]]],name:["define",{sourceInterval:[1342,1382]},"a name",[],["seq",{sourceInterval:[1363,1382]},["app",{sourceInterval:[1363,1372]},"nameFirst",[]],["star",{sourceInterval:[1373,1382]},["app",{sourceInterval:[1373,1381]},"nameRest",[]]]]],nameFirst:["define",{sourceInterval:[1386,1418]},null,[],["alt",{sourceInterval:[1402,1418]},["terminal",{sourceInterval:[1402,1405]},"_"],["app",{sourceInterval:[1412,1418]},"letter",[]]]],nameRest:["define",{sourceInterval:[1422,1452]},null,[],["alt",{sourceInterval:[1437,1452]},["terminal",{sourceInterval:[1437,1440]},"_"],["app",{sourceInterval:[1447,1452]},"alnum",[]]]],ident:["define",{sourceInterval:[1456,1489]},"an identifier",[],["app",{sourceInterval:[1485,1489]},"name",[]]],terminal:["define",{sourceInterval:[1493,1531]},null,[],["seq",{sourceInterval:[1508,1531]},["terminal",{sourceInterval:[1508,1512]},'"'],["star",{sourceInterval:[1513,1526]},["app",{sourceInterval:[1513,1525]},"terminalChar",[]]],["terminal",{sourceInterval:[1527,1531]},'"']]],oneCharTerminal:["define",{sourceInterval:[1535,1579]},null,[],["seq",{sourceInterval:[1557,1579]},["terminal",{sourceInterval:[1557,1561]},'"'],["app",{sourceInterval:[1562,1574]},"terminalChar",[]],["terminal",{sourceInterval:[1575,1579]},'"']]],terminalChar:["define",{sourceInterval:[1583,1660]},null,[],["alt",{sourceInterval:[1602,1660]},["app",{sourceInterval:[1602,1612]},"escapeChar",[]],["seq",{sourceInterval:[1621,1660]},["not",{sourceInterval:[1621,1626]},["terminal",{sourceInterval:[1622,1626]},"\\"]],["not",{sourceInterval:[1627,1632]},["terminal",{sourceInterval:[1628,1632]},'"']],["not",{sourceInterval:[1633,1638]},["terminal",{sourceInterval:[1634,1638]},`
|
|
209
|
+
`]],["range",{sourceInterval:[1639,1660]},"\0",""]]]],escapeChar_backslash:["define",{sourceInterval:[1703,1758]},null,[],["terminal",{sourceInterval:[1703,1709]},"\\\\"]],escapeChar_doubleQuote:["define",{sourceInterval:[1765,1822]},null,[],["terminal",{sourceInterval:[1765,1771]},'\\"']],escapeChar_singleQuote:["define",{sourceInterval:[1829,1886]},null,[],["terminal",{sourceInterval:[1829,1835]},"\\'"]],escapeChar_backspace:["define",{sourceInterval:[1893,1948]},null,[],["terminal",{sourceInterval:[1893,1898]},"\\b"]],escapeChar_lineFeed:["define",{sourceInterval:[1955,2009]},null,[],["terminal",{sourceInterval:[1955,1960]},"\\n"]],escapeChar_carriageReturn:["define",{sourceInterval:[2016,2076]},null,[],["terminal",{sourceInterval:[2016,2021]},"\\r"]],escapeChar_tab:["define",{sourceInterval:[2083,2132]},null,[],["terminal",{sourceInterval:[2083,2088]},"\\t"]],escapeChar_unicodeCodePoint:["define",{sourceInterval:[2139,2243]},null,[],["seq",{sourceInterval:[2139,2221]},["terminal",{sourceInterval:[2139,2145]},"\\u{"],["app",{sourceInterval:[2146,2154]},"hexDigit",[]],["opt",{sourceInterval:[2155,2164]},["app",{sourceInterval:[2155,2163]},"hexDigit",[]]],["opt",{sourceInterval:[2165,2174]},["app",{sourceInterval:[2165,2173]},"hexDigit",[]]],["opt",{sourceInterval:[2188,2197]},["app",{sourceInterval:[2188,2196]},"hexDigit",[]]],["opt",{sourceInterval:[2198,2207]},["app",{sourceInterval:[2198,2206]},"hexDigit",[]]],["opt",{sourceInterval:[2208,2217]},["app",{sourceInterval:[2208,2216]},"hexDigit",[]]],["terminal",{sourceInterval:[2218,2221]},"}"]]],escapeChar_unicodeEscape:["define",{sourceInterval:[2250,2309]},null,[],["seq",{sourceInterval:[2250,2291]},["terminal",{sourceInterval:[2250,2255]},"\\u"],["app",{sourceInterval:[2256,2264]},"hexDigit",[]],["app",{sourceInterval:[2265,2273]},"hexDigit",[]],["app",{sourceInterval:[2274,2282]},"hexDigit",[]],["app",{sourceInterval:[2283,2291]},"hexDigit",[]]]],escapeChar_hexEscape:["define",{sourceInterval:[2316,2371]},null,[],["seq",{sourceInterval:[2316,2339]},["terminal",{sourceInterval:[2316,2321]},"\\x"],["app",{sourceInterval:[2322,2330]},"hexDigit",[]],["app",{sourceInterval:[2331,2339]},"hexDigit",[]]]],escapeChar:["define",{sourceInterval:[1664,2371]},"an escape sequence",[],["alt",{sourceInterval:[1703,2371]},["app",{sourceInterval:[1703,1709]},"escapeChar_backslash",[]],["app",{sourceInterval:[1765,1771]},"escapeChar_doubleQuote",[]],["app",{sourceInterval:[1829,1835]},"escapeChar_singleQuote",[]],["app",{sourceInterval:[1893,1898]},"escapeChar_backspace",[]],["app",{sourceInterval:[1955,1960]},"escapeChar_lineFeed",[]],["app",{sourceInterval:[2016,2021]},"escapeChar_carriageReturn",[]],["app",{sourceInterval:[2083,2088]},"escapeChar_tab",[]],["app",{sourceInterval:[2139,2221]},"escapeChar_unicodeCodePoint",[]],["app",{sourceInterval:[2250,2291]},"escapeChar_unicodeEscape",[]],["app",{sourceInterval:[2316,2339]},"escapeChar_hexEscape",[]]]],space:["extend",{sourceInterval:[2375,2394]},null,[],["app",{sourceInterval:[2387,2394]},"comment",[]]],comment_singleLine:["define",{sourceInterval:[2412,2458]},null,[],["seq",{sourceInterval:[2412,2443]},["terminal",{sourceInterval:[2412,2416]},"//"],["star",{sourceInterval:[2417,2429]},["seq",{sourceInterval:[2418,2427]},["not",{sourceInterval:[2418,2423]},["terminal",{sourceInterval:[2419,2423]},`
|
|
210
|
+
`]],["app",{sourceInterval:[2424,2427]},"any",[]]]],["lookahead",{sourceInterval:[2430,2443]},["alt",{sourceInterval:[2432,2442]},["terminal",{sourceInterval:[2432,2436]},`
|
|
211
|
+
`],["app",{sourceInterval:[2439,2442]},"end",[]]]]]],comment_multiLine:["define",{sourceInterval:[2465,2501]},null,[],["seq",{sourceInterval:[2465,2487]},["terminal",{sourceInterval:[2465,2469]},"/*"],["star",{sourceInterval:[2470,2482]},["seq",{sourceInterval:[2471,2480]},["not",{sourceInterval:[2471,2476]},["terminal",{sourceInterval:[2472,2476]},"*/"]],["app",{sourceInterval:[2477,2480]},"any",[]]]],["terminal",{sourceInterval:[2483,2487]},"*/"]]],comment:["define",{sourceInterval:[2398,2501]},null,[],["alt",{sourceInterval:[2412,2501]},["app",{sourceInterval:[2412,2443]},"comment_singleLine",[]],["app",{sourceInterval:[2465,2487]},"comment_multiLine",[]]]],tokens:["define",{sourceInterval:[2505,2520]},null,[],["star",{sourceInterval:[2514,2520]},["app",{sourceInterval:[2514,2519]},"token",[]]]],token:["define",{sourceInterval:[2524,2600]},null,[],["alt",{sourceInterval:[2532,2600]},["app",{sourceInterval:[2532,2540]},"caseName",[]],["app",{sourceInterval:[2543,2550]},"comment",[]],["app",{sourceInterval:[2553,2558]},"ident",[]],["app",{sourceInterval:[2561,2569]},"operator",[]],["app",{sourceInterval:[2572,2583]},"punctuation",[]],["app",{sourceInterval:[2586,2594]},"terminal",[]],["app",{sourceInterval:[2597,2600]},"any",[]]]],operator:["define",{sourceInterval:[2604,2669]},null,[],["alt",{sourceInterval:[2615,2669]},["terminal",{sourceInterval:[2615,2619]},"<:"],["terminal",{sourceInterval:[2622,2625]},"="],["terminal",{sourceInterval:[2628,2632]},":="],["terminal",{sourceInterval:[2635,2639]},"+="],["terminal",{sourceInterval:[2642,2645]},"*"],["terminal",{sourceInterval:[2648,2651]},"+"],["terminal",{sourceInterval:[2654,2657]},"?"],["terminal",{sourceInterval:[2660,2663]},"~"],["terminal",{sourceInterval:[2666,2669]},"&"]]],punctuation:["define",{sourceInterval:[2673,2709]},null,[],["alt",{sourceInterval:[2687,2709]},["terminal",{sourceInterval:[2687,2690]},"<"],["terminal",{sourceInterval:[2693,2696]},">"],["terminal",{sourceInterval:[2699,2702]},","],["terminal",{sourceInterval:[2705,2709]},"--"]]]}]),si=Object.create(B.prototype);function Ma(t,e){for(const n in t)if(n===e)return!0;return!1}function ll(t,e,n,s){const r=new Xs(s);let i,o,a,c=!1;return(n||To).createSemantics().addOperation("visit",{Grammars(d){return d.children.map(f=>f.visit())},Grammar(d,f,p,h,m){const g=d.visit();i=r.newGrammar(g),f.child(0)&&f.child(0).visit(),h.children.map(b=>b.visit());const y=i.build();if(y.source=this.source.trimmed(),Ma(e,g))throw Bf(y);return e[g]=y,y},SuperGrammar(d,f){const p=f.visit();if(p==="null")i.withSuperGrammar(null);else{if(!e||!Ma(e,p))throw Uf(p,e,f.source);i.withSuperGrammar(e[p])}},Rule_define(d,f,p,h,m){o=d.visit(),a=f.children.map(v=>v.visit())[0]||[],!i.defaultStartRule&&i.ensureSuperGrammar()!==je.ProtoBuiltInRules&&i.withDefaultStartRule(o);const g=m.visit(),y=p.children.map(v=>v.visit())[0],b=this.source.trimmed();return i.define(o,a,g,y,b)},Rule_override(d,f,p,h){o=d.visit(),a=f.children.map(y=>y.visit())[0]||[];const m=this.source.trimmed();i.ensureSuperGrammarRuleForOverriding(o,m),c=!0;const g=h.visit();return c=!1,i.override(o,a,g,null,m)},Rule_extend(d,f,p,h){o=d.visit(),a=f.children.map(y=>y.visit())[0]||[];const m=h.visit(),g=this.source.trimmed();return i.extend(o,a,m,null,g)},RuleBody(d,f){return r.alt(...f.visit()).withSource(this.source)},OverrideRuleBody(d,f){const p=f.visit(),h=p.indexOf(si);if(h>=0){const m=p.slice(0,h),g=p.slice(h+1);return g.forEach(y=>{if(y===si)throw Yf(y)}),new Dr(i.superGrammar,o,m,g).withSource(this.source)}else return r.alt(...p).withSource(this.source)},Formals(d,f,p){return f.visit()},Params(d,f,p){return f.visit()},Alt(d){return r.alt(...d.visit()).withSource(this.source)},TopLevelTerm_inline(d,f){const p=o+"_"+f.visit(),h=d.visit(),m=this.source.trimmed(),g=!(i.superGrammar&&i.superGrammar.rules[p]);c&&!g?i.override(p,a,h,null,m):i.define(p,a,h,null,m);const y=a.map(b=>r.app(b));return r.app(p,y).withSource(h.source)},OverrideTopLevelTerm_superSplice(d){return si},Seq(d){return r.seq(...d.children.map(f=>f.visit())).withSource(this.source)},Iter_star(d,f){return r.star(d.visit()).withSource(this.source)},Iter_plus(d,f){return r.plus(d.visit()).withSource(this.source)},Iter_opt(d,f){return r.opt(d.visit()).withSource(this.source)},Pred_not(d,f){return r.not(f.visit()).withSource(this.source)},Pred_lookahead(d,f){return r.lookahead(f.visit()).withSource(this.source)},Lex_lex(d,f){return r.lex(f.visit()).withSource(this.source)},Base_application(d,f){const p=f.children.map(h=>h.visit())[0]||[];return r.app(d.visit(),p).withSource(this.source)},Base_range(d,f,p){return r.range(d.visit(),p.visit()).withSource(this.source)},Base_terminal(d){return r.terminal(d.visit()).withSource(this.source)},Base_paren(d,f,p){return f.visit()},ruleDescr(d,f,p){return f.visit()},ruleDescrText(d){return this.sourceString.trim()},caseName(d,f,p,h,m){return p.visit()},name(d,f){return this.sourceString},nameFirst(d){},nameRest(d){},terminal(d,f,p){return f.children.map(h=>h.visit()).join("")},oneCharTerminal(d,f,p){return f.visit()},escapeChar(d){try{return Ju(this.sourceString)}catch(f){throw f instanceof RangeError&&f.message.startsWith("Invalid code point ")?Xf(d):f}},NonemptyListOf(d,f,p){return[d.visit()].concat(p.children.map(h=>h.visit()))},EmptyListOf(){return[]},_terminal(){return this.sourceString}})(t).visit()}const Eh=Co(["grammar",{source:`OperationsAndAttributes {
|
|
212
|
+
|
|
213
|
+
AttributeSignature =
|
|
214
|
+
name
|
|
215
|
+
|
|
216
|
+
OperationSignature =
|
|
217
|
+
name Formals?
|
|
218
|
+
|
|
219
|
+
Formals
|
|
220
|
+
= "(" ListOf<name, ","> ")"
|
|
221
|
+
|
|
222
|
+
name (a name)
|
|
223
|
+
= nameFirst nameRest*
|
|
224
|
+
|
|
225
|
+
nameFirst
|
|
226
|
+
= "_"
|
|
227
|
+
| letter
|
|
228
|
+
|
|
229
|
+
nameRest
|
|
230
|
+
= "_"
|
|
231
|
+
| alnum
|
|
232
|
+
|
|
233
|
+
}`},"OperationsAndAttributes",null,"AttributeSignature",{AttributeSignature:["define",{sourceInterval:[29,58]},null,[],["app",{sourceInterval:[54,58]},"name",[]]],OperationSignature:["define",{sourceInterval:[62,100]},null,[],["seq",{sourceInterval:[87,100]},["app",{sourceInterval:[87,91]},"name",[]],["opt",{sourceInterval:[92,100]},["app",{sourceInterval:[92,99]},"Formals",[]]]]],Formals:["define",{sourceInterval:[104,143]},null,[],["seq",{sourceInterval:[118,143]},["terminal",{sourceInterval:[118,121]},"("],["app",{sourceInterval:[122,139]},"ListOf",[["app",{sourceInterval:[129,133]},"name",[]],["terminal",{sourceInterval:[135,138]},","]]],["terminal",{sourceInterval:[140,143]},")"]]],name:["define",{sourceInterval:[147,187]},"a name",[],["seq",{sourceInterval:[168,187]},["app",{sourceInterval:[168,177]},"nameFirst",[]],["star",{sourceInterval:[178,187]},["app",{sourceInterval:[178,186]},"nameRest",[]]]]],nameFirst:["define",{sourceInterval:[191,223]},null,[],["alt",{sourceInterval:[207,223]},["terminal",{sourceInterval:[207,210]},"_"],["app",{sourceInterval:[217,223]},"letter",[]]]],nameRest:["define",{sourceInterval:[227,257]},null,[],["alt",{sourceInterval:[242,257]},["terminal",{sourceInterval:[242,245]},"_"],["app",{sourceInterval:[252,257]},"alnum",[]]]]}]);Ih(je.BuiltInRules);_h(Eh);function Ih(t){const e={empty(){return this.iteration()},nonEmpty(n,s,r){return this.iteration([n].concat(r.children))},self(...n){return this}};Ke.BuiltInSemantics=Ke.createSemantics(t,null).addOperation("asIteration",{emptyListOf:e.empty,nonemptyListOf:e.nonEmpty,EmptyListOf:e.empty,NonemptyListOf:e.nonEmpty,_iter:e.self})}function _h(t){Ke.prototypeGrammarSemantics=t.createSemantics().addOperation("parse",{AttributeSignature(e){return{name:e.parse(),formals:[]}},OperationSignature(e,n){return{name:e.parse(),formals:n.children.map(s=>s.parse())[0]||[]}},Formals(e,n,s){return n.asIteration().children.map(r=>r.parse())},name(e,n){return this.sourceString}}),Ke.prototypeGrammar=t}function xh(t){let e=0;const n=[0],s=()=>n[n.length-1],r={},i=/( *).*(?:$|\r?\n|\r)/g;let o;for(;(o=i.exec(t))!=null;){const[a,c]=o;if(a.length===0)break;const u=c.length,l=s(),d=e+u;if(u>l)n.push(u),r[d]=1;else if(u<l){const f=n.length;for(;s()!==u;)n.pop();r[d]=-1*(f-n.length)}e+=a.length}return n.length>1&&(r[e]=1-n.length),r}const dl="an indented block",fl="a dedent",Da=1114112;class Ch extends $r{constructor(e){super(e.input),this.state=e}_indentationAt(e){return this.state.userData[e]||0}atEnd(){return super.atEnd()&&this._indentationAt(this.pos)===0}next(){if(this._indentationAt(this.pos)!==0){this.examinedLength=Math.max(this.examinedLength,this.pos);return}return super.next()}nextCharCode(){return this._indentationAt(this.pos)!==0?(this.examinedLength=Math.max(this.examinedLength,this.pos),Da):super.nextCharCode()}nextCodePoint(){return this._indentationAt(this.pos)!==0?(this.examinedLength=Math.max(this.examinedLength,this.pos),Da):super.nextCodePoint()}}class $a extends B{constructor(e=!0){super(),this.isIndent=e}allowsSkippingPrecedingSpace(){return!0}eval(e){const{inputStream:n}=e,s=e.userData;e.doNotMemoize=!0;const r=n.pos,i=this.isIndent?1:-1;return(s[r]||0)*i>0?(e.userData=Object.create(s),e.userData[r]-=i,e.pushBinding(new wn(0),r),!0):(e.processFailure(r,this),!1)}getArity(){return 1}_assertAllApplicationsAreValid(e,n){}_isNullable(e,n){return!1}assertChoicesHaveUniformArity(e){}assertIteratedExprsAreNotNullable(e){}introduceParams(e){return this}substituteParams(e){return this}toString(){return this.isIndent?"indent":"dedent"}toDisplayString(){return this.toString()}toFailure(e){const n=this.isIndent?dl:fl;return new Je(this,n,"description")}}const Oh=new X("indent"),Th=new X("dedent"),Rh=new Dr(Oo,"any",[Oh,Th],[]),Nh=new Xs().newGrammar("IndentationSensitive").withSuperGrammar(Oo).define("indent",[],new $a(!0),dl,void 0,!0).define("dedent",[],new $a(!1),fl,void 0,!0).extend("any",[],Rh,"any character",void 0).build();Object.assign(Nh,{_matchStateInitializer(t){t.userData=xh(t.input),t.inputStream=new Ch(t)},supportsIncrementalParsing:!1});je.initApplicationParser(To,ll);const Lh=t=>!!t.constructor&&typeof t.constructor.isBuffer=="function"&&t.constructor.isBuffer(t);function Mh(t,e,n){const s=To.match(t,"Grammars");if(s.failed())throw qf(s);return ll(s,e,void 0,n)}function Dh(t,e,n){const s=$h(t,e,n),r=Object.keys(s);if(r.length===0)throw new Error("Missing grammar definition");if(r.length>1){const o=s[r[1]].source;throw new Error(Eo(o.sourceString,o.startIdx)+"Found more than one grammar definition -- use ohm.grammars() instead.")}return s[r[0]]}function $h(t,e,n){const s=Object.create({});if(typeof t!="string")if(Lh(t))t=t.toString();else throw new TypeError("Expected string as first argument, got "+Ao(t));return Mh(t,s,n),s}function Ph(t,e){return Dh(t,e)}const Fh=`FirestoreRules {
|
|
234
|
+
// === Top-level ===
|
|
235
|
+
// Syntactic rules (capitalized) auto-skip spaces between terms.
|
|
236
|
+
// Lexical rules (lowercase) do NOT skip spaces.
|
|
237
|
+
|
|
238
|
+
// Two accepted orderings. Real \`firestore.rules\` files put
|
|
239
|
+
// \`rules_version\` at line 1 (Firebase convention), so the
|
|
240
|
+
// \`versionFirst\` branch matches that natural shape. The
|
|
241
|
+
// \`importsFirst\` branch keeps legacy samples that put \`import\`
|
|
242
|
+
// declarations above the version line working. The semantic
|
|
243
|
+
// action below normalizes both into the same AST shape, so
|
|
244
|
+
// downstream code doesn't have to care which path matched.
|
|
245
|
+
// Declaration order is STRICT: imports, then functions (#347 probe,
|
|
246
|
+
// 2026-07-17): the production Rules Test API rejects \`import\` after a
|
|
247
|
+
// \`function\` ("Unexpected 'import'") and any declaration before
|
|
248
|
+
// \`rules_version\` ("Unexpected 'rules_version'"), under both
|
|
249
|
+
// rules_version '2' and '2+modules'. Pinned by
|
|
250
|
+
// test/rules/corpus/invalid/009-/010-.
|
|
251
|
+
RulesFile = RulesVersion? ImportDecl* FunctionDef* ServiceBlock -- versionFirst
|
|
252
|
+
| ImportDecl* RulesVersion FunctionDef* ServiceBlock -- importsFirst
|
|
253
|
+
|
|
254
|
+
ImportDecl = "import" "{" ListOf<ident, ","> ","? "}" "from" string ";"
|
|
255
|
+
|
|
256
|
+
RulesVersion = "rules_version" "=" string ";"
|
|
257
|
+
|
|
258
|
+
ServiceBlock = "service" serviceName "{" FunctionDef* DocumentsMatch FunctionDef* "}"
|
|
259
|
+
|
|
260
|
+
DocumentsMatch = "match" matchPath "{" MatchBody "}"
|
|
261
|
+
|
|
262
|
+
MatchBody = MatchBodyItem*
|
|
263
|
+
|
|
264
|
+
MatchBodyItem
|
|
265
|
+
= FunctionDef
|
|
266
|
+
| MatchBlock
|
|
267
|
+
| AllowStatement
|
|
268
|
+
|
|
269
|
+
MatchBlock = "match" matchPath "{" MatchBody "}"
|
|
270
|
+
|
|
271
|
+
// === Statements ===
|
|
272
|
+
|
|
273
|
+
AllowStatement = "allow" OperationList ":" "if" Expr ";"
|
|
274
|
+
|
|
275
|
+
OperationList = Operation ("," Operation)*
|
|
276
|
+
|
|
277
|
+
FunctionDef = "export"? "function" ident "(" ParameterList ")" "{" FunctionBody "}"
|
|
278
|
+
|
|
279
|
+
ParameterList = ListOf<ident, ",">
|
|
280
|
+
|
|
281
|
+
FunctionBody = LetBinding* ReturnStatement
|
|
282
|
+
|
|
283
|
+
LetBinding = "let" ident "=" Expr ";"
|
|
284
|
+
|
|
285
|
+
ReturnStatement = "return" Expr ";"
|
|
286
|
+
|
|
287
|
+
// === Lexical: operations and service name ===
|
|
288
|
+
|
|
289
|
+
Operation
|
|
290
|
+
= "read" ~identChar
|
|
291
|
+
| "write" ~identChar
|
|
292
|
+
| "get" ~identChar
|
|
293
|
+
| "list" ~identChar
|
|
294
|
+
| "create" ~identChar
|
|
295
|
+
| "update" ~identChar
|
|
296
|
+
| "delete" ~identChar
|
|
297
|
+
|
|
298
|
+
serviceName = letter (letter | ".")*
|
|
299
|
+
|
|
300
|
+
// === Lexical: match paths ===
|
|
301
|
+
|
|
302
|
+
matchPath = "/" matchPathSegment ("/" matchPathSegment)*
|
|
303
|
+
|
|
304
|
+
matchPathSegment
|
|
305
|
+
= "{" matchWildcard "}" -- wildcard
|
|
306
|
+
| pathIdent -- literal
|
|
307
|
+
|
|
308
|
+
matchWildcard
|
|
309
|
+
= identStart identChar* "=" "**" -- recursive
|
|
310
|
+
| identStart identChar* -- single
|
|
311
|
+
|
|
312
|
+
pathIdent = (letter | digit | "_" | "-" | ".")+
|
|
313
|
+
|
|
314
|
+
// === Expressions ===
|
|
315
|
+
|
|
316
|
+
Expr = Ternary
|
|
317
|
+
|
|
318
|
+
Ternary
|
|
319
|
+
= LogicalOr "?" Ternary ":" Ternary -- ternary
|
|
320
|
+
| LogicalOr
|
|
321
|
+
|
|
322
|
+
LogicalOr
|
|
323
|
+
= LogicalOr "||" LogicalAnd -- or
|
|
324
|
+
| LogicalAnd
|
|
325
|
+
|
|
326
|
+
LogicalAnd
|
|
327
|
+
= LogicalAnd "&&" InIsExpr -- and
|
|
328
|
+
| InIsExpr
|
|
329
|
+
|
|
330
|
+
InIsExpr
|
|
331
|
+
= Equality in Equality -- in
|
|
332
|
+
| Equality is typeName -- is
|
|
333
|
+
| Equality
|
|
334
|
+
|
|
335
|
+
in = "in" ~identChar
|
|
336
|
+
is = "is" ~identChar
|
|
337
|
+
|
|
338
|
+
Equality
|
|
339
|
+
= Equality "==" Comparison -- eq
|
|
340
|
+
| Equality "!=" Comparison -- neq
|
|
341
|
+
| Comparison
|
|
342
|
+
|
|
343
|
+
Comparison
|
|
344
|
+
= Comparison ">=" Additive -- gte
|
|
345
|
+
| Comparison "<=" Additive -- lte
|
|
346
|
+
| Comparison ">" Additive -- gt
|
|
347
|
+
| Comparison "<" Additive -- lt
|
|
348
|
+
| Additive
|
|
349
|
+
|
|
350
|
+
Additive
|
|
351
|
+
= Additive "+" Multiplicative -- add
|
|
352
|
+
| Additive "-" Multiplicative -- sub
|
|
353
|
+
| Multiplicative
|
|
354
|
+
|
|
355
|
+
Multiplicative
|
|
356
|
+
= Multiplicative "*" UnaryExpr -- mul
|
|
357
|
+
| Multiplicative "/" UnaryExpr -- div
|
|
358
|
+
| Multiplicative "%" UnaryExpr -- mod
|
|
359
|
+
| UnaryExpr
|
|
360
|
+
|
|
361
|
+
UnaryExpr
|
|
362
|
+
= "!" UnaryExpr -- not
|
|
363
|
+
| "-" UnaryExpr -- neg
|
|
364
|
+
| PostfixExpr
|
|
365
|
+
|
|
366
|
+
PostfixExpr
|
|
367
|
+
= PostfixExpr "." memberName "(" ListOf<Expr, ","> ")" -- methodCall
|
|
368
|
+
| PostfixExpr "." memberName -- memberAccess
|
|
369
|
+
| PostfixExpr "[" Expr ":" Expr "]" -- sliceAccess
|
|
370
|
+
| PostfixExpr "[" Expr "]" -- bracketAccess
|
|
371
|
+
| Primary
|
|
372
|
+
|
|
373
|
+
memberName = identStart identChar*
|
|
374
|
+
|
|
375
|
+
Primary
|
|
376
|
+
= "(" Expr ")" -- paren
|
|
377
|
+
| PathLiteral -- path
|
|
378
|
+
| ListLiteral -- list
|
|
379
|
+
| MapLiteral -- map
|
|
380
|
+
| ident "(" ListOf<Expr, ","> ")" -- functionCall
|
|
381
|
+
| literal
|
|
382
|
+
| ident
|
|
383
|
+
|
|
384
|
+
// === Path literals ===
|
|
385
|
+
|
|
386
|
+
PathLiteral = "/" PathLitContSegment* PathLitSegment
|
|
387
|
+
|
|
388
|
+
PathLitContSegment
|
|
389
|
+
= "$(" Expr closeParenSlash -- interpolation
|
|
390
|
+
| "{" ident closeBraceSlash -- captureRef
|
|
391
|
+
| parenLiteralSlash -- parenLiteral
|
|
392
|
+
| pathIdentSlash -- literal
|
|
393
|
+
|
|
394
|
+
closeParenSlash = ")" "/"
|
|
395
|
+
closeBraceSlash = "}" "/"
|
|
396
|
+
parenLiteralSlash = "(" pathIdent ")" "/"
|
|
397
|
+
pathIdentSlash = pathIdent "/"
|
|
398
|
+
|
|
399
|
+
PathLitSegment
|
|
400
|
+
= "$(" Expr ")" -- interpolation
|
|
401
|
+
| "{" ident "}" -- captureRef
|
|
402
|
+
| "(" pathIdent ")" -- parenLiteral
|
|
403
|
+
| pathIdent -- literal
|
|
404
|
+
|
|
405
|
+
// === Literals ===
|
|
406
|
+
|
|
407
|
+
literal
|
|
408
|
+
= number
|
|
409
|
+
| bytes
|
|
410
|
+
| string
|
|
411
|
+
| bool
|
|
412
|
+
| null
|
|
413
|
+
|
|
414
|
+
number
|
|
415
|
+
= digit+ "." digit+ -- float
|
|
416
|
+
| digit+ -- int
|
|
417
|
+
|
|
418
|
+
// String and bytes literals share one body rule and one escape rule. A raw
|
|
419
|
+
// line feed or carriage return inside the quotes is a parse error, as in
|
|
420
|
+
// production; a raw tab is a plain character.
|
|
421
|
+
string
|
|
422
|
+
= "'" literalChar<"'", stringEscape>* "'" -- single
|
|
423
|
+
| "\\"" literalChar<"\\"", stringEscape>* "\\"" -- double
|
|
424
|
+
|
|
425
|
+
// Bytes literal: a \`b\` or \`B\` prefix directly before a quoted body. A plain
|
|
426
|
+
// character is its UTF-8 encoding and a hex or octal escape is one byte.
|
|
427
|
+
bytes
|
|
428
|
+
= ("b" | "B") "'" literalChar<"'", literalEscape>* "'" -- single
|
|
429
|
+
| ("b" | "B") "\\"" literalChar<"\\"", literalEscape>* "\\"" -- double
|
|
430
|
+
|
|
431
|
+
literalChar<quote, escape>
|
|
432
|
+
= "\\\\" escape -- escape
|
|
433
|
+
| ~"\\\\" ~quote ~"\\n" ~"\\r" any -- char
|
|
434
|
+
|
|
435
|
+
// \`\\u\` with exactly four hexadecimal digits is one UTF-16 code unit. Only a
|
|
436
|
+
// string literal takes it; production rejects it in a bytes literal.
|
|
437
|
+
stringEscape
|
|
438
|
+
= "u" hexDigit hexDigit hexDigit hexDigit -- unicode
|
|
439
|
+
| literalEscape
|
|
440
|
+
|
|
441
|
+
// The escapes production accepts in both string and bytes literals. \`\\x\`
|
|
442
|
+
// takes exactly two hexadecimal digits and \`\\\` takes three octal digits up
|
|
443
|
+
// to \`\\377\`. In a string each is the code point of that value; in bytes
|
|
444
|
+
// each is one byte. Production rejects every other escape, including \`\\/\`,
|
|
445
|
+
// \`\\a\`, \`\\v\`, \`\\?\`, \`\\0\`, \`\\U\`, and \`\\X\`.
|
|
446
|
+
literalEscape
|
|
447
|
+
= "x" hexDigit hexDigit -- hex
|
|
448
|
+
| "0".."3" "0".."7" "0".."7" -- octal
|
|
449
|
+
| ("\\\\" | "'" | "\\"" | "n" | "r" | "t" | "b" | "f") -- simple
|
|
450
|
+
|
|
451
|
+
ListLiteral = "[" ListOf<Expr, ","> ","? "]"
|
|
452
|
+
|
|
453
|
+
MapLiteral = "{" ListOf<MapEntry, ","> ","? "}"
|
|
454
|
+
|
|
455
|
+
MapEntry = (string | ident) ":" Expr
|
|
456
|
+
|
|
457
|
+
bool
|
|
458
|
+
= "true" ~identChar -- true
|
|
459
|
+
| "false" ~identChar -- false
|
|
460
|
+
|
|
461
|
+
null = "null" ~identChar
|
|
462
|
+
|
|
463
|
+
typeName
|
|
464
|
+
= "string" ~identChar
|
|
465
|
+
| "int" ~identChar
|
|
466
|
+
| "float" ~identChar
|
|
467
|
+
| "number" ~identChar
|
|
468
|
+
| "bool" ~identChar
|
|
469
|
+
| "list" ~identChar
|
|
470
|
+
| "set" ~identChar
|
|
471
|
+
| "map" ~identChar
|
|
472
|
+
| "timestamp" ~identChar
|
|
473
|
+
| "path" ~identChar
|
|
474
|
+
| "bytes" ~identChar
|
|
475
|
+
| "duration" ~identChar
|
|
476
|
+
| "latlng" ~identChar
|
|
477
|
+
| "reference" ~identChar
|
|
478
|
+
|
|
479
|
+
ident = ~keyword identStart identChar*
|
|
480
|
+
|
|
481
|
+
keyword
|
|
482
|
+
= ("true" | "false" | "null" | "in" | "is" | "if" | "return" | "let") ~identChar
|
|
483
|
+
|
|
484
|
+
identStart = letter | "_"
|
|
485
|
+
|
|
486
|
+
identChar = alnum | "_"
|
|
487
|
+
|
|
488
|
+
// === Whitespace and comments ===
|
|
489
|
+
|
|
490
|
+
space += comment
|
|
491
|
+
|
|
492
|
+
comment
|
|
493
|
+
= "//" (~"\\n" any)* &("\\n" | end) -- singleLine
|
|
494
|
+
| "/*" (~"*/" any)* "*/" -- multiLine
|
|
495
|
+
}
|
|
496
|
+
`,hl=new WeakMap;function Ts(t){return hl.get(t)??0}function Ro(t){hl.set(t,Ts(t)+1)}const er=128,pl=new Set(["if","return","in","is","let"]),jh=new Set(["true","false","null"]),Pa=new Set(["group","call","list","map"]),Wn=t=>t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122||t===95||t===36;function ml(t,e){const n=[],s=[];let r=0,i="none",o="",a=!1,c=!1,u="",l=null;const d=t.length;let f=0;const p=()=>{const h=s[s.length-1];h!==void 0&&(h.tail=!0)};for(;f<d;){const h=t.charCodeAt(f);if(h===32||h===9||h===10||h===13){f++;continue}if(e.comments&&h===47){const m=t.charCodeAt(f+1);if(m===47){const g=t.indexOf(`
|
|
497
|
+
`,f+2);f=g===-1?d:g;continue}if(m===42){const g=t.indexOf("*/",f+2);f=g===-1?d:g+2;continue}}if(h!==41&&h!==93&&h!==125&&h!==44&&p(),h===39||h===34){f=Uh(t,f,h,!e.multilineStrings),i="operand",u="";continue}if(e.regexLiterals&&h===47&&i!=="word"&&i!=="operand"){for(f=Bh(t,f);f<d&&Wn(t.charCodeAt(f));)f++;i="operand",u="";continue}if(Wn(h)&&h!==36){const m=f;for(;f<d&&Wn(t.charCodeAt(f));)f++;const g=i==="word"&&o==="function"&&!a&&u==="";o=t.slice(m,f),a=u===".";const y=i;i=h>=48&&h<=57||!a&&jh.has(o)?"operand":"word",c=g&&i==="word"&&!pl.has(o),o==="match"&&!a&&y!=="slash"&&(l=s.length),u="";continue}if(h===36){const m=t.charCodeAt(f+1);if(m!==40&&Wn(m)){const g=f;for(f++;f<d&&Wn(t.charCodeAt(f));)f++;o=t.slice(g,f),a=u===".",i="word",u="";continue}i="dollar",u="$",f++;continue}if(h===40||h===91||h===123){const m=h===40?"(":h===91?"[":"{";let g;m==="{"&&l!==null&&s.length===l?(g="block",i!=="slash"&&(l=null)):g=qh(m,i,o,a),Pa.has(g)&&r++;const b=g==="call"&&c&&u==="",v={char:m,kind:g,open:f,close:-1,depth:s.length+1,levels:r,items:0};b&&(v.declaration=!0),i==="slash"&&(v.afterSlash=!0),c=!1,n.push(v),s.push({span:v,commas:0,tail:!1}),i="other",u=m,f++;continue}if(h===41||h===93||h===125){const m=s.pop();m!==void 0&&(m.span.close=f,m.span.items=m.commas+(m.tail?1:0),Pa.has(m.span.kind)&&r--),h===125&&l!==null&&s.length<l&&(l=null),i="operand",u="",f++;continue}if(h===59&&l!==null&&s.length<=l&&(l=null),h===44){const m=s[s.length-1];m!==void 0&&(m.commas++,m.tail=!1)}i=h===47?"slash":"other",u=t[f],f++}for(const h of s)h.span.items=h.commas+(h.tail?1:0);return n}function qh(t,e,n,s){const r=e==="word"&&(s||!pl.has(n));return t==="("?e==="dollar"?"interpolation":r?s?"method":"call":"group":t==="["?r||e==="operand"?"index":"list":r||e==="operand"||e==="slash"?"block":"map"}function Uh(t,e,n,s){const r=t.length;let i=e+1;for(;i<r;){const o=t.charCodeAt(i);if(o===92){i+=2;continue}if(o===n)return i+1;if(s&&(o===10||o===13))return i;i++}return r}function Bh(t,e){const n=t.length;let s=e+1,r=!1;for(;s<n;){const i=t.charCodeAt(s);if(i===92){s+=2;continue}if(i===10||i===13)return s;if(r){i===93&&(r=!1),s++;continue}if(i===91){r=!0,s++;continue}if(i===47)return s+1;s++}return n}function No(t){let e="",n=0,s=!1,r=!1;for(;n<t.length;){const i=t[n];if(i==="\\"){const o=t[n+1];if(o===void 0){e+="\\";break}if(!s&&o==="A"){e+="^",n+=2;continue}if(!s&&o==="z"){e+="$",n+=2;continue}if((o==="x"||o==="u")&&t[n+2]==="{"){const a=t.indexOf("}",n+3);if(a!==-1){const c=t.slice(n+3,a);if(/^[0-9A-Fa-f]+$/.test(c)){e+=String.fromCodePoint(parseInt(c,16)),n=a+1,r=!1;continue}}}e+=t.slice(n,n+2),n+=2,r=!1;continue}if(s){if(i==="]"&&r){e+="\\]",n++,r=!1;continue}i==="]"&&(s=!1),e+=i,n++,r=!1;continue}if(i==="["){s=!0,e+="[",n++,t[n]==="^"&&(e+="^",n++),r=!0;continue}if(i==="("&&t[n+1]==="?"){const o=t.slice(n+2),a=/^P<([A-Za-z_][A-Za-z0-9_]*)>/.exec(o);if(a){e+=`(?<${a[1]}>`,n+=2+a[0].length;continue}const c=/^([imsU-]+):/.exec(o);if(c){e+="(?:",n+=2+c[0].length;continue}const u=/^([imsU-]+)\)/.exec(o);if(u){const l=t[n+2+u[0].length];if(l==="*"||l==="+"||l==="?"||l==="{")throw new Error("Nothing to repeat after inline flag group");e+="(?:)",n+=2+u[0].length;continue}}e+=i,n++}return e}const ri="\\t\\n\\f\\r ";function zh(t){return`\\x00-\\x08\\x0B\\x0E-\\x1F!-${t?"\\u{10FFFF}":"\\uFFFF"}`}function Mi(t,e){let n="",s=!1,r=0;for(;r<t.length;){const i=t[r];if(i==="\\"&&r+1<t.length){n+=Wh(t[r+1],s,e)??t.slice(r,r+2),r+=2;continue}i==="["?s=!0:i==="]"&&(s=!1),n+=i,r++}return n}function Wh(t,e,n){if(t==="s")return e?ri:`[${ri}]`;if(t==="S")return e?zh(n):`[^${ri}]`}function Vh(t,e){if(e)return t;let n="",s=!1,r=0;for(;r<t.length;){const i=t[r];if(i==="\\"&&r+1<t.length){n+=t.slice(r,r+2),r+=2;continue}i==="["?s=!0:i==="]"&&(s=!1),n+=i==="."&&!s?"[^\\n]":i,r++}return n}function Gh(t){let e=!1,n=!1,s=!1,r=!1,i=!1,o=0;for(;o<t.length;){const c=t[o];if(c==="\\"){const u=t[o+1];if(!e&&u!==void 0&&u>="1"&&u<="9")return{unsupported:"backreference",inlineFlags:""};o+=2,n=!1;continue}if(e){c==="]"&&!n&&(e=!1),n=!1,o++;continue}if(c==="["){e=!0,o++,t[o]==="^"&&o++,n=!0;continue}if(c==="("&&t[o+1]==="?"){const u=t.slice(o+2);if(u.startsWith("=")||u.startsWith("!")||u.startsWith("<=")||u.startsWith("<!"))return{unsupported:"lookaround",inlineFlags:""};const l=/^([imsU-]+)[):]/.exec(u);if(l){let d=!1;for(const f of l[1])f==="-"?d=!0:f==="i"?s=!d:f==="m"?r=!d:f==="s"&&(i=!d)}}o++}return{unsupported:null,inlineFlags:`${s?"i":""}${r?"m":""}${i?"s":""}`}}function Hh(t){let e="",n=0;for(;n<t.length;){const s=t[n];if(s!=="\\"||n+1>=t.length){e+=s,n++;continue}const r=t[n+1],i=t[n+2],o=(r==="p"||r==="P")&&i!==void 0&&/[A-Za-z]/.test(i);e+=o?`\\${r}{${i}}`:t.slice(n,n+2),n+=o?3:2}return e}class I extends Error{expr;constructor(e,n){super(e),this.expr=n,this.name="EvalError"}}class dn extends I{constructor(e,n){super(e,n),this.name="ResourceLimitError"}}class gl extends dn{position;constructor(e,n){super(e),this.position=n,this.name="ExpressionLimitError"}}const Kh="Divide by zero error.";function os(t){return`Function not found error: Name: [${t}].`}class Di extends I{}const me=Symbol.for("pyric.RulesValue.NO_OP");class oe{field(e){return null}callMethod(e,n){return me}binaryOp(e,n){return me}}function Zh(t){const e=t.toExponential();if(e.includes("."))return e;const n=t.toExponential(1);return Number(n)===t?n:e}function Jh(t){if(Number.isNaN(t))return"NaN";if(t===1/0)return"Infinity";if(t===-1/0)return"-Infinity";if(t===0)return Object.is(t,-0)?"-0.0":"0.0";const e=Math.abs(t);if(e>=.001&&e<1e7){const i=String(t);return i.includes(".")?i:`${i}.0`}const[n,s]=Zh(t).split("e");return`${n.includes(".")?n:`${n}.0`}E${Number(s)}`}class te extends oe{typeName="float";value;constructor(e){super(),this.value=e}valueOf(){return this.value}toString(){return Jh(this.value)}toJSON(){return{__type:"float",value:this.value}}equals(e){return e instanceof te?this.value===e.value:typeof e=="number"?this.value===e:!1}binaryOp(e,n){const s=n instanceof te?n.value:typeof n=="number"?n:void 0;if(s===void 0)return me;const r=this.value;switch(e){case"+":return new te(r+s);case"-":return new te(r-s);case"*":return new te(r*s);case"/":return new te(r/s);case"%":return new te(r%s);case"<":return r<s;case"<=":return r<=s;case">":return r>s;case">=":return r>=s;default:return me}}}function Fa(t,e){return Pr(t,e,(n,s)=>n.value===s.value,Mo)}function Lo(t,e){return Pr(t,e,(n,s)=>n.float===s.float&&n.value===s.value,Mo)}function nt(t,e){return Pr(t,e,(n,s)=>n.value===s.value||Number.isNaN(n.value)&&Number.isNaN(s.value),nt)}function Mo(t,e){return Pr(t,e,(n,s)=>n.float===s.float&&n.value===s.value&&Object.is(n.value,s.value),Mo)}function ja(t){if(t instanceof te)return{value:t.value,float:!0};if(typeof t=="number")return{value:t,float:!Number.isInteger(t)}}function Pr(t,e,n,s){const r=ja(t),i=ja(e);if(r||i)return r!==void 0&&i!==void 0&&n(r,i);if(t instanceof oe)return t.equals(e);if(e instanceof oe)return e.equals(t);if(t instanceof ue||e instanceof ue)return t instanceof ue&&t.equals(e);if(Array.isArray(t)||Array.isArray(e))return!Array.isArray(t)||!Array.isArray(e)||t.length!==e.length?!1:t.every((o,a)=>s(o,e[a]));if(Ge(t)||Ge(e)){if(!Ge(t)||!Ge(e))return!1;const o=Object.keys(t);return o.length!==Object.keys(e).length?!1:o.every(a=>Object.hasOwn(e,a)&&s(t[a],e[a]))}return t===e}class ue{items;constructor(e){this.items=[];for(const n of e)this.items.some(s=>nt(s,n))||this.items.push(n)}hasOnly(e){const n=e instanceof ue?e.toArray():e;return this.items.every(s=>n.some(r=>nt(s,r)))}equals(e){return!(e instanceof ue)||e.items.length!==this.items.length?!1:this.items.every(n=>e.items.some(s=>nt(n,s)))}hasAll(e){const n=e instanceof ue?e.toArray():e;for(const s of n)if(!this.items.some(r=>nt(r,s)))return!1;return!0}hasAny(e){const n=e instanceof ue?e.toArray():e;for(const s of n)if(this.items.some(r=>nt(r,s)))return!0;return!1}has(e){return this.items.some(n=>nt(n,e))}size(){return this.items.length}toArray(){return[...this.items]}difference(e){const n=e.toArray(),s=[];for(const r of this.items)n.some(i=>nt(r,i))||s.push(r);return new ue(s)}union(e){const n=e.toArray();return new ue([...this.items,...n])}intersection(e){const n=e.toArray(),s=[];for(const r of this.items)n.some(i=>nt(r,i))&&s.push(r);return new ue(s)}}class on{message;constructor(e){this.message=e}}const Qh=["hasAll","hasAny","hasOnly"],Yh=["difference","intersection","union"],$i=new Set(Yh);function Xh(t){return Qh.includes(t)}function ep(t,e,n){if(e==="size")return n.length!==0?new on(`Incorrect number of arguments. Received: ${n.length}. Expected: set.size().`):t.size();if(Xh(e)){const s=`set.${e}(set), set.${e}(list)`;if(n.length!==1)return new on(`Incorrect number of arguments. Received: ${n.length}. Expected: ${s}.`);const[r]=n;return!Array.isArray(r)&&!(r instanceof ue)?new on(`Unsupported operation error. Received: set.${e}(${J(r)}). Expected: ${s}.`):t[e](r)}if($i.has(e)){const s=e;if(n.length!==1)return new on(`Incorrect number of arguments. Received: ${n.length}. Expected: set.${s}(set).`);const[r]=n;return r instanceof ue?t[s](r):new on(`Unsupported operation error. Received: set.${s}(${J(r)}). Expected: set.${s}(set).`)}return new on(os(e))}class tr{before;after;constructor(e,n){this.before=e,this.after=n}addedKeys(){const e=[];for(const n of Object.keys(this.after))Object.hasOwn(this.before,n)||e.push(n);return new ue(e)}removedKeys(){const e=[];for(const n of Object.keys(this.before))Object.hasOwn(this.after,n)||e.push(n);return new ue(e)}changedKeys(){const e=[];for(const n of Object.keys(this.after))Object.hasOwn(this.before,n)&&!nt(this.before[n],this.after[n])&&e.push(n);return new ue(e)}affectedKeys(){const e=[],n=new Set([...Object.keys(this.before),...Object.keys(this.after)]);for(const s of n)(!Object.hasOwn(this.before,s)||!Object.hasOwn(this.after,s)||!nt(this.before[s],this.after[s]))&&e.push(s);return new ue(e)}unchangedKeys(){const e=[];for(const n of Object.keys(this.before))Object.hasOwn(this.after,n)&&nt(this.before[n],this.after[n])&&e.push(n);return new ue(e)}}function tp(t,e){return bl(yl(t),e)}function mk(t){const e=yl(t);if(e.hasAsserts)return s=>bl(e,s);const n=new sp(e);return s=>n.matches(s)}function yl(t){const e=[{kind:"accept"}],n=o=>{const a=e.length;return e.push(o),a},s=(o,a)=>{switch(o.kind){case"empty":return a;case"char":return n({kind:"char",test:o.test,out:a});case"assert":return n({kind:"assert",check:o.check,out:a});case"seq":{let c=a;for(let u=o.items.length-1;u>=0;u--)c=s(o.items[u],c);return c}case"alt":{const c=s(o.left,a),u=s(o.right,a);return n({kind:"split",out1:c,out2:u})}case"rep":{let c=a;if(o.max===1/0){const u=n({kind:"split",out1:0,out2:a}),l=s(o.body,u);e[u]={kind:"split",out1:l,out2:a},c=u}else for(let u=o.min;u<o.max;u++){const l=s(o.body,c);c=n({kind:"split",out1:l,out2:c})}for(let u=o.min-1;u>=0;u--)c=s(o.body,c);return c}}},r=s(t,0),i=e.some(o=>o.kind==="assert");return{states:e,start:r,hasAsserts:i}}function bl(t,e){const n=new wl(t.states);let s=n.of([t.start],e,0);for(let r=0;r<e.length&&s.length>0;r++)s=n.of(vl(t.states,s,e[r]),e,r+1);return s.includes(0)}function vl(t,e,n){const s=[];for(const r of e){const i=t[r];i.kind==="char"&&i.test(n)&&s.push(i.out)}return s}class wl{states;marks;mark=0;constructor(e){this.states=e,this.marks=new Uint32Array(e.length)}of(e,n,s){this.nextMark();const r=[...e],i=[];for(;r.length>0;){const o=r.pop();if(this.marks[o]===this.mark)continue;this.marks[o]=this.mark;const a=this.states[o];a.kind==="split"?r.push(a.out1,a.out2):a.kind==="assert"?a.check(n,s)&&r.push(a.out):i.push(o)}return i}nextMark(){this.mark++,this.mark===4294967295&&(this.marks.fill(0),this.mark=1)}}const np=1<<22,qa=[];class sp{nfa;closure;sets=[];accepting=[];transitions=[];index=new Map;stored=0;start=0;constructor(e){this.nfa=e,this.closure=new wl(e.states),this.reset()}matches(e){let n=this.start;for(const s of e)if(n=this.step(n,s),this.sets[n].length===0)return!1;return this.accepting[n]}step(e,n){const s=this.transitions[e].get(n);if(s!==void 0)return s;const r=this.closure.of(vl(this.nfa.states,this.sets[e],n),qa,0);if(this.stored+r.length+1>np)return this.reset(),this.intern(r);const i=this.intern(r);return this.transitions[e].set(n,i),this.stored++,i}intern(e){e.sort((i,o)=>i-o);const n=e.join(","),s=this.index.get(n);if(s!==void 0)return s;const r=this.sets.length;return this.sets.push(e),this.accepting.push(e.includes(0)),this.transitions.push(new Map),this.index.set(n,r),this.stored+=e.length,r}reset(){this.sets=[],this.accepting=[],this.transitions=[],this.index=new Map,this.stored=0,this.start=this.intern(this.closure.of([this.nfa.start],qa,0))}}const gk=2147483647,ls=1e4,Zt=2e5,Ua=1e3;function yk(t){return`For input string: "${t}"`}const rp="Illegal regular expression, could not determinize efficiently",ip=`Regular expression expands to more than ${Zt} matcher states: pyric matches at most ${Zt}, a limit of pyric, not of production.`,bk=`Regular expression groups and quantifiers nest more than ${Ua} levels deep: pyric reads at most ${Ua}, a limit of pyric, not of production.`;function op(t){return Xn(t)>ls?rp:es(t)>Zt?ip:null}function Xn(t){switch(t.kind){case"empty":return 0;case"char":case"assert":return 1;case"seq":return fn(t.items.map(Xn),ls);case"alt":return fn([Xn(t.left),Xn(t.right)],ls);case"rep":return ap(Xn(t.body),t.min,t.max)}}function ap(t,e,n){if(n===0||t===0)return 0;if(t===1/0)return 1/0;const s=n===1/0?e+1:n;return fn([t*s],ls)}function es(t){switch(t.kind){case"empty":return 0;case"char":case"assert":return 1;case"seq":return fn(t.items.map(es),Zt);case"alt":return fn([es(t.left),es(t.right),1],Zt);case"rep":return cp(es(t.body),t.min,t.max)}}function cp(t,e,n){return n===0?0:t===1/0?1/0:fn(n===1/0?[t*(e+1),1]:[(n-e)*(t+1),e*t],Zt)}function fn(t,e){let n=0;for(const s of t)if(n+=s,n>e)return 1/0;return n}function Ge(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function J(t){return t===null?"null":t===void 0?"undefined":t instanceof oe?t.typeName:t instanceof ue?"set":t instanceof tr?"map_diff":typeof t=="number"?Number.isInteger(t)?"int":"float":typeof t=="boolean"?"bool":Array.isArray(t)?"list":Ge(t)?"map":typeof t}function Ps(t,e){if(e<0||e>=t.length)return!1;const n=t[e];if(n.length!==1)return!1;const s=n.charCodeAt(0);return s>=48&&s<=57||s>=65&&s<=90||s>=97&&s<=122||s===95}function Sl(t){return`Invalid regular expression pattern. Pattern: ${t}.`}function Al(t,e){return op(e)===null?null:`${Sl(t)} pyric refuses patterns that expand past ${ls.toLocaleString("en-US")} characters or ${Zt.toLocaleString("en-US")} matcher states, a limit of pyric; production's limit has not been measured.`}function up(t){const e=$o(t),n=Al(t,e);if(n!==null)throw new Error(n);return e}function Do(t,e,n,s){const{unsupported:r,inlineFlags:i}=Gh(e);if(r!==null)throw new Error(`${t}() pattern uses an RE2-unsupported construct (${r}) that production would reject`);const o=[...new Set(`${s??""}${i}`)].join(""),a=Mi(No(n),!1);let c;try{c=new RegExp(Vh(a,o.includes("s")),o)}catch(u){throw new Error(`Invalid regex '${e}' in ${t}(): ${u.message}`)}return up(e),c}function lp(t,e){Do("matches",t,`^(?:${t})$`);const n=$o(t);return tp(n,Array.from(e))}function qt(t,e){let n="u";e&&(n="iu");try{const s=new RegExp(`^${Mi(Hh(t),!0)}$`,n);return r=>s.test(r)}catch{const s=e?"i":"",r=new RegExp(`^${Mi(t,!1)}$`,s);return i=>r.test(i)}}function $o(t){let e=0,n=!1,s=!1,r=!1;const i=d=>{let f=!1;for(const p of d)p==="-"?f=!0:p==="i"?n=!f:p==="m"?s=!f:p==="s"&&(r=!f)},o=()=>{let d=a();for(;e<t.length&&t[e]==="|";){e++;const f=a();d={kind:"alt",left:d,right:f}}return d},a=()=>{const d=[];for(;e<t.length&&t[e]!=="|"&&t[e]!==")";)d.push(c());return d.length===0?{kind:"empty"}:d.length===1?d[0]:{kind:"seq",items:d}},c=()=>{let d=l();for(;e<t.length;){const f=t[e];if(f==="*"||f==="+"||f==="?"){e++,e<t.length&&t[e]==="?"&&e++;let p=0,h=1/0;f==="+"?p=1:f==="?"&&(h=1),d={kind:"rep",body:d,min:p,max:h}}else if(f==="{"){const p=/^\{(\d+)(?:,(\d*))?\}/.exec(t.slice(e));if(!p)break;e+=p[0].length,e<t.length&&t[e]==="?"&&e++;const h=Number(p[1]);let m=h;if(p[2]!==void 0&&(m=p[2]===""?1/0:Number(p[2])),h>m||h>1e3||m!==1/0&&m>1e3)throw new Error(`Invalid repeat count in '${t}'`);d={kind:"rep",body:d,min:h,max:m}}else break}return d},u=(d,f)=>{if(f){const p=d.toLowerCase(),h=d.toUpperCase();return{kind:"char",test:m=>m===p||m===h}}return{kind:"char",test:p=>p===d}},l=()=>{const d=t[e];if(d==="("){e++;const h=n,m=s,g=r;if(t[e]==="?")if(e++,t[e]===":")e++;else if(t[e]==="<"||t[e]==="P"&&t[e+1]==="<")e=t.indexOf(">",e)+1;else{const b=/^[imsU-]+/.exec(t.slice(e));if(b){if(i(b[0]),e+=b[0].length,t[e]===")")return e++,{kind:"empty"};t[e]===":"&&e++}}const y=o();return t[e]===")"&&e++,n=h,s=m,r=g,y}if(d==="["){const h=e;for(e++,t[e]==="^"&&e++,t[e]==="]"&&e++;e<t.length&&t[e]!=="]";)t[e]==="\\"?e+=2:e++;t[e]==="]"&&e++;const m=No(t.slice(h,e));return{kind:"char",test:qt(m,n)}}if(d==="^"){e++;const h=s;return{kind:"assert",check:(m,g)=>g===0||h&&g>0&&m[g-1]===`
|
|
498
|
+
`}}if(d==="$"){e++;const h=s;return{kind:"assert",check:(m,g)=>g===m.length||h&&g<m.length&&m[g]===`
|
|
499
|
+
`}}if(d==="."){e++;const h=r;return{kind:"char",test:m=>h||m!==`
|
|
500
|
+
`}}if(d==="\\"){const h=e;e++;const m=t[e];if(m==="b")return e++,{kind:"assert",check:(b,v)=>Ps(b,v-1)!==Ps(b,v)};if(m==="B")return e++,{kind:"assert",check:(b,v)=>Ps(b,v-1)===Ps(b,v)};if(m==="A")return e++,{kind:"assert",check:(b,v)=>v===0};if(m==="z")return e++,{kind:"assert",check:(b,v)=>v===b.length};if((m==="x"||m==="u")&&t[e+1]==="{"){const b=t.indexOf("}",e+2),v=t.slice(e+2,b);return e=b+1,u(String.fromCodePoint(parseInt(v,16)),n)}if((m==="p"||m==="P")&&/[A-Za-z]/.test(t[e+1]??""))return e+=2,{kind:"char",test:qt(`\\${m}{${t[e-1]}}`,n)};if((m==="p"||m==="P")&&t[e+1]==="{"){e=t.indexOf("}",e+2)+1;const v=t.slice(h,e);return{kind:"char",test:qt(v,n)}}if(m==="d"||m==="D"||m==="w"||m==="W"||m==="s"||m==="S"||m==="t"||m==="n"||m==="r"||m==="v"||m==="f"){e++;const b=t.slice(h,e);return{kind:"char",test:qt(b,n)}}if(m==="x")return e+=3,{kind:"char",test:qt(t.slice(h,e),n)};if(m==="u")return e+=5,{kind:"char",test:qt(t.slice(h,e),n)};if(m==="c")return e+=2,{kind:"char",test:qt(t.slice(h,e),n)};if(m>="0"&&m<="7"){const b=/^[0-7]{1,3}/.exec(t.slice(e));return e+=b[0].length,{kind:"char",test:qt(t.slice(h,e),n)}}const g=t.codePointAt(e),y=String.fromCodePoint(g);return e+=y.length,u(y,n)}const f=t.codePointAt(e),p=String.fromCodePoint(f);return e+=p.length,u(p,n)};return o()}function kl(t){const e=new RegExp(`${t.source}|`).exec("");return e===null?0:e.length-1}function dp(t,e,n){const s=Do("replace",e,e,"g"),r=kl(s);return t.replace(s,(...i)=>{const o=i.slice(0,r+1),a=i[i.length-1];let c={};return typeof a=="object"&&a!==null&&(c=a),fp(n,o,c)})}function fp(t,e,n){const s=e.length-1;let r="",i=0;for(;i<t.length;){const o=t[i];if(o==="\\"){if(i+1>=t.length)throw new Error("replace() replacement ends with an escape character");r+=t[i+1],i+=2;continue}if(o!=="$"){r+=o,i+=1;continue}const a=t[i+1];if(a==="{"){const l=t.indexOf("}",i+2);if(l===-1)throw new Error(`replace() replacement has an unclosed group name: ${t.slice(i)}`);const d=t.slice(i+2,l);if(!Object.hasOwn(n,d))throw new Error(`replace() replacement names no group: ${t.slice(i,l+1)}`);r+=n[d]??"",i=l+1;continue}if(a===void 0||a<"0"||a>"9")throw new Error(`replace() replacement has an illegal group reference: ${t.slice(i)}`);let c=Number(a),u=i+2;for(;u<t.length&&t[u]>="0"&&t[u]<="9";){const l=c*10+Number(t[u]);if(l>s)break;c=l,u+=1}if(c>s)throw new Error(`replace() replacement names group ${c}, but the pattern has ${s}`);r+=e[c]??"",i=u}return r}function hp(t){const e=Sl(t);if(/\\[1-9]/.test(t)||/\(\?<?[=!]/.test(t))return e;try{const n=Al(t,$o(t));return n!==null?n:(new RegExp(`^(?:${No(t)})$`),null)}catch{return e}}const ts=21,El=11,Po=99,pp="Maximum allowed variable count of 10 for a given function has been reached.",Il="Expression is too complex to evaluate safely.",_l="Missing 'match' keyword before path.",mp="Invalid glob match expression. Only one glob match is permitted in a match declaration path.";function gp(t){return`Maximum allowed call depth of 20 is reached for [${t.join("->")}] call stack.`}function yp(t){return`Function ${t} is already defined.`}function xl(t){const e=Ap(t),n=[],s=t.service.name!=="firebase.storage";t.version!=="1"&&t.version!=="2"&&t.version!=="2+modules"?n.push({code:"UNSUPPORTED_RULES_VERSION",message:`Unsupported rules version ${t.version}.`,line:t.loc?.line??1}):s&&(t.version==="2+modules"||(t.imports?.length??0)>0)&&n.push({code:"UNRESOLVED_MODULES",message:"Rules source uses '2+modules' or import statements that must be resolved before compilation.",line:t.loc?.line??1});for(const i of e){const o=i.fn;if(o.lets.length>El){const a=o.returnLoc??o.loc;n.push({code:"LET_LIMIT",message:pp,...Fr(a),...o.returnLoc===void 0?{}:{column:o.returnLoc.col},functionName:o.name})}for(const a of o.lets)ii(n,a.value,a.loc?.line??o.loc?.line,o.name),Ws(n,a.value,a.loc?.line??o.loc?.line,s,o.name);ii(n,o.body,o.loc?.line,o.name),Ws(n,o.body,o.returnLoc?.line??o.loc?.line,s,o.name)}const r=i=>{for(const o of i.allows)ii(n,o.condition,o.loc?.line),Ws(n,o.condition,o.loc?.line,s);for(const o of i.children)r(o)};return r(t.service.match),n.push(...kp(e)),n.push(...bp(t)),n.push(...Cl(t.service.match,0)),n.sort((i,o)=>(i.line??0)-(o.line??0))}function Cl(t,e){const n=t.path.segments.filter(r=>r.type==="recursive").length,s=n>0&&e+n>1?[{code:"GLOB_MATCH_COUNT",message:mp,...Fr(t.loc)}]:[];for(const r of t.children)s.push(...Cl(r,e+n));return s}function bp(t){const e=[],n=(r,i)=>{const o=new Set;for(const a of r)o.has(a.name)&&e.push({code:"FUNCTION_REDEFINED",message:yp(a.name),...Fr(a.loc),functionName:a.name,scope:i}),o.add(a.name)},s=r=>{n(r.functions,r.path.raw);for(const i of r.children)s(i)};return n(t.functions??[],"global scope"),n(t.service.functions??[],`service ${t.service.name}`),s(t.service.match),e}function vp(t){return t.map(e=>e.line===void 0?e.message:`Line ${e.line}: ${e.message}`).join(" ")}function Fr(t){return t===void 0?{}:{line:t.line}}function ii(t,e,n,s){const r=wp(e);for(let i=0;i<r;i++)t.push({code:"NESTING_DEPTH",message:Il,...n===void 0?{}:{line:n},...s===void 0?{}:{functionName:s}})}function Ws(t,e,n,s,r){if(e.type==="binaryOp"&&e.slashStartsPath&&t.push({code:"SLASH_STARTS_PATH",message:_l,...n===void 0?{}:{line:n},...r===void 0?{}:{functionName:r}}),s&&e.type==="methodCall"&&e.method==="matches"&&e.args.length===1){const i=e.args[0],o=i?.type==="literal"&&typeof i.value=="string"?hp(i.value):null;o!==null&&t.push({code:"INVALID_REGEX_PATTERN",message:o,...n===void 0?{}:{line:n},...r===void 0?{}:{functionName:r}})}for(const i of Fo(e))Ws(t,i,n,s,r)}function wp(t){return Ol(t,1)}function Ba(t,e,n){for(let s=e;s<n;s++){const r=t.charCodeAt(s);if(r!==32&&r!==9&&r!==10&&r!==13)return!1}return!0}function za(t){const e=ml(t,{comments:!0,regexLiterals:!1,multilineStrings:!1});let n,s,r=-1;for(let i=0;i<e.length;i++){const o=e[i];if(o.open<r)continue;if(o.depth>er)return{offset:o.open,expected:`brackets nested at most ${er} levels deep`};if(o.levels<Po||o.items===0)continue;const a=o.close===-1?t.length:o.close,c=t.slice(o.open+1,a),u=o.kind==="map"?"a:1":"1",l=Array.from({length:o.items},()=>u).join(",");if(c.replace(/[\n\r]/g,"").length<l.length)continue;let d=0;const f=c.replace(/[^\n\r]/g,()=>d<l.length?l[d++]:" ");if(n??=[],n.push(t.slice(Math.max(r,0),o.open+1),f),r=a===t.length?1/0:a,o.close!==-1){let p=i;for(;p+1<e.length;){const g=e[p],y=e[p+1],b=(g.kind==="group"||g.kind==="list")&&g.items===1,v=y.close!==-1&&y.open>g.open&&y.close<g.close,w=(y.kind==="group"||y.kind==="list"||y.kind==="map")&&y.items>=1;if(!b||!v||!w||!Ba(t,g.open+1,y.open)||!Ba(t,y.close+1,g.close))break;p++}const h=e[p];let m=t.slice(h.open,h.close+1);h.kind==="call"&&(m=`[${t.slice(h.open+1,h.close)}]`),s??=[],s.push({offset:h.open,text:m})}}return n===void 0?{source:t}:(r!==1/0&&n.push(t.slice(r)),{source:n.join(""),...s===void 0?{}:{elided:s}})}function Ol(t,e){const n=e+Ts(t);if(n>Po)return 1;const s=Sp(t)?n+1:n;let r=0;for(const i of Fo(t))r+=Ol(i,s);return r}function Sp(t){switch(t.type){case"binaryOp":case"inExpr":case"isExpr":case"listLiteral":case"mapLiteral":case"functionCall":return!0;default:return!1}}function Fo(t){switch(t.type){case"literal":case"identifier":return[];case"memberAccess":return[t.object];case"methodCall":return[t.object,...t.args];case"bracketAccess":return[t.object,t.index];case"sliceAccess":return[t.object,t.start,t.end];case"binaryOp":return[t.left,t.right];case"unaryOp":return[t.operand];case"ternary":return[t.condition,t.consequent,t.alternate];case"inExpr":return[t.element,t.collection];case"isExpr":return[t.value];case"listLiteral":return t.elements;case"mapLiteral":return t.entries.flatMap(e=>[e.key,e.value]);case"pathLiteral":return t.segments.filter(e=>typeof e!="string");case"functionCall":return t.args}}function Ap(t){const e=[],n=[],s=(o,a)=>{const c={names:new Map,parent:a};for(const u of o){const l={fn:u,callees:[]};e.push(l),c.names.set(u.name,l),n.push({node:l,scope:c})}return c},r=s(t.service.functions??[],s(t.functions??[],void 0)),i=(o,a)=>{const c=s(o.functions,a);for(const u of o.children)i(u,c)};i(t.service.match,r);for(const{node:o,scope:a}of n){const c=new Set,u=l=>{if(l.type==="functionCall")for(let d=a;d;d=d.parent){const f=d.names.get(l.name);if(f!==void 0){c.has(f)||(c.add(f),o.callees.push(f));break}}for(const d of Fo(l))u(d)};for(const l of o.fn.lets)u(l.value);u(o.fn.body)}return e}function kp(t){const e=new Map,n=new Set,s=u=>{const l=e.get(u);if(l!==void 0)return l;if(n.has(u))return 1/0;n.add(u);let d=0;for(const f of u.callees)d=Math.max(d,s(f));return n.delete(u),e.set(u,d+1),d+1},r=new Set;for(const u of t)for(const l of u.callees)l!==u&&r.add(l);const i=new Set,o=u=>{if(!i.has(u)){i.add(u);for(const l of u.callees)o(l)}},a=[];for(const u of t)r.has(u)||(a.push(u),o(u));for(const u of t)i.has(u)||s(u)!==1/0||(a.push(u),o(u));const c=[];for(const u of a){if(s(u)<=ts)continue;const l=[u];for(;l.length<=ts;){const f=l[l.length-1];let p=f.callees[0];for(const h of f.callees)s(h)>s(p)&&(p=h);l.push(p)}const d=l[ts];c.push({code:"CALL_DEPTH",message:gp(l.slice(0,ts).map(f=>f.fn.name)),...Fr(d.fn.loc),functionName:d.fn.name})}return c}const ds=new WeakMap;function An(t){return ds.get(t)}function Ep(t,e){ds.set(t,e)}const nr=new WeakMap;function Tl(t){return nr.get(t)??ds.get(t)}function Rl(t,e){nr.set(t,e)}function vk(t,e){const n=ds.get(t);n!==void 0&&ds.set(e,n);const s=nr.get(t);s!==void 0&&nr.set(e,s)}function Ip(t){return`line ${t.line}, column ${t.column}`}class Nl{lineOffset;firstLineColumnOffset;lineStarts=[0];constructor(e,n,s){this.lineOffset=n,this.firstLineColumnOffset=s;for(let r=0;r<e.length;r++)e.charCodeAt(r)===10&&this.lineStarts.push(r+1)}at(e){let n=0,s=this.lineStarts.length-1;for(;n<s;){const i=n+s+1>>1;this.lineStarts[i]<=e?n=i:s=i-1}const r=e-this.lineStarts[n]+1;return{line:n+1+this.lineOffset,column:n===0?r+this.firstLineColumnOffset:r}}}const jo=24,Nn="ǂǂ",hn=`${Nn}wǂ`,_p=t=>t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122||t===95||t===450;function Pi(t,e){if(!(t.length<=e.length)&&!/[\n\r]/.test(t.slice(0,e.length)))return e+t.slice(e.length).replace(/[^\n\r]/g," ")}function xp(t,e,n){if(e.close===-1)return;let s=32;switch(e.open>0&&(s=t.charCodeAt(e.open-1)),e.kind){case"group":case"list":case"map":{if(e.afterSlash||s===47||e.items===0)return;const r=t.slice(e.open,e.close+1),i=Pi(r,_p(s)?` ${n}`:n);return i===void 0?void 0:{name:n,kind:"expr",start:e.open,original:r,replacement:i,text:r,prefix:0}}case"interpolation":case"call":case"method":case"index":{if(e.items===0||e.declaration)return;const r=t.slice(e.open+1,e.close),i=Pi(` ${r}`,` ${n}`)?.slice(1);if(i===void 0)return;if(e.kind==="interpolation")return{name:n,kind:"expr",start:e.open+1,original:r,replacement:i,text:r,prefix:0};const o=e.kind==="index"?"index":"args",a=`${hn}${t.slice(e.open,e.close+1)}`;return{name:n,kind:o,start:e.open+1,original:r,replacement:i,text:a,prefix:hn.length+1}}default:return}}function Cp(t,e=jo){if(t.indexOf(Nn,t.startsWith(hn)?hn.length:0)!==-1)return;const n=Math.max(e,2),s=ml(t,{comments:!0,regexLiterals:!1,multilineStrings:!1}),r=[],i=[];let o=0;for(const a of s){if(a.depth<n||a.open<o)continue;const c=xp(t,a,`${Nn}${r.length}ǂ`);c!==void 0&&(i.push(t.slice(o,c.start),c.replacement),o=c.start+c.original.length,r.push(c))}if(r.length!==0)return i.push(t.slice(o)),{text:i.join(""),segments:r}}function fs(t){if(typeof t!="object"||t===null)return;const e=t;if(!(e.type!=="identifier"||typeof e.name!="string"||!e.name.startsWith(Nn)))return e.name===hn?void 0:e.name}function Wa(t){return t.type==="identifier"&&t.name===hn}function Op(t){return fs(t)!==void 0}function Tp(t,e){const n=new Set,s=new WeakSet,r=c=>e.get(c)?.segment.kind,i=(c,u)=>{const l=e.get(c);if(!(l===void 0||l.segment.kind!==u||n.has(c)))return n.add(c),s.add(l.ast),l},o=fs(t);if(o!==void 0){const c=i(o,"expr");return c===void 0||n.size!==e.size?void 0:Va(t,c.ast)}const a=[t];for(;a.length>0;){const c=a.pop();if(!(s.has(c)||ArrayBuffer.isView(c))){if(!Rp(c,r,i)||c.type==="pathLiteral"&&!Np(c,e))return;for(const u of Object.keys(c)){const l=c[u];if(typeof l!="object"||l===null)continue;const d=fs(l);if(d===void 0){a.push(l);continue}if(u==="key"&&"value"in c&&!("type"in c))return;const f=i(d,"expr");if(f===void 0)return;c[u]=Va(l,f.ast)}}}return n.size===e.size?t:void 0}function Va(t,e){const n=Ts(t);for(let r=0;r<n;r++)Ro(e);const s=Tl(t);return n>0&&s!==void 0&&e.type==="binaryOp"&&e.op==="&&"&&Rl(e,s),e}function Rp(t,e,n){if(t.type==="functionCall"||t.type==="methodCall"){const s=t.args;if(s.length!==1)return!0;const r=fs(s[0]);if(r===void 0||e(r)!=="args")return!0;const i=n(r,"args")?.ast;return i===void 0||i.type!=="functionCall"||i.name!==hn?!1:(t.args=i.args,!0)}if(t.type==="bracketAccess"){const s=fs(t.index);if(s===void 0||e(s)!=="index")return!0;const r=n(s,"index")?.ast;return r===void 0?!1:r.type==="bracketAccess"&&Wa(r.object)?(t.index=r.index,!0):r.type==="sliceAccess"&&Wa(r.object)?(delete t.index,t.type="sliceAccess",t.start=r.start,t.end=r.end,!0):!1}return!0}function Np(t,e){let n=t.raw;if(!n.includes(Nn))return!0;for(const{segment:s}of e.values())n.includes(s.name)&&(n=n.split(s.replacement).join(s.original));return t.raw=n,!n.includes(Nn)}function Lp(t){return t.length<4||/[\n\r]/.test(t.slice(-2))?Pi(t,"(!1)"):`(!${t.slice(2,-2).replace(/[^\n\r]/g," ")}1)`}function Mp(t,e){const n=[];let s=0;for(const r of e){let i;r.kind==="expr"&&(i=Lp(r.original)),n.push(t.slice(s,r.start),i??r.replacement),s=r.start+r.original.length}return n.push(t.slice(s)),n.join("")}function Ll(t,e,n,s=0,r=0,i=jo){const o=Cp(t,i);if(o===void 0)return n(t,e,s,r);const a=n(o.text,e,s,r);if(!a.ok)return a;const c=new Map;for(const l of o.segments){const d=s+l.start-r,f=Ll(l.text,"Expr",n,d,l.prefix,i);if(!f.ok)return f;c.set(l.name,{segment:l,ast:f.ast})}const u=Tp(a.ast,c);if(u===void 0){const l=n(Mp(t,o.segments),e,s,r);return l.ok?n(t,e,s,r):l}return{ok:!0,ast:u}}const Fi=Ph(Fh),Ml=Fi.createSemantics();let Nt=null;function H(t,e){return Nt!==null&&Ep(t,Nt.at(e.source.startIdx)),t}function Ga(t,e){return Nt!==null&&Rl(t,Nt.at(e.source.startIdx)),t}Ml.addOperation("toAST",{RulesFile_versionFirst(t,e,n,s){return{imports:e.children.map(r=>r.toAST()),version:t.children.length>0?t.children[0].toAST():"1",functions:n.children.map(r=>r.toAST()),service:s.toAST()}},RulesFile_importsFirst(t,e,n,s){return{imports:t.children.map(r=>r.toAST()),version:e.toAST(),functions:n.children.map(r=>r.toAST()),service:s.toAST()}},ImportDecl(t,e,n,s,r,i,o,a){const{lineNum:c,colNum:u}=t.source.getLineAndColumn();return{functions:n.asIteration().children.map(l=>l.sourceString),module:o.toAST().value,loc:{line:c,col:u}}},RulesVersion(t,e,n,s){return n.toAST().value},ServiceBlock(t,e,n,s,r,i,o){const{lineNum:a,colNum:c}=t.source.getLineAndColumn();return{name:e.sourceString,functions:[...s.children.map(u=>u.toAST()),...i.children.map(u=>u.toAST())],match:r.toAST(),loc:{line:a,col:c}}},DocumentsMatch(t,e,n,s,r){const{lineNum:i,colNum:o}=t.source.getLineAndColumn();return{...s.toAST(),path:Za(e.sourceString),loc:{line:i,col:o}}},MatchBody(t){const e=[],n=[],s=[];for(const r of t.children){const i=r.toAST();i._kind==="function"?e.push(i):i._kind==="allow"?n.push(i):i._kind==="match"&&s.push(i)}return{functions:e,allows:n,children:s}},MatchBodyItem(t){return t.toAST()},MatchBlock(t,e,n,s,r){const{functions:i,allows:o,children:a}=s.toAST(),{lineNum:c,colNum:u}=t.source.getLineAndColumn();return{_kind:"match",path:Za(e.sourceString),functions:i,allows:o,children:a,loc:{line:c,col:u}}},AllowStatement(t,e,n,s,r,i){const{lineNum:o,colNum:a}=t.source.getLineAndColumn();return{_kind:"allow",operations:e.toAST(),condition:r.toAST(),loc:{line:o,col:a}}},OperationList(t,e,n){return[t.toAST(),...n.children.map(s=>s.toAST())]},Operation(t){return t.sourceString},FunctionDef(t,e,n,s,r,i,o,a,c){const{lets:u,expr:l,returnLoc:d}=a.toAST(),{lineNum:f,colNum:p}=e.source.getLineAndColumn();return{_kind:"function",name:n.sourceString,parameters:r.toAST(),exported:t.sourceString.trim()==="export",lets:u,body:l,returnLoc:d,loc:{line:f,col:p}}},ParameterList(t){return t.asIteration().children.map(e=>e.sourceString)},FunctionBody(t,e){const{lineNum:n,colNum:s}=e.child(1).source.getLineAndColumn();return{lets:t.children.map(r=>r.toAST()),expr:e.toAST(),returnLoc:{line:n,col:s}}},LetBinding(t,e,n,s,r){const{lineNum:i,colNum:o}=t.source.getLineAndColumn();return H({name:e.sourceString,value:s.toAST(),loc:{line:i,col:o}},this)},ReturnStatement(t,e,n){return e.toAST()},Expr(t){return t.toAST()},Ternary_ternary(t,e,n,s,r){return H({type:"ternary",condition:t.toAST(),consequent:n.toAST(),alternate:r.toAST()},this)},LogicalOr_or(t,e,n){return H({type:"binaryOp",op:"||",left:t.toAST(),right:n.toAST()},e)},LogicalAnd_and(t,e,n){return Ga(H({type:"binaryOp",op:"&&",left:t.toAST(),right:n.toAST()},e),this)},InIsExpr_in(t,e,n){return H({type:"inExpr",element:t.toAST(),collection:n.toAST()},e)},InIsExpr_is(t,e,n){return H({type:"isExpr",value:t.toAST(),typeName:n.sourceString},e)},Equality_eq(t,e,n){return H({type:"binaryOp",op:"==",left:t.toAST(),right:n.toAST()},e)},Equality_neq(t,e,n){return H({type:"binaryOp",op:"!=",left:t.toAST(),right:n.toAST()},e)},Comparison_gte(t,e,n){return H({type:"binaryOp",op:">=",left:t.toAST(),right:n.toAST()},e)},Comparison_lte(t,e,n){return H({type:"binaryOp",op:"<=",left:t.toAST(),right:n.toAST()},e)},Comparison_gt(t,e,n){return H({type:"binaryOp",op:">",left:t.toAST(),right:n.toAST()},e)},Comparison_lt(t,e,n){return H({type:"binaryOp",op:"<",left:t.toAST(),right:n.toAST()},e)},Additive_add(t,e,n){return H({type:"binaryOp",op:"+",left:t.toAST(),right:n.toAST()},e)},Additive_sub(t,e,n){return H({type:"binaryOp",op:"-",left:t.toAST(),right:n.toAST()},e)},Multiplicative_mul(t,e,n){return H({type:"binaryOp",op:"*",left:t.toAST(),right:n.toAST()},e)},Multiplicative_div(t,e,n){const s=e.source,r=s.sourceString.charAt(s.endIdx);return H({type:"binaryOp",op:"/",left:t.toAST(),right:n.toAST(),.../\s/.test(r)?{}:{slashStartsPath:!0}},e)},Multiplicative_mod(t,e,n){return H({type:"binaryOp",op:"%",left:t.toAST(),right:n.toAST()},e)},UnaryExpr_not(t,e){return H({type:"unaryOp",op:"!",operand:e.toAST()},this)},UnaryExpr_neg(t,e){return H({type:"unaryOp",op:"-",operand:e.toAST()},this)},PostfixExpr_methodCall(t,e,n,s,r,i){return H({type:"methodCall",object:t.toAST(),method:n.sourceString,args:r.asIteration().children.map(o=>o.toAST())},this)},PostfixExpr_memberAccess(t,e,n){return H({type:"memberAccess",object:t.toAST(),property:n.sourceString},this)},PostfixExpr_bracketAccess(t,e,n,s){return H({type:"bracketAccess",object:t.toAST(),index:n.toAST()},this)},PostfixExpr_sliceAccess(t,e,n,s,r,i){return H({type:"sliceAccess",object:t.toAST(),start:n.toAST(),end:r.toAST()},this)},Primary_paren(t,e,n){const s=e.toAST();return Ro(s),(s.type==="binaryOp"&&s.op==="&&"||Op(s))&&Ga(s,this),s},Primary_path(t){return t.toAST()},Primary_list(t){return t.toAST()},Primary_map(t){return t.toAST()},Primary_functionCall(t,e,n,s){return H({type:"functionCall",name:t.sourceString,args:n.asIteration().children.map(r=>r.toAST())},this)},PathLiteral(t,e,n){const s=[];for(const r of e.children)s.push(r.toAST());return s.push(n.toAST()),H({type:"pathLiteral",raw:this.sourceString,segments:s},this)},PathLitContSegment_interpolation(t,e,n){return e.toAST()},PathLitContSegment_captureRef(t,e,n){return`{${e.sourceString}}`},PathLitContSegment_parenLiteral(t){return t.sourceString.slice(0,-1)},PathLitContSegment_literal(t){return t.sourceString.slice(0,-1)},PathLitSegment_interpolation(t,e,n){return e.toAST()},PathLitSegment_captureRef(t,e,n){return`{${e.sourceString}}`},PathLitSegment_parenLiteral(t,e,n){return`(${e.sourceString})`},PathLitSegment_literal(t){return t.sourceString},ListLiteral(t,e,n,s){return H({type:"listLiteral",elements:e.asIteration().children.map(r=>r.toAST())},this)},MapLiteral(t,e,n,s){return H({type:"mapLiteral",entries:e.asIteration().children.map(r=>r.toAST())},this)},MapEntry(t,e,n){return{key:t.toAST(),value:n.toAST()}},literal(t){return t.toAST()},number_float(t,e,n){return H({type:"literal",value:parseFloat(this.sourceString),raw:this.sourceString},this)},number_int(t){return H({type:"literal",value:parseInt(this.sourceString,10),raw:this.sourceString},this)},string_single(t,e,n){return H({type:"literal",value:Ha(e.sourceString),raw:this.sourceString},this)},string_double(t,e,n){return H({type:"literal",value:Ha(e.sourceString),raw:this.sourceString},this)},bytes_single(t,e,n,s){return H({type:"literal",value:Ka(n.sourceString),raw:this.sourceString},this)},bytes_double(t,e,n,s){return H({type:"literal",value:Ka(n.sourceString),raw:this.sourceString},this)},bool_true(t){return H({type:"literal",value:!0,raw:"true"},this)},bool_false(t){return H({type:"literal",value:!1,raw:"false"},this)},null(t){return H({type:"literal",value:null,raw:"null"},this)},ident(t,e){return H({type:"identifier",name:this.sourceString},this)},_nonterminal(...t){return t.length===1?t[0].toAST():t.map(e=>e.toAST())},_terminal(){return this.sourceString}});const Dp={"\\":92,"'":39,'"':34,n:10,r:13,t:9,b:8,f:12};function Dl(t,e,n){let s=0,r=0;for(;r<t.length;){if(t[r]!=="\\"){r++;continue}r>s&&e(t.slice(s,r));const i=t[r+1];i==="x"?(n(parseInt(t.slice(r+2,r+4),16)),r+=4):i==="u"?(n(parseInt(t.slice(r+2,r+6),16)),r+=6):i>="0"&&i<="3"?(n(parseInt(t.slice(r+1,r+4),8)),r+=4):(n(Dp[i]),r+=2),s=r}t.length>s&&e(t.slice(s))}function Ha(t){let e="";return Dl(t,n=>{e+=n},n=>{e+=String.fromCharCode(n)}),e}function Ka(t){const e=[],n=new TextEncoder;return Dl(t,s=>{e.push(...n.encode(s))},s=>{e.push(s)}),new Uint8Array(e)}function Za(t){const e=[],n=t.split("/").filter(Boolean);for(const s of n)if(s.startsWith("{")&&s.endsWith("}")){const r=s.slice(1,-1);r.endsWith("=**")?e.push({type:"recursive",name:r.slice(0,-3)}):e.push({type:"wildcard",name:r})}else e.push({type:"literal",value:s});return{raw:t,segments:e}}function $l(t,e,n=0){const s=t,r=n+(s.getRightmostFailurePosition?.()??0),i=s.getExpectedText?.()??"",o=s.getInterval?.();let a=s.message??"Parse error";return o!==void 0&&(s.input!==e||n!==0)&&(a=`${new o.constructor(e,r,r).getLineAndColumnMessage()}Expected ${i}`),qo(e,r,i,a)}function qo(t,e,n,s){let r=1,i=-1;for(let u=0;u<e&&u<t.length;u++)t.charCodeAt(u)===10&&(r++,i=u);const o=e-i;let a=t.indexOf(`
|
|
501
|
+
`,e);a===-1&&(a=t.length);const c=t.slice(e,Math.min(a,e+40));return{line:r,column:o,offset:e,expected:n,actual:c,message:s}}function Ja(t,e){const n=qo(t,e.offset,e.expected,"");return n.message=`Line ${n.line}, col ${n.column}: Brackets nest more than ${er} levels deep: the rules parser reads at most ${er}, a limit of this parser, not of production.`,n}function $p(t){const e=qo(t,0,"an expression with fewer chained terms","");return e.message="Line 1, col 1: The rules source chains more terms than the rules parser reads.",e}function Pl(t,e){return e===void 0?Fi.match(t):Fi.match(t,e)}function Pp(t,e,n,s,r,i){const o=Pl(t,e);if(!o.succeeded())return{ok:!1,error:$l(o,r,i+n-s)};const a=Nt;if(a!==null&&(n!==0||s!==0)){const c=a.at(n);Nt=new Nl(t,c.line-1,c.column-1-s)}try{return{ok:!0,ast:Ml(o).toAST()}}finally{Nt=a}}function Fp(t,e,n,s=t,r=0,i=jo){const o=za(t);if(!("source"in o))return{ok:!1,error:Ja(s,{offset:r+o.offset,expected:o.expected})};const a=(c,u,l,d)=>Ll(c,u,(f,p,h,m)=>{if(l||f!==c)return Pp(f,p,h,m,s,d);const g=Pl(f,p);return g.succeeded()?{ok:!0,ast:{}}:{ok:!1,error:$l(g,s,d)}},0,0,i);try{const c=a(o.source,e,n,r);if(!c.ok)return c;if(o.elided!==void 0){const u=o.elided.map(l=>({offset:r+l.offset,text:l.text}));for(let l=0;l<u.length;l++){const d=u[l],f=za(d.text);if(!("source"in f))return{ok:!1,error:Ja(s,{offset:d.offset+f.offset,expected:f.expected})};const p=a(f.source,"Expr",!1,d.offset);if(!p.ok)return p;if(f.elided!==void 0)for(const h of f.elided)u.push({offset:d.offset+h.offset,text:h.text})}}return{ok:!0,value:c.ast}}catch(c){if(c instanceof RangeError)return{ok:!1,error:$p(s)};throw c}}function Fl(t){const e=Rs(t);return e.ok?e.ast:null}function Rs(t,e={}){const n=t.trim();if(!n)return{ok:!1,error:{line:1,column:1,offset:0,expected:"",actual:"",message:"Empty rules file"}};const s=t.length-t.trimStart().length;let r=0,i=-1;for(let c=0;c<s;c++)t.charCodeAt(c)===10&&(r++,i=c);Nt=new Nl(n,r,s-i-1);let o;try{o=Fp(n,void 0,!0,t.trimEnd(),s,e.segmentDepth)}finally{Nt=null}if(!o.ok)return o;const a=o.value;return r>0&&jp(a,r),{ok:!0,ast:a}}function at(t,e){t!==void 0&&(t.line+=e)}function Vs(t,e){at(t.loc,e);for(const n of t.lets)at(n.loc,e),at(n.value.loc,e);at(t.body.loc,e),at(t.returnLoc,e)}function jp(t,e){at(t.loc,e);for(const s of t.imports)at(s.loc,e);for(const s of t.functions??[])Vs(s,e);at(t.service.loc,e);for(const s of t.service.functions??[])Vs(s,e);const n=[t.service.match];for(;n.length>0;){const s=n.pop();at(s.loc,e);for(const r of s.functions)Vs(r,e);for(const r of s.allows)at(r.loc,e),at(r.condition.loc,e);for(const r of s.children)n.push(r)}}function qp(t,e){t.loc!==void 0&&(t.loc.file=e);for(const n of t.lets)n.loc!==void 0&&(n.loc.file=e),n.value.loc!==void 0&&(n.value.loc.file=e);t.returnLoc!==void 0&&(t.returnLoc.file=e),t.body.loc!==void 0&&(t.body.loc.file=e)}function Up(t,e){const n=`rules_version = '2';
|
|
502
|
+
service cloud.firestore {
|
|
503
|
+
match /databases/{db}/documents {
|
|
504
|
+
${t}
|
|
505
|
+
}
|
|
506
|
+
}`,s=Fl(n);if(s===null)return null;const r=s.service.match.functions;for(const i of r)Vs(i,-3),e!==void 0&&qp(i,e);return r}const jl={"||":2,"&&":3,"==":5,"!=":5,">":6,"<":6,">=":6,"<=":6,"+":7,"-":7,"*":8,"/":8,"%":8};function Bp(t){switch(t.type){case"ternary":return 1;case"binaryOp":return jl[t.op]??0;case"inExpr":return 4;case"isExpr":return 4;case"pathLiteral":return 7.5;case"unaryOp":return 9;default:return 100}}function zp(t){switch(t.type){case"literal":return t.raw;case"identifier":return t.name;case"memberAccess":return`${tt(t.object,10)}.${t.property}`;case"methodCall":return`${tt(t.object,10)}.${t.method}(${t.args.map(e=>Se(e)).join(", ")})`;case"bracketAccess":return`${tt(t.object,10)}[${Se(t.index)}]`;case"sliceAccess":return`${tt(t.object,10)}[${Se(t.start)}:${Se(t.end)}]`;case"binaryOp":{const e=jl[t.op]??0,n=tt(t.left,e),s=tt(t.right,e+1);return t.op==="/"&&t.slashStartsPath?`${n}/${s}`:`${n} ${t.op} ${s}`}case"unaryOp":return`${t.op}${tt(t.operand,9)}`;case"ternary":return`${tt(t.condition,2)} ? ${Se(t.consequent)} : ${Se(t.alternate)}`;case"inExpr":return`${tt(t.element,5)} in ${tt(t.collection,5)}`;case"isExpr":return`${tt(t.value,5)} is ${t.typeName}`;case"listLiteral":return t.elements.length===0?"[]":`[${t.elements.map(e=>Se(e)).join(", ")}]`;case"mapLiteral":return t.entries.length===0?"{}":`{${t.entries.map(e=>`${Se(e.key)}: ${Se(e.value)}`).join(", ")}}`;case"pathLiteral":return"/"+t.segments.map(e=>typeof e=="string"?e:`$(${Se(e)})`).join("/");case"functionCall":return`${t.name}(${t.args.map(e=>Se(e)).join(", ")})`}}function tt(t,e){const n=zp(t),r=Bp(t)<e,i=Math.max(Ts(t),r?1:0);return i>0?`${"(".repeat(i)}${n}${")".repeat(i)}`:n}function Se(t){return tt(t,0)}function Wp(t){return"/"+t.segments.map(e=>{switch(e.type){case"literal":return e.value;case"wildcard":return`{${e.name}}`;case"recursive":return`{${e.name}=**}`}}).join("/")}function sr(t){return" ".repeat(t)}function On(t,e,n,s){if(t!==void 0&&t.file!==void 0){const i=t.file,o={generatedLine:e,authoredLine:t.line,authoredCol:t.col,authoredFile:i};s!==void 0&&(o.expression=s),n.push(o)}}function ji(t,e,n,s){const r=sr(e),i=sr(e+2),o=t.parameters.join(", ");let a="";t.exported===!0&&(a="export ");const u=n.length+1;n.push(`${r}${a}function ${t.name}(${o}) {`),On(t.loc,u,s);for(const d of t.lets){const f=n.length+1;n.push(`${i}let ${d.name} = ${Se(d.value)};`),On(d.loc??t.loc,f,s)}const l=n.length+1;n.push(`${i}return ${Se(t.body)};`),On(t.returnLoc??t.body.loc??t.loc,l,s),n.push(`${r}}`)}function Vp(t,e,n,s){const r=sr(e),i=t.operations.join(", "),o=Se(t.condition),a=n.length+1;n.push(`${r}allow ${i}: if ${o};`),On(t.loc,a,s,o)}function ql(t,e,n,s){const r=sr(e),i=e+2,o=n.length+1;n.push(`${r}match ${Wp(t.path)} {`),On(t.loc,o,s);for(const a of t.functions)ji(a,i,n,s);for(const a of t.allows)Vp(a,i,n,s);for(const a of t.children)ql(a,i,n,s);n.push(`${r}}`)}function Qa(t){return t.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r")}function Ya(t){const e=[],n=[];for(const a of t.imports)e.push(`import { ${a.functions.join(", ")} } from '${Qa(a.module)}';`);if(e.push(`rules_version = '${Qa(t.version)}';`),t.functions!==void 0)for(const a of t.functions)ji(a,0,e,n);const r=e.length+1;if(e.push(`service ${t.service.name} {`),On(t.service.loc,r,n),t.service.functions!==void 0)for(const a of t.service.functions)ji(a,2,e,n);const o=t.service.match;return ql(o,2,e,n),e.push("}"),e.push(""),{resolved:e.join(`
|
|
507
|
+
`),sourceMap:n}}const Gp=new Set(["get","exists","getAfter","existsAfter"]);function Ul(t,e,n=new Set,s){const r=new Map,i=new Set;return a(t,e).count;function o(c,u){const l=r.get(c);if(l!==void 0)return{count:l,hitStack:!1};if(i.has(c)||n.has(c.name))return{count:0,hitStack:!0};const d=s?.get(c)??u;i.add(c),n.add(c.name);let f=0,p=!1;for(const m of c.lets){const g=a(m.value,d);f+=g.count,g.hitStack&&(p=!0)}const h=a(c.body,d);return f+=h.count,h.hitStack&&(p=!0),n.delete(c.name),i.delete(c),p||r.set(c,f),{count:f,hitStack:p}}function a(c,u){let l=0,d=!1;const f=p=>{const h=a(p,u);l+=h.count,h.hitStack&&(d=!0)};switch(c.type){case"functionCall":if(Gp.has(c.name))l++;else{const p=u.get(c.name);if(p!==void 0){const h=o(p,u);l+=h.count,h.hitStack&&(d=!0)}}c.args.forEach(f);break;case"binaryOp":f(c.left),f(c.right);break;case"unaryOp":f(c.operand);break;case"ternary":f(c.condition),f(c.consequent),f(c.alternate);break;case"methodCall":c.object.type==="identifier"&&c.object.name==="firestore"&&(c.method==="get"||c.method==="exists")&&l++,f(c.object),c.args.forEach(f);break;case"memberAccess":f(c.object);break;case"bracketAccess":f(c.object),f(c.index);break;case"sliceAccess":f(c.object),f(c.start),f(c.end);break;case"inExpr":f(c.element),f(c.collection);break;case"isExpr":f(c.value);break;case"listLiteral":c.elements.forEach(f);break;case"mapLiteral":c.entries.forEach(p=>{f(p.key),f(p.value)});break;case"pathLiteral":for(const p of c.segments)typeof p!="string"&&f(p);break}return{count:l,hitStack:d}}}function oi(t){return t.map(e=>e.type==="literal"?`/${e.value}`:e.type==="wildcard"?`/{${e.name}}`:`/{${e.name}=**}`).join("")}function Hp(t){const e=t.findIndex(u=>u.type==="recursive");if(e===-1)return null;const n=oi(t),s=oi(t.slice(0,e)),r=t.slice(e+1);if(r.length===0)return{kind:"subtree",fullPath:n,description:s?`every document under ${s}`:"every document in the database"};const i=s?` under ${s}`:"",[o,a]=r,c=r.length===2&&o?.type==="literal"&&a?.type==="wildcard"?`every document in a collection named ${o.value} at any depth${i}`:`every document whose path ends in ${oi(r)}${i}`;return{kind:"suffix",fullPath:n,description:c}}const Bl=new Set(["get","exists","getAfter","existsAfter","int","float","string","path"]),Kp=new Set(["int","float","string","path"]),Uo=new Set(["request","resource","math","timestamp","duration","latlng","hashing"]),Zp=new Set([...Uo,"firestore"]);function zl(t){const e={functions:[],rules:[]},n=t.service?.name==="firebase.storage",s=new Set(n?Kp:Bl);for(const f of t.imports??[]){const p=f.functions??f.names??[];for(const h of p)s.add(h)}const r=n?Zp:Uo,i=t.functions??[],o=t.service.functions??[],a=ai(new Map,i),c=ai(a,o),u=new Set;for(const f of i)e.functions.push({fn:f,label:"global scope",functions:a,captures:u,globalFunctions:s,globalIdentifiers:r});const l=`service ${t.service.name}`;for(const f of o)e.functions.push({fn:f,label:l,functions:c,captures:u,globalFunctions:s,globalIdentifiers:r});const d=(f,p,h)=>{const m=ai(p,f.functions),g=new Set(h);for(const b of f.path.segments)b.type!=="literal"&&g.add(b.name);const y=f.path.raw;for(const b of f.functions)e.functions.push({fn:b,label:y,functions:m,captures:g,globalFunctions:s,globalIdentifiers:r});for(const b of f.allows)e.rules.push({rule:b,match:f,label:y,functions:m,captures:g,globalFunctions:s,globalIdentifiers:r});for(const b of f.children)d(b,m,g)};return d(t.service.match,c,u),e}function ai(t,e){const n=new Map(t);for(const s of e)n.set(s.name,s);return n}function Wl(t){const e=Jp(),n=new Set(t.fn.parameters);for(const s of t.fn.lets)Xa(s.value,t,n,e),n.add(s.name);return Xa(t.fn.body,t,n,e),e}function Jp(){return{callees:[],undefinedCalls:[],unboundVariables:[]}}function Xa(t,e,n,s){const r=e.globalIdentifiers??Uo,i=e.globalFunctions??Bl,o=(c,u)=>{c.includes(u)||c.push(u)},a=c=>{switch(c.type){case"identifier":!n.has(c.name)&&!e.captures.has(c.name)&&!r.has(c.name)&&o(s.unboundVariables,c.name);return;case"functionCall":{const u=e.functions.get(c.name);u?o(s.callees,u):i.has(c.name)||o(s.undefinedCalls,c.name),c.args.forEach(a);return}case"binaryOp":a(c.left),a(c.right);return;case"unaryOp":a(c.operand);return;case"ternary":a(c.condition),a(c.consequent),a(c.alternate);return;case"methodCall":a(c.object),c.args.forEach(a);return;case"bracketAccess":a(c.object),a(c.index);return;case"sliceAccess":a(c.object),a(c.start),a(c.end);return;case"memberAccess":a(c.object);return;case"inExpr":a(c.element),a(c.collection);return;case"isExpr":a(c.value);return;case"listLiteral":c.elements.forEach(a);return;case"mapLiteral":c.entries.forEach(u=>{a(u.key),a(u.value)});return;case"pathLiteral":for(const u of c.segments)typeof u!="string"&&a(u);return;case"literal":return;default:{const u=c;throw new Error(`collectReferences: unhandled type ${u.type}`)}}};a(t)}function Qp(t){const e=new Map;for(const o of t.functions)e.set(o.fn,Wl(o).callees);const n=new Map,s=new Map,r=new Set,i=(o,a)=>{const c=n.get(o);if(c!==void 0)return{depth:c,hitStack:!1};if(a.has(o))return{depth:0,hitStack:!0};a.add(o);let u=0,l=!1;for(const f of e.get(o)??[]){const p=i(f,a);u=Math.max(u,p.depth),p.hitStack&&(l=!0)}a.delete(o);const d=1+u;return l||n.set(o,d),{depth:d,hitStack:l}};for(const o of t.functions){const a=i(o.fn,new Set);s.set(o.fn,a.depth),a.hitStack&&r.add(o.fn)}return{depths:s,cyclic:r}}const Yp={allow:"the allow statement",let:"the let binding",return:"the return expression",rules_version:"the version line"},Xp={service:"the service block",match:"the match block",function:"the function body"},em="the map literal",tm="at the end of the statement",nm=8;function sm(t,e,n){let s=0;for(let r=1;r<e;r++){const i=t.indexOf(`
|
|
508
|
+
`,s);if(i===-1)return t.length;s=i+1}return Math.min(t.length,s+n-1)}function rm(t,e){const n=[];let s=1,r=0;for(;r<e;){const i=t[r];if(i===`
|
|
509
|
+
`)s++,r++;else if(/\s/.test(i))r++;else if(t.startsWith("//",r))for(;r<t.length&&t[r]!==`
|
|
510
|
+
`;)r++;else if(t.startsWith("/*",r)){const o=t.indexOf("*/",r+2),a=o===-1?t.length:o+2;for(;r<a;r++)t[r]===`
|
|
511
|
+
`&&s++}else if(i==="'"||i==='"'){for(r++;r<t.length&&t[r]!==i&&t[r]!==`
|
|
512
|
+
`;)r+=t[r]==="\\"?2:1;r++}else if(/[A-Za-z_]/.test(i)){const o=r;for(;r<t.length&&/[A-Za-z0-9_]/.test(t[r]);)r++;n.push({text:t.slice(o,r),offset:o,line:s})}else n.push({text:i,offset:r,line:s}),r++}return n}function Vl(t,e){return t[e-1]?.text!=="."}function Bo(t,e,n){const s=e[n-1];return s!==void 0&&s.text==="/"&&s.offset===e[n].offset-1}function im(t){for(let e=t.length-1;e>=0;e--){const n=t[e].text;if(n===";")return;const s=Yp[n];if(s!==void 0&&Vl(t,e))return s}}function Gl(t,e,n){for(let s=n-1;s>=0;s--){const r=e[s].text;if(r===";"||(r==="{"||r==="}")&&!Bo(t,e,s)&&!Hl(t,e,s))return;const i=Xp[r];if(i!==void 0&&Vl(e,s))return i}}function Hl(t,e,n){if(e[n].text!=="}")return!1;for(let s=n-1;s>=0;s--){const r=e[s].text;if(r==="{")return Bo(t,e,s);if(r==="}"||r===";")return!1}return!1}function om(t,e){const n=[];for(let s=0;s<e.length;s++){const r=e[s];r.text==="{"&&!Bo(t,e,s)?n.push({construct:Gl(t,e,s)??em,line:r.line}):r.text==="}"&&!Hl(t,e,s)&&n.pop()}return n}function Kl(t,e){return t.includes(`"${e}"`)}function Zl(t){const e=t.match(/"[^"]*"/g);return e===null?0:e.length}function ec(t,e){return Zl(t)===1&&Kl(t,e)}function am(t,e){const n=rm(e,sm(e,t.line,t.column));if(Kl(t.expected,";")){const s=im(n);return s===void 0?`expected ';' ${tm}`:`expected ';' after ${s}`}if(ec(t.expected,"{")){const s=Gl(e,n,n.length);if(s!==void 0)return`expected '{' to open ${s}`}if(ec(t.expected,"}")){const s=om(e,n).at(-1);if(s!==void 0)return`expected '}' to close ${s.construct} opened at line ${s.line}`}return Zl(t.expected)<=nm?`expected ${t.expected}`:"syntax error"}function cm(t){const e=zo(t);return e.ok?null:e.rejection}function zo(t){const e=fm(t);if(!e.ok)return e;const n=e.ast.service;return um(n)?{ok:!1,rejection:lm(n)}:e}const Jl="cloud.firestore";function um(t){return t!==void 0&&t.name!==Jl}function lm(t){return{kind:"parse",line:t.loc?.line??1,column:t.loc?.col??1,message:`rules did not compile: ${dm(t.name)}`,otherService:t.name}}function dm(t){return`Expected 'service ${Jl}', got 'service ${t}'.`}function fm(t){const e=Rs(t);if(!e.ok){const{line:s,column:r}=e.error;return{ok:!1,rejection:{kind:"parse",line:s,column:r,message:`rules did not parse at line ${s}, column ${r}: ${am(e.error,t)}.`}}}const n=xl(e.ast);return n.length===0?{ok:!0,ast:e.ast}:{ok:!1,rejection:{kind:"compile",violations:n,message:`rules did not compile: ${vp(n)}`}}}const ci=new Set(["get","exists","getAfter","debug"]);function tc(t,e){if(t.type!=="binaryOp"||t.op!==e)return 0;let n=1,s=t;for(;s.type==="binaryOp"&&s.op===e;)n++,s=s.left;return n}function hm(t){let e={op:"",depth:0};function n(r){if(r.type==="binaryOp"){const i=tc(r,"&&"),o=tc(r,"||");i>e.depth&&(e={op:"&&",depth:i}),o>e.depth&&(e={op:"||",depth:o}),n(r.left),n(r.right)}else s(r)}function s(r){switch(r.type){case"unaryOp":n(r.operand);break;case"methodCall":n(r.object),r.args.forEach(n);break;case"memberAccess":n(r.object);break;case"bracketAccess":n(r.object),n(r.index);break;case"ternary":n(r.condition),n(r.consequent),n(r.alternate);break;case"inExpr":n(r.element),n(r.collection);break;case"isExpr":n(r.value);break;case"listLiteral":r.elements.forEach(n);break;case"mapLiteral":r.entries.forEach(i=>{n(i.key),n(i.value)});break;case"functionCall":r.args.forEach(n);break}}return n(t),e}function re(t){switch(t.type){case"literal":return`L:${t.raw}`;case"identifier":return`I:${t.name}`;case"memberAccess":return`M:${re(t.object)}.${t.property}`;case"methodCall":return`MC:${re(t.object)}.${t.method}(${t.args.map(re).join(",")})`;case"bracketAccess":return`B:${re(t.object)}[${re(t.index)}]`;case"binaryOp":return`BO:${re(t.left)}${t.op}${re(t.right)}`;case"unaryOp":return`UO:${t.op}${re(t.operand)}`;case"ternary":return`T:${re(t.condition)}?${re(t.consequent)}:${re(t.alternate)}`;case"inExpr":return`IN:${re(t.element)}in${re(t.collection)}`;case"isExpr":return`IS:${re(t.value)}is${t.typeName}`;case"listLiteral":return`LL:[${t.elements.map(re).join(",")}]`;case"mapLiteral":return`ML:{${t.entries.map(e=>re(e.key)+":"+re(e.value)).join(",")}}`;case"functionCall":return`FC:${t.name}(${t.args.map(re).join(",")})`;case"pathLiteral":return`PL:${t.raw}`;case"sliceAccess":return`SL:${re(t.object)}[${re(t.start)}:${re(t.end)}]`;default:{const e=t;throw new Error(`expressionFingerprint: unhandled type ${e.type}`)}}}function Ql(t){return t.type==="binaryOp"&&t.op==="&&"?Ql(t.left):t}function pm(t,e){const n=new Map,s=r=>{switch(r.type){case"functionCall":e.has(r.name)&&n.set(r.name,(n.get(r.name)??0)+1),r.args.forEach(s);break;case"binaryOp":s(r.left),s(r.right);break;case"unaryOp":s(r.operand);break;case"methodCall":s(r.object),r.args.forEach(s);break;case"memberAccess":s(r.object);break;case"bracketAccess":s(r.object),s(r.index);break;case"ternary":s(r.condition),s(r.consequent),s(r.alternate);break;case"inExpr":s(r.element),s(r.collection);break;case"isExpr":s(r.value);break;case"listLiteral":r.elements.forEach(s);break;case"mapLiteral":r.entries.forEach(i=>{s(i.key),s(i.value)});break}};return s(t),n}function Yl(t,e,n=new Set,s,r=new Set){const i=e.get(t);if(!i||r.has(i)||n.has(t))return!1;n.add(t),r.add(i);const o=s?.get(i)??e,a=c=>{switch(c.type){case"functionCall":return c.name==="get"||c.name==="exists"||c.name==="getAfter"||c.name==="existsAfter"||o.has(c.name)&&Yl(c.name,o,new Set,s,r)?!0:c.args.some(a);case"binaryOp":return a(c.left)||a(c.right);case"unaryOp":return a(c.operand);case"methodCall":return c.object.type==="identifier"&&c.object.name==="firestore"&&(c.method==="get"||c.method==="exists")?!0:a(c.object)||c.args.some(a);case"memberAccess":return a(c.object);case"bracketAccess":return a(c.object)||a(c.index);case"sliceAccess":return a(c.object)||a(c.start)||a(c.end);case"ternary":return a(c.condition)||a(c.consequent)||a(c.alternate);case"inExpr":return a(c.element)||a(c.collection);case"isExpr":return a(c.value);case"listLiteral":return c.elements.some(a);case"mapLiteral":return c.entries.some(u=>a(u.key)||a(u.value));case"pathLiteral":return c.segments.some(u=>typeof u!="string"&&a(u));default:return!1}};return a(i.body)||i.lets.some(c=>a(c.value))}function qi(t,e,n=new Set,s,r=new Set){const i=o=>{switch(o.type){case"memberAccess":return o.property==="time"&&o.object.type==="identifier"&&o.object.name==="request"?!0:i(o.object);case"bracketAccess":return o.object.type==="identifier"&&o.object.name==="request"&&o.index.type==="literal"&&o.index.value==="time"?!0:i(o.object)||i(o.index);case"sliceAccess":return i(o.object)||i(o.start)||i(o.end);case"functionCall":{const a=e.get(o.name);if(a&&!r.has(a)&&!n.has(o.name)){n.add(o.name),r.add(a);const c=s?.get(a)??e;if(qi(a.body,c,new Set,s,r)||a.lets.some(u=>qi(u.value,c,new Set,s,r)))return!0}return o.args.some(i)}case"binaryOp":return i(o.left)||i(o.right);case"unaryOp":return i(o.operand);case"methodCall":return i(o.object)||o.args.some(i);case"ternary":return i(o.condition)||i(o.consequent)||i(o.alternate);case"inExpr":return i(o.element)||i(o.collection);case"isExpr":return i(o.value);case"listLiteral":return o.elements.some(i);case"mapLiteral":return o.entries.some(a=>i(a.key)||i(a.value));case"pathLiteral":return o.segments.some(a=>typeof a!="string"&&i(a));default:return!1}};return i(t)}function mm(t){return[...t.functions??[],...t.service.functions??[],...Xl(t.service.match)]}function Xl(t){const e=[...t.functions];for(const n of t.children)e.push(...Xl(n));return e}function gm(t,e){if(!t)return e;const n=t.endsWith("/")?t.slice(0,-1):t,s=e.startsWith("/")?e:`/${e}`;return`${n}${s}`}function Wo(t,e=""){const n=t.path.raw.includes("databases")&&t.path.raw.includes("documents")||t.path.raw.includes("/b/")&&t.path.raw.includes("/o")||/^\/?b\/[^/]+\/o$/.test(t.path.raw),s=gm(e,t.path.raw),r=n&&!e?"":s,i=[];for(const o of t.allows)i.push({rule:o,path:s,matchFunctions:t.functions});for(const o of t.children){const a=Wo(o,r);for(const c of a)c.matchFunctions=[...t.functions,...c.matchFunctions];i.push(...a)}return i}function ym(t){let e="",n=0;for(;n<t.length;){const s=t[n],r=t[n+1];if(s==="/"&&r==="/")for(n+=2;n<t.length&&t[n]!==`
|
|
513
|
+
`;)n++;else if(s==="/"&&r==="*"){for(n+=2;n<t.length&&!(t[n]==="*"&&t[n+1]==="/");)t[n]===`
|
|
514
|
+
`&&(e+=`
|
|
515
|
+
`),n++;n<t.length&&(n+=2)}else if(s==="'"||s==='"'){const i=s;for(e+=i,n++;n<t.length&&t[n]!==i&&t[n]!==`
|
|
516
|
+
`;)t[n]==="\\"&&n+1<t.length?(e+=" ",n+=2):(e+=" ",n++);n<t.length&&t[n]===i&&(e+=i,n++)}else e+=s,n++}return e}function Bt(t){if(t.type==="literal"&&typeof t.value=="boolean")return t.value;if(t.type==="binaryOp"){const e=Bt(t.left),n=Bt(t.right);if(t.op==="&&")return e===!1||n===!1?!1:e===!0&&n===!0?!0:null;if(t.op==="||")return e===!0||n===!0?!0:e===!1&&n===!1?!1:null}if(t.type==="unaryOp"&&t.op==="!"){const e=Bt(t.operand);return e===null?null:!e}if(t.type==="ternary"){const e=Bt(t.condition);return e===!0?Bt(t.consequent):e===!1?Bt(t.alternate):null}return null}function fe(t){switch(t.type){case"literal":return t.raw;case"identifier":return t.name;case"memberAccess":return`${fe(t.object)}.${t.property}`;case"methodCall":return`${fe(t.object)}.${t.method}(${t.args.map(fe).join(",")})`;case"bracketAccess":return`${fe(t.object)}[${fe(t.index)}]`;case"sliceAccess":return`${fe(t.object)}[${fe(t.start)}:${fe(t.end)}]`;case"binaryOp":return`(${fe(t.left)}${t.op}${fe(t.right)})`;case"unaryOp":return`(${t.op}${fe(t.operand)})`;case"ternary":return`(${fe(t.condition)}?${fe(t.consequent)}:${fe(t.alternate)})`;case"inExpr":return`(${fe(t.element)} in ${fe(t.collection)})`;case"isExpr":return`(${fe(t.value)} is ${t.typeName})`;case"listLiteral":return`[${t.elements.map(fe).join(",")}]`;case"mapLiteral":return`{${t.entries.map(e=>`${fe(e.key)}:${fe(e.value)}`).join(",")}}`;case"pathLiteral":return t.raw;case"functionCall":return`${t.name}(${t.args.map(fe).join(",")})`}}function rr(t){return t.type==="binaryOp"&&t.op==="&&"?[...rr(t.left),...rr(t.right)]:[t]}const Ui={where:"No equivalent in rules — restructure logic instead of filtering a list",filter:"No equivalent in rules — restructure logic instead of filtering a list",find:"No equivalent in rules",findIndex:"No equivalent in rules",map:"No equivalent in rules — lists are not transformable",reduce:"No equivalent in rules",forEach:"No equivalent in rules",every:'Use `list.hasAll([...])` for "all elements present"',some:'Use `list.hasAny([...])` for "any element present"',includes:"Use `x in list` instead of `list.includes(x)`",indexOf:"No equivalent in rules",push:"Lists are immutable in rules",pop:"Lists are immutable in rules",shift:"Lists are immutable in rules",unshift:"Lists are immutable in rules",splice:"Lists are immutable in rules",slice:"No equivalent in rules",sort:"Lists are immutable in rules",reverse:"Lists are immutable in rules",flat:"No equivalent in rules",flatMap:"No equivalent in rules",toLowerCase:"Use `.lower()` instead of `.toLowerCase()`",toUpperCase:"Use `.upper()` instead of `.toUpperCase()`",charAt:'No equivalent in rules — use `.split("")` and index',charCodeAt:"No equivalent in rules",substring:"No `.substring()` — use `.split()` and reassembly",substr:"No `.substr()` — use `.split()` and reassembly",padStart:"No equivalent in rules",padEnd:"No equivalent in rules",trimStart:"Use `.trim()` (trims both ends)",trimEnd:"Use `.trim()` (trims both ends)",toString:"Use the `string(x)` cast instead of `.toString()`"},xt={Object:"No `Object` in rules — use `data.keys()` / `data.values()` directly",Array:"No `Array` in rules — test list type with `x is list`",JSON:"No `JSON` in rules — rules cannot parse or serialize JSON",Math:"No `Math` in rules — inline arithmetic or ternaries",Date:"No `Date` in rules — use `request.time` (a Timestamp)",String:"Use lowercase `string(x)` for casting",Number:"Use lowercase `int(x)` or `float(x)` for casting",Boolean:"Use direct comparison or validation instead of boolean casting",bool:"No `bool()` cast in rules — boolean casting is not supported in production Firestore rules.",parseInt:"Use `int(x)` instead",parseFloat:"Use `float(x)` instead",isNaN:"No equivalent in rules",isFinite:"No equivalent in rules",Promise:"Rules are synchronous — no Promise support",undefined:"`undefined` does not exist in rules — use `null`"},bm=new Set(["abs","ceil","floor","round","sqrt","pow","isNaN"]),vm=[{receiver:"request",property:"data",suggestion:"Use `request.resource.data` (the incoming write payload)",storageSuggestion:"Use `request.resource` (e.g. `request.resource.size`, `request.resource.contentType`, or `request.resource.metadata`)"},{receiver:"request",property:"uid",suggestion:"Use `request.auth.uid`"},{receiver:"request",property:"token",suggestion:"Use `request.auth.token`"},{receiver:"request",property:"user",suggestion:"Use `request.auth` (or `request.auth.uid` for the user id)"},{receiver:"request.auth",property:"id",suggestion:"Use `request.auth.uid`"},{receiver:"resource",property:"path",suggestion:"`resource.path` is not available — bind path captures in the match pattern"},{receiver:"resource",property:"exists",suggestion:"Use `resource != null` (or `exists()` for cross-document checks)",storageSuggestion:"Use `resource != null` (or `firestore.exists()` for cross-service document checks)"},{receiver:"resource",property:"id",suggestion:"`resource.id` is not available — capture the document id with `/{docId}` in the match path"},{receiver:"resource",property:"data",suggestion:"`resource.data` does not exist in Storage rules — use `resource.size`, `resource.contentType`, or `resource.metadata`",storageOnly:!0},{receiver:"request.resource",property:"data",suggestion:"`request.resource.data` does not exist in Storage rules — use `request.resource.size`, `request.resource.contentType`, or `request.resource.metadata`",storageOnly:!0},{receiver:"resource",property:"timeUpdated",suggestion:"Use `resource.updated` instead of `resource.timeUpdated`",storageOnly:!0},{receiver:"request.resource",property:"timeUpdated",suggestion:"Use `request.resource.updated` instead of `request.resource.timeUpdated`",storageOnly:!0}],wm=new Set(["email_verified"]),Sm=new Set(["size","keys","values","lower","upper","trim","hasAll","hasAny","hasOnly","toSet","toUtf8"]),Am=[{pattern:/===/,message:"Strict equality `===` is not supported in Firestore rules — use `==`."},{pattern:/!==/,message:"Strict inequality `!==` is not supported in Firestore rules — use `!=`."},{pattern:/\?\./,message:"Optional chaining `?.` is not supported — use `'field' in obj && obj.field`."},{pattern:/\?\?/,message:"Nullish coalescing `??` is not supported — use a ternary `cond ? a : b`."},{pattern:/=>/,message:"Arrow functions `=>` are not supported — define functions with `function name() { return ...; }`."},{pattern:/`[^`]*`/,message:"Backtick strings are not supported — use single or double quoted strings with `+` for concatenation."}];function km(t){const e=[],n=ym(t);for(const s of Am)s.pattern.test(n)&&e.push({rule:"INVALID_OPERATOR",severity:"error",message:s.message});return e}function ed(t,e,n,s){const r=t.path.raw,i=new Set(e);for(const a of t.functions)i.add(a.name);const o=new Set(n);for(const a of t.path.segments)a.type!=="literal"&&o.add(a.name);for(const a of t.functions){const c={matchPath:r,functionName:a.name},u=new Set([...o,...a.parameters]);for(const l of a.lets)Y(l.value,c,i,u,s),u.add(l.name);Y(a.body,c,i,u,s)}for(let a=0;a<t.allows.length;a++)Y(t.allows[a].condition,{matchPath:r,ruleIndex:a},i,o,s);for(const a of t.children)ed(a,i,o,s)}function Y(t,e,n,s,r){switch(r(t,e,n,s),t.type){case"binaryOp":Y(t.left,e,n,s,r),Y(t.right,e,n,s,r);break;case"unaryOp":Y(t.operand,e,n,s,r);break;case"methodCall":Y(t.object,e,n,s,r),t.args.forEach(i=>Y(i,e,n,s,r));break;case"memberAccess":Y(t.object,e,n,s,r);break;case"bracketAccess":Y(t.object,e,n,s,r),Y(t.index,e,n,s,r);break;case"sliceAccess":Y(t.object,e,n,s,r),Y(t.start,e,n,s,r),Y(t.end,e,n,s,r);break;case"ternary":Y(t.condition,e,n,s,r),Y(t.consequent,e,n,s,r),Y(t.alternate,e,n,s,r);break;case"inExpr":Y(t.element,e,n,s,r),Y(t.collection,e,n,s,r);break;case"isExpr":Y(t.value,e,n,s,r);break;case"listLiteral":t.elements.forEach(i=>Y(i,e,n,s,r));break;case"mapLiteral":t.entries.forEach(i=>{Y(i.key,e,n,s,r),Y(i.value,e,n,s,r)});break;case"functionCall":t.args.forEach(i=>Y(i,e,n,s,r));break;case"pathLiteral":t.segments.forEach(i=>{typeof i!="string"&&Y(i,e,n,s,r)});break}}function Em(t,e,n){return n?!1:t.type==="functionCall"&&t.name==="debug"&&!e.has("debug")}function Im(t){return t.type==="methodCall"&&Object.hasOwn(Ui,t.method)}function _m(t){return t.type!=="methodCall"||t.object.type!=="identifier"||t.object.name!=="math"?!1:!bm.has(t.method)}function xm(t){return t.type!=="methodCall"||t.method!=="hasAll"&&t.method!=="hasAny"&&t.method!=="hasOnly"?!1:t.object.type==="mapLiteral"||t.object.type==="memberAccess"&&t.object.property==="data"}function Cm(t,e){return t.type!=="methodCall"||t.object.type!=="identifier"||e.has(t.object.name)?!1:Object.hasOwn(xt,t.object.name)}function Om(t,e){return t.type!=="functionCall"||e.has(t.name)?!1:Object.hasOwn(xt,t.name)}function Tm(t,e){return t.type!=="identifier"||e.has(t.name)?!1:Object.hasOwn(xt,t.name)}function Rm(t,e=!1){if(t.type!=="memberAccess")return;let n;if(t.object.type==="identifier"?n=t.object.name:t.object.type==="memberAccess"&&t.object.object.type==="identifier"&&(n=`${t.object.object.name}.${t.object.property}`),!n)return;const s=t.property,r=vm.find(i=>i.receiver===n&&i.property===s&&(!i.storageOnly||e));if(r)return{path:`${n}.${s}`,suggestion:e&&r.storageSuggestion?r.storageSuggestion:r.suggestion}}function Nm(t){if(t.type!=="memberAccess"||!wm.has(t.property))return;const e=t.object;if(e.type!=="memberAccess"||e.property!=="token")return;const n=e.object;if(!(n.type!=="memberAccess"||n.property!=="auth"))return n.object.type==="identifier"&&n.object.name==="request"?t.property:void 0}function Lm(t){if(!(t.type!=="binaryOp"||t.op!=="=="&&t.op!=="!="))for(const[e,n]of[[t.left,t.right],[t.right,t.left]]){const s=Nm(e);if(s&&n.type==="literal"&&typeof n.value=="string")return{claim:s,op:t.op,literal:n.value}}}function Mm(t){return t.type==="memberAccess"&&t.property==="length"&&t.object.type==="methodCall"}function Dm(t,e=!1){if(t.type!=="memberAccess"||!Sm.has(t.property))return!1;if(e&&t.property==="size"){const s=t.object.type==="identifier"&&t.object.name==="resource",r=t.object.type==="memberAccess"&&t.object.property==="resource"&&t.object.object.type==="identifier"&&t.object.object.name==="request";if(s||r)return!1}return t.object.type==="identifier"&&(t.object.name==="request"||t.object.name==="resource")||t.object.type==="memberAccess"||t.object.type==="methodCall"||t.object.type==="bracketAccess"}function $m(t,e={}){const n=[],s=new Set,r=t.service?.name==="firebase.storage";function i(u,l,d,f){const p=`${u}|${l}|${d.matchPath||""}|${d.functionName||""}|${d.ruleIndex??""}`;s.has(p)||(s.add(p),n.push(f))}const o=new Set;for(const u of t.imports??[]){const l=u.functions??u.names??[];for(const d of l)o.add(d)}for(const u of t.functions??[])o.add(u.name);const a=new Set(o);for(const u of t.service.functions??[])a.add(u.name);const c=(u,l,d,f)=>{if(Em(u,d,e.allowDebug)&&i("HALLUCINATED_GLOBAL","debug",l,{rule:"HALLUCINATED_GLOBAL",severity:"error",message:"`debug()` is not a Firestore rules function and no function named `debug` is declared in scope. Production rejects the whole ruleset at compile time with `Function not found error: Name: [debug]`, so nothing in the file deploys.",location:l,fix:"Remove the debug() call and evaluate the inner expression directly."}),Im(u)&&u.type==="methodCall"&&i("HALLUCINATED_METHOD",u.method,l,{rule:"HALLUCINATED_METHOD",severity:"error",message:`\`.${u.method}()\` does not exist in Firestore rules. ${Ui[u.method]}`,location:l,fix:Ui[u.method]}),_m(u)&&u.type==="methodCall"&&i("HALLUCINATED_METHOD",`math.${u.method}`,l,{rule:"HALLUCINATED_METHOD",severity:"error",message:`\`math.${u.method}()\` does not exist in production Firestore security rules.`,location:l,fix:"Use supported math namespace functions: abs, ceil, floor, round, sqrt, pow, isNaN."}),xm(u)&&u.type==="methodCall"&&i("HALLUCINATED_METHOD",`map.${u.method}`,l,{rule:"HALLUCINATED_METHOD",severity:"error",message:`\`.${u.method}()\` cannot be called directly on a map in Firestore rules — call it on \`.keys()\` instead.`,location:l,fix:`Insert \`.keys()\`: e.g. \`data.keys().${u.method}(...)\`.`}),Cm(u,f)&&u.type==="methodCall"&&u.object.type==="identifier"){const m=u.object.name;i("HALLUCINATED_GLOBAL",`${m}.${u.method}`,l,{rule:"HALLUCINATED_GLOBAL",severity:"error",message:`\`${m}.${u.method}()\` does not exist in Firestore rules. ${xt[m]}`,location:l,fix:xt[m]})}Om(u,d)&&u.type==="functionCall"&&i("HALLUCINATED_GLOBAL",u.name,l,{rule:"HALLUCINATED_GLOBAL",severity:"error",message:`\`${u.name}()\` does not exist in Firestore rules. ${xt[u.name]}`,location:l,fix:xt[u.name]}),Tm(u,f)&&u.type==="identifier"&&i("HALLUCINATED_GLOBAL",`ref:${u.name}`,l,{rule:"HALLUCINATED_GLOBAL",severity:"error",message:`\`${u.name}\` is not a Firestore rules identifier. ${xt[u.name]}`,location:l,fix:xt[u.name]});const p=Rm(u,r);p&&i("WRONG_CONTEXT_PATH",p.path,l,{rule:"WRONG_CONTEXT_PATH",severity:"error",message:`\`${p.path}\` is not a valid ${r?"Storage":"Firestore"} rules path. ${p.suggestion}`,location:l,fix:p.suggestion});const h=Lm(u);if(h){const{claim:m,op:g,literal:y}=h;i("BOOL_TOKEN_CLAIM",`${m}|${g}|${y}`,l,{rule:"BOOL_TOKEN_CLAIM",severity:"error",message:`\`request.auth.token.${m}\` is a bool, but it is compared against the string "${y}", a cross-type comparison that is always ${g==="=="?"false (rule always denies)":"true (rule silently allows)"}. Compare against the boolean literal instead: \`request.auth.token.${m} ${g} true\`.`,location:l,fix:`Drop the quotes: \`request.auth.token.${m} ${g} ${y==="false"?"false":"true"}\`.`})}if(Mm(u)&&i("LENGTH_PROPERTY","",l,{rule:"LENGTH_PROPERTY",severity:"error",message:"`.length` is not a valid property in Firestore rules — use `.size()` (a method, with parentheses).",location:l,fix:"Replace `.length` with `.size()`."}),u.type==="pathLiteral")for(const m of u.segments){if(typeof m!="string")continue;const g=m.match(/^\{([A-Za-z_][A-Za-z0-9_]*)\}$/);if(!g)continue;const y=g[1];i("INVALID_PATH_INTERPOLATION",`${u.raw}|${y}`,l,{rule:"INVALID_PATH_INTERPOLATION",severity:"error",message:`\`{${y}}\` is not valid inside a path literal — Firestore rejects this at deploy. The \`{var}\` syntax is for match statement wildcards (e.g. \`match /users/{userId}\`); path interpolation in get()/exists()/getAfter()/existsAfter() requires \`$(var)\`. Replace \`{${y}}\` with \`$(${y})\` in path \`${u.raw}\`.`,location:l,fix:`Replace \`{${y}}\` with \`$(${y})\` inside the path argument.`})}Dm(u,r)&&u.type==="memberAccess"&&i("METHOD_MISSING_PARENS",u.property,l,{rule:"METHOD_MISSING_PARENS",severity:"warning",message:`\`.${u.property}\` looks like a built-in method called without parentheses. Use \`.${u.property}()\` if you meant to invoke it (otherwise this is a field access).`,location:l,fix:`Add parentheses: \`.${u.property}()\`.`})};for(const u of t.functions??[]){const l={functionName:u.name},d=new Set(u.parameters);for(const f of u.lets)Y(f.value,l,o,d,c),d.add(f.name);Y(u.body,l,o,d,c)}for(const u of t.service.functions??[]){const l={functionName:u.name},d=new Set(u.parameters);for(const f of u.lets)Y(f.value,l,a,d,c),d.add(f.name);Y(u.body,l,a,d,c)}return ed(t.service.match,a,new Set,c),n}const hs=1e3,nc=["get","list","create","update","delete"];function ui(t,e){return t.operations.some(n=>n===e||n==="read"&&(e==="get"||e==="list")||n==="write"&&(e==="create"||e==="update"||e==="delete"))}const as=new Map;function Pm(t){return t.size===0?"":[...t.entries()].sort(([e],[n])=>e<n?-1:1).map(([e,n])=>`${e}=${n}`).join("|")}function Fm(t,e){for(const[n,s]of e){const r=t.get(n);if(r!==void 0&&r!==s)return null}return ns(t,e)}function ns(t,e){if(e.size===0)return t;if(t.size===0)return e;const n=new Map(t);for(const[s,r]of e)n.set(s,r);return n}function ps(t){switch(t.type){case"identifier":return t.name==="request"||t.name==="resource";case"memberAccess":return ps(t.object);case"bracketAccess":return t.index.type==="literal"&&ps(t.object);default:return!1}}function sc(t){return t.type!=="binaryOp"||t.op!=="=="&&t.op!=="!="?null:t.right.type==="literal"&&ps(t.left)?{path:re(t.left),literal:Bi(t.right)}:t.left.type==="literal"&&ps(t.right)?{path:re(t.right),literal:Bi(t.left)}:null}function Bi(t){const{value:e}=t;return e instanceof Uint8Array?`bytes:${[...e].join(",")}`:`${typeof e}:${String(e)}`}class jm{fns;memo=new Map;factMemo=new Map;depth=0;constructor(e){this.fns=e}factsOf(e){const n=this.factMemo.get(e);if(n)return n;let s=as;if(e.type==="binaryOp"&&e.op==="&&")s=ns(this.factsOf(e.left),this.factsOf(e.right));else if(e.type==="binaryOp"&&e.op==="=="){const r=sc(e);r&&(s=new Map([[r.path,r.literal]]))}else e.type==="functionCall"&&this.fns.has(e.name)&&this.depth<20&&(this.depth++,s=this.factsOf(this.fns.get(e.name).body),this.depth--);return this.factMemo.set(e,s),s}known(e,n){if(e.type==="inExpr"&&e.collection.type==="listLiteral"&&ps(e.element)){const o=n.get(re(e.element)),a=e.collection.elements;return o===void 0||!a.every(c=>c.type==="literal")?void 0:a.some(c=>c.type==="literal"&&Bi(c)===o)}const s=sc(e);if(!s||e.type!=="binaryOp")return;const r=n.get(s.path);if(r===void 0)return;const i=r===s.literal;return e.op==="=="?i:!i}cost(e,n,s){const r=`${n}#${Pm(s)}`;let i=this.memo.get(e);if(i||this.memo.set(e,i=new Map),i.has(r))return i.get(r);const o=this.compute(e,n,s);return i.set(r,o),o}any(e,n){return this.cost(e,"A",n)??0}compute(e,n,s){if(n==="A"&&(qm(e)||e.type==="unaryOp"&&e.op==="!"))return Vn(this.cost(e,"T",s),this.cost(e,"F",s));switch(e.type){case"literal":return typeof e.value=="boolean"&&n!=="A"&&e.value!==(n==="T")?null:1;case"identifier":return 1;case"memberAccess":return 1+this.any(e.object,s);case"methodCall":return 1+this.any(e.object,s)+kn(e.args.map(r=>this.any(r,s)));case"bracketAccess":return 1+this.any(e.object,s)+this.any(e.index,s);case"sliceAccess":return 1+this.any(e.object,s)+this.any(e.start,s)+this.any(e.end,s);case"inExpr":{const r=this.known(e,s);return r!==void 0&&n!=="A"&&r!==(n==="T")?null:1+this.any(e.element,s)+this.any(e.collection,s)}case"isExpr":return 2+this.any(e.value,s);case"listLiteral":return 1+kn(e.elements.map(r=>this.any(r,s)));case"mapLiteral":return 1+kn(e.entries.map(r=>this.any(r.key,s)+this.any(r.value,s)));case"pathLiteral":return 1+kn(e.segments.map(r=>typeof r=="string"?1:this.any(r,s)));case"unaryOp":if(e.op==="!"){const r=this.cost(e.operand,n==="T"?"F":n==="F"?"T":"A",s);return r===null?null:1+r}return 1+this.any(e.operand,s);case"ternary":{const r=(a,c)=>{const u=this.cost(e.condition,a,s);if(u===null)return null;const l=a==="T"?ns(s,this.factsOf(e.condition)):s,d=this.cost(c,n,l);return d===null?null:u+d},i=r("T",e.consequent),o=r("F",e.alternate);return Vn(i===null?null:2+i,o===null?null:4+o)}case"binaryOp":if(e.op==="&&")return this.and(e.left,e.right,n,s);if(e.op==="||")return this.or(e.left,e.right,n,s);{const r=this.known(e,s);return r!==void 0&&n!=="A"&&r!==(n==="T")?null:1+this.any(e.left,s)+this.any(e.right,s)}case"functionCall":{const r=kn(e.args.map(o=>this.any(o,s))),i=this.fns.get(e.name);if(!i||this.depth>=20)return 1+r;this.depth++;try{const o=kn(i.lets.map(c=>1+this.any(c.value,s))),a=this.cost(i.body,n,s);return a===null?null:1+r+o+a}finally{this.depth--}}}}failAtGate(e,n){let s=0,r=e;for(;r.type==="binaryOp"&&r.op==="&&";)s++,r=r.left;const i=this.cost(r,"F",n);return i===null?null:s+i}and(e,n,s,r){const i=this.cost(e,"T",r),o=ns(r,this.factsOf(e));if(s==="T"){const u=this.cost(n,"T",o);return i===null||u===null?null:2+i+u}const a=this.cost(e,"F",r),c=this.cost(n,"F",o);return Vn(a===null?null:1+a,i===null||c===null?null:2+i+c)}or(e,n,s,r){if(s==="F"){const c=this.factsOf(Vo(n));if(c.size===0){const h=this.cost(e,"F",r),m=this.cost(n,"F",r);return h===null||m===null?null:2+h+m}const u=this.failAtGate(n,r),l=this.cost(e,"F",r),d=Fm(r,c),f=d&&this.cost(e,"F",d),p=d&&this.cost(n,"F",d);return Vn(l===null||u===null?null:2+l+u,f===null||p===null||!d?null:2+f+p)}this.cost(e,"F",r);const i=this.cost(e,"T",r),o=this.cost(n,"T",r),a=this.cost(e,"F",ns(r,this.factsOf(n)));return Vn(i===null?null:1+i,a===null||o===null?null:2+a+o)}}function qm(t){return t.type==="binaryOp"&&(t.op==="&&"||t.op==="||")}function kn(t){let e=0;for(const n of t)e+=n;return e}function Vn(...t){let e=null;for(const n of t)n!==null&&(e===null||n>e)&&(e=n);return e}function td(t){const e=[],n=new Map;for(const r of t.functions??[])n.set(r.name,r);for(const r of t.service.functions??[])n.set(r.name,r);const s=(r,i,o)=>{const a=new Map(o);for(const u of r.functions)a.set(u.name,u);const c=`${i}${r.path.raw}`;e.push({block:r,path:c,fns:a});for(const u of r.children)s(u,c,a)};return s(t.service.match,"",n),e}function Um(t){const e=[],n=[];let s=0;for(const{block:r,path:i,fns:o}of td(t)){const a=new jm(o),c=r.allows,u=c.map(()=>s++),l=(d,f)=>a.cost(d.condition,"F",f);c.forEach((d,f)=>{const p=a.cost(d.condition,"T",as),h=a.factsOf(d.condition);let m=null;for(const g of nc){if(p===null||!ui(d,g))continue;let y=p;for(let b=0;b<f;b++)ui(c[b],g)&&(y+=l(c[b],h)??l(c[b],as)??0);m=Math.max(m??0,y)}e.push({ruleIndex:u[f],matchPath:i,blockPath:r.path.raw,blockRuleIndex:f,...d.loc?.line!==void 0?{line:d.loc.line}:{},operations:[...d.operations],grantCost:m})});for(const d of nc){const f=c.filter(h=>ui(h,d));if(f.length===0)continue;let p=0;for(const h of Bm(a,f)){let m=0;for(const g of f)m+=l(g,h)??l(g,as)??0;p=Math.max(p,m)}n.push({matchPath:i,blockPath:r.path.raw,method:d,denyCost:p})}}return{rules:e,blocks:n}}function Bm(t,e){const n=new Map;for(const i of e)for(const[o,a]of t.factsOf(Vo(i.condition)))n.has(o)||n.set(o,new Set),n.get(o).add(a);let s;for(const[i,o]of n)(!s||o.size>n.get(s).size)&&(s=i);return s?[...[...n.get(s)],"unmatched"].map(i=>new Map([[s,i]])):[as]}function Vo(t){return t.type==="binaryOp"&&t.op==="&&"?Vo(t.left):t}function zm(t){const e=[];let n=0;for(const{block:s,path:r,fns:i}of td(t))for(const o of s.allows){const a=new Map,c=(u,l)=>{if(u.type==="functionCall"){const d=i.get(u.name);if(d&&(a.set(d,(a.get(d)??0)+1),l<20)){for(const f of d.lets)c(f.value,l+1);c(d.body,l+1)}}for(const d of Wm(u))c(d,l)};c(o.condition,0),e.push({ruleIndex:n++,matchPath:r,blockPath:s.path.raw,...o.loc?.line!==void 0?{line:o.loc.line}:{},calls:[...a].map(([u,l])=>({fn:u,count:l}))})}return e}function Wm(t){switch(t.type){case"binaryOp":return[t.left,t.right];case"unaryOp":return[t.operand];case"ternary":return[t.condition,t.consequent,t.alternate];case"memberAccess":return[t.object];case"methodCall":return[t.object,...t.args];case"bracketAccess":return[t.object,t.index];case"sliceAccess":return[t.object,t.start,t.end].filter(e=>!!e);case"inExpr":return[t.element,t.collection];case"isExpr":return[t.value];case"listLiteral":return t.elements;case"mapLiteral":return t.entries.flatMap(e=>[e.key,e.value]);case"pathLiteral":return t.segments.filter(e=>typeof e!="string");case"functionCall":return t.args;default:return[]}}const Go={atomic:["cloud.firestore"],auth:["cloud.firestore","firebase.storage"],content:["cloud.firestore"],counters:["cloud.firestore"],fairness:["cloud.firestore"],geometry:["cloud.firestore"],joining:["cloud.firestore"],lifecycle:["cloud.firestore"],lobby:["cloud.firestore"],membership:["cloud.firestore","firebase.storage"],results:["cloud.firestore"],spaces:["cloud.firestore"],state:["cloud.firestore"],"storage/metadata":["firebase.storage"],"storage/objects":["firebase.storage"],"storage/time":["firebase.storage"],"storage/uploads":["firebase.storage"],timing:["cloud.firestore"],transitions:["cloud.firestore"],turns:["cloud.firestore"],validation:["cloud.firestore"]};Object.freeze(Object.keys(Go).sort());const Vm={atomic:[],auth:["storage-rules#125","firestore-rules#189"],content:[],counters:[],fairness:[],geometry:[],joining:[],lifecycle:[],lobby:[],membership:["storage-rules#125","firestore-rules#189"],results:[],spaces:[],state:[],"storage/metadata":["storage-rules#132"],"storage/objects":["storage-rules#132"],"storage/time":["storage-rules#132"],"storage/uploads":["storage-rules#132"],timing:[],transitions:[],turns:[],validation:[]},Gm=["exists","existsAfter","float","get","getAfter","int","path","string"],Hm=["addedKeys","affectedKeys","bind","changedKeys","concat","date","day","dayOfWeek","dayOfYear","diff","difference","distance","get","hasAll","hasAny","hasOnly","hours","intersection","join","keys","latitude","longitude","lower","matches","minutes","month","nanos","removeAll","removedKeys","replace","seconds","size","split","time","toBase64","toHexString","toMillis","toSet","toUtf8","trim","unchangedKeys","union","upper","values","year"],Km={addedKeys:["mapdiff"],affectedKeys:["mapdiff"],bind:["path"],changedKeys:["mapdiff"],concat:["list"],date:["timestamp"],day:["timestamp"],dayOfWeek:["timestamp"],dayOfYear:["timestamp"],diff:["map"],difference:["set"],distance:["latlng"],get:["map"],hasAll:["list","set"],hasAny:["list","set"],hasOnly:["list","set"],hours:["timestamp"],intersection:["set"],join:["list"],keys:["map"],latitude:["latlng"],longitude:["latlng"],lower:["string"],matches:["string"],minutes:["timestamp"],month:["timestamp"],nanos:["duration","timestamp"],removeAll:["list"],removedKeys:["mapdiff"],replace:["string"],seconds:["duration","timestamp"],size:["bytes","list","map","set","string"],split:["string"],time:["timestamp"],toBase64:["bytes"],toHexString:["bytes"],toMillis:["timestamp"],toSet:["list"],toUtf8:["string"],trim:["string"],unchangedKeys:["mapdiff"],union:["set"],upper:["string"],values:["map"],year:["timestamp"]},nd={duration:["abs","time","value"],hashing:["crc32","crc32c","md5","sha256"],latlng:["value"],math:["abs","ceil","floor","isNaN","pow","round","sqrt"],timestamp:["date","value"]},sd=["request","request.auth","request.auth.token","request.auth.uid","request.method","request.path","request.resource","request.resource.contentType","request.resource.metadata","request.resource.name","request.resource.size","request.time","resource","resource.bucket","resource.cacheControl","resource.contentDisposition","resource.contentEncoding","resource.contentLanguage","resource.contentType","resource.crc32c","resource.etag","resource.generation","resource.md5Hash","resource.metadata","resource.metageneration","resource.name","resource.size","resource.timeCreated","resource.updated"],Zm=["float","int","path","string"],Jm=["addedKeys","affectedKeys","bind","changedKeys","concat","date","day","dayOfWeek","dayOfYear","diff","difference","distance","get","hasAll","hasAny","hasOnly","hours","intersection","join","keys","latitude","longitude","lower","matches","minutes","month","nanos","removeAll","removedKeys","replace","seconds","size","split","time","toBase64","toHexString","toMillis","toSet","toUtf8","trim","unchangedKeys","union","upper","values","year"],Qm={addedKeys:["mapdiff"],affectedKeys:["mapdiff"],bind:["path"],changedKeys:["mapdiff"],concat:["list"],date:["timestamp"],day:["timestamp"],dayOfWeek:["timestamp"],dayOfYear:["timestamp"],diff:["map"],difference:["set"],distance:["latlng"],get:["map"],hasAll:["list","set"],hasAny:["list","set"],hasOnly:["list","set"],hours:["timestamp"],intersection:["set"],join:["list"],keys:["map"],latitude:["latlng"],longitude:["latlng"],lower:["string"],matches:["string"],minutes:["timestamp"],month:["timestamp"],nanos:["duration","timestamp"],removeAll:["list"],removedKeys:["mapdiff"],replace:["string"],seconds:["duration","timestamp"],size:["bytes","list","map","set","string"],split:["string"],time:["timestamp"],toBase64:["bytes"],toHexString:["bytes"],toMillis:["timestamp"],toSet:["list"],toUtf8:["string"],trim:["string"],unchangedKeys:["mapdiff"],union:["set"],upper:["string"],values:["map"],year:["timestamp"]},rd={duration:["abs","time","value"],firestore:["exists","get"],hashing:["crc32","crc32c","md5","sha256"],latlng:["value"],math:["abs","ceil","floor","isNaN","pow","round","sqrt"],timestamp:["date","value"]},Ym=new Set(sd),Xm=["request.auth.token","request.resource.metadata","resource.metadata"];function eg(t,e){if(e.length===1)return!0;if(t==="firebase.storage"){const n=e.join(".");return Ym.has(n)||Xm.some(s=>n.startsWith(`${s}.`))}return e[0]==="request"?e[1]==="auth"||e[1]==="query"?!0:["time","method","path"].includes(e[1])?e.length===2:e[1]==="resource"&&(e.length===2||e[2]==="data"):e[0]==="resource"&&(e.length===1||e[1]==="data")}const tg=new Set(["request","request.resource","resource"]);function ng(t,e){const n=e.join(".");return t==="cloud.firestore"?tg.has(n):ms(t,e)?!1:sd.some(s=>s.startsWith(`${n}.`))}function ms(t,e){return e[0]==="request"&&e[1]==="auth"&&e[2]==="token"?!0:t==="firebase.storage"?e[0]==="resource"&&e[1]==="metadata"||e[0]==="request"&&e[1]==="resource"&&e[2]==="metadata":e[0]==="resource"&&e[1]==="data"||e[0]==="request"&&e[1]==="resource"&&e[2]==="data"||e[0]==="request"&&e[1]==="query"}function sg(t,e){if(!e||e==="unknown-ambient")return null;const n=e.join(".");return n==="request"?"request":n==="request.resource"||n==="resource"?"resource":n==="request.auth"||n==="request.auth.token"||t==="cloud.firestore"&&(n==="request.resource.data"||n==="resource.data"||n==="request.query")||n==="request.resource.metadata"||n==="resource.metadata"?"map":n==="request.auth.uid"||n==="request.method"||n==="request.resource.contentType"||n==="resource.contentType"||t==="firebase.storage"&&(n==="request.resource.name"||n==="resource.name"||n==="resource.bucket"||n.startsWith("request.resource.metadata.")||n.startsWith("resource.metadata."))?"string":n==="request.path"?"path":n==="request.time"||n==="resource.timeCreated"||n==="resource.updated"?"timestamp":["request.resource.size","resource.size","resource.generation","resource.metageneration"].includes(n)?"number":null}function rc(t){if(t.type!=="methodCall")return null;if(t.object.type==="identifier"){if(t.object.name==="firestore"){if(t.method==="get")return"document";if(t.method==="exists")return"boolean"}if(t.object.name==="duration")return"duration";if(t.object.name==="timestamp")return"timestamp";if(t.object.name==="latlng")return"latlng";if(t.object.name==="hashing")return"bytes";if(t.object.name==="math")return"number"}return["lower","upper","trim","replace","join","toBase64","toHexString"].includes(t.method)?"string":["matches","hasAny","hasAll","hasOnly"].includes(t.method)?"boolean":["concat","keys","removeAll","split","values"].includes(t.method)?"list":["toSet","addedKeys","removedKeys","changedKeys","affectedKeys","unchangedKeys","difference","union","intersection"].includes(t.method)?"set":t.method==="diff"?"mapdiff":t.method==="get"?null:t.method==="toUtf8"?"bytes":t.method==="date"?"timestamp":["size","year","month","day","hours","minutes","seconds","nanos","dayOfWeek","dayOfYear","toMillis","latitude","longitude","distance"].includes(t.method)?"number":null}const rg=new Set(["exists","existsAfter","get","getAfter"]),ig=Object.fromEntries(Object.entries(nd).map(([t,e])=>[t,new Set(e)])),og=Object.fromEntries(Object.entries(rd).map(([t,e])=>[t,new Set(e)]));function zi(t,e){return t.some(n=>n==="unknown-ambient"||n!==null&&ng(e.service,n))?"unknown-ambient":null}function Et(t,e){return zi(t.map(n=>Ce(n,e)),e)}function id(t,e,n){const s=n.declarations?.get(t),r=new Map(s?.aliases),i=new Map(s?.receiverTypes);return t.parameters.forEach((o,a)=>{r.set(o,e[a]?.provenance??null),i.set(o,e[a]?.receiverType??null)}),{aliases:r,receiverTypes:i,functions:s?.functions??n.functions,service:n.service,stack:new Set([...n.stack,t.name]),declarations:n.declarations}}function Ln(t,e){return{expression:t,provenance:Ce(t,e),receiverType:ve(t,e)}}function Ce(t,e){if(t.type==="identifier")return t.name==="request"||t.name==="resource"?[t.name]:e.aliases.get(t.name)??null;if(t.type==="memberAccess"){const n=Ce(t.object,e);return n==="unknown-ambient"?n:n?[...n,t.property]:null}if(t.type==="bracketAccess"){const n=Ce(t.object,e);return!n||n==="unknown-ambient"?n:t.index.type==="literal"&&typeof t.index.value=="string"?[...n,t.index.value]:[...n,"*"]}if(t.type==="ternary"){const n=Ce(t.consequent,e),s=Ce(t.alternate,e);return!n&&!s?null:Array.isArray(n)&&Array.isArray(s)&&n.join(".")===s.join(".")?n:zi([n,s],e)}if(t.type==="functionCall"){const n=e.functions.get(t.name),s=t.args.map(i=>Ln(i,e));if(!n&&rg.has(t.name))return null;if(!n||e.stack.has(n.name))return zi(s.map(({provenance:i})=>i),e);const r=id(n,s,e);for(const i of n.lets){const o=Ln(i.value,r);r.aliases.set(i.name,o.provenance),r.receiverTypes.set(i.name,o.receiverType)}return Ce(n.body,r)}if(t.type==="methodCall"&&t.object.type==="identifier"&&t.object.name==="firestore"&&(t.method==="get"||t.method==="exists"))return null;switch(t.type){case"literal":return null;case"methodCall":return Et([t.object,...t.args],e);case"sliceAccess":return Et([t.object,t.start,t.end],e);case"binaryOp":return Et([t.left,t.right],e);case"unaryOp":return Et([t.operand],e);case"inExpr":return Et([t.element,t.collection],e);case"isExpr":return Et([t.value],e);case"listLiteral":return Et(t.elements,e);case"mapLiteral":return Et(t.entries.flatMap(({key:n,value:s})=>[n,s]),e);case"pathLiteral":return Et(t.segments.filter(n=>typeof n!="string"),e);default:return null}}function ve(t,e){const n=sg(e.service,Ce(t,e));if(n)return n;switch(t.type){case"identifier":{const s=e.receiverTypes.get(t.name);return s||((e.service==="cloud.firestore"?ig:og)[t.name]||t.name==="firestore"?"namespace":null)}case"literal":return t.value===null?"null":typeof t.value=="string"?"string":typeof t.value=="number"?"number":typeof t.value=="boolean"?"boolean":t.value instanceof Uint8Array?"bytes":null;case"listLiteral":return"list";case"mapLiteral":return"map";case"pathLiteral":return"path";case"memberAccess":{const s=ve(t.object,e);if(s==="mixed")return"mixed";if(t.property==="data"&&s==="document")return"map";if(t.object.type==="mapLiteral"){const r=t.object.entries.find(({key:i})=>i.type==="literal"&&i.value===t.property);return r?ve(r.value,e):null}return null}case"bracketAccess":{const s=ve(t.object,e);if(s==="mixed")return"mixed";if(t.object.type==="listLiteral"&&t.index.type==="literal"&&typeof t.index.value=="number"&&Number.isInteger(t.index.value)){const i=t.object.elements[t.index.value];return i?ve(i,e):null}if(t.object.type==="mapLiteral"&&t.index.type==="literal"){const i=t.index.value,o=t.object.entries.find(({key:a})=>a.type==="literal"&&a.value===i);return o?ve(o.value,e):null}if(s==="string")return"string";const r=Ce(t.object,e);return e.service==="firebase.storage"&&Array.isArray(r)&&(r.join(".")==="request.resource.metadata"||r.join(".")==="resource.metadata")?"string":null}case"sliceAccess":{const s=ve(t.object,e);return s==="mixed"?"mixed":s==="list"||s==="string"?s:null}case"methodCall":{const s=rc(t);if(t.object.type==="identifier"&&s)return s;if(t.method==="get"){const r=Ce(t.object,e);if(e.service==="firebase.storage"&&Array.isArray(r)&&(r.join(".")==="request.resource.metadata"||r.join(".")==="resource.metadata"))return"string";const i=t.args[1];if(t.object.type==="mapLiteral"&&t.args[0]?.type==="literal"){const o=t.args[0].value,a=t.object.entries.find(({key:c})=>c.type==="literal"&&c.value===o);return a?ve(a.value,e):i?ve(i,e):null}return i&&ve(i,e)?"mixed":null}return rc(t)}case"binaryOp":{const s=ve(t.left,e),r=ve(t.right,e);return t.op==="+"&&(s==="string"||r==="string")?"string":["==","!=","<","<=",">",">=","&&","||"].includes(t.op)?"boolean":["+","-","*","/","%"].includes(t.op)&&s==="number"&&r==="number"?"number":null}case"unaryOp":return t.op==="!"?"boolean":t.op==="-"&&ve(t.operand,e)==="number"?"number":null;case"inExpr":case"isExpr":return"boolean";case"ternary":{const s=ve(t.consequent,e),r=ve(t.alternate,e);return!s&&!r?null:s===r?s:"mixed"}case"functionCall":{const s=e.functions.get(t.name);if(!s&&e.service==="cloud.firestore"){if(t.name==="get"||t.name==="getAfter")return"document";if(t.name==="exists")return"boolean";if(t.name==="string")return"string";if(t.name==="int"||t.name==="float")return"number";if(t.name==="path")return"path"}if(!s||e.stack.has(s.name))return null;const r=id(s,t.args.map(i=>Ln(i,e)),e);for(const i of s.lets){const o=Ln(i.value,r);r.aliases.set(i.name,o.provenance),r.receiverTypes.set(i.name,o.receiverType)}return ve(s.body,r)}default:return null}}function ag(t){return t.match(/^\.\/stdlib\/(.+?)(?:\.rules)?$/)?.[1]??t}function cg(t,e,n){const s=ag(e),r=Go[s];return r?r.includes(t)?null:`Function '${n}' from module '${e}' is not compatible with service '${t}'`:null}function ug(t){throw new Error(`Unhandled Rules expression: ${JSON.stringify(t)}`)}const lg=new Set(Gm),dg=new Set(Hm),fg=Object.fromEntries(Object.entries(nd).map(([t,e])=>[t,new Set(e)])),hg=new Set(Zm),pg=new Set(Jm),mg=Object.fromEntries(Object.entries(rd).map(([t,e])=>[t,new Set(e)]));function ir(t,e){return t==="unknown-ambient"?"binding '<derived ambient value>'":t&&!eg(e,t)?`binding '${t.join(".")}'`:null}function gg(t,e,n,s,r){if(e!=="get"&&e!=="keys"&&e!=="values")return null;const i=Ce(t,r);if(i==="unknown-ambient")return"binding '<derived ambient value>'";if(!i)return null;if(e==="get"){const o=n[0];if(o?.type==="literal"&&typeof o.value=="string")return ir([...i,o.value],s);if(!ms(s,i))return`binding '${i.join(".")}.get(...)'`}return(e==="keys"||e==="values")&&!ms(s,i)?`binding '${i.join(".")}.${e}()'`:null}function yg(t,e,n,s){const r=ve(t,s);if(!r||r==="unknown"||r==="mixed")return null;const o=(n==="cloud.firestore"?Km:Qm)[e];return o?.includes(r)?null:`method '.${e}()' requires ${o?.join("|")??"an accepted"} receiver, got ${r}`}function bg(t,e,n,s){const r=Ce(e,s);return r==="unknown-ambient"?"binding '<derived ambient value>'":r?t.type==="literal"&&typeof t.value=="string"?ir([...r,t.value],n):ms(n,r)?null:`binding '<value> in ${r.join(".")}'`:null}function ic(t,e,n){const s=r=>{switch(r.type){case"memberAccess":{const i=ir(Ce(r,n),e);return i||s(r.object)}case"functionCall":{const i=n.functions.get(r.name);if(!i&&!(e==="cloud.firestore"?lg:hg).has(r.name))return`function '${r.name}()'`;for(const a of r.args){const c=s(a);if(c)return c}if(i&&!n.stack.has(i.name)){const a=new Map,c=new Map;i.parameters.forEach((l,d)=>{const f=r.args[d];a.set(l,f?Ce(f,n):null),c.set(l,f?ve(f,n):null)});const u=od(i,e,{aliases:a,receiverTypes:c,functions:n.functions,service:e,stack:new Set([...n.stack,i.name])});if(u)return u}return null}case"methodCall":{if(r.object.type==="identifier"&&!n.aliases.has(r.object.name)){const u=(e==="cloud.firestore"?fg:mg)[r.object.name];if(u){if(!u.has(r.method))return`method '${r.object.name}.${r.method}()'`;for(const l of r.args){const d=s(l);if(d)return d}return null}return r.object.name==="firestore"?`method 'firestore.${r.method}()'`:`namespace '${r.object.name}'`}if(!(e==="cloud.firestore"?dg:pg).has(r.method))return`method '.${r.method}()'`;const o=yg(r.object,r.method,e,n);if(o)return o;const a=gg(r.object,r.method,r.args,e,n);return a||(s(r.object)??r.args.map(s).find(Boolean)??null)}case"binaryOp":return s(r.left)??s(r.right);case"unaryOp":return s(r.operand);case"bracketAccess":{const i=Ce(r.object,n);if(i==="unknown-ambient")return"binding '<derived ambient value>[...]'";const o=r.index.type==="literal"&&typeof r.index.value=="string";if(i&&!o)return ms(e,i)?s(r.object)??s(r.index):`binding '${i.join(".")}[...]'`;const a=ir(Ce(r,n),e);return a||(s(r.object)??s(r.index))}case"sliceAccess":return s(r.object)??s(r.start)??s(r.end);case"ternary":return s(r.condition)??s(r.consequent)??s(r.alternate);case"inExpr":return bg(r.element,r.collection,e,n)??s(r.element)??s(r.collection);case"isExpr":return s(r.value);case"listLiteral":return r.elements.map(s).find(Boolean)??null;case"mapLiteral":for(const i of r.entries){const o=s(i.key)??s(i.value);if(o)return o}return null;case"pathLiteral":for(const i of r.segments)if(typeof i!="string"){const o=s(i);if(o)return o}return null;case"literal":return null;case"identifier":return r.name==="request"||r.name==="resource"||n.aliases.has(r.name)?null:`identifier '${r.name}'`;default:return ug(r)}};return s(t)}function od(t,e,n){const s=new Map(n.aliases),r=new Map(n.receiverTypes),i={...n,aliases:s,receiverTypes:r};for(const o of t.lets){const a=ic(o.value,e,i);if(a)return a;s.set(o.name,Ce(o.value,i)),r.set(o.name,ve(o.value,i))}return ic(t.body,e,i)}function vg(t,e,n=new Map([[t.name,t]]),s=[]){const r={aliases:new Map,receiverTypes:new Map,functions:n,service:e,stack:new Set([t.name])};return od(t,e,{aliases:new Map(t.parameters.map((i,o)=>[i,o<s.length?s[o]?.provenance??null:null])),receiverTypes:new Map(t.parameters.map((i,o)=>[i,s[o]?ve(s[o].expression,r)??s[o].receiverType??null:null])),functions:n,service:e,stack:new Set([t.name])})}function wg(t){throw new Error(`Unhandled Rules expression: ${JSON.stringify(t)}`)}function Sg(t){const e=t.replace(/^\.\.\//,"_").replace(/^\.\//,"").replace(/[^A-Za-z0-9_]/g,"_");return e.length===0||/^[0-9]/.test(e)?`_${e}`:e}function Ye(t,e){if(t!==e){const n=Ts(t);for(let s=0;s<n;s++)Ro(e)}return e}function ce(t,e){switch(t.type){case"functionCall":{const n=e.get(t.name)??t.name,s=t.args.map(r=>ce(r,e));return Ye(t,n===t.name&&s.every((r,i)=>r===t.args[i])?t:{...t,name:n,args:s})}case"binaryOp":{const n=ce(t.left,e),s=ce(t.right,e);return Ye(t,n===t.left&&s===t.right?t:{...t,left:n,right:s})}case"unaryOp":{const n=ce(t.operand,e);return Ye(t,n===t.operand?t:{...t,operand:n})}case"methodCall":{const n=ce(t.object,e),s=t.args.map(r=>ce(r,e));return Ye(t,n===t.object&&s.every((r,i)=>r===t.args[i])?t:{...t,object:n,args:s})}case"memberAccess":{const n=ce(t.object,e);return Ye(t,n===t.object?t:{...t,object:n})}case"bracketAccess":{const n=ce(t.object,e),s=ce(t.index,e);return Ye(t,n===t.object&&s===t.index?t:{...t,object:n,index:s})}case"sliceAccess":{const n=ce(t.object,e),s=ce(t.start,e),r=ce(t.end,e);return Ye(t,n===t.object&&s===t.start&&r===t.end?t:{...t,object:n,start:s,end:r})}case"ternary":{const n=ce(t.condition,e),s=ce(t.consequent,e),r=ce(t.alternate,e);return Ye(t,n===t.condition&&s===t.consequent&&r===t.alternate?t:{...t,condition:n,consequent:s,alternate:r})}case"inExpr":{const n=ce(t.element,e),s=ce(t.collection,e);return Ye(t,n===t.element&&s===t.collection?t:{...t,element:n,collection:s})}case"isExpr":{const n=ce(t.value,e);return Ye(t,n===t.value?t:{...t,value:n})}case"listLiteral":{const n=t.elements.map(s=>ce(s,e));return Ye(t,n.every((s,r)=>s===t.elements[r])?t:{...t,elements:n})}case"mapLiteral":{const n=t.entries.map(s=>{const r=ce(s.key,e),i=ce(s.value,e);return r===s.key&&i===s.value?s:{key:r,value:i}});return Ye(t,n.every((s,r)=>s===t.entries[r])?t:{...t,entries:n})}case"pathLiteral":{const n=t.segments.map(s=>typeof s=="string"?s:ce(s,e));return Ye(t,n.every((s,r)=>s===t.segments[r])?t:{...t,segments:n})}case"literal":case"identifier":return t;default:return wg(t)}}function Ag(t,e){const n=Sg(e),s=new Map;for(const r of t)r.exported||s.set(r.name,`${n}__${r.name}`);return s.size===0?t:t.map(r=>{const i=ce(r.body,s),o=r.lets.map(c=>{const u=ce(c.value,s);return u===c.value?c:{...c,value:u}}),a=r.exported?r.name:s.get(r.name)??r.name;return i===r.body&&o===r.lets&&a===r.name?r:{...r,name:a,body:i,lets:o}})}function kg(t){throw new Error(`Unhandled Rules expression: ${JSON.stringify(t)}`)}function Ho(t){const e=[],n=s=>{switch(s.type){case"functionCall":e.push(s),s.args.forEach(n);break;case"binaryOp":n(s.left),n(s.right);break;case"unaryOp":n(s.operand);break;case"methodCall":n(s.object),s.args.forEach(n);break;case"memberAccess":n(s.object);break;case"bracketAccess":n(s.object),n(s.index);break;case"sliceAccess":n(s.object),n(s.start),n(s.end);break;case"ternary":n(s.condition),n(s.consequent),n(s.alternate);break;case"inExpr":n(s.element),n(s.collection);break;case"isExpr":n(s.value);break;case"listLiteral":s.elements.forEach(n);break;case"mapLiteral":s.entries.forEach(({key:r,value:i})=>{n(r),n(i)});break;case"pathLiteral":s.segments.forEach(r=>{typeof r!="string"&&n(r)});break;case"literal":case"identifier":break;default:kg(s)}};return n(t),e}function Eg(t){return{expression:t.expression,provenance:t.provenance,receiverType:!t.receiverType||t.receiverType==="mixed"?"unknown":t.receiverType}}function Ig(t,e,n=new Map){const s=[],r=new Map,i=new Set,o=t.service.name==="firebase.storage"?"firebase.storage":"cloud.firestore",a=(h,m=new Set)=>({aliases:new Map(h.aliases),receiverTypes:new Map(h.receiverTypes),functions:h.functions,service:o,stack:m,declarations:r}),c=(h,m,g)=>{if(g.has(h.name))return;const y=r.get(h);if(!y)return;i.add(h);const b=new Map(y.aliases),v=new Map(y.receiverTypes);h.parameters.forEach((k,O)=>{b.set(k,m[O]?.provenance??null),v.set(k,m[O]?.receiverType??null)});const w=a({aliases:b,receiverTypes:v,functions:y.functions},new Set([...g,h.name]));for(const k of h.lets){u(k.value,w);const O=Ln(k.value,w);w.aliases.set(k.name,O.provenance),w.receiverTypes.set(k.name,O.receiverType)}u(h.body,w)},u=(h,m)=>{for(const g of Ho(h)){const y=g.args.map(v=>Ln(v,m));g.name===e&&s.push({arguments:y.map(Eg)});const b=m.functions.get(g.name);b&&!n.has(g.name)&&c(b,y,m.stack)}},l=new Map((t.functions??[]).map(h=>[h.name,h])),d=new Map([...l,...n]);for(const h of t.service.functions??[])d.set(h.name,h);for(const h of n.values())r.set(h,{aliases:new Map,receiverTypes:new Map,functions:n});const f=[];for(const h of t.functions??[])r.set(h,{aliases:new Map,receiverTypes:new Map,functions:l}),f.push(h);for(const h of t.service.functions??[])r.set(h,{aliases:new Map,receiverTypes:new Map,functions:d}),f.push(h);const p=(h,m)=>{const g=new Map(m.receiverTypes);for(const w of h.path.segments)w.type==="wildcard"&&g.set(w.name,"string"),w.type==="recursive"&&g.set(w.name,"path");const y=new Map(m.functions),b={aliases:m.aliases,receiverTypes:g,functions:y};for(const w of h.functions)y.set(w.name,w),r.set(w,b),f.push(w);const v=a(b);for(const{condition:w}of h.allows)u(w,v);h.children.forEach(w=>p(w,b))};p(t.service.match,{aliases:new Map,receiverTypes:new Map,functions:d});for(const h of f)i.has(h)||c(h,[],new Set);return s}function Gn(t){return Ho(t).map(({name:e})=>e)}function _g(t,e){return[...t.values()].flatMap(s=>[...s.lets.map(({value:r})=>r),s.body]).flatMap(Ho).filter(({name:s})=>s===e).map(({args:s})=>s)}const xg=/^(?:\s+|\/\/[^\n]*|\/\*[\s\S]*?\*\/)/,Cg=/^rules_version\s*=\s*(['"])([^'"]*)\1\s*;/,Og=/^import\s*\{([^}]*)\}\s*from\s*(['"])([^'"]+)\2\s*;/,Tg=/^\s*(?:import\s*\{|rules_version\b)/m;function oc(t){return t.replace(/[^\n]/g," ")}function Rg(t,e){const n=[];let s=t,r=0;for(;;){const i=t.slice(r),o=xg.exec(i);if(o){r+=o[0].length;continue}const a=Cg.exec(i);if(a){if(a[2]!=="2+modules")return{success:!1,error:{code:"NOT_MODULE_SOURCE",message:`Module '${e}' declares rules_version '${a[2]}'; a module's version is '2+modules'`}};s=s.slice(0,r)+oc(a[0])+s.slice(r+a[0].length),r+=a[0].length;continue}const c=Og.exec(i);if(c){const u=c[1].split(",").map(l=>l.trim()).filter(l=>l!=="");n.push({module:c[3],functions:u}),s=s.slice(0,r)+oc(c[0])+s.slice(r+c[0].length),r+=c[0].length;continue}return{success:!0,body:s,imports:n}}}function ac(t,e,n){const s=Rg(t,e);if(!s.success)return s;const r=Up(s.body,e);return r===null?{success:!1,error:{code:"PARSE_FAILED",message:Tg.test(s.body)?`Failed to parse module '${e}': a module puts rules_version and imports before its first function`:`Failed to parse module '${e}'`}}:{success:!0,functions:r,imports:s.imports,bundled:n}}function Ng(t,e){if(t===null||!gs(e)||!gs(t))return e;const n=[];for(const r of[...t.split("/").slice(0,-1),...e.split("/")]){if(r==="."||r==="")continue;const i=n.length>0&&n[n.length-1]!=="..";r===".."&&i?n.pop():n.push(r)}const s=n.join("/");return s.startsWith("..")?s:`./${s}`}function gs(t){return t.startsWith("./")||t.startsWith("../")}function ys(t){return/^\.\/stdlib\/([A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*)(?:\.rules)?$/.exec(t)?.[1]??null}function cc(t,e,n,s=new Set){return n?.modules&&Object.prototype.hasOwnProperty.call(n.modules,e)?s.has(e)?ys(e)??e:e:(gs(e)&&n?.basePath,ys(e)??e)}function Lg(t,e,n,s=new Set){if(n?.modules&&Object.prototype.hasOwnProperty.call(n.modules,e))return ac(n.modules[e],e,s.has(e));if(gs(e)&&n?.basePath){const i=`${n.basePath}/${e}${e.endsWith(".rules")?"":".rules"}`;if(!ys(e))return{success:!1,error:{code:"UNKNOWN_MODULE",message:`Module '${e}' not found at ${i}`}}}const r=ys(e);return r?n?.modules&&Object.prototype.hasOwnProperty.call(n.modules,r)?ac(n.modules[r],e,s.has(r)):{success:!1,error:{code:"UNKNOWN_MODULE",message:`Module '${e}' not found`}}:gs(e)?{success:!1,error:{code:"UNKNOWN_MODULE",message:`Module '${e}' requires basePath for relative imports`}}:{success:!1,error:{code:"UNKNOWN_MODULE",message:`Module '${e}' not found`}}}function Mg(t,e,n,s=new Set){const r=Rs(e);if(!r.ok){const{line:A,column:M,message:se}=r.error;return{success:!1,error:{code:"PARSE_FAILED",message:`Failed to parse source at line ${A}, col ${M}: ${se}`}}}const i=r.ast,o=i.version==="2+modules",a=i.service.name==="firebase.storage";let c=a?"storage.rules":"firestore.rules";if(o&&(c=a?"storage.modules.rules":"firestore.modules.rules"),n!==void 0&&n.sourceFile!==void 0&&n.sourceFile!==""&&(c=n.sourceFile),Dg(i,c),o===!1)return{success:!1,error:{code:"NOT_MODULE_SOURCE",message:`Version '${i.version}' is not a module source`}};if(i.service.name==="cloud.firestore"===!1&&i.service.name==="firebase.storage"===!1)return{success:!1,error:{code:"UNSUPPORTED_SERVICE",message:`Module resolution does not support service '${i.service.name}'`}};const d=new Set([...(i.functions??[]).map(A=>A.name),...(i.service.functions??[]).map(A=>A.name)]),f=A=>{A.functions.forEach(M=>d.add(M.name)),A.children.forEach(f)};f(i.service.match);const p=[...d].find(A=>ci.has(A));if(p)return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Source function '${p}' conflicts with a Rules builtin`}};if(i.imports.length===0){i.version="2";const A=Ya(i),M=JSON.stringify(A.sourceMap);return{success:!0,data:{resolved:`${A.resolved}// @pyric-source-map: ${M}
|
|
517
|
+
`,modules:[],bundledModules:[],evidenceIds:[],sourceMap:A.sourceMap}}}const m=i.imports.find(A=>A.functions.length===0);if(m)return{success:!1,error:{code:"UNKNOWN_FUNCTION",message:`Import from '${m.module}' must request at least one function`}};const g=new Map,y=new Map,b=new Map,v=new Map,w=[],k=[],O=new Map,R=new Map,V=new Map,G=new Map,N=new Map,D=i.imports.map(A=>({module:A.module,functions:A.functions,importer:null}));for(let A=D.shift();A!==void 0;A=D.shift()){const M=cc(t,A.module,n,s);if(!R.has(M)){const U=Lg(t,A.module,n,s);if(!U.success)return{success:!1,error:U.error};w.push(A.module),b.set(M,A.module),V.set(M,U.bundled),U.bundled&&k.push(A.module);for(const de of U.imports){if(de.functions.length===0)return{success:!1,error:{code:"UNKNOWN_FUNCTION",message:`Import from '${de.module}' in module '${A.module}' must request at least one function`}};D.push({...de,module:Ng(A.module,de.module),importer:M})}const ae=new Set,kt=U.functions.find(de=>ae.has(de.name)?!0:(ae.add(de.name),!1));if(kt)return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Module '${A.module}' defines duplicate function '${kt.name}'`}};const Bn=U.functions.find(de=>ci.has(de.name));if(Bn)return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Function '${Bn.name}' from module '${A.module}' conflicts with a Rules builtin`}};const Sn=new Set;for(const de of U.functions)de.exported||Sn.add(de.name);O.set(M,Sn);const Ie=Ag(U.functions,A.module),Xr=new Map;for(const de of Ie){if(Xr.has(de.name))return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Module '${A.module}' defines conflicting function name '${de.name}'`}};Xr.set(de.name,de),y.has(de.name)||y.set(de.name,A.module)}const $f=new Set(Ie.filter(de=>de.exported).map(de=>de.name));g.set(M,Xr),R.set(M,$f)}const se=R.get(M),Ve=b.get(M)??A.module;for(const U of A.functions){if(!se.has(U))return{success:!1,error:{code:"UNKNOWN_FUNCTION",message:O.get(M)?.has(U)?`Function '${U}' in module '${A.module}' is not exported`:`Function '${U}' not found in module '${A.module}'`}};if(i.service.name==="cloud.firestore"||i.service.name==="firebase.storage"){const ae=V.get(M)?cg(i.service.name,A.module,U):null;if(ae)return{success:!1,error:{code:"INCOMPATIBLE_FUNCTION",message:ae}}}if(A.importer===null){const ae=N.get(U);if(ae!==void 0&&ae!==M)return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Function '${U}' exported by both '${b.get(ae)}' and '${Ve}'`}};N.set(U,M)}else{const ae=G.get(A.importer)??new Map,kt=ae.get(U);if(kt!==void 0&&kt!==M)return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Function '${U}' exported by both '${b.get(kt)}' and '${Ve}'`}};ae.set(U,M),G.set(A.importer,ae)}}}const K=new Set(i.imports.flatMap(A=>A.functions)),q=[],x=[],S={cycle:null,error:null};function _(A,M){if(S.cycle||S.error)return;const se=x.findIndex(Ie=>Ie.modKey===A&&Ie.fnName===M);if(se>=0){S.cycle=[...x.slice(se).map(Ie=>Ie.fnName),M];return}const Ve=v.get(M);if(Ve!==void 0){if(Ve===A)return;S.error={code:"DUPLICATE_FUNCTION",message:`Function '${M}' from module '${b.get(A)}' conflicts with module '${b.get(Ve)}'`};return}const U=g.get(A)?.get(M);if(!U)return;x.push({modKey:A,fnName:M});const ae=[...U.lets.flatMap(({value:Ie})=>Gn(Ie)),...Gn(U.body)],kt=g.get(A),Bn=G.get(A);for(const Ie of ae)if(!ci.has(Ie)){if(kt?.has(Ie))_(A,Ie);else if(Bn?.has(Ie))_(Bn.get(Ie),Ie);else if(y.has(Ie)){S.error={code:"UNKNOWN_FUNCTION",message:`Function '${U.name}' in module '${b.get(A)}' cannot call '${Ie}' from another module`},x.pop();return}if(S.cycle||S.error){x.pop();return}}if(x.pop(),S.cycle||S.error)return;const Sn=v.get(M);if(Sn!==void 0&&Sn!==A){S.error={code:"DUPLICATE_FUNCTION",message:`Function '${M}' from module '${b.get(A)}' conflicts with module '${b.get(Sn)}'`};return}v.set(M,A),q.push({...U,exported:!1})}for(const A of i.imports){const M=cc(t,A.module,n,s);for(const se of A.functions)_(M,se)}if(S.cycle)return{success:!1,error:{code:"CIRCULAR_DEPENDENCY",message:`Recursive module function dependency: ${S.cycle.join(" -> ")}`}};if(S.error)return{success:!1,error:S.error};const P=new Set(q.map(A=>A.name)),$=new Map((i.functions??[]).map(A=>[A.name,A])),z=new Set((i.service.functions??[]).map(A=>A.name)),ee=(A,M)=>A.flatMap(Gn).find(se=>y.has(se)&&!K.has(se)&&!M.has(se))??null,ne=A=>A.flatMap(M=>[...M.lets.map(({value:se})=>se),M.body]),Qe=new Set($.keys());let jt=ee(ne(i.functions??[]),Qe);const le=new Set([...Qe,...z]);jt??=ee(ne(i.service.functions??[]),le);const Le=(A,M)=>{const se=new Set([...M,...A.functions.map(U=>U.name)]),Ve=[...ne(A.functions),...A.allows.map(({condition:U})=>U)];return ee(Ve,se)??A.children.map(U=>Le(U,se)).find(Boolean)??null};if(jt??=Le(i.service.match,le),jt)return{success:!1,error:{code:"UNKNOWN_FUNCTION",message:`Source calls function '${jt}' from module '${y.get(jt)}' without importing it`}};const pe=(A,M)=>{if(M.has(A.name))return!1;const se=new Set([...M,A.name]);return[...A.lets.flatMap(({value:U})=>Gn(U)),...Gn(A.body)].some(U=>{const ae=$.get(U);return ae?pe(ae,se):P.has(U)||z.has(U)})},et=[...$.values()].find(A=>pe(A,new Set));if(et)return{success:!1,error:{code:"INCOMPATIBLE_FUNCTION",message:`Global function '${et.name}' cannot call a service-scoped function`}};if(i.service.name==="firebase.storage"||i.service.name==="cloud.firestore"){const A=new Map(q.map(M=>[M.name,M]));for(const M of q){const se=[...Ig(i,M.name,A),..._g(A,M.name).map(U=>({arguments:U.map(ae=>({expression:ae,provenance:null,receiverType:"unknown"}))}))],Ve=se.length>0?se:[{arguments:[]}];for(const{arguments:U}of Ve){const ae=vg(M,i.service.name,A,U);if(ae)return{success:!1,error:{code:"INCOMPATIBLE_FUNCTION",message:`Function '${M.name}' requires unsupported ${ae} for service '${i.service.name}'`}}}}}for(const A of q)if(d.has(A.name))return{success:!1,error:{code:"DUPLICATE_FUNCTION",message:`Imported function '${A.name}' conflicts with a function defined in the source`}};i.service.functions=[...q,...i.service.functions??[]],i.version="2",i.imports=[];const be=new Set,We=i.service.name==="firebase.storage"?"storage-rules#":"firestore-rules#";for(const A of k){const M=ys(A)??A,se=Vm[M]??[];for(const Ve of se)Ve.startsWith(We)&&be.add(Ve)}const ie=Ya(i),sn=JSON.stringify(ie.sourceMap);return{success:!0,data:{resolved:`${ie.resolved}// @pyric-source-map: ${sn}
|
|
518
|
+
`,modules:w,bundledModules:k,evidenceIds:[...be].sort(),sourceMap:ie.sourceMap}}}function Dg(t,e){const n=a=>{a.loc!==void 0&&(a.loc.file=e);for(const c of a.lets)c.loc!==void 0&&(c.loc.file=e);a.returnLoc!==void 0&&(a.returnLoc.file=e),a.body?.loc!==void 0&&(a.body.loc.file=e)};if(t.service.loc!==void 0&&(t.service.loc.file=e),t.functions!==void 0)for(const a of t.functions)n(a);if(t.service.functions!==void 0)for(const a of t.service.functions)n(a);const i=[t.service.match];let o=i.length;for(;o>0;){const a=i.pop();a.loc!==void 0&&(a.loc.file=e);for(const u of a.allows)u.loc!==void 0&&(u.loc.file=e);for(const u of a.functions)n(u);for(const u of a.children)i.push(u);o=i.length}}const uc="// @pyric-source-map: ";function Ko(t){const e=new Map,n=t.indexOf(uc);if(!(n!==-1))return e;const r=n+uc.length,i=t.indexOf(`
|
|
519
|
+
`,r);let o="";i!==-1?o=t.slice(r,i).trim():o=t.slice(r).trim();try{const c=JSON.parse(o);if(Array.isArray(c))for(const l of c)!e.has(l.generatedLine)&&e.set(l.generatedLine,l)}catch{}return e}function $g(t,e,n,s,r){if(e!==void 0)return ad(Ko(t),e,n,s,r)}function ad(t,e,n,s,r){if(e===void 0)return;let o=e,a=1;n!==void 0&&(a=n);let u="firestore.rules";s!==void 0&&s!==""&&(u=s);let d;r!==void 0&&(d=r);const p=t.get(o);p!==void 0&&(o=p.authoredLine,a=p.authoredCol,u=p.authoredFile,p.expression!==void 0&&(d=p.expression));const m=`${u}:${o}:${a}`,g={line:o,col:a,file:u,citation:m};return d!==void 0&&(g.expression=d),g}const Pg={atomic:`// @pyric-services cloud.firestore
|
|
520
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
521
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
522
|
+
// function is paid on every call.
|
|
523
|
+
//
|
|
524
|
+
// Atomic module — cross-document integrity for BATCH writes, via the
|
|
525
|
+
// get()/getAfter() pair. Firestore evaluates every write in a batch
|
|
526
|
+
// against rules, and getAfter() returns another document's POST-BATCH
|
|
527
|
+
// state — so a rule can require "this write is only valid if a
|
|
528
|
+
// companion write happened in the same atomic batch".
|
|
529
|
+
//
|
|
530
|
+
// All semantics live-verified against a production database: companion
|
|
531
|
+
// visibility, solo-write denial, wrong-delta denial, single-use consumption
|
|
532
|
+
// incl. replay denial, and out-of-batch getAfter() falling back to current
|
|
533
|
+
// state.
|
|
534
|
+
//
|
|
535
|
+
// Explicit-param design: pass BOTH states of the companion doc —
|
|
536
|
+
// \`get(path).data\` (pre-batch) and \`getAfter(path).data\` (post-batch).
|
|
537
|
+
//
|
|
538
|
+
// import { companionChangedBy, consumedFlag } from 'atomic';
|
|
539
|
+
//
|
|
540
|
+
// // Denormalized counter: creating a task REQUIRES the team's
|
|
541
|
+
// // taskCount to have been incremented in the same batch:
|
|
542
|
+
// match /teams/{teamId}/tasks/{taskId} {
|
|
543
|
+
// function teamBefore() {
|
|
544
|
+
// return get(/databases/$(database)/documents/teams/$(teamId)).data;
|
|
545
|
+
// }
|
|
546
|
+
// function teamAfter() {
|
|
547
|
+
// return getAfter(/databases/$(database)/documents/teams/$(teamId)).data;
|
|
548
|
+
// }
|
|
549
|
+
// allow create: if companionChangedBy(teamBefore(), teamAfter(), 'taskCount', 1);
|
|
550
|
+
// }
|
|
551
|
+
//
|
|
552
|
+
// // Single-use invite: the join is valid only when the invite was
|
|
553
|
+
// // consumed (false -> true) IN THIS BATCH — replays deny because
|
|
554
|
+
// // the pre-batch state is already true:
|
|
555
|
+
// allow update: if consumedFlag(inviteBefore(), inviteAfter(), 'used');
|
|
556
|
+
//
|
|
557
|
+
// NOTE (simulator): in-batch companion semantics cannot be expressed
|
|
558
|
+
// in the simulator or the Rules Test API mock surface — the simulator
|
|
559
|
+
// treats cross-doc getAfter() as get(). These function BODIES are
|
|
560
|
+
// simulator-tested with explicit values; the getAfter() WIRING is the
|
|
561
|
+
// live v1 scope's job. Companion writes need their own allow rules too —
|
|
562
|
+
// every write in a batch is evaluated.
|
|
563
|
+
|
|
564
|
+
// The companion doc's field changed by EXACTLY n in this batch.
|
|
565
|
+
// before/after are the SAME doc's get()/getAfter() data.
|
|
566
|
+
// cost 10 to 10 expressions per call
|
|
567
|
+
export function companionChangedBy(before, after, field, n) {
|
|
568
|
+
return after[field] == before[field] + n;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// A single-use flag was consumed IN THIS BATCH: pre-batch false,
|
|
572
|
+
// post-batch true. Replays deny (pre-batch is already true), and a
|
|
573
|
+
// solo write denies (getAfter == get, so false != true).
|
|
574
|
+
// cost 7 to 13 expressions per call
|
|
575
|
+
export function consumedFlag(before, after, flagField) {
|
|
576
|
+
return before[flagField] == false && after[flagField] == true;
|
|
577
|
+
}
|
|
578
|
+
`,auth:`// @pyric-services cloud.firestore,firebase.storage
|
|
579
|
+
// @pyric-evidence storage-rules#125,firestore-rules#189
|
|
580
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
581
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
582
|
+
// function is paid on every call.
|
|
583
|
+
//
|
|
584
|
+
// cost 5 to 5 expressions per call
|
|
585
|
+
export function isAuthenticated() {
|
|
586
|
+
return request.auth != null;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// cost 7 to 13 expressions per call
|
|
590
|
+
export function isOwner(userId) {
|
|
591
|
+
return isAuthenticated() && request.auth.uid == userId;
|
|
592
|
+
}
|
|
593
|
+
`,content:`// @pyric-services cloud.firestore
|
|
594
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
595
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
596
|
+
// function is paid on every call.
|
|
597
|
+
//
|
|
598
|
+
// Content module for author-owned documents, the most common
|
|
599
|
+
// Firebase app shape (posts, notes, docs, comments, tasks).
|
|
600
|
+
//
|
|
601
|
+
// Convention: documents carry an author field (a UID string) and
|
|
602
|
+
// usually a status field ('draft' | 'published' | ...). Field names
|
|
603
|
+
// are parameters, not conventions: pass yours.
|
|
604
|
+
//
|
|
605
|
+
// Usage:
|
|
606
|
+
// import { validAuthorCreate, isAuthor, canReadContent, notDeleted } from 'content';
|
|
607
|
+
// import { onlyFieldsChanged } from 'lifecycle';
|
|
608
|
+
//
|
|
609
|
+
// match /posts/{postId} {
|
|
610
|
+
// // Create: author is the signed-in user.
|
|
611
|
+
// allow create: if validAuthorCreate('author');
|
|
612
|
+
// // Read: published to everyone, drafts to the author only.
|
|
613
|
+
// allow read: if canReadContent('status', 'author') && notDeleted();
|
|
614
|
+
// // Update: author edits content fields; authorship immutable.
|
|
615
|
+
// allow update: if isAuthor('author') && onlyFieldsChanged(['title', 'body', 'status']);
|
|
616
|
+
// allow delete: if isAuthor('author');
|
|
617
|
+
// }
|
|
618
|
+
//
|
|
619
|
+
// Hidden per-player documents: a fleet, a hand or a secret pick that only
|
|
620
|
+
// its owner reads until the match ends. The document lives under its match,
|
|
621
|
+
// at {collection}/{matchId}/{sub}/{uid}: the document id is the owner's UID,
|
|
622
|
+
// and the parent match document carries a \`status\` field. When your owner is
|
|
623
|
+
// a field instead, pass resource.data.<field> as the owner.
|
|
624
|
+
//
|
|
625
|
+
// import { ownerOnlyUntil } from 'content';
|
|
626
|
+
//
|
|
627
|
+
// match /battleship/{matchId}/boards/{uid} {
|
|
628
|
+
// allow read: if ownerOnlyUntil(
|
|
629
|
+
// /databases/$(database)/documents/battleship/$(matchId), uid, ['won', 'resigned']);
|
|
630
|
+
// }
|
|
631
|
+
|
|
632
|
+
// Create guard: signed in, and the incoming doc's author field is the
|
|
633
|
+
// caller. Use on \`create\` (reads request.resource).
|
|
634
|
+
// cost 6 to 16 expressions per call
|
|
635
|
+
export function validAuthorCreate(authorField) {
|
|
636
|
+
return request.auth != null
|
|
637
|
+
&& request.resource.data[authorField] == request.auth.uid;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// The caller is the EXISTING document's author. Use on update/delete
|
|
641
|
+
// (reads resource).
|
|
642
|
+
// cost 6 to 15 expressions per call
|
|
643
|
+
export function isAuthor(authorField) {
|
|
644
|
+
return request.auth != null
|
|
645
|
+
&& resource.data[authorField] == request.auth.uid;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Read visibility: published content is public; anything else is
|
|
649
|
+
// visible to its author only. Works for get; for list queries the
|
|
650
|
+
// client must filter (rules are not filters: a bare collection query
|
|
651
|
+
// is denied unless it proves status == 'published').
|
|
652
|
+
// cost 8 to 23 expressions per call
|
|
653
|
+
export function canReadContent(statusField, authorField) {
|
|
654
|
+
return resource.data[statusField] == 'published'
|
|
655
|
+
|| (request.auth != null && resource.data[authorField] == request.auth.uid);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Soft-delete guard: the document is not marked deleted. Reads the
|
|
659
|
+
// EXISTING doc. A doc without the field passes: map.get() returns the
|
|
660
|
+
// default for a missing key, while dotted or bracket access of a missing
|
|
661
|
+
// key is an error in production and denies.
|
|
662
|
+
// cost 8 to 8 expressions per call
|
|
663
|
+
export function notDeleted() {
|
|
664
|
+
return resource.data.get('deleted', false) != true;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Read rule for a hidden per-player document: the owner reads it at any
|
|
668
|
+
// time, and any other signed-in caller reads it once the status of the match
|
|
669
|
+
// at \`parentPath\` is in \`statuses\`. Pass one status as a one-item list, such
|
|
670
|
+
// as ['finished'], or several, such as ['won', 'draw', 'resigned']. The owner
|
|
671
|
+
// check runs before the get(), so the owner's read stops there and spends no
|
|
672
|
+
// read. A missing parent match is an error and denies every caller but the
|
|
673
|
+
// owner.
|
|
674
|
+
// cost 6 to 20 expressions per call, reads 1
|
|
675
|
+
export function ownerOnlyUntil(parentPath, ownerUid, statuses) {
|
|
676
|
+
return request.auth != null
|
|
677
|
+
&& (request.auth.uid == ownerUid
|
|
678
|
+
|| get(parentPath).data.status in statuses);
|
|
679
|
+
}
|
|
680
|
+
`,counters:`// @pyric-services cloud.firestore
|
|
681
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
682
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
683
|
+
// function is paid on every call.
|
|
684
|
+
//
|
|
685
|
+
// Counters module for denormalized numeric integrity.
|
|
686
|
+
//
|
|
687
|
+
// The recurring shape: a client-maintained count (likes, votes, moves,
|
|
688
|
+
// quantities) that rules must keep honest: it may only change by a
|
|
689
|
+
// known step, or stay within known bounds. Generalizes the
|
|
690
|
+
// state-module's moveIncremented() (hardcoded to moveCount) to any
|
|
691
|
+
// field.
|
|
692
|
+
//
|
|
693
|
+
// Usage:
|
|
694
|
+
// import { incrementedBy, changedBy, boundedNumber, improvedBy } from 'counters';
|
|
695
|
+
//
|
|
696
|
+
// // A like toggle: likeCount moves by exactly ±1:
|
|
697
|
+
// allow update: if changedBy('likeCount', -1, 1);
|
|
698
|
+
//
|
|
699
|
+
// // A move counter: strictly +1 per move:
|
|
700
|
+
// allow update: if incrementedBy('moveCount', 1);
|
|
701
|
+
//
|
|
702
|
+
// // A rating: any write keeps it in [1, 5]:
|
|
703
|
+
// allow write: if boundedNumber('rating', 1, 5);
|
|
704
|
+
//
|
|
705
|
+
// // A best score: a new score replaces the old one only when it is
|
|
706
|
+
// // higher, and only the score and its solve id change:
|
|
707
|
+
// allow update: if improvedBy('score', 'up', ['solve']);
|
|
708
|
+
//
|
|
709
|
+
// A best-score check: improvedBy(field, direction, mayChange) allows an
|
|
710
|
+
// update where \`field\` moves strictly 'up' or 'down' and every other
|
|
711
|
+
// changed top-level field is in \`mayChange\`. Write the score's shape
|
|
712
|
+
// checks (type, bounds, owner) beside it: improvedBy only compares the
|
|
713
|
+
// old and new values and pins the unlisted fields. For a score ranked on
|
|
714
|
+
// two fields, such as fewest moves and then fewest pushes, call it once
|
|
715
|
+
// per field. The second call leaves \`moves\` out of \`mayChange\`, so it
|
|
716
|
+
// allows fewer pushes only on as many moves:
|
|
717
|
+
// improvedBy('moves', 'down', ['pushes', 'solve'])
|
|
718
|
+
// || improvedBy('pushes', 'down', ['solve'])
|
|
719
|
+
|
|
720
|
+
// The field changed by EXACTLY n relative to the existing document.
|
|
721
|
+
// n may be negative (decrement). Update rules only (needs resource).
|
|
722
|
+
// cost 13 to 13 expressions per call
|
|
723
|
+
export function incrementedBy(field, n) {
|
|
724
|
+
return request.resource.data[field] == resource.data[field] + n;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// The field's delta is within [min, max] (inclusive) — and it is NOT
|
|
728
|
+
// required to change (delta 0 passes when min <= 0 <= max).
|
|
729
|
+
// cost 14 to 27 expressions per call
|
|
730
|
+
export function changedBy(field, min, max) {
|
|
731
|
+
return request.resource.data[field] - resource.data[field] >= min
|
|
732
|
+
&& request.resource.data[field] - resource.data[field] <= max;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// The incoming value is a number within [min, max] (inclusive).
|
|
736
|
+
// Works on create and update. A missing field is an error under dynamic
|
|
737
|
+
// access, so the call denies.
|
|
738
|
+
// cost 19 to 35 expressions per call
|
|
739
|
+
export function boundedNumber(field, min, max) {
|
|
740
|
+
return (request.resource.data[field] is int || request.resource.data[field] is float)
|
|
741
|
+
&& request.resource.data[field] >= min
|
|
742
|
+
&& request.resource.data[field] <= max;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// The numeric \`field\` moved strictly in \`direction\`, 'up' or 'down', and no
|
|
746
|
+
// other top-level field changed except the ones in \`mayChange\`, a List. A
|
|
747
|
+
// listed field may stay unchanged. Both values must be numbers, int or
|
|
748
|
+
// float; they compare by value. An unchanged value, a move the other way, a
|
|
749
|
+
// non-numeric value on either side, an unlisted field added, removed, or
|
|
750
|
+
// changed, and any other direction make the call false. A field missing
|
|
751
|
+
// from either document is an error in production, which denies, and stays
|
|
752
|
+
// an error under \`!\`. Update rules only: on create the call is an error and
|
|
753
|
+
// the rule denies.
|
|
754
|
+
// cost 18 to 50 expressions per call
|
|
755
|
+
export function improvedBy(field, direction, mayChange) {
|
|
756
|
+
let before = resource.data[field];
|
|
757
|
+
let after = request.resource.data[field];
|
|
758
|
+
return before is number && after is number
|
|
759
|
+
&& ((direction == 'up' && after > before) || (direction == 'down' && after < before))
|
|
760
|
+
&& request.resource.data.diff(resource.data).affectedKeys().hasOnly(mayChange.concat([field]));
|
|
761
|
+
}
|
|
762
|
+
`,fairness:`// @pyric-services cloud.firestore
|
|
763
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
764
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
765
|
+
// function is paid on every call.
|
|
766
|
+
//
|
|
767
|
+
// Fairness for hidden choices and commit-reveal randomness: a player commits
|
|
768
|
+
// to a secret salt before the other players add their input, then reveals
|
|
769
|
+
// the salt. The rules check the reveal against the commitment and derive
|
|
770
|
+
// values from a digest.
|
|
771
|
+
//
|
|
772
|
+
// Convention: commit-reveal as Yacht stores it:
|
|
773
|
+
// commit: string, the uppercase hex SHA-256 of the salt, the form
|
|
774
|
+
// hashing.sha256(salt).toHexString() produces (64 characters)
|
|
775
|
+
// salt: string, the secret, written on the reveal
|
|
776
|
+
//
|
|
777
|
+
// The commitment is a hex string, not Bytes, because the client computes it
|
|
778
|
+
// and writes it as a string field. A commitment stored as Bytes, or as
|
|
779
|
+
// lowercase hex, does not match. The salt is hashed as its UTF-8 bytes.
|
|
780
|
+
//
|
|
781
|
+
// Production Bytes have no index operator: digest[0] is an error.
|
|
782
|
+
// digestByte reads the byte from the digest's hex string instead, two
|
|
783
|
+
// characters per byte, and pays for a 16-entry lookup map on every call.
|
|
784
|
+
//
|
|
785
|
+
// Usage:
|
|
786
|
+
// import { commitmentMatches, digestByte } from 'fairness';
|
|
787
|
+
//
|
|
788
|
+
// // The reveal matches the commitment stored by the commit write:
|
|
789
|
+
// allow update: if commitmentMatches(resource.data.commit, request.resource.data.salt);
|
|
790
|
+
//
|
|
791
|
+
// // A die face from the digest of the salt and another player's nonce:
|
|
792
|
+
// allow update: if request.resource.data.die
|
|
793
|
+
// == digestByte(hashing.sha256(request.resource.data.salt + resource.data.nonce), 0) % 6 + 1;
|
|
794
|
+
|
|
795
|
+
// The salt is a non-empty string and its SHA-256, as uppercase hex, equals
|
|
796
|
+
// \`commitment\`. An empty salt is refused because anyone can compute its
|
|
797
|
+
// digest, so it hides nothing.
|
|
798
|
+
// cost 6 to 16 expressions per call
|
|
799
|
+
export function commitmentMatches(commitment, salt) {
|
|
800
|
+
return salt is string
|
|
801
|
+
&& salt != ''
|
|
802
|
+
&& hashing.sha256(salt).toHexString() == commitment;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// Byte \`index\` of the Bytes value \`digest\`, as an int from 0 to 255. An
|
|
806
|
+
// index outside the digest, or a digest that is not Bytes, is an error, so
|
|
807
|
+
// the rule that uses the value denies. A die face is digestByte(d, i) % 6 + 1:
|
|
808
|
+
// 256 is not a multiple of 6, so faces 1 to 4 come up 43 times in 256 and
|
|
809
|
+
// faces 5 and 6 come up 42 times. Read a new index for each value.
|
|
810
|
+
// cost 63 to 63 expressions per call
|
|
811
|
+
export function digestByte(digest, index) {
|
|
812
|
+
let hex = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
|
|
813
|
+
'8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15};
|
|
814
|
+
let h = digest.toHexString();
|
|
815
|
+
let i = index * 2;
|
|
816
|
+
return hex[h[i:i + 1]] * 16 + hex[h[i + 1:i + 2]];
|
|
817
|
+
}
|
|
818
|
+
`,geometry:`// @pyric-services cloud.firestore
|
|
819
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
820
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
821
|
+
// function is paid on every call.
|
|
822
|
+
//
|
|
823
|
+
// Geometry module for movement game validation via config document lookup.
|
|
824
|
+
//
|
|
825
|
+
// Caller must pass the config document data as an explicit parameter.
|
|
826
|
+
// The config doc is read via get() and cached per request — define a
|
|
827
|
+
// config() function in your rules and pass its result to these functions.
|
|
828
|
+
//
|
|
829
|
+
// Config doc schema:
|
|
830
|
+
// moves[pieceType][fromCell][toCell] = true
|
|
831
|
+
// jumps[pieceType][fromCell][toCell] = capturedCellName
|
|
832
|
+
//
|
|
833
|
+
// Usage:
|
|
834
|
+
// import { validSimpleMove, validJumpMove } from 'geometry';
|
|
835
|
+
//
|
|
836
|
+
// function config() {
|
|
837
|
+
// return get(/databases/$(database)/documents/gameConfig/checkers).data;
|
|
838
|
+
// }
|
|
839
|
+
//
|
|
840
|
+
// allow update: if validSimpleMove(config())
|
|
841
|
+
// && piecePlaced() && moveIntegrity();
|
|
842
|
+
//
|
|
843
|
+
// allow update: if validJumpMove(config())
|
|
844
|
+
// && captureValid() && captureDecrement() && moveIntegrity();
|
|
845
|
+
//
|
|
846
|
+
// Named squares: file, rank, step and inBounds read squares named the way
|
|
847
|
+
// chess and checkers name them, on an 8 by 8 board.
|
|
848
|
+
//
|
|
849
|
+
// Convention: a square is a string of two characters:
|
|
850
|
+
// file: 'a' to 'h', left to right; file() reads 'a' as 1 and 'h' as 8
|
|
851
|
+
// rank: '1' to '8', bottom to top; rank() reads '1' as 1
|
|
852
|
+
//
|
|
853
|
+
// file, rank and step read a square; they don't check it. A malformed
|
|
854
|
+
// square is an error, which denies, except that rank reads only the second
|
|
855
|
+
// character, so rank('e9') is 9 and rank('e44') is 4. Call inBounds on a
|
|
856
|
+
// square the client wrote before you trust it. A board keyed by rank and
|
|
857
|
+
// file digits, such as '34' for rank 3 and file 4, needs none of these:
|
|
858
|
+
// string(int(sq) + 10 * dr + df) is the step.
|
|
859
|
+
//
|
|
860
|
+
// Each costs what the same check costs written inline: file 23 and rank 6,
|
|
861
|
+
// the same map lookup and int(). step(from, df, dr) == to costs 51, where
|
|
862
|
+
// the same test written as file and rank differences costs 53 to 71. To
|
|
863
|
+
// test that \`to\` is any one diagonal neighbor of \`from\`, compare file and
|
|
864
|
+
// rank differences (73 to 145) rather than calling step four times (over
|
|
865
|
+
// 200 when none match).
|
|
866
|
+
//
|
|
867
|
+
// Usage:
|
|
868
|
+
// import { file, rank, step, inBounds } from 'geometry';
|
|
869
|
+
//
|
|
870
|
+
// // The piece moves one square diagonally forward:
|
|
871
|
+
// allow update: if inBounds(request.resource.data.to)
|
|
872
|
+
// && (request.resource.data.to == step(resource.data.from, 1, 1)
|
|
873
|
+
// || request.resource.data.to == step(resource.data.from, -1, 1));
|
|
874
|
+
//
|
|
875
|
+
// // A man crowns only on the far rank:
|
|
876
|
+
// allow update: if rank(request.resource.data.to) == 8;
|
|
877
|
+
|
|
878
|
+
// Validate a simple (non-capture) move via config document lookup.
|
|
879
|
+
// Uses 3-level dynamic nesting: cfg.moves[piece][from][to].
|
|
880
|
+
// piece comes from resource.data (pre-write board) so client can't fake it.
|
|
881
|
+
// cost 26 to 26 expressions per call
|
|
882
|
+
export function validSimpleMove(cfg) {
|
|
883
|
+
let mf = request.resource.data.moveFrom;
|
|
884
|
+
let mt = request.resource.data.moveTo;
|
|
885
|
+
let piece = resource.data[mf];
|
|
886
|
+
return cfg.moves[piece][mf][mt] == true;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// Validate a jump (capture) move via config document lookup.
|
|
890
|
+
// cfg.jumps[piece][from][to] returns the expected captured cell name.
|
|
891
|
+
// Caller must separately verify the captured piece is an opponent piece.
|
|
892
|
+
// cost 31 to 31 expressions per call
|
|
893
|
+
export function validJumpMove(cfg) {
|
|
894
|
+
let mf = request.resource.data.moveFrom;
|
|
895
|
+
let mt = request.resource.data.moveTo;
|
|
896
|
+
let cap = request.resource.data.captured;
|
|
897
|
+
let piece = resource.data[mf];
|
|
898
|
+
return cfg.jumps[piece][mf][mt] == cap;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// The file of a square as a number, 'a' is 1 and 'h' is 8. A first
|
|
902
|
+
// character outside 'a' to 'h', an empty string, or a non-string square is
|
|
903
|
+
// an error, which denies.
|
|
904
|
+
// cost 23 to 23 expressions per call
|
|
905
|
+
export function file(square) {
|
|
906
|
+
return {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8}[square[0:1]];
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// The rank of a square as a number: the second character read as a digit.
|
|
910
|
+
// A second character that is not a digit, a square shorter than two
|
|
911
|
+
// characters, or a non-string square is an error, which denies.
|
|
912
|
+
// cost 6 to 6 expressions per call
|
|
913
|
+
export function rank(square) {
|
|
914
|
+
return int(square[1:2]);
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
// The square \`df\` files and \`dr\` ranks away from \`square\`, as a name. A
|
|
918
|
+
// step off the board in any direction is an error, which denies.
|
|
919
|
+
// cost 49 to 49 expressions per call
|
|
920
|
+
export function step(square, df, dr) {
|
|
921
|
+
let f = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7}[square[0:1]] + df;
|
|
922
|
+
let r = int(square[1:2]) - 1 + dr;
|
|
923
|
+
return 'abcdefgh'[f:f + 1] + '12345678'[r:r + 1];
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// The square names a square of the board: a string of one file letter
|
|
927
|
+
// 'a' to 'h' and one rank digit '1' to '8'. Anything else, a non-string
|
|
928
|
+
// included, is false.
|
|
929
|
+
// cost 5 to 9 expressions per call
|
|
930
|
+
export function inBounds(square) {
|
|
931
|
+
return square is string && square.matches('[a-h][1-8]');
|
|
932
|
+
}
|
|
933
|
+
`,joining:`// @pyric-services cloud.firestore
|
|
934
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
935
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
936
|
+
// function is paid on every call.
|
|
937
|
+
//
|
|
938
|
+
// Joining module — how membership CHANGES, safely. The connective
|
|
939
|
+
// tissue between content/spaces: spaces gates children behind a
|
|
940
|
+
// members field; joining lets users enter and leave that field
|
|
941
|
+
// WITHOUT an admin backend, with no privilege escalation.
|
|
942
|
+
//
|
|
943
|
+
// Convention: a MAP-shaped members field (uid -> role) on the parent
|
|
944
|
+
// doc. Compose with lifecycle's onlyFieldsChanged so a join/leave
|
|
945
|
+
// write can't touch anything else:
|
|
946
|
+
//
|
|
947
|
+
// import { onlyAddedSelf, onlyRemovedSelf } from 'joining';
|
|
948
|
+
// import { onlyFieldsChanged } from 'lifecycle';
|
|
949
|
+
// import { isSpaceMember, hasSpaceRole } from 'spaces';
|
|
950
|
+
//
|
|
951
|
+
// match /teams/{teamId} {
|
|
952
|
+
// allow read: if isSpaceMember(resource.data);
|
|
953
|
+
//
|
|
954
|
+
// // Open self-service join (public team) at a fixed role, and
|
|
955
|
+
// // self-service leave — nothing else about the doc may change:
|
|
956
|
+
// allow update: if onlyFieldsChanged(['members'])
|
|
957
|
+
// && (onlyAddedSelf('members', 'editor') || onlyRemovedSelf('members'));
|
|
958
|
+
// // Admins manage the doc freely:
|
|
959
|
+
// allow update: if hasSpaceRole(resource.data, 'admin');
|
|
960
|
+
// }
|
|
961
|
+
//
|
|
962
|
+
// Every guarantee here is production-verified against the live Rules Test API:
|
|
963
|
+
// the field-level map diff is reliable; the empty no-op diff DENIES (set
|
|
964
|
+
// equality, not hasOnly — hasOnly on an empty set passes); role escalation via
|
|
965
|
+
// CHANGING an existing entry denies; adding or removing anyone else denies.
|
|
966
|
+
|
|
967
|
+
// The write adds EXACTLY the caller to the members map, at EXACTLY
|
|
968
|
+
// \`role\`, changing and removing nobody. Update rules only.
|
|
969
|
+
// cost 20 to 53 expressions per call
|
|
970
|
+
export function onlyAddedSelf(membersField, role) {
|
|
971
|
+
let diff = request.resource.data[membersField].diff(resource.data[membersField]);
|
|
972
|
+
return request.auth != null
|
|
973
|
+
&& diff.addedKeys() == [request.auth.uid].toSet()
|
|
974
|
+
&& diff.changedKeys().size() == 0
|
|
975
|
+
&& diff.removedKeys().size() == 0
|
|
976
|
+
&& request.resource.data[membersField][request.auth.uid] == role;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
// The write removes EXACTLY the caller from the members map, adding
|
|
980
|
+
// and changing nobody. Self-service leave. Update rules only.
|
|
981
|
+
// cost 19 to 40 expressions per call
|
|
982
|
+
export function onlyRemovedSelf(membersField) {
|
|
983
|
+
let diff = request.resource.data[membersField].diff(resource.data[membersField]);
|
|
984
|
+
return request.auth != null
|
|
985
|
+
&& diff.removedKeys() == [request.auth.uid].toSet()
|
|
986
|
+
&& diff.addedKeys().size() == 0
|
|
987
|
+
&& diff.changedKeys().size() == 0;
|
|
988
|
+
}
|
|
989
|
+
`,lifecycle:`// @pyric-services cloud.firestore
|
|
990
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
991
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
992
|
+
// function is paid on every call.
|
|
993
|
+
//
|
|
994
|
+
// Lifecycle module for field immutability and timestamp enforcement.
|
|
995
|
+
//
|
|
996
|
+
// Common pattern: certain fields must never change after document creation
|
|
997
|
+
// (createdBy, createdAt, authorId).
|
|
998
|
+
//
|
|
999
|
+
// Usage:
|
|
1000
|
+
// import { fieldUnchanged, immutableFields, onlyFieldsChanged, exactlyChanged, isServerTimestamp } from 'lifecycle';
|
|
1001
|
+
//
|
|
1002
|
+
// // Single field:
|
|
1003
|
+
// allow update: if fieldUnchanged('createdBy');
|
|
1004
|
+
//
|
|
1005
|
+
// // Multiple fields (replaces chained fieldUnchanged calls):
|
|
1006
|
+
// allow update: if immutableFields(['createdBy', 'createdAt', 'authorId']);
|
|
1007
|
+
//
|
|
1008
|
+
// // The dual: users may edit title/body but NOTHING else:
|
|
1009
|
+
// allow update: if onlyFieldsChanged(['title', 'body']);
|
|
1010
|
+
//
|
|
1011
|
+
// // Every listed field changes and nothing else does:
|
|
1012
|
+
// allow update: if exactlyChanged(['board', 'lastMove', 'currentTurn', 'moveCount']);
|
|
1013
|
+
//
|
|
1014
|
+
// allow create: if isServerTimestamp('createdAt');
|
|
1015
|
+
//
|
|
1016
|
+
// Changed-key checks: each one compares the set of top-level keys the write
|
|
1017
|
+
// adds, removes, or changes against the keys you pass, as a List or a Set.
|
|
1018
|
+
// onlyFieldsChanged(keys): the changed keys are a subset of \`keys\`. A
|
|
1019
|
+
// listed key may stay unchanged. Use it when a transition may leave
|
|
1020
|
+
// some listed fields alone, such as the move checks in reversi, chess,
|
|
1021
|
+
// and checkers, where status and winner change only on the last move.
|
|
1022
|
+
// exactlyChanged(keys): the changed keys equal \`keys\`. Every listed key
|
|
1023
|
+
// changes. Use it when each transition always writes the same fields,
|
|
1024
|
+
// such as a tic-tac-toe move, which changes board, lastMove,
|
|
1025
|
+
// currentTurn, and moveCount, and never status or winner. In
|
|
1026
|
+
// tic-tac-toe it replaces one affectedKeys().hasOnly([...]) shared by
|
|
1027
|
+
// the move, win, and draw rules with one list per rule: a win adds
|
|
1028
|
+
// status and winner, and a draw adds status.
|
|
1029
|
+
// Both read resource.data, so on create, where there is no existing
|
|
1030
|
+
// document, the call is an error and the rule denies. On create, check
|
|
1031
|
+
// request.resource.data.keys() instead.
|
|
1032
|
+
//
|
|
1033
|
+
// A "the move squares changed" check on a nested map, such as
|
|
1034
|
+
// board.diff(resource.data.board), is not a top-level diff: write it in the
|
|
1035
|
+
// game with diff() on the two maps.
|
|
1036
|
+
|
|
1037
|
+
// Ensure a field's value is identical between existing and incoming document.
|
|
1038
|
+
// Use on update rules to enforce immutability.
|
|
1039
|
+
// cost 11 to 11 expressions per call
|
|
1040
|
+
export function fieldUnchanged(field) {
|
|
1041
|
+
return resource.data[field] == request.resource.data[field];
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// Ensure multiple fields are unchanged between existing and incoming document.
|
|
1045
|
+
// Uses MapDiff — one expression instead of N chained fieldUnchanged() calls.
|
|
1046
|
+
// cost 10 to 10 expressions per call
|
|
1047
|
+
export function immutableFields(fields) {
|
|
1048
|
+
return request.resource.data.diff(resource.data).unchangedKeys().hasAll(fields);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// Ensure a field is set to the server timestamp.
|
|
1052
|
+
// Use on create or update rules to enforce server-side time.
|
|
1053
|
+
// cost 9 to 9 expressions per call
|
|
1054
|
+
export function isServerTimestamp(field) {
|
|
1055
|
+
return request.resource.data[field] == request.time;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// The dual of immutableFields: every changed field is in the allowed
|
|
1059
|
+
// list (fields NOT listed are implicitly immutable). Top-level keys
|
|
1060
|
+
// only — nested-map diffs are unreliable in production; flatten the
|
|
1061
|
+
// schema instead of reaching for a nested diff.
|
|
1062
|
+
// cost 10 to 10 expressions per call
|
|
1063
|
+
export function onlyFieldsChanged(fields) {
|
|
1064
|
+
return request.resource.data.diff(resource.data).affectedKeys().hasOnly(fields);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// Exactly n top-level fields changed in this write. n == 1 is the
|
|
1068
|
+
// board-integrity / edit-one-field-per-write guard (Pattern 5,
|
|
1069
|
+
// generalized beyond games).
|
|
1070
|
+
// cost 11 to 11 expressions per call
|
|
1071
|
+
export function nFieldsChanged(n) {
|
|
1072
|
+
return request.resource.data.diff(resource.data).affectedKeys().size() == n;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// The top-level fields this write adds, removes, or changes are exactly
|
|
1076
|
+
// \`keys\`, a List or a Set: every listed field changed and no other field
|
|
1077
|
+
// did. A key listed twice counts once. An empty \`keys\` allows only a write
|
|
1078
|
+
// that changes nothing. On create the call is an error, so the rule denies.
|
|
1079
|
+
// cost 13 to 17 expressions per call
|
|
1080
|
+
export function exactlyChanged(keys) {
|
|
1081
|
+
let changed = request.resource.data.diff(resource.data).affectedKeys();
|
|
1082
|
+
return changed.hasAll(keys) && changed.hasOnly(keys);
|
|
1083
|
+
}
|
|
1084
|
+
`,lobby:`// @pyric-services cloud.firestore
|
|
1085
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1086
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1087
|
+
// function is paid on every call.
|
|
1088
|
+
//
|
|
1089
|
+
// Lobby module for 2-participant coordination.
|
|
1090
|
+
//
|
|
1091
|
+
// Convention: documents must have these fields:
|
|
1092
|
+
// host: string (creator's UID)
|
|
1093
|
+
// guest: string ('' when waiting, joiner's UID when joined)
|
|
1094
|
+
// status: 'waiting' | 'playing' | 'ready' (or any active state);
|
|
1095
|
+
// 'won' | 'draw' | 'resigned' once finished
|
|
1096
|
+
//
|
|
1097
|
+
// Rematch convention: the player who asks for a rematch hosts the new match,
|
|
1098
|
+
// which opens like any other lobby: guest '' and status 'waiting'. Either
|
|
1099
|
+
// seat of the finished match can ask, so the seats swap when the guest asks.
|
|
1100
|
+
// The other player takes the open seat through validJoin. Tic-tac-toe, Chess
|
|
1101
|
+
// and Reversi start their rematches this way.
|
|
1102
|
+
//
|
|
1103
|
+
// Usage:
|
|
1104
|
+
// import { validCreate, validJoin, canCancel, validRematch } from 'lobby';
|
|
1105
|
+
//
|
|
1106
|
+
// allow create: if validCreate();
|
|
1107
|
+
// allow update: if validJoin();
|
|
1108
|
+
// allow delete: if canCancel();
|
|
1109
|
+
//
|
|
1110
|
+
// // A new match that names the finished match it follows in \`rematchOf\`:
|
|
1111
|
+
// allow create: if validRematch(
|
|
1112
|
+
// /databases/$(database)/documents/matches/$(request.resource.data.rematchOf));
|
|
1113
|
+
|
|
1114
|
+
// Is this a waiting lobby with an open seat?
|
|
1115
|
+
function isWaiting() {
|
|
1116
|
+
return resource.data.status == 'waiting'
|
|
1117
|
+
&& resource.data.guest == '';
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// Create: caller is host, seat empty, status waiting
|
|
1121
|
+
// cost 8 to 31 expressions per call
|
|
1122
|
+
export function validCreate() {
|
|
1123
|
+
return request.auth != null
|
|
1124
|
+
&& request.resource.data.host == request.auth.uid
|
|
1125
|
+
&& request.resource.data.guest == ''
|
|
1126
|
+
&& request.resource.data.status == 'waiting';
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// Join: fill empty seat, transition to next status, no self-join
|
|
1130
|
+
// cost 10 to 57 expressions per call
|
|
1131
|
+
export function validJoin() {
|
|
1132
|
+
return request.auth != null
|
|
1133
|
+
&& isWaiting()
|
|
1134
|
+
&& request.resource.data.guest == request.auth.uid
|
|
1135
|
+
&& request.auth.uid != resource.data.host
|
|
1136
|
+
&& request.resource.data.status == 'playing'
|
|
1137
|
+
&& request.resource.data.host == resource.data.host;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// Cancel: only host, only while waiting
|
|
1141
|
+
// cost 7 to 21 expressions per call
|
|
1142
|
+
export function canCancel() {
|
|
1143
|
+
return request.auth != null
|
|
1144
|
+
&& resource.data.status == 'waiting'
|
|
1145
|
+
&& request.auth.uid == resource.data.host;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// Rematch: the finished match at \`previousPath\` ('won', 'draw' or
|
|
1149
|
+
// 'resigned') seated the caller as host or guest, and the new match opens
|
|
1150
|
+
// with the caller as host, the other seat open and status 'waiting'. A
|
|
1151
|
+
// missing previous match is an error and denies the request.
|
|
1152
|
+
// cost 14 to 55 expressions per call, reads 1
|
|
1153
|
+
export function validRematch(previousPath) {
|
|
1154
|
+
let previous = get(previousPath).data;
|
|
1155
|
+
return request.auth != null
|
|
1156
|
+
&& previous.status in ['won', 'draw', 'resigned']
|
|
1157
|
+
&& request.auth.uid in [previous.host, previous.guest]
|
|
1158
|
+
&& request.resource.data.host == request.auth.uid
|
|
1159
|
+
&& request.resource.data.guest == ''
|
|
1160
|
+
&& request.resource.data.status == 'waiting';
|
|
1161
|
+
}
|
|
1162
|
+
`,membership:`// @pyric-services cloud.firestore,firebase.storage
|
|
1163
|
+
// @pyric-evidence storage-rules#125,firestore-rules#189
|
|
1164
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1165
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1166
|
+
// function is paid on every call.
|
|
1167
|
+
//
|
|
1168
|
+
// Membership module for role-based and claims-based access control.
|
|
1169
|
+
//
|
|
1170
|
+
// Two access patterns:
|
|
1171
|
+
// 1. Custom claims on auth token (0 get() calls, set server-side)
|
|
1172
|
+
// 2. Member maps on documents (0 get() calls on the doc itself)
|
|
1173
|
+
//
|
|
1174
|
+
// Usage:
|
|
1175
|
+
// import { hasClaim, hasClaimRole, isMemberOf, hasRole } from 'membership';
|
|
1176
|
+
//
|
|
1177
|
+
// // Workspace access via custom claims
|
|
1178
|
+
// allow read: if hasClaim('workspace_id');
|
|
1179
|
+
// allow write: if hasClaimRole('workspace_role', 'admin');
|
|
1180
|
+
//
|
|
1181
|
+
// // Project access via member map on document
|
|
1182
|
+
// allow read: if isMemberOf(resource.data.members);
|
|
1183
|
+
// allow update: if hasRole(resource.data.members, 'admin');
|
|
1184
|
+
|
|
1185
|
+
// Check if the auth token has a non-null value for a claim key.
|
|
1186
|
+
// cost 6 to 14 expressions per call
|
|
1187
|
+
export function hasClaim(claim) {
|
|
1188
|
+
return request.auth != null
|
|
1189
|
+
&& request.auth.token[claim] != null;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// Check if the auth token has a specific value for a claim key.
|
|
1193
|
+
// cost 6 to 14 expressions per call
|
|
1194
|
+
export function hasClaimRole(claim, role) {
|
|
1195
|
+
return request.auth != null
|
|
1196
|
+
&& request.auth.token[claim] == role;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// Check if the caller's UID exists as a key in a members map.
|
|
1200
|
+
// cost 6 to 12 expressions per call
|
|
1201
|
+
export function isMemberOf(membersMap) {
|
|
1202
|
+
return request.auth != null
|
|
1203
|
+
&& request.auth.uid in membersMap;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
// Check if the caller has a specific role in a members map.
|
|
1207
|
+
// cost 6 to 14 expressions per call
|
|
1208
|
+
export function hasRole(membersMap, role) {
|
|
1209
|
+
return request.auth != null
|
|
1210
|
+
&& membersMap[request.auth.uid] == role;
|
|
1211
|
+
}
|
|
1212
|
+
`,results:`// @pyric-services cloud.firestore
|
|
1213
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1214
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1215
|
+
// function is paid on every call.
|
|
1216
|
+
//
|
|
1217
|
+
// Game results for 2-participant games/sessions: how a game in play ends,
|
|
1218
|
+
// and that other writes leave the result alone.
|
|
1219
|
+
//
|
|
1220
|
+
// Convention: documents must have these fields:
|
|
1221
|
+
// host: string (UID)
|
|
1222
|
+
// guest: string (UID)
|
|
1223
|
+
// status: 'playing' while in play; 'won' | 'draw' | 'resigned' once finished
|
|
1224
|
+
// winner: 'host' | 'guest' on 'won' and 'resigned'; '' while playing and on 'draw'
|
|
1225
|
+
//
|
|
1226
|
+
// The status names how the game ended, so a result needs no separate reason
|
|
1227
|
+
// field. This is the shape the 2-player turn games share: a resignation is
|
|
1228
|
+
// status 'resigned' with the other seat as winner, a win is 'won' with the
|
|
1229
|
+
// winning seat, and a draw is 'draw' with winner ''.
|
|
1230
|
+
//
|
|
1231
|
+
// Usage:
|
|
1232
|
+
// import { resignedBy, finishedWithWinner, resultUnchanged } from 'results';
|
|
1233
|
+
//
|
|
1234
|
+
// // The caller resigns their own seat:
|
|
1235
|
+
// allow update: if resignedBy(request.auth.uid == resource.data.host ? 'host' : 'guest');
|
|
1236
|
+
//
|
|
1237
|
+
// // A finish write names the winner and how the game ended:
|
|
1238
|
+
// allow update: if finishedWithWinner('host', 'won');
|
|
1239
|
+
//
|
|
1240
|
+
// // Every other update leaves the result alone:
|
|
1241
|
+
// allow update: if resultUnchanged() && isMyTurn();
|
|
1242
|
+
|
|
1243
|
+
import { onlyFieldsChanged, immutableFields } from 'lifecycle';
|
|
1244
|
+
import { statusIs, newStatusIs } from 'transitions';
|
|
1245
|
+
|
|
1246
|
+
// The caller holds \`seat\` ('host' or 'guest') and resigns: status goes from
|
|
1247
|
+
// 'playing' to 'resigned', the other seat wins, and only status and winner
|
|
1248
|
+
// change. The auth check comes first so a signed-out request stops there
|
|
1249
|
+
// instead of evaluating every clause after the null uid.
|
|
1250
|
+
// cost 10 to 72 expressions per call
|
|
1251
|
+
export function resignedBy(seat) {
|
|
1252
|
+
return request.auth != null
|
|
1253
|
+
&& ((seat == 'host' && request.resource.data.winner == 'guest')
|
|
1254
|
+
|| (seat == 'guest' && request.resource.data.winner == 'host'))
|
|
1255
|
+
&& resource.data[seat] == request.auth.uid
|
|
1256
|
+
&& statusIs('status', 'playing')
|
|
1257
|
+
&& newStatusIs('status', 'resigned')
|
|
1258
|
+
&& onlyFieldsChanged(['status', 'winner']);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
// A game in play finishes: status goes from 'playing' to \`reason\`, 'won' or
|
|
1262
|
+
// 'draw'. \`winner\` is 'host' or 'guest' for 'won' and '' for 'draw', and
|
|
1263
|
+
// only status and winner change. Resignations go through resignedBy, which
|
|
1264
|
+
// also checks the caller.
|
|
1265
|
+
// cost 14 to 61 expressions per call
|
|
1266
|
+
export function finishedWithWinner(winner, reason) {
|
|
1267
|
+
return statusIs('status', 'playing')
|
|
1268
|
+
&& ((reason == 'won' && winner in ['host', 'guest'])
|
|
1269
|
+
|| (reason == 'draw' && winner == ''))
|
|
1270
|
+
&& newStatusIs('status', reason)
|
|
1271
|
+
&& request.resource.data.winner == winner
|
|
1272
|
+
&& onlyFieldsChanged(['status', 'winner']);
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// The write keeps the result: status and winner are unchanged. Use on every
|
|
1276
|
+
// update that is not a finish.
|
|
1277
|
+
// cost 14 to 14 expressions per call
|
|
1278
|
+
export function resultUnchanged() {
|
|
1279
|
+
return immutableFields(['status', 'winner']);
|
|
1280
|
+
}
|
|
1281
|
+
`,spaces:`// @pyric-services cloud.firestore
|
|
1282
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1283
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1284
|
+
// function is paid on every call.
|
|
1285
|
+
//
|
|
1286
|
+
// Spaces module — cross-document membership gating for shared spaces
|
|
1287
|
+
// (teams, rooms, groups, projects, parties). The second-most-common
|
|
1288
|
+
// app shape after author-owned content: a PARENT document defines who
|
|
1289
|
+
// may touch its children.
|
|
1290
|
+
//
|
|
1291
|
+
// Explicit-param design (like geometry): the caller reads the parent
|
|
1292
|
+
// doc ONCE via a helper and passes its data in. Define the helper in
|
|
1293
|
+
// your rules — get() is cached per request, so every function below
|
|
1294
|
+
// can share one read (of the 10-get budget):
|
|
1295
|
+
//
|
|
1296
|
+
// import { isSpaceMember, hasSpaceRole, validMemberCreate } from 'spaces';
|
|
1297
|
+
//
|
|
1298
|
+
// match /spaces/{spaceId}/tasks/{taskId} {
|
|
1299
|
+
// function space() {
|
|
1300
|
+
// return get(/databases/$(database)/documents/spaces/$(spaceId)).data;
|
|
1301
|
+
// }
|
|
1302
|
+
// allow read: if isSpaceMember(space());
|
|
1303
|
+
// allow create: if validMemberCreate(space(), 'author');
|
|
1304
|
+
// allow delete: if hasSpaceRole(space(), 'admin');
|
|
1305
|
+
// }
|
|
1306
|
+
//
|
|
1307
|
+
// Members field shapes verified against the production engine:
|
|
1308
|
+
// list: members: ['uidA', 'uidB'] → isSpaceMember only
|
|
1309
|
+
// map: members: { uidA: 'admin', ... } → isSpaceMember + hasSpaceRole
|
|
1310
|
+
// A missing members field, a non-member uid, or a missing parent doc
|
|
1311
|
+
// (get() of a missing doc errors) all fail CLOSED.
|
|
1312
|
+
|
|
1313
|
+
// The caller is in the space's members field. \`in\` covers both
|
|
1314
|
+
// shapes: list membership and map keys.
|
|
1315
|
+
// cost 6 to 13 expressions per call
|
|
1316
|
+
export function isSpaceMember(spaceData) {
|
|
1317
|
+
return request.auth != null && request.auth.uid in spaceData.members;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// The caller's role in a MAP-shaped members field equals \`role\`.
|
|
1321
|
+
// List-shaped members carry no roles — this denies on them.
|
|
1322
|
+
// cost 6 to 15 expressions per call
|
|
1323
|
+
export function hasSpaceRole(spaceData, role) {
|
|
1324
|
+
return request.auth != null && spaceData.members[request.auth.uid] == role;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
// Member-gated authored create: the caller is a member AND the
|
|
1328
|
+
// incoming child doc's author field is the caller. The "post a
|
|
1329
|
+
// message / add a task" guard.
|
|
1330
|
+
// cost 9 to 26 expressions per call
|
|
1331
|
+
export function validMemberCreate(spaceData, authorField) {
|
|
1332
|
+
return isSpaceMember(spaceData)
|
|
1333
|
+
&& request.resource.data[authorField] == request.auth.uid;
|
|
1334
|
+
}
|
|
1335
|
+
`,state:`// @pyric-services cloud.firestore
|
|
1336
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1337
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1338
|
+
// function is paid on every call.
|
|
1339
|
+
//
|
|
1340
|
+
// Game state machine helpers.
|
|
1341
|
+
//
|
|
1342
|
+
// Convention: documents must have these fields:
|
|
1343
|
+
// status: 'waiting' | 'playing' | 'won' | 'draw'
|
|
1344
|
+
// moveCount: number
|
|
1345
|
+
// host: string (UID)
|
|
1346
|
+
// guest: string (UID)
|
|
1347
|
+
//
|
|
1348
|
+
// Usage:
|
|
1349
|
+
// import { isPlaying, moveIncremented, participantsUnchanged } from 'state';
|
|
1350
|
+
//
|
|
1351
|
+
// allow update: if isPlaying() && moveIncremented() && participantsUnchanged();
|
|
1352
|
+
|
|
1353
|
+
// Is the game actively in play?
|
|
1354
|
+
// cost 6 to 6 expressions per call
|
|
1355
|
+
export function isPlaying() {
|
|
1356
|
+
return resource.data.status == 'playing';
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
// Did moveCount increment by exactly 1?
|
|
1360
|
+
// cost 11 to 11 expressions per call
|
|
1361
|
+
export function moveIncremented() {
|
|
1362
|
+
return request.resource.data.moveCount == resource.data.moveCount + 1;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// Are host and guest unchanged? (prevents mid-game identity swap)
|
|
1366
|
+
// cost 10 to 19 expressions per call
|
|
1367
|
+
export function participantsUnchanged() {
|
|
1368
|
+
return request.resource.data.host == resource.data.host
|
|
1369
|
+
&& request.resource.data.guest == resource.data.guest;
|
|
1370
|
+
}
|
|
1371
|
+
`,"storage/metadata":`// @pyric-services firebase.storage
|
|
1372
|
+
// @pyric-evidence storage-rules#132
|
|
1373
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1374
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1375
|
+
// function is paid on every call.
|
|
1376
|
+
//
|
|
1377
|
+
// Storage custom-metadata policies. Custom metadata is a flat string map.
|
|
1378
|
+
|
|
1379
|
+
// cost 7 to 7 expressions per call
|
|
1380
|
+
export function hasRequiredMetadata(keys) {
|
|
1381
|
+
return request.resource.metadata.keys().hasAll(keys);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
// cost 28 to 28 expressions per call
|
|
1385
|
+
export function metadataString(key, min, max) {
|
|
1386
|
+
return request.resource.metadata[key] is string
|
|
1387
|
+
&& request.resource.metadata[key].size() >= min
|
|
1388
|
+
&& request.resource.metadata[key].size() <= max;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// cost 6 to 16 expressions per call
|
|
1392
|
+
export function incomingMetadataOwner(key) {
|
|
1393
|
+
return request.auth != null
|
|
1394
|
+
&& request.resource.metadata[key] == request.auth.uid;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// cost 6 to 15 expressions per call
|
|
1398
|
+
export function existingMetadataOwner(key) {
|
|
1399
|
+
return request.auth != null
|
|
1400
|
+
&& resource.metadata[key] == request.auth.uid;
|
|
1401
|
+
}
|
|
1402
|
+
`,"storage/objects":`// @pyric-services firebase.storage
|
|
1403
|
+
// @pyric-evidence storage-rules#132
|
|
1404
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1405
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1406
|
+
// function is paid on every call. matchesDocument reads one Firestore
|
|
1407
|
+
// document per call.
|
|
1408
|
+
//
|
|
1409
|
+
// Storage operation identity and object names. Use request.method rather
|
|
1410
|
+
// than null checks: production treats missing resource/request.resource
|
|
1411
|
+
// bindings as errors.
|
|
1412
|
+
//
|
|
1413
|
+
// Convention: the object name is the full path within the bucket, such as
|
|
1414
|
+
// 'scores/alice/3/abc-33-8.txt'. On create and update the name comes from
|
|
1415
|
+
// request.resource.name, since a create may have no stored object yet. On
|
|
1416
|
+
// get and delete it comes from resource.name, since those requests carry no
|
|
1417
|
+
// incoming object. Call nameSegment and matchesDocument from get, create,
|
|
1418
|
+
// update and delete rules.
|
|
1419
|
+
//
|
|
1420
|
+
// A Storage rule reads at most two distinct Firestore documents, so a rule
|
|
1421
|
+
// may call matchesDocument at most twice with different paths. A third
|
|
1422
|
+
// distinct document denies the request.
|
|
1423
|
+
//
|
|
1424
|
+
// Usage:
|
|
1425
|
+
// import { nameSegment, matchesDocument } from 'storage/objects';
|
|
1426
|
+
//
|
|
1427
|
+
// // The user named in the second segment reads every object below it:
|
|
1428
|
+
// match /scores/{allPaths=**} {
|
|
1429
|
+
// allow get: if nameSegment(1) == request.auth.uid;
|
|
1430
|
+
// }
|
|
1431
|
+
//
|
|
1432
|
+
// // An upload is allowed once the score document names it in \`object\`:
|
|
1433
|
+
// match /scores/{uid}/{level}/{file} {
|
|
1434
|
+
// allow create: if matchesDocument(
|
|
1435
|
+
// /databases/(default)/documents/levels/$(level)/scores/$(uid), 'object');
|
|
1436
|
+
// }
|
|
1437
|
+
|
|
1438
|
+
// cost 5 to 5 expressions per call
|
|
1439
|
+
export function isCreate() {
|
|
1440
|
+
return request.method == 'create';
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// cost 5 to 5 expressions per call
|
|
1444
|
+
export function isUpdate() {
|
|
1445
|
+
return request.method == 'update';
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
// cost 5 to 5 expressions per call
|
|
1449
|
+
export function isDelete() {
|
|
1450
|
+
return request.method == 'delete';
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
// The object's name for this request (see the convention above).
|
|
1454
|
+
function objectName() {
|
|
1455
|
+
return request.method in ['create', 'update'] ? request.resource.name : resource.name;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// Segment \`index\` of the object name split on '/', counting from 0. An index
|
|
1459
|
+
// past the last segment is an error that denies the request, and a name with
|
|
1460
|
+
// no '/' has one segment.
|
|
1461
|
+
// cost 17 to 18 expressions per call
|
|
1462
|
+
export function nameSegment(index) {
|
|
1463
|
+
return objectName().split('/')[index];
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
// The Firestore document at \`path\` exists and its \`field\` equals the object
|
|
1467
|
+
// name. A signed-out request denies before the read. A missing document or
|
|
1468
|
+
// field is an error that denies the request. Each call reads one document.
|
|
1469
|
+
// cost 6 to 26 expressions per call, reads 1
|
|
1470
|
+
export function matchesDocument(path, field) {
|
|
1471
|
+
return request.auth != null
|
|
1472
|
+
&& firestore.get(path).data[field] == objectName();
|
|
1473
|
+
}
|
|
1474
|
+
`,"storage/time":`// @pyric-services firebase.storage
|
|
1475
|
+
// @pyric-evidence storage-rules#132
|
|
1476
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1477
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1478
|
+
// function is paid on every call.
|
|
1479
|
+
//
|
|
1480
|
+
// Freshness checks over server-owned Storage object timestamps. Boundaries are
|
|
1481
|
+
// strict: equality with the deadline is not "within" the window.
|
|
1482
|
+
|
|
1483
|
+
// cost 10 to 10 expressions per call
|
|
1484
|
+
export function createdWithin(seconds) {
|
|
1485
|
+
return request.time < resource.timeCreated + duration.value(seconds, 's');
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// cost 10 to 10 expressions per call
|
|
1489
|
+
export function updatedWithin(seconds) {
|
|
1490
|
+
return request.time < resource.updated + duration.value(seconds, 's');
|
|
1491
|
+
}
|
|
1492
|
+
`,"storage/uploads":`// @pyric-services firebase.storage
|
|
1493
|
+
// @pyric-evidence storage-rules#132
|
|
1494
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1495
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1496
|
+
// function is paid on every call.
|
|
1497
|
+
//
|
|
1498
|
+
// Storage upload request primitives. These inspect declared object metadata;
|
|
1499
|
+
// MIME helpers do not inspect or authenticate the uploaded bytes.
|
|
1500
|
+
|
|
1501
|
+
// cost 6 to 6 expressions per call
|
|
1502
|
+
export function sizeAtMost(maxBytes) {
|
|
1503
|
+
return request.resource.size <= maxBytes;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
// cost 7 to 13 expressions per call
|
|
1507
|
+
export function sizeBetween(minBytes, maxBytes) {
|
|
1508
|
+
return request.resource.size >= minBytes
|
|
1509
|
+
&& request.resource.size <= maxBytes;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
// cost 6 to 6 expressions per call
|
|
1513
|
+
export function contentTypeMatches(pattern) {
|
|
1514
|
+
return request.resource.contentType.matches(pattern);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
// cost 6 to 6 expressions per call
|
|
1518
|
+
export function contentTypeIsOneOf(types) {
|
|
1519
|
+
return request.resource.contentType in types;
|
|
1520
|
+
}
|
|
1521
|
+
`,timing:`// @pyric-services cloud.firestore
|
|
1522
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1523
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1524
|
+
// function is paid on every call.
|
|
1525
|
+
//
|
|
1526
|
+
// Timing module for cooldown / rate-limit enforcement.
|
|
1527
|
+
//
|
|
1528
|
+
// Rules CAN rate-limit (contrary to a common assumption — jrpg
|
|
1529
|
+
// FINDINGS F-004): compare request.time against a stored server
|
|
1530
|
+
// timestamp. Pair with lifecycle's isServerTimestamp on the SAME
|
|
1531
|
+
// write so the stored timestamp cannot be forged by the client:
|
|
1532
|
+
//
|
|
1533
|
+
// import { cooldownElapsed } from 'timing';
|
|
1534
|
+
// import { isServerTimestamp } from 'lifecycle';
|
|
1535
|
+
//
|
|
1536
|
+
// // At most one move every 2 seconds:
|
|
1537
|
+
// allow update: if cooldownElapsed('lastMoveAt', 2)
|
|
1538
|
+
// && isServerTimestamp('lastMoveAt');
|
|
1539
|
+
|
|
1540
|
+
// The stored timestamp is more than \`seconds\` old (strict). Update
|
|
1541
|
+
// rules only — needs \`resource\`. The field must be a Timestamp; a
|
|
1542
|
+
// missing field errors, which denies (fail-closed).
|
|
1543
|
+
// cost 12 to 12 expressions per call
|
|
1544
|
+
export function cooldownElapsed(field, seconds) {
|
|
1545
|
+
return request.time > resource.data[field] + duration.value(seconds, 's');
|
|
1546
|
+
}
|
|
1547
|
+
`,transitions:`// @pyric-services cloud.firestore
|
|
1548
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1549
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1550
|
+
// function is paid on every call.
|
|
1551
|
+
//
|
|
1552
|
+
// Transitions module for state machine enforcement.
|
|
1553
|
+
//
|
|
1554
|
+
// Validates that a field transitions from one known value to another.
|
|
1555
|
+
// Use to enforce valid status flows (e.g., open -> in_progress -> completed).
|
|
1556
|
+
//
|
|
1557
|
+
// Usage:
|
|
1558
|
+
// import { validTransition, statusIs, newStatusIs } from 'transitions';
|
|
1559
|
+
//
|
|
1560
|
+
// // Only allow open -> in_progress
|
|
1561
|
+
// allow update: if validTransition('status', 'open', 'in_progress');
|
|
1562
|
+
//
|
|
1563
|
+
// // Allow update only when currently active
|
|
1564
|
+
// allow update: if statusIs('status', 'active');
|
|
1565
|
+
//
|
|
1566
|
+
// // Compound: multiple valid transitions via OR
|
|
1567
|
+
// allow update: if validTransition('status', 'open', 'in_progress')
|
|
1568
|
+
// || validTransition('status', 'in_progress', 'completed')
|
|
1569
|
+
// || validTransition('status', 'completed', 'archived');
|
|
1570
|
+
|
|
1571
|
+
// Check that a field transitions from one value to another.
|
|
1572
|
+
// cost 8 to 16 expressions per call
|
|
1573
|
+
export function validTransition(field, from, to) {
|
|
1574
|
+
return resource.data[field] == from
|
|
1575
|
+
&& request.resource.data[field] == to;
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
// Check the current (existing) value of a field.
|
|
1579
|
+
// cost 7 to 7 expressions per call
|
|
1580
|
+
export function statusIs(field, value) {
|
|
1581
|
+
return resource.data[field] == value;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
// Check the incoming (new) value of a field.
|
|
1585
|
+
// cost 8 to 8 expressions per call
|
|
1586
|
+
export function newStatusIs(field, value) {
|
|
1587
|
+
return request.resource.data[field] == value;
|
|
1588
|
+
}
|
|
1589
|
+
`,turns:`// @pyric-services cloud.firestore
|
|
1590
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1591
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1592
|
+
// function is paid on every call.
|
|
1593
|
+
//
|
|
1594
|
+
// Turn enforcement for games/sessions: two-seat games with named seats, and
|
|
1595
|
+
// games of any size with a seat list.
|
|
1596
|
+
//
|
|
1597
|
+
// Two-seat convention: documents must have these fields:
|
|
1598
|
+
// host: string (UID)
|
|
1599
|
+
// guest: string (UID)
|
|
1600
|
+
// currentTurn: 'host' | 'guest'
|
|
1601
|
+
//
|
|
1602
|
+
// Seat-list convention: documents must have these fields:
|
|
1603
|
+
// players: list of UIDs, one per seat, in turn order
|
|
1604
|
+
// turn: int, the index in \`players\` of the seat whose turn it is
|
|
1605
|
+
//
|
|
1606
|
+
// Yacht and Uno store these two fields under these names. isSeatTurn takes
|
|
1607
|
+
// the list and the index as arguments, so a document that names them
|
|
1608
|
+
// differently can still use it; turnAdvanced reads \`players\` and \`turn\`.
|
|
1609
|
+
//
|
|
1610
|
+
// Usage:
|
|
1611
|
+
// import { isMyTurn, turnFlipped, isSeatTurn, turnAdvanced } from 'turns';
|
|
1612
|
+
//
|
|
1613
|
+
// // Two seats:
|
|
1614
|
+
// allow update: if isMyTurn() && turnFlipped();
|
|
1615
|
+
//
|
|
1616
|
+
// // A seat list:
|
|
1617
|
+
// allow update: if isSeatTurn(resource.data.players, resource.data.turn)
|
|
1618
|
+
// && turnAdvanced(resource.data.players.size());
|
|
1619
|
+
|
|
1620
|
+
// Is the caller the participant whose turn it is?
|
|
1621
|
+
// cost 16 to 23 expressions per call
|
|
1622
|
+
export function isMyTurn() {
|
|
1623
|
+
return (resource.data.currentTurn == 'host'
|
|
1624
|
+
&& request.auth.uid == resource.data.host)
|
|
1625
|
+
|| (resource.data.currentTurn == 'guest'
|
|
1626
|
+
&& request.auth.uid == resource.data.guest);
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
// Did the turn alternate?
|
|
1630
|
+
// cost 15 to 22 expressions per call
|
|
1631
|
+
export function turnFlipped() {
|
|
1632
|
+
return (resource.data.currentTurn == 'host'
|
|
1633
|
+
&& request.resource.data.currentTurn == 'guest')
|
|
1634
|
+
|| (resource.data.currentTurn == 'guest'
|
|
1635
|
+
&& request.resource.data.currentTurn == 'host');
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// Is the caller's uid \`seats[turnIndex]\`? \`seats\` is a list of UIDs and
|
|
1639
|
+
// \`turnIndex\` an int. A signed-out request is false. An index past the last
|
|
1640
|
+
// seat, or below 0, is an error, and the request is denied.
|
|
1641
|
+
// cost 6 to 14 expressions per call
|
|
1642
|
+
export function isSeatTurn(seats, turnIndex) {
|
|
1643
|
+
return request.auth != null && seats[turnIndex] == request.auth.uid;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
// Did the turn move to the next seat? The new \`turn\` equals the old \`turn\`
|
|
1647
|
+
// plus one, modulo \`seatCount\`, so the last seat wraps to seat 0. \`%\` on two
|
|
1648
|
+
// ints is the remainder, as in production. The \`players\` list is unchanged.
|
|
1649
|
+
// cost 14 to 23 expressions per call
|
|
1650
|
+
export function turnAdvanced(seatCount) {
|
|
1651
|
+
return request.resource.data.turn == (resource.data.turn + 1) % seatCount
|
|
1652
|
+
&& request.resource.data.players == resource.data.players;
|
|
1653
|
+
}
|
|
1654
|
+
`,validation:`// @pyric-services cloud.firestore
|
|
1655
|
+
// Costs are production expressions per call, not counting arguments. Calls
|
|
1656
|
+
// are not memoized: every call pays its full cost again, and a let inside a
|
|
1657
|
+
// function is paid on every call.
|
|
1658
|
+
//
|
|
1659
|
+
// Validation module for document field shape and value checks.
|
|
1660
|
+
//
|
|
1661
|
+
// Usage:
|
|
1662
|
+
// import { hasRequired, hasOnly, validString, isOneOf } from 'validation';
|
|
1663
|
+
//
|
|
1664
|
+
// allow create: if hasRequired(['title', 'status'])
|
|
1665
|
+
// && validString('title', 1, 100)
|
|
1666
|
+
// && isOneOf('status', ['draft', 'published']);
|
|
1667
|
+
|
|
1668
|
+
// cost 7 to 7 expressions per call
|
|
1669
|
+
export function hasRequired(fields) {
|
|
1670
|
+
return request.resource.data.keys().hasAll(fields);
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
// cost 7 to 7 expressions per call
|
|
1674
|
+
export function hasOnly(fields) {
|
|
1675
|
+
return request.resource.data.keys().hasOnly(fields);
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
// Incoming field is a string with size in [min, max] (inclusive).
|
|
1679
|
+
// A missing field is an error under dynamic access, so the call denies.
|
|
1680
|
+
// For an optional field, guard it:
|
|
1681
|
+
// \`!('title' in request.resource.data) || validString('title', 1, 80)\`.
|
|
1682
|
+
// cost 10 to 28 expressions per call
|
|
1683
|
+
export function validString(field, min, max) {
|
|
1684
|
+
return request.resource.data[field] is string
|
|
1685
|
+
&& request.resource.data[field].size() >= min
|
|
1686
|
+
&& request.resource.data[field].size() <= max;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
// Enum check: the incoming field value is one of the allowed values.
|
|
1690
|
+
// (\`in\` on a list — NOT \`.includes()\`, which does not exist in rules.)
|
|
1691
|
+
// cost 8 to 8 expressions per call
|
|
1692
|
+
export function isOneOf(field, values) {
|
|
1693
|
+
return request.resource.data[field] in values;
|
|
1694
|
+
}
|
|
1695
|
+
`};function Fg(){const t={};for(const[e,n]of Object.entries(Pg))t[e]=n,t[`./stdlib/${e}.rules`]=n;return t}const cd=Fg(),jg=new Set(Object.keys(cd));function qg(t,e,n){const s=Object.entries(n?.modules??{}),r=Object.fromEntries(s),i=new Set(s.map(([a])=>a)),o=new Set([...jg].filter(a=>!i.has(a)));return Mg(t,e,{...n,modules:{...cd,...r}},o)}function Ug(t,e){return qg(null,t,e)}const Bg={key:"builtins",kind:"language-namespace",description:"Top-level functions always in scope inside rules: get, exists, getAfter. Called bare, no namespace prefix. (debug() is docs-only: production rejects it at compile.)",purpose:"The built-in functions Firestore Rules ships with at the top level. They are NOT inside a namespace: call `get(path)`, not `firestore.get(path)`. Used to read other documents (cross-document gates), check existence, and peek at post-write state.",whenToUse:"Reach for `builtins` any time a rule needs information that isn't already on `request` or `resource`. Most common: `get(path)` to read another document's fields inside a predicate.",entries:[{signature:"get(path: path): Resource",description:"Read another document. Returns a Resource whose `.data` is the doc map. Counts against the rule's `get()` budget (cap 10 per evaluation).",examples:["allow update: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';"],notes:"Path must start with `/databases/$(database)/documents/`. Hardcoding a different database id silently fails."},{signature:"exists(path: path): bool",description:"True if a document at `path` exists. Counts against the get() budget like `get`.",examples:["allow create: if exists(/databases/$(database)/documents/teams/$(request.resource.data.teamId));"]},{signature:"getAfter(path: path): Resource",description:"Like `get`, but reads the doc AS IT WILL BE after the current transaction commits. Use for cross-document consistency gates that depend on the post-write state of another doc in the same batch.",notes:"Only meaningful inside transactions / batched writes. Outside a batch, equivalent to `get`."},{signature:"debug(value: any): bool",acceptance:"rejected",description:"DO NOT USE. Although Firebase reference docs list `debug()`, production Firestore REJECTS rulesets that call it at compile time (`Function not found error: Name: [debug]`). The linter and local simulator reject it for the same reason.",notes:"Remove any debug() wrapper before deploying and evaluate the inner expression directly. There is no deployable logging primitive in rules."}],relatedKeys:["request","resource","path"]},zg={key:"math",kind:"language-namespace",description:"Numeric helpers: abs, ceil, floor, round, sqrt, pow, isNaN. Use when rules need to coerce or bound numbers.",purpose:"The `math` namespace exposes a small set of numeric utilities for use inside rule predicates. Functions are called as `math.<fn>(...)`. Always in scope; no import needed.",whenToUse:"Reach for `math` whenever a rule needs to round, bound, or guard against NaN in a user-supplied field.",entries:[{signature:"math.abs(n: number): number",description:"Absolute value of `n`."},{signature:"math.ceil(n: number): int",description:"Smallest integer >= `n`."},{signature:"math.floor(n: number): int",description:"Largest integer <= `n`."},{signature:"math.round(n: number): int",description:"Nearest integer to `n`."},{signature:"math.sqrt(n: number): number",description:"Square root of `n`. Negative input returns NaN."},{signature:"math.pow(base: number, exp: number): number",description:"`base` raised to `exp`."},{signature:"math.isNaN(n: number): bool",description:"True if `n` is NaN.",notes:"There is NO isInfinite function in the math namespace. Production Firestore rejects it at compile time (`Function not found error: Name: [math.isInfinite]`), despite it appearing in some Firebase reference material."}],examples:["allow update: if math.ceil(request.resource.data.score) <= 100;","allow create: if !math.isNaN(request.resource.data.lat);"],relatedKeys:["hashing"]},Wg={key:"timestamp",kind:"language-namespace",description:"Timestamp constructors — date(year, month, day), value(epochMillis). Use to build timestamps in rule comparisons.",purpose:"The `timestamp` namespace contains constructors that produce Timestamp values for use in comparisons. The Timestamp TYPE has its own methods (year, month, etc.) — those live under the `string`/`list`/`map`-style key `timestamp-methods` in this stdlib, accessed via dot notation on a timestamp value.",whenToUse:"Reach for the `timestamp` namespace when a rule needs to construct a specific Timestamp value to compare against `request.time` or a document field.",entries:[{signature:"timestamp.date(year: int, month: int, day: int): Timestamp",description:"Construct a Timestamp at UTC midnight of the given date.",examples:["allow read: if request.time > timestamp.date(2024, 1, 1);"]},{signature:"timestamp.value(epochMillis: int): Timestamp",description:"Construct a Timestamp from epoch milliseconds."}],relatedKeys:["duration","request","lifecycle"]},Vg={key:"duration",kind:"language-namespace",description:'Duration constructors — value(magnitude, unit), time(h, m, s, ns), abs(d). Use for "within N seconds" windows.',purpose:"The `duration` namespace builds Duration values that can be added to or subtracted from Timestamps. Useful for time-window predicates in security rules.",whenToUse:'Reach for `duration` whenever a rule expresses a time window — "within 5 minutes of write", "older than 30 days", etc.',entries:[{signature:"duration.value(magnitude: int, unit: 'w' | 'd' | 'h' | 'm' | 's' | 'ms' | 'ns'): Duration",description:"Construct a Duration of `magnitude` of the given unit.",examples:["allow update: if request.time < resource.data.createdAt + duration.value(5, 'm');"]},{signature:"duration.time(h: int, m: int, s: int, ns: int): Duration",description:"Construct a Duration as a sum of hours, minutes, seconds, nanoseconds."},{signature:"duration.abs(d: Duration): Duration",description:"Absolute value of a Duration (drops sign)."}],relatedKeys:["timestamp"]},Gg={key:"latlng",kind:"language-namespace",description:"GeoPoint constructor — value(lat, lng). Builds LatLng values for proximity rules.",purpose:"The `latlng` namespace constructs LatLng values. The LatLng type itself has methods (`latitude()`, `longitude()`, `distance(other)`) accessed via dot notation on a latlng value.",whenToUse:'Reach for `latlng` when a rule gates on physical proximity — e.g. "this write must come within N meters of the document\'s anchor point".',entries:[{signature:"latlng.value(lat: number, lng: number): LatLng",description:"Construct a LatLng. Latitude in [-90, 90], longitude in [-180, 180].",examples:["allow update: if latlng.value(request.resource.data.lat, request.resource.data.lng).distance(resource.data.anchor) < 1000;"]}]},Hg={key:"hashing",kind:"language-namespace",description:"Hash digests — md5, sha256, crc32, crc32c. Each takes Bytes or String and returns Bytes.",purpose:"The `hashing` namespace exposes one-shot digest functions. Output is Bytes; compare equality with `==` against a stored Bytes value.",whenToUse:"Reach for `hashing` for tamper-evidence checks — comparing a submitted hash against a stored digest, or verifying a public-facing checksum.",entries:[{signature:"hashing.md5(input: Bytes | String): Bytes",description:"MD5 digest. 128-bit; do not use for security-sensitive integrity proofs."},{signature:"hashing.sha256(input: Bytes | String): Bytes",description:"SHA-256 digest. 256-bit; the right choice for integrity proofs."},{signature:"hashing.crc32(input: Bytes | String): Bytes",description:"CRC32 checksum (Bytes). Use for non-cryptographic integrity."},{signature:"hashing.crc32c(input: Bytes | String): Bytes",description:"CRC32C checksum (Bytes). Same role as crc32 with a different polynomial."}],examples:["allow update: if hashing.sha256(request.resource.data.payload) == resource.data.checksum;"],relatedKeys:["bytes"]},Kg={key:"string",kind:"type-methods",description:"Methods on string values — matches, lower, upper, trim, size, split, replace, toUtf8. Called as `value.method(...)`.",purpose:"Methods available on values of type `string` inside rule expressions. Dispatched on the value: `myField.matches(...)`, not `string.matches(myField, ...)`. The engine routes the call based on the value's runtime type.",whenToUse:"Reach for these whenever a rule examines a string field — pattern checks, case-insensitive comparisons, trimming user input, encoding to bytes.",entries:[{signature:"string.matches(pattern: string): bool",description:"True if the string matches the given RE2 regex (full match).",examples:["allow create: if request.resource.data.email.matches('.*@example[.]com');"],notes:"Pattern is RE2 syntax, NOT JavaScript regex. No anchors needed — the match is full-string by default."},{signature:"string.lower(): string",description:"Return the string lowercased."},{signature:"string.upper(): string",description:"Return the string uppercased."},{signature:"string.trim(): string",description:"Strip leading + trailing whitespace."},{signature:"string.size(): int",description:"Length in characters (NOT bytes — use `toUtf8().size()` for byte length)."},{signature:"string.split(separator: string): list<string>",description:"Split the string into a list on `separator`."},{signature:"string.replace(old: string, new: string): string",description:"Replace all occurrences of `old` with `new`."},{signature:"string.toUtf8(): bytes",description:"Encode the string as UTF-8 bytes.",notes:"Use before hashing if the input is a string."}],examples:["allow create: if request.resource.data.slug.size() > 0 && request.resource.data.slug.size() <= 64;","allow update: if request.resource.data.kind.lower() == 'public';"],relatedKeys:["bytes","hashing","validation"]},Zg={key:"list",kind:"type-methods",description:"Methods on list values — hasAll, hasAny, hasOnly, size, toSet, concat, removeAll, join. Called as `value.method(...)`.",purpose:"Methods on list values — used to check membership, compare contents, transform to sets, and concatenate. Lists in rules are ordered + finite; methods often have parallel semantics on the `set` view produced by `toSet()`.",whenToUse:'Reach for these whenever a rule examines an array field — tag membership ("user can update if their uid is in editors"), array-shape validation, or projecting to a set for difference checks.',entries:[{signature:"list.hasAll(other: list): bool",description:"True if every element of `other` is present in this list.",examples:["allow update: if request.resource.data.tags.hasAll(['public', 'reviewed']);"]},{signature:"list.hasAny(other: list): bool",description:"True if at least one element of `other` is present in this list."},{signature:"list.hasOnly(other: list): bool",description:"True if every element of THIS list is in `other` (i.e. this is a subset).",notes:'Often the right call for "no fields outside this allowlist" patterns when used with `request.resource.data.keys()`.'},{signature:"list.size(): int",description:"Number of elements."},{signature:"list.toSet(): set",description:"Convert to a Set view (de-duplicated, unordered). Useful for `difference`/`union`/`intersection` operations."},{signature:"list.concat(other: list): list",description:"Return a new list with `other` appended."},{signature:"list.removeAll(other: list): list",description:"Return a new list with every element of `other` removed."},{signature:"list.join(separator: string): string",description:"Join elements into a single string with `separator` between them."}],relatedKeys:["map","string"]},Jg={key:"map",kind:"type-methods",description:"Methods on map values — keys, values, size, get, diff. Called as `value.method(...)`.",purpose:"Methods on map values. The most common in rule code: `keys()` returns a list of map keys (combined with `list.hasAll`/`list.hasOnly` for shape checks), and `diff(other)` returns a MapDiff used to assert which fields changed across an update.",whenToUse:"Reach for these for shape validation (which keys exist), for default-aware reads (`get(key, default)`), and for diff-based immutability gates on updates.",entries:[{signature:"map.keys(): list<string>",description:"List of top-level keys in the map.",examples:["allow create: if request.resource.data.keys().hasOnly(['title','body','authorId']);"]},{signature:"map.values(): list",description:"List of top-level values in the map."},{signature:"map.size(): int",description:"Number of top-level keys."},{signature:"map.get(key: string, fallback: any): any",description:"Return `map[key]` if present, otherwise `fallback`. Same shape as `get(map, key, fallback)`."},{signature:"map.diff(other: map): MapDiff",description:"Return a MapDiff with `.addedKeys()`, `.removedKeys()`, `.changedKeys()`, `.affectedKeys()`, `.unchangedKeys()` methods, each returning a Set of keys.",examples:["allow update: if request.resource.data.diff(resource.data).affectedKeys().hasOnly(['updatedAt']);"],notes:"The MapDiff result is the right surface for immutability gates — easier to read than chaining individual field-unchanged checks."}],relatedKeys:["list","lifecycle","validation"]},Qg={key:"bytes",kind:"type-methods",description:"Methods on bytes values — size, toBase64, toHexString. Called as `value.method(...)`.",purpose:"Methods on Bytes values — the output of hashing operations and the storage shape for arbitrary binary payloads. Bytes also support comparison operators (<, <=, >, >=) for lexicographic ordering.",whenToUse:"Reach for these when a rule examines a Bytes field — typically a stored digest from `hashing.sha256(...)` — or when comparing two hashes for tamper-evidence.",entries:[{signature:"bytes.size(): int",description:"Number of bytes."},{signature:"bytes.toBase64(): string",description:"Padded base64url encoding of the bytes: `-` and `_` in place of `+` and `/`, with `=` padding."},{signature:"bytes.toHexString(): string",description:"Uppercase hexadecimal encoding of the bytes."}],relatedKeys:["hashing","string"]},Yg={key:"path",kind:"type-methods",description:"Methods on path values — bind. Used to fill in template variables in document paths.",purpose:"Path values are the type used for cross-document references inside rules (e.g. the path passed to `get()` or `exists()`). The `bind` method substitutes template variables into a path literal.",whenToUse:"Reach for `path.bind` when a `get()` or `exists()` call needs a dynamic path with one or more template variables filled in from rule context.",entries:[{signature:"path.bind(bindings: map<string, string>): path",description:"Return a new path with template variables (`{name}`) replaced by values from `bindings`.",examples:["allow update: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/profile/main);"],notes:"In practice most rule code constructs paths inline with `$()` interpolation instead of `path.bind`. `bind` is here for completeness."}],relatedKeys:["request","resource"]},Xg={key:"request",kind:"globals",description:"Root namespace for the in-flight request — auth, resource.data, time, path, method, query. Always available, no import.",purpose:"The `request` identifier carries everything the engine knows about the current request — who is making it (`auth`), what they are sending (`resource.data`), when (`time`), and where (`path`, `method`). These are *paths*, not callables — read fields off them in rule predicates.",whenToUse:"Every non-trivial rule reads from `request` to authorize the operation. The two most common touchpoints: `request.auth` (who) and `request.resource.data` (what).",entries:[{signature:"request.auth: map | null",description:"The authenticated user. `null` for unauthenticated requests.",examples:["allow read: if request.auth != null;"]},{signature:"request.auth.uid: string",description:"The signed-in user's UID. Only safe to read after a null-check on `request.auth`.",examples:["allow update: if request.auth.uid == resource.data.ownerId;"]},{signature:"request.auth.token: map",description:"Map of custom claims set on the user's ID token (e.g. `request.auth.token.admin`).",examples:["allow delete: if request.auth.token.admin == true;"],notes:"Custom claims live under `request.auth.token.*`, NOT `request.auth.*`. Agents often emit `request.auth.admin` — that always reads `null`."},{signature:"request.resource.data: map",description:"The document data being written (create/update/set). Read it to validate what the client is sending.",examples:["allow create: if request.resource.data.keys().hasOnly(['title','body','authorId']);"]},{signature:"request.time: timestamp",description:"Server time of the request. Compare against document timestamps for windowed gates."},{signature:"request.path: path",description:"Path of the document being operated on (e.g. `/databases/(default)/documents/users/alice`)."},{signature:"request.method: 'get' | 'list' | 'create' | 'update' | 'delete'",description:"Which operation triggered the rule. Usually inferred from the `allow` clause, but available for fine-grained checks."},{signature:"request.query: map",description:"Query metadata for `list` requests — `limit`, `offset`, `orderBy`. Available on `allow list` rules only."}],relatedKeys:["resource","auth"]},ey={key:"resource",kind:"globals",description:"Root namespace for the existing document — use resource.data to compare against what is already there.",purpose:"The `resource` identifier is the document state BEFORE the request — what is currently stored. When the target does not exist, evaluating `resource` raises a null-value error; it is not a comparable null. On an update/delete of an existing document, it contains the pre-write data. Use it to compare incoming changes against existing values.",whenToUse:'Whenever a rule needs the pre-write state — e.g. "the existing owner is the one updating", "the field already had this value before the write".',entries:[{signature:"resource.data: map",description:"The currently stored document data. When the target does not exist, evaluating `resource` raises a null-value error.",examples:["allow update: if resource.data.ownerId == request.auth.uid;"]}],relatedKeys:["request"]},ty={key:"auth",kind:"user-module",description:"User-authored module: authentication primitives (isAuthenticated, isOwner). Self-contained. Import via `import { isAuthenticated, isOwner } from 'auth';` (the resolver also accepts the path form `from './stdlib/auth.rules'` if you prefer).",purpose:'Two-function module covering the most common access-control predicates in any user-facing app: "is the request authenticated" and "is the request the owner of this document".',whenToUse:"Import as the first stdlib module on any project that has user-owned documents. Pairs with `validation` and `lifecycle` for full create/update/delete coverage.",entries:[{signature:"isAuthenticated(): bool",cost:{min:5,max:5},reads:0,description:"`request.auth != null`."},{signature:"isOwner(userId: string): bool",cost:{min:7,max:13},reads:0,description:"`request.auth.uid == userId`. Pass a field path like `resource.data.ownerId`.",examples:["allow update: if isAuthenticated() && isOwner(resource.data.ownerId);"]}],examples:[`rules_version = '2+modules';
|
|
1696
|
+
import { isAuthenticated } from 'auth';
|
|
1697
|
+
|
|
1698
|
+
service cloud.firestore {
|
|
1699
|
+
match /databases/{db}/documents {
|
|
1700
|
+
match /posts/{id} { allow read: if isAuthenticated(); }
|
|
1701
|
+
}
|
|
1702
|
+
}`],relatedKeys:["validation","lifecycle","membership"]},ny={key:"validation",kind:"user-module",description:"User-authored module: shape validation (hasRequired, hasOnly). Self-contained. Import via `import { hasRequired, hasOnly } from 'validation';` after `rules_version = '2+modules';`.",purpose:'Field-shape predicates: "the incoming doc has all these fields" and "the incoming doc has only these fields". Layered on top of `request.resource.data.keys()` so the agent does not have to remember the list-method idioms.',whenToUse:"Reach for `validation` on every `create` allow rule to gate field shape — and on `update` rules when the schema is strict.",entries:[{signature:"hasRequired(fields: list<string>): bool",cost:{min:7,max:7},reads:0,description:"`request.resource.data.keys().hasAll(fields)`."},{signature:"hasOnly(fields: list<string>): bool",cost:{min:7,max:7},reads:0,description:"`request.resource.data.keys().hasOnly(fields)`.",examples:["allow create: if hasRequired(['title','body']) && hasOnly(['title','body','tags']);"]},{signature:"validString(field: string, min: int, max: int): bool",cost:{min:10,max:28},reads:0,description:"The incoming field is a string with size in [min, max] (inclusive). A missing field is an error under dynamic access, so the call denies; guard an optional field with `!('title' in request.resource.data) || validString('title', 1, 80)`.",examples:["allow create: if validString('title', 1, 100);"]},{signature:"isOneOf(field: string, values: list): bool",cost:{min:8,max:8},reads:0,description:"Enum check: the incoming field value is in the allowed list (`request.resource.data[field] in values`). The rules idiom for what JS would write as `.includes()` — which does not exist here.",examples:["allow create: if isOneOf('status', ['draft', 'published']);"]}],relatedKeys:["map","lifecycle","content"]},sy={key:"lobby",kind:"user-module",description:"User-authored module: lobby lifecycle (validCreate, validJoin, canCancel, validRematch) for two-player game sessions. Self-contained; validRematch reads the finished match with one get().",purpose:"Convention-based lifecycle for game lobbies — assumes the document has `host`, `guest`, and `status` fields. Encapsulates the rules for opening a lobby, joining as the second player, cancelling, and opening a rematch of a finished match ('won', 'draw' or 'resigned').",whenToUse:"Reach for `lobby` on games with a join-then-start flow. The convention names are load-bearing — if your schema differs, fork these functions rather than try to remap.",entries:[{signature:"validCreate(): bool",cost:{min:8,max:31},reads:0,description:'Host is the auth user, guest is empty, status is "waiting".'},{signature:"validJoin(): bool",cost:{min:10,max:57},reads:0,description:'Guest slot is empty, joiner is not the host, status transitions to "playing".'},{signature:"canCancel(): bool",cost:{min:7,max:21},reads:0,description:'Status is "waiting" and the requester is the host.'},{signature:"validRematch(previousPath: path): bool",cost:{min:14,max:55},reads:1,description:"The match at `previousPath` is finished ('won', 'draw' or 'resigned') and seated the caller as host or guest; the new match has the caller as host, guest '' and status 'waiting'.",examples:["allow create: if validRematch(/databases/$(database)/documents/matches/$(request.resource.data.rematchOf));"],notes:"Either seat can ask, so the seats swap when the guest asks. The other player takes the open seat through validJoin, which does not check that they held a seat in the finished match. A missing previous match is an error and denies the request. The `let` that holds the `get()` is evaluated before the auth check, so a signed-out request also pays for the `get()`."}],relatedKeys:["turns","state","transitions","results"]},ry={key:"turns",kind:"user-module",description:"User-authored module: turn enforcement for two-player games (isMyTurn, turnFlipped) and games with a seat list (isSeatTurn, turnAdvanced). Self-contained.",purpose:"Convention-based turn handling. Two-seat docs have `host`, `guest`, and `currentTurn` fields. Seat-list docs have `players`, a list of UIDs in turn order, and `turn`, the int index of the seat on turn. Asserts the request is from the current player and that the turn moves to the next seat across writes.",whenToUse:"Reach for `turns` on any turn-based game where exactly one player can act per state: isMyTurn and turnFlipped for two named seats, isSeatTurn and turnAdvanced for a seat list of any size.",entries:[{signature:"isMyTurn(): bool",cost:{min:16,max:23},reads:0,description:"Current player matches the auth uid (matches against `host` or `guest`)."},{signature:"turnFlipped(): bool",cost:{min:15,max:22},reads:0,description:"After the write, `currentTurn` has switched from host to guest (or vice-versa)."},{signature:"isSeatTurn(seats: list, turnIndex: int): bool",cost:{min:6,max:14},reads:0,description:"The caller is signed in and their uid is `seats[turnIndex]`. An index past the last seat, or below 0, is an error and denies the request.",examples:["allow update: if isSeatTurn(resource.data.players, resource.data.turn);"]},{signature:"turnAdvanced(seatCount: int): bool",cost:{min:14,max:23},reads:0,description:"The new `turn` is the old `turn` plus one modulo `seatCount` (production's `%` on ints), so the last seat wraps to seat 0, and `players` is unchanged.",examples:["allow update: if turnAdvanced(resource.data.players.size());"]}],relatedKeys:["lobby","state","transitions"]},iy={key:"state",kind:"user-module",description:"User-authored module: game state tracking (isPlaying, moveIncremented, participantsUnchanged). Self-contained.",purpose:"Mid-game state predicates: the game is in play, the move counter incremented by exactly one, the participant list did not change.",whenToUse:"Reach for `state` on per-move updates to assert the move actually advanced the game and did not change the players.",entries:[{signature:"isPlaying(): bool",cost:{min:6,max:6},reads:0,description:'`resource.data.status == "playing"`.'},{signature:"moveIncremented(): bool",cost:{min:11,max:11},reads:0,description:"`request.resource.data.moveCount == resource.data.moveCount + 1`."},{signature:"participantsUnchanged(): bool",cost:{min:10,max:19},reads:0,description:"Host and guest fields are identical pre- and post-write."}],relatedKeys:["turns","lifecycle","transitions"]},oy={key:"results",kind:"user-module",description:"User-authored module: how a two-player game ends (resignedBy, finishedWithWinner, resultUnchanged). Imports onlyFieldsChanged and immutableFields from lifecycle, statusIs and newStatusIs from transitions.",purpose:"Result writes on docs with `host`, `guest`, `status` and `winner` fields. `status` is 'playing' while in play and names how the game ended once finished: 'won' with the winning seat in `winner`, 'draw' with `winner` '', or 'resigned' with the other seat in `winner`. There is no separate reason field.",whenToUse:"Reach for `results` on the update rule of a turn-based game: resignedBy for the resign button, finishedWithWinner for a write that only records the result, and resultUnchanged on every other update so a move cannot rewrite the result.",entries:[{signature:"resignedBy(seat: string): bool",cost:{min:10,max:72},reads:0,description:"The caller holds `seat` ('host' or 'guest'), status goes from 'playing' to 'resigned', `winner` is the other seat, and only status and winner change.",examples:["allow update: if resignedBy(request.auth.uid == resource.data.host ? 'host' : 'guest');"]},{signature:"finishedWithWinner(winner: string, reason: string): bool",cost:{min:14,max:61},reads:0,description:"Status goes from 'playing' to `reason`, 'won' or 'draw'; `winner` is 'host' or 'guest' for 'won' and '' for 'draw'; only status and winner change.",examples:["allow update: if finishedWithWinner('host', 'won') || finishedWithWinner('', 'draw');"],notes:"The caller is not checked: compose it with the rule that decides who may record a result. Resignations go through resignedBy."},{signature:"resultUnchanged(): bool",cost:{min:14,max:14},reads:0,description:"Status and winner are unchanged by the write."}],relatedKeys:["state","turns","lobby","lifecycle","transitions"]},ay={key:"fairness",kind:"user-module",description:"User-authored module: commit-reveal fairness (commitmentMatches, digestByte). Self-contained.",purpose:"Hidden choices and shared randomness: a player stores `commit`, the uppercase hex SHA-256 of a secret salt, before the other players add their input, then reveals `salt`. commitmentMatches checks the reveal against the commitment, and digestByte derives values such as die faces from a digest.",whenToUse:"Reach for `fairness` on the reveal write of a commit-reveal game: dice, card draws, or a hidden move that must not change after the other players act.",entries:[{signature:"commitmentMatches(commitment: string, salt: string): bool",cost:{min:6,max:16},reads:0,description:"`salt` is a non-empty string and `hashing.sha256(salt).toHexString()` equals `commitment`.",examples:["allow update: if commitmentMatches(resource.data.commit, request.resource.data.salt);"],notes:"The commitment is the uppercase hex string, not Bytes: a commitment stored as Bytes or as lowercase hex does not match."},{signature:"digestByte(digest: Bytes, index: int): int",cost:{min:63,max:63},reads:0,description:"Byte `index` of `digest` as an int from 0 to 255. An index outside the digest, or a digest that is not Bytes, is an error, so the rule denies.",examples:["allow update: if request.resource.data.die == digestByte(hashing.sha256(request.resource.data.salt + resource.data.nonce), 0) % 6 + 1;"],notes:"Production Bytes have no index operator, so the byte is read from `toHexString()` through a 16-entry lookup map on every call. `% 6 + 1` gives faces 1 to 4 a 43 in 256 chance and faces 5 and 6 a 42 in 256 chance."}],relatedKeys:["hashing","bytes","turns","results"]},cy={key:"membership",kind:"user-module",description:"User-authored module: claims + role-based access (hasClaim, hasClaimRole, isMemberOf, hasRole). Self-contained.",purpose:'Two halves: claim-based checks against the auth token, and role checks against a `members` map on a document. The module is the right cover for "team-style" apps where each doc has a participant map.',whenToUse:"Reach for `membership` whenever a rule gates on a custom claim (`request.auth.token.admin`) or on a role inside a participant map.",entries:[{signature:"hasClaim(claim: string): bool",cost:{min:6,max:14},reads:0,description:"Auth token has a non-null value for the named claim."},{signature:"hasClaimRole(claim: string, role: string): bool",cost:{min:6,max:14},reads:0,description:"Auth token claim equals the named role value."},{signature:"isMemberOf(membersMap: map): bool",cost:{min:6,max:12},reads:0,description:"Auth uid is a key in the members map."},{signature:"hasRole(membersMap: map, role: string): bool",cost:{min:6,max:14},reads:0,description:"Auth uid is in the members map with the named role."}],relatedKeys:["auth","request"]},uy={key:"lifecycle",kind:"user-module",description:"User-authored module: field immutability, changed-field checks, and server-timestamp checks (fieldUnchanged, immutableFields, onlyFieldsChanged, exactlyChanged, nFieldsChanged, isServerTimestamp). Self-contained.",purpose:"Locks specific fields against modification on updates and asserts that a timestamp field matches `request.time` (i.e. the client used the server-timestamp sentinel).",whenToUse:"Reach for `lifecycle` on every update rule to lock identity fields (`createdAt`, `ownerId`) and to enforce server-set timestamps.",entries:[{signature:"fieldUnchanged(field: string): bool",cost:{min:11,max:11},reads:0,description:"The named field is byte-identical before and after the write."},{signature:"immutableFields(fields: list<string>): bool",cost:{min:10,max:10},reads:0,description:"All listed fields are unchanged. Implemented via MapDiff so it is cheaper than chaining `fieldUnchanged` calls."},{signature:"isServerTimestamp(field: string): bool",cost:{min:9,max:9},reads:0,description:"The named field equals `request.time` (i.e. the client wrote `FieldValue.serverTimestamp()`)."},{signature:"onlyFieldsChanged(fields: list<string>): bool",cost:{min:10,max:10},reads:0,description:"The dual of immutableFields: every CHANGED field is in the allowed list, so unlisted fields are implicitly immutable (adds and removes count as changes). The most common update guard: users may edit title and body and nothing else. Top-level keys only; nested-map diffs are unreliable in production.",examples:["allow update: if onlyFieldsChanged(['title', 'body']);"]},{signature:"nFieldsChanged(n: int): bool",cost:{min:11,max:11},reads:0,description:"Exactly n top-level fields changed in this write. `nFieldsChanged(1)` is the board-integrity / edit-one-field-per-write guard."},{signature:"exactlyChanged(keys: list<string> | set<string>): bool",cost:{min:13,max:17},reads:0,description:"The top-level fields the write adds, removes, or changes are exactly `keys`: every listed field changed and no other field did. `onlyFieldsChanged` is the subset form, where a listed field may stay unchanged.",examples:["allow update: if exactlyChanged(['board', 'lastMove', 'currentTurn', 'moveCount']);"],notes:"Use it for a transition that always writes the same fields, such as a tic-tac-toe move. Reads `resource.data`, so on create the call is an error and the rule denies."}],relatedKeys:["map","validation","request","counters"]},ly={key:"transitions",kind:"user-module",description:"User-authored module: state-machine transitions (validTransition, statusIs, newStatusIs). Self-contained.",purpose:"Asserts that a field moves from one specific value to another specific value on a write. Use to encode state-machine edges directly in rules.",whenToUse:"Reach for `transitions` whenever a rule encodes a state machine — order: pending → paid → shipped, etc.",entries:[{signature:"validTransition(field: string, from: string, to: string): bool",cost:{min:8,max:16},reads:0,description:"Field was `from` before and is `to` after."},{signature:"statusIs(field: string, value: string): bool",cost:{min:7,max:7},reads:0,description:"Pre-write field equals `value`."},{signature:"newStatusIs(field: string, value: string): bool",cost:{min:8,max:8},reads:0,description:"Post-write field equals `value`."}],relatedKeys:["state","lifecycle"]},dy={key:"geometry",kind:"user-module",description:"User-authored module: movement validation via config-doc lookup (validSimpleMove, validJumpMove) and named squares such as 'e4' on an 8 by 8 board (file, rank, step, inBounds). The config-doc functions take the config from a `get()` call.",purpose:"Board-game movement rules expressed as lookups in a config document, `cfg.moves[piece][from][to]` for simple moves and `cfg.jumps[piece][from][to]` for jumps (with captured-cell info), or as arithmetic on square names: file letter 'a' to 'h', then rank digit '1' to '8'. The module is \"explicit parameter\" style: no implicit reads. The caller passes the config and the squares explicitly.",whenToUse:"Reach for `geometry` on grid-based games (chess, checkers, go variants). Pair the config-doc functions with a `get()` on your config document. Use the named-square functions when the board is a map keyed by square names; check a client-written square with `inBounds` before you read it.",entries:[{signature:"validSimpleMove(cfg: map): bool",cost:{min:26,max:26},reads:0,description:"`cfg.moves[piece][from][to] == true`."},{signature:"validJumpMove(cfg: map): bool",cost:{min:31,max:31},reads:0,description:"`cfg.jumps[piece][from][to] == capturedCell`."},{signature:"file(square: string): int",cost:{min:23,max:23},reads:0,description:"The square's file as a number: 'a' is 1 and 'h' is 8.",examples:["allow update: if file(request.resource.data.to) - file(resource.data.from) == 1;"],notes:"A first character outside 'a' to 'h', an empty string, or a non-string square is an error, which denies. Costs the same as the map lookup written inline."},{signature:"rank(square: string): int",cost:{min:6,max:6},reads:0,description:"The square's rank as a number: the second character read as a digit.",examples:["allow update: if rank(request.resource.data.to) == 8;"],notes:"Reads only the second character, so `rank('e9')` is 9 and `rank('e44')` is 4: check the square with `inBounds` first. A non-digit second character, a square shorter than two characters, or a non-string square is an error, which denies."},{signature:"step(square: string, df: int, dr: int): string",cost:{min:49,max:49},reads:0,description:"The square `df` files and `dr` ranks away from `square`, as a name.",examples:["allow update: if request.resource.data.to == step(resource.data.from, 1, 1);"],notes:"`step(from, df, dr) == to` costs 51, where the same test written as file and rank differences costs 53 to 71. A step off the board in any direction is an error, which denies. To test for any one diagonal neighbor, compare file and rank differences instead of calling `step` four times."},{signature:"inBounds(square: any): bool",cost:{min:5,max:9},reads:0,description:"The value is a string of one file letter 'a' to 'h' and one rank digit '1' to '8'.",examples:["allow update: if inBounds(request.resource.data.to);"],notes:"Anything else, a non-string included, is false rather than an error."}],relatedKeys:["transitions","state"]},fy={key:"counters",kind:"user-module",description:"User-authored module: denormalized numeric integrity and best scores (incrementedBy, changedBy, boundedNumber, improvedBy). Self-contained.",purpose:"Keeps client-maintained counts honest: likes, votes, moves, quantities may only change by a known step, stay within known bounds, or move strictly one way. Generalizes the state module's moveIncremented() (hardcoded to moveCount) to any field.",whenToUse:"Reach for `counters` whenever a numeric field is client-written but semantically constrained: vote/like toggles (`changedBy(f, -1, 1)`), move counters (`incrementedBy(f, 1)`), ratings (`boundedNumber(f, 1, 5)`), best scores that only get better (`improvedBy(f, 'up', [...])`).",entries:[{signature:"incrementedBy(field: string, n: int): bool",cost:{min:13,max:13},reads:0,description:"The field changed by EXACTLY n vs the existing document (n may be negative). Update rules only.",examples:["allow update: if incrementedBy('moveCount', 1);"]},{signature:"changedBy(field: string, min: int, max: int): bool",cost:{min:14,max:27},reads:0,description:"The field's delta is within [min, max] inclusive; a zero delta passes when the range spans 0.",examples:["allow update: if changedBy('likeCount', -1, 1);"]},{signature:"boundedNumber(field: string, min: number, max: number): bool",cost:{min:19,max:35},reads:0,description:"The incoming value is an int or float within [min, max]. A missing field is an error under dynamic access, so the call denies.",examples:["allow write: if boundedNumber('rating', 1, 5);"]},{signature:"improvedBy(field: string, direction: 'up' | 'down', mayChange: list<string>): bool",cost:{min:18,max:50},reads:0,description:"The numeric field moved strictly in `direction` (`up`: new > old, `down`: new < old) and every other changed top-level field is in `mayChange`. Both values must be an int or a float; they compare by value.",examples:["allow update: if improvedBy('score', 'up', ['solve']);",`allow update: if improvedBy('moves', 'down', ['pushes', 'solve'])
|
|
1703
|
+
|| improvedBy('pushes', 'down', ['solve']);`],notes:"A listed field may stay unchanged. An unchanged or worse value, a non-numeric or missing value on either side, an unlisted field added, removed, or changed, and a direction other than `up` or `down` deny. For a score ranked on two fields, call it once per field: the second call leaves the first field out of `mayChange`, so it allows fewer pushes only on as many moves. Write the score's type, bounds, and owner checks beside it. Reads `resource.data`, so on create the call is an error and the rule denies."}],relatedKeys:["lifecycle","state"]},hy={key:"timing",kind:"user-module",description:"User-authored module: cooldown / rate-limit enforcement (cooldownElapsed). Self-contained. Live-verified against the production engine.",purpose:"Rules CAN rate-limit: compare `request.time` against a stored server timestamp with duration arithmetic. Enforces a minimum interval between writes to a document.",whenToUse:"Reach for `timing` to throttle per-document writes — game move intervals, post cooldowns, retry backoff. ALWAYS pair with lifecycle's `isServerTimestamp(field)` on the same write so the stored timestamp cannot be forged by the client. Per-document intervals only; sliding-window quotas need a counter document plus this guard.",entries:[{signature:"cooldownElapsed(field: string, seconds: int): bool",cost:{min:12,max:12},reads:0,description:"`request.time > resource.data[field] + duration.value(seconds, 's')` — the stored timestamp is STRICTLY older than the window. Update rules only (needs `resource`); a missing or non-timestamp field errors, which denies (fail-closed).",examples:["allow update: if cooldownElapsed('lastMoveAt', 2) && isServerTimestamp('lastMoveAt');"]}],relatedKeys:["lifecycle","timestamp","duration"]},py={key:"content",kind:"user-module",description:"User-authored module: author-owned documents (validAuthorCreate, isAuthor, canReadContent, notDeleted) and hidden per-player documents (ownerOnlyUntil). Self-contained; ownerOnlyUntil reads the parent match with one get(). Field names are parameters, not conventions.",purpose:"The most common Firebase app shape — posts, notes, docs, comments, tasks. Covers the create/read/update/delete lifecycle of documents that belong to their author, with draft/published visibility and soft delete.",whenToUse:"Reach for `content` on any collection whose documents have an author/owner field. Compose with lifecycle.onlyFieldsChanged to keep authorship immutable on edits.",entries:[{signature:"validAuthorCreate(authorField: string): bool",cost:{min:6,max:16},reads:0,description:"Create guard: signed in AND the incoming doc's author field is the caller's uid.",examples:["allow create: if validAuthorCreate('author');"]},{signature:"isAuthor(authorField: string): bool",cost:{min:6,max:15},reads:0,description:"The caller is the EXISTING document's author. Update/delete rules.",examples:["allow update: if isAuthor('author') && onlyFieldsChanged(['title', 'body']);"]},{signature:"canReadContent(statusField: string, authorField: string): bool",cost:{min:8,max:23},reads:0,description:"Published content is public; anything else is visible to its author only. `get` rules — a bare collection `list` will be denied unless the query proves `status == 'published'` via filters (rules are not filters).",examples:["allow read: if canReadContent('status', 'author') && notDeleted();"]},{signature:"notDeleted(): bool",cost:{min:8,max:8},reads:0,description:"Soft-delete guard: `resource.data.get('deleted', false) != true`. `get()` returns the default for a missing key, so a document WITHOUT the field passes. Dotted or bracket access of a missing key is an error in production and would deny it."},{signature:"ownerOnlyUntil(parentPath: path, ownerUid: string, statuses: list): bool",cost:{min:6,max:20},reads:1,description:"Read rule for a hidden per-player document under a match: the owner reads it at any time, and any other signed-in caller reads it once the match at `parentPath` has a `status` in `statuses`.",examples:["allow read: if ownerOnlyUntil(/databases/$(database)/documents/battleship/$(matchId), uid, ['won', 'resigned']);"],notes:"The document lives at {collection}/{matchId}/{sub}/{uid}. Pass the `uid` wildcard as the owner when the document id is the owner's UID, or `resource.data.<field>` when the owner is a field. Pass one status as a one-item list, such as ['finished']. The owner check runs before the `get()`, so the owner's read spends no read; everyone else pays one `get()` of the parent. A missing parent match is an error and denies every caller but the owner."}],relatedKeys:["auth","lifecycle","validation"]},my={key:"spaces",kind:"user-module",description:"User-authored module: cross-document membership gating (isSpaceMember, hasSpaceRole, validMemberCreate). Explicit param — pass the parent doc data from a get(). Live-verified against the production engine.",purpose:"Shared spaces — teams, rooms, groups, projects, parties: a PARENT document's members field gates its children. The second-most-common app shape after author-owned content.",whenToUse:"Reach for `spaces` whenever a subcollection is gated by a parent doc. Define ONE helper in the child match block — `function space() { return get(/databases/$(database)/documents/spaces/$(spaceId)).data; }` — and pass it to every function: get() is cached per request, so all rules on the request share a single read of the 10-get budget. Do NOT inline a get() per allow clause.",entries:[{signature:"isSpaceMember(spaceData: map): bool",cost:{min:6,max:13},reads:0,description:"The caller's uid is in `spaceData.members`. `in` covers BOTH shapes: list membership (`members: ['a','b']`) and map keys (`members: {a: 'admin'}`). Missing field / non-member / missing parent doc all fail closed.",examples:["allow read: if isSpaceMember(space());"]},{signature:"hasSpaceRole(spaceData: map, role: string): bool",cost:{min:6,max:15},reads:0,description:"The caller's role in a MAP-shaped members field equals `role` (`spaceData.members[request.auth.uid] == role`). List-shaped members carry no roles — denies.",examples:["allow delete: if hasSpaceRole(space(), 'admin');"]},{signature:"validMemberCreate(spaceData: map, authorField: string): bool",cost:{min:9,max:26},reads:0,description:`Member-gated authored create: caller is a member AND the incoming child doc's author field is the caller. The "post a message / add a task" guard.`,examples:["allow create: if validMemberCreate(space(), 'author');"]}],relatedKeys:["membership","content","builtins"]},gy={key:"joining",kind:"user-module",description:"User-authored module: safe self-service membership changes (onlyAddedSelf, onlyRemovedSelf). Self-contained. Live-verified against the production engine.",purpose:"How membership CHANGES without an admin backend: users join and leave a MAP-shaped members field (uid -> role) with zero privilege escalation — no self-granted roles, no touching other members, no-op writes denied.",whenToUse:"Reach for `joining` on the PARENT doc's update rule wherever spaces gates the children. ALWAYS compose with lifecycle's onlyFieldsChanged(['members']) so a join/leave write cannot modify anything else on the doc. Invite-doc consumption (single-use invites) is a Pattern, not a function — it needs a batch write + getAfter().",entries:[{signature:"onlyAddedSelf(membersField: string, role: string): bool",cost:{min:20,max:53},reads:0,description:"The write adds EXACTLY the caller to the members map at EXACTLY `role` — changing nobody, removing nobody; a no-op write denies (uses set equality `diff.addedKeys() == [uid].toSet()`, not hasOnly, which passes on an empty diff). Update rules only.",examples:["allow update: if onlyFieldsChanged(['members']) && (onlyAddedSelf('members', 'editor') || onlyRemovedSelf('members'));"]},{signature:"onlyRemovedSelf(membersField: string): bool",cost:{min:19,max:40},reads:0,description:"The write removes EXACTLY the caller — adding nobody, changing nobody. Self-service leave. Update rules only."}],relatedKeys:["spaces","lifecycle","membership"]},yy={key:"atomic",kind:"user-module",description:"User-authored module: cross-document BATCH-write integrity via get()/getAfter() (companionChangedBy, consumedFlag). Explicit param. Live-verified against a real production database.",purpose:"Rules that require a COMPANION write in the same atomic batch: denormalized counters (create task + increment team.taskCount), single-use invite consumption (join + mark invite used), paired documents. getAfter(path) returns the post-batch state of another doc in the batch; for docs not in the batch it equals get(path).",whenToUse:"Reach for `atomic` when two documents must change together. Define before()/after() helpers — `get(path).data` and `getAfter(path).data` for the SAME companion path — and pass both. Every write in a batch is rules-evaluated: the companion write needs its own allow rule. The client must use a batch/transaction (writeBatch / runTransaction); solo writes deny by construction.",entries:[{signature:"companionChangedBy(before: map, after: map, field: string, n: int): bool",cost:{min:10,max:10},reads:0,description:"The companion doc's field changed by EXACTLY n in this batch (`after[field] == before[field] + n`). A solo write denies: without a companion write, getAfter == get, so the delta is 0.",examples:["allow create: if companionChangedBy(teamBefore(), teamAfter(), 'taskCount', 1);"]},{signature:"consumedFlag(before: map, after: map, flagField: string): bool",cost:{min:7,max:13},reads:0,description:"A single-use flag was consumed IN THIS BATCH: pre-batch false AND post-batch true. Replays deny (already true before the batch); solo writes deny (false != true when getAfter == get). Pair with an allow rule on the flag doc itself (e.g. invitee-only, resource.used == false).",examples:["allow update: if consumedFlag(inviteBefore(), inviteAfter(), 'used');"]}],relatedKeys:["counters","joining","spaces","builtins"]},by={key:"storage/uploads",kind:"user-module",description:"Storage module: inclusive upload-size limits and declared MIME metadata allowlists.",purpose:"Apply bounded upload policies to the incoming Storage object. MIME helpers inspect declared metadata; they do not inspect or authenticate the uploaded bytes.",whenToUse:"Use for Storage create or update rules that limit object size or accepted content-type metadata.",entries:[{signature:"sizeAtMost(maxBytes: int): bool",cost:{min:6,max:6},reads:0,description:"The incoming object size is at most the inclusive byte limit."},{signature:"sizeBetween(minBytes: int, maxBytes: int): bool",cost:{min:7,max:13},reads:0,description:"The incoming object size is inside the inclusive byte range."},{signature:"contentTypeMatches(pattern: string): bool",cost:{min:6,max:6},reads:0,description:"The incoming content-type metadata matches the entire RE2 pattern.",notes:"This checks declared metadata, not the uploaded bytes."},{signature:"contentTypeIsOneOf(types: list): bool",cost:{min:6,max:6},reads:0,description:"The incoming content-type metadata equals one allowlisted value.",notes:"This checks declared metadata, not the uploaded bytes."}],relatedKeys:["auth","membership","storage/metadata","storage/objects"]},vy={key:"storage/metadata",kind:"user-module",description:"Storage module: required custom metadata, bounded string values, and metadata ownership.",purpose:"Validate the flat string map in Storage custom metadata and connect incoming or existing ownership metadata to the authenticated UID.",whenToUse:"Use when object paths alone do not carry every upload invariant and custom metadata must be present, bounded, or owner-bound.",entries:[{signature:"hasRequiredMetadata(keys: list): bool",cost:{min:7,max:7},reads:0,description:"The incoming custom metadata contains every required key."},{signature:"metadataString(key: string, min: int, max: int): bool",cost:{min:28,max:28},reads:0,description:"The incoming metadata value is a string within the inclusive size range."},{signature:"incomingMetadataOwner(key: string): bool",cost:{min:6,max:16},reads:0,description:"The incoming metadata value equals the authenticated UID."},{signature:"existingMetadataOwner(key: string): bool",cost:{min:6,max:15},reads:0,description:"The existing metadata value equals the authenticated UID."}],relatedKeys:["auth","membership","storage/uploads","storage/objects"]},wy={key:"storage/objects",kind:"user-module",description:"Storage module: distinguish create, update, and delete operations safely, read segments of the object name, and tie an object to the Firestore document that names it.",purpose:"Branch Storage authorization by request method without relying on missing resource bindings or null checks, and check an object by its name: one segment at a time, or against a field of a Firestore document.",whenToUse:"Use when create, update, and delete require different ownership or validation checks, when the object name carries an owner or key, or when an upload is allowed only once a Firestore document names it.",entries:[{signature:"isCreate(): bool",cost:{min:5,max:5},reads:0,description:"The Storage request method is 'create'."},{signature:"isUpdate(): bool",cost:{min:5,max:5},reads:0,description:"The Storage request method is 'update'."},{signature:"isDelete(): bool",cost:{min:5,max:5},reads:0,description:"The Storage request method is 'delete'."},{signature:"nameSegment(index: int): string",cost:{min:17,max:18},reads:0,description:"Segment `index` of the object name split on '/', counting from 0. The name is `request.resource.name` on create and update and `resource.name` on get and delete.",examples:["allow create: if nameSegment(1) == request.auth.uid;"],notes:"An index past the last segment is an error that denies the request, and a name with no '/' has one segment. A create may have no stored object, and a get or delete carries no incoming object, so the name comes from the binding each operation has."},{signature:"matchesDocument(path: path, field: string): bool",cost:{min:6,max:26},reads:1,description:"The caller is signed in, and the Firestore document at `path` exists and its `field` equals the object name.",examples:["allow create: if matchesDocument(/databases/(default)/documents/scores/$(request.auth.uid), 'object');"],notes:"Each call reads one document. A Storage rule reads at most two distinct Firestore documents, so a rule may call matchesDocument at most twice with different paths; a third distinct document denies the request. A missing document or field is an error that denies the request. The lookup reads the (default) database."}],relatedKeys:["auth","membership","storage/uploads","storage/metadata"]},Sy={key:"storage/time",kind:"user-module",description:"Storage module: strict freshness windows over server-owned object timestamps.",purpose:"Check whether an existing Storage object was created or updated within a bounded number of seconds.",whenToUse:"Use for access policies whose validity expires relative to an existing object timestamp.",entries:[{signature:"createdWithin(seconds: int): bool",cost:{min:10,max:10},reads:0,description:"Request time is strictly before creation time plus the window.",notes:"Equality with the deadline denies. Requires an existing object."},{signature:"updatedWithin(seconds: int): bool",cost:{min:10,max:10},reads:0,description:"Request time is strictly before update time plus the window.",notes:"Equality with the deadline denies. Requires an existing object."}],relatedKeys:["storage/objects","auth","membership"]};function Ay(t){if(t.kind!=="user-module")return["firestore"];const e=Go[t.key];return e?e.map(n=>n==="firebase.storage"?"storage":"firestore"):["firestore"]}const ky=[Bg,zg,Wg,Vg,Gg,Hg,Kg,Zg,Jg,Qg,Yg,Xg,ey,ty,ny,sy,ry,iy,oy,ay,cy,uy,ly,dy,fy,hy,py,my,gy,yy,by,vy,wy,Sy].map(t=>({...t,services:Ay(t)}));function ud(t){return JSON.stringify([t.parameters,t.lets.map(e=>[e.name,re(e.value)]),re(t.body)])}let li=null;function Ey(){if(li)return li;const t=new Map;for(const e of ky){if(e.kind!=="user-module")continue;const n=e.entries.map(a=>a.signature.slice(0,a.signature.indexOf("("))),s=e.services.includes("firestore")?"service cloud.firestore { match /databases/{database}/documents { } }":"service firebase.storage { match /b/{bucket}/o { } }",r=Ug(`rules_version = '2+modules';
|
|
1704
|
+
import { ${n.join(", ")} } from '${e.key}';
|
|
1705
|
+
${s}
|
|
1706
|
+
`);if(!r.success)continue;const i=Fl(r.data.resolved);if(!i)continue;const o=new Map;for(const a of[...i.functions??[],...i.service.functions??[]])o.set(a.name,a);for(const a of e.entries){const c=a.signature.slice(0,a.signature.indexOf("(")),u=o.get(c);!u||!a.cost||t.set(c,{module:e.key,name:c,cost:a.cost,reads:a.reads??0,fingerprint:ud(u)})}}return li=t,t}function Iy(t){const e=Ey().get(t.name);if(!e||e.fingerprint!==ud(t))return null;const{fingerprint:n,...s}=e;return s}function _y(t){const e=[];for(const n of zm(t)){const s=[];for(const{fn:r,count:i}of n.calls){const o=Iy(r);o&&s.push({...o,count:i})}s.length!==0&&(s.sort((r,i)=>i.cost.max*i.count-r.cost.max*r.count||r.name.localeCompare(i.name)),e.push({ruleIndex:n.ruleIndex,matchPath:n.matchPath,blockPath:n.blockPath,...n.line!==void 0?{line:n.line}:{},calls:s}))}return e}const Ct={SOURCE_SIZE:256*1024,LET_LIMIT:El,CALL_DEPTH_WARN:18,CALL_DEPTH_LIMIT:ts,GET_COUNT_WARN:5,GET_COUNT_ERROR:10};function xy(t,e){t.length>Ct.SOURCE_SIZE&&e.push({rule:"SOURCE_SIZE",severity:"error",message:`Rules source is ${(t.length/1024).toFixed(0)} KB, exceeding the 256 KB limit.`,fix:"Reduce string literals, remove comments, or split into smaller match blocks."})}function Cy(t,e){for(const n of t)n.lets.length>Ct.LET_LIMIT&&e.push({rule:"LET_LIMIT",severity:"error",message:`Function '${n.name}' has ${n.lets.length} let bindings. Limit is ${Ct.LET_LIMIT}.`,location:{functionName:n.name},fix:"Inline some let expressions into the return statement, or split the function."})}function Oy(t,e){const n=new Set;for(const s of t){if(s.code!=="NESTING_DEPTH")continue;const r=`${s.functionName??""}@${s.line??""}`;if(n.has(r))continue;n.add(r);const i=s.functionName!==void 0?`Function '${s.functionName}'`:s.line!==void 0?`The rule at line ${s.line}`:"An allow rule";e.push({rule:"NESTING_DEPTH",severity:"error",message:`${i} nests an expression deeper than ${Po} levels. Production rejects the ruleset: "${Il}"`,...s.functionName!==void 0?{location:{functionName:s.functionName}}:{},fix:"Remove redundant parentheses, or move a nested group into its own function and call it."})}}function Ty(t,e){for(const n of t){if(n.code!=="SLASH_STARTS_PATH")continue;let s="in an allow rule";if(n.functionName!==void 0){const r=n.line===void 0?"":` at line ${n.line}`;s=`in function '${n.functionName}'${r}`}else n.line!==void 0&&(s=`in the rule at line ${n.line}`);e.push({rule:"SLASH_STARTS_PATH",severity:"error",message:`A '/' ${s} is directly followed by a character other than whitespace, which production reads as the start of a path. Production rejects the ruleset: "${_l}"`,...n.functionName!==void 0?{location:{functionName:n.functionName}}:{},fix:"To divide, put whitespace after the '/': `a / b`."})}}function Ry(t,e){for(const n of t){if(n.code!=="GLOB_MATCH_COUNT")continue;const s={rule:"GLOB_MATCH_COUNT",severity:"error",message:n.message,fix:"Restructure match blocks so a path contains at most one recursive wildcard `{name=**}`."};n.scope!==void 0&&(s.location={matchPath:n.scope}),e.push(s)}}function Ny(t,e,n){for(const s of e)switch(s.code){case"UNSUPPORTED_RULES_VERSION":n.push({rule:"UNSUPPORTED_RULES_VERSION",severity:"error",message:s.message,fix:"Set rules_version to '1', '2', or '2+modules'."});break;case"UNRESOLVED_MODULES":t.version!=="2+modules"&&n.push({rule:"UNRESOLVED_MODULES",severity:"error",message:s.message,fix:"Set `rules_version = '2+modules';` or resolve module imports before compiling."});break;case"INVALID_REGEX_PATTERN":n.push({rule:"INVALID_REGEX_PATTERN",severity:"error",message:s.message,...s.functionName!==void 0?{location:{functionName:s.functionName}}:{},fix:"Rewrite the regular expression using RE2-compatible syntax (no lookahead, lookbehind, or backreferences)."});break;case"FUNCTION_REDEFINED":n.push({rule:"FUNCTION_REDEFINED",severity:"error",message:s.message,...s.functionName!==void 0||s.scope!==void 0?{location:{...s.functionName!==void 0?{functionName:s.functionName}:{},...s.scope!==void 0?{matchPath:s.scope}:{}}}:{},fix:`Rename or remove the duplicate declaration of '${s.functionName??"function"}' in ${s.scope??"this scope"}.`});break}}const lc=4900;function Ly(t,e,n){const s=[];for(const r of e){for(const i of r.lets)s.push({expr:i.value,functionName:r.name});s.push({expr:r.body,functionName:r.name})}for(const{rule:r}of Wo(t.service.match))s.push({expr:r.condition,...r.loc===void 0?{}:{line:r.loc.line}});for(const r of s){let i=0;const o=[r.expr];for(;o.length>0;){const c=o.pop();let u=1,l=c;for(;l.type==="memberAccess";)u++,l=l.object;c.type==="memberAccess"&&(i=Math.max(i,u)),o.push(...My(l))}if(i<lc)continue;const a=r.functionName!==void 0?`Function '${r.functionName}'`:r.line!==void 0?`The rule at line ${r.line}`:"An allow rule";n.push({rule:"MEMBER_CHAIN_LENGTH",severity:"error",message:`${a} reads a member chain of ${i} terms. The Rules Test API answered a ruleset holding a ${lc.toLocaleString("en-US")}-term member chain with an internal error instead of compiling it.`,...r.functionName!==void 0?{location:{functionName:r.functionName}}:{},fix:"Shorten the chain: bind a value partway along it to a `let` or a function parameter, and read the rest of the chain from that name."})}}function My(t){switch(t.type){case"literal":case"identifier":return[];case"memberAccess":return[t.object];case"methodCall":return[t.object,...t.args];case"bracketAccess":return[t.object,t.index];case"sliceAccess":return[t.object,t.start,t.end];case"binaryOp":return[t.left,t.right];case"unaryOp":return[t.operand];case"ternary":return[t.condition,t.consequent,t.alternate];case"inExpr":return[t.element,t.collection];case"isExpr":return[t.value];case"listLiteral":return t.elements;case"mapLiteral":return t.entries.flatMap(e=>[e.key,e.value]);case"pathLiteral":return t.segments.filter(e=>typeof e!="string");case"functionCall":return t.args}}function Dy(t,e){const n=new Map;for(let s=0;s<t.length;s++){const r=t[s];if(!r.rule.operations.some(a=>a==="update"||a==="write"))continue;const i=re(Ql(r.rule.condition)),o=r.path;n.has(o)||n.set(o,[]),n.get(o).push({index:s,gate:i,ops:r.rule.operations})}for(const[s,r]of n){const i=new Map;for(const o of r)i.has(o.gate)||i.set(o.gate,[]),i.get(o.gate).push(o.index);for(const[o,a]of i)a.length>=2&&e.push({rule:"SHARED_GATE",severity:"warning",message:`${a.length} allow rules in '${s}' share the same gate expression. This may cause cross-rule budget exhaustion. Rules: ${a.join(", ")}.`,location:{matchPath:s},fix:"Assign unique moveType or discriminator values so each rule has a unique first expression."})}}function $y(t,e){for(const n of t)n.grantCost===null||n.grantCost<hs||e.push({rule:"EXPRESSION_BUDGET",severity:"warning",message:`Rule #${n.ruleIndex} in '${n.blockPath}' can evaluate up to ~${n.grantCost} expressions for a request it grants, counting the earlier rules that deny it first. Production denies a request that reaches ${hs}.`,location:{ruleIndex:n.ruleIndex,matchPath:n.blockPath},fix:"Put a cheap discriminator first in each rule so earlier rules fail at their gate, split expensive checks so a request evaluates only the branch it needs, or move lookup work into documents."})}function Py(t,e){for(const n of _y(t)){const s=n.calls.slice(0,3).map(r=>{const i=r.cost.min===r.cost.max?`${r.cost.max}`:`${r.cost.min} to ${r.cost.max}`,o=r.reads>0?`, ${r.reads} read${r.reads===1?"":"s"} per call`:"";return`${r.name} (${r.module}): ${r.count} call${r.count===1?"":"s"}, ${i} expressions per call${o}`});e.push({rule:"EXPRESSION_LIBRARY_CALLS",severity:"info",message:`Rule #${n.ruleIndex} in '${n.blockPath}' spends most on these library calls: ${s.join("; ")}. Calls are not memoized: each call pays again.`,location:{ruleIndex:n.ruleIndex,matchPath:n.blockPath}})}}function Fy(t,e){const{depths:n,cyclic:s}=Qp(t),r=new Set;for(const o of t.functions)for(const a of Wl(o).callees)a!==o.fn&&r.add(a);let i=!1;for(const o of t.functions){if(s.has(o.fn)){i||(i=!0,e.push({rule:"CALL_DEPTH",severity:"error",message:`Function '${o.fn.name}' is part of a recursive call cycle, exceeding the call depth limit of ${Ct.CALL_DEPTH_LIMIT}.`,location:{functionName:o.fn.name,matchPath:o.label},fix:"Remove recursion between helper functions; Firestore rules do not allow recursive calls."}));continue}if(r.has(o.fn))continue;const a=n.get(o.fn)??1;if(a<Ct.CALL_DEPTH_WARN)continue;const c=a>Ct.CALL_DEPTH_LIMIT;e.push({rule:"CALL_DEPTH",severity:c?"error":"warning",message:`Function '${o.fn.name}' starts a function call chain of depth ${a}. Limit is ${Ct.CALL_DEPTH_LIMIT}.`,location:{functionName:o.fn.name,matchPath:o.label},...c?{fix:"Inline intermediate functions to reduce call depth."}:{}})}return n}function jy(t,e,n,s,r=!1){const i=new Map,o=r?2:Ct.GET_COUNT_ERROR,a=r?2:Ct.GET_COUNT_WARN,c=r?"firestore.get()/firestore.exists()":"get()/exists()/getAfter()/existsAfter()";for(let u=0;u<t.length;u++){const l=e.get(t[u].rule)??i,d=Ul(t[u].rule.condition,l,new Set,n);d>o?s.push({rule:"GET_COUNT",severity:"error",message:`Rule #${u} may invoke ${d} ${c} calls. Limit is ${o}.`,location:{ruleIndex:u},fix:"Cache get() results via a config() wrapper function. Same-path calls are cached by Firestore."}):d>=a&&s.push({rule:"GET_COUNT",severity:"warning",message:`Rule #${u} invokes ${d} ${c} calls. Limit is ${o}.`,location:{ruleIndex:u}})}}function qy(t,e,n,s){const r=new Map;for(let i=0;i<t.length;i++){const o=e.get(t[i].rule)??r,a=new Set(o.keys()),c=pm(t[i].rule.condition,a);for(const[u,l]of c)l>=2&&Yl(u,o,new Set,n)&&s.push({rule:"GET_DUPLICATION",severity:"warning",message:`Function '${u}' (contains get/exists) is called ${l} times in rule #${i}. Cache the result with a let binding in a wrapper function to reduce get() calls from ${l} to 1.`,location:{ruleIndex:i},fix:`Create a wrapper: function verifyAll(ret) { let c = ${u}(); return verify1(ret, c) && verify2(ret, c) && ...; }`})}}function Uy(t,e,n,s,r){const i=new Map,o=new Set;for(let c=0;c<t.length;c++){const u=e.get(t[c].rule)??i;qi(t[c].rule.condition,u,new Set,n)&&o.add(c)}if(o.size===0)return;function a(c,u){const l=c.split("/").filter(Boolean),d=u.split("/").filter(Boolean);if(l.length!==d.length)return!1;for(let f=0;f<l.length;f++){const p=l[f];if(!(p.startsWith("{")&&p.endsWith("}"))&&p!==d[f])return!1}return!0}for(const c of s)if(!c.requestTime)for(const u of o)a(t[u].path,c.path)&&r.push({rule:"REQUEST_TIME_NOT_PINNED",severity:"warning",message:`Test case "${c.description}" targets rule #${u} (path '${t[u].path}') which reads request.time, but does not set requestTime. Result is non-deterministic across runs.`,location:{ruleIndex:u,matchPath:t[u].path,testCaseDescription:c.description},fix:"Set requestTime on this TestCase to an ISO-8601 timestamp so the rule evaluates deterministically."})}const By=new Set(["write","create","update","delete"]);function zy(t,e,n,s=!1){for(let r=0;r<t.length;r++){const i=t[r];if(Bt(i.rule.condition)!==!0||!i.rule.operations.some(c=>By.has(c)))continue;const a=i.rule.operations.join(", ");n.push({rule:"PERMISSIVE_RULE",severity:"warning",message:`allow ${a} at ${i.path} resolves to a constant true predicate — this disables write security for ${e.get(i.rule)?.description??"the matched paths"}. If you reached for \`if true\` to escape a denial you don't understand, narrow the predicate to the specific request shape instead (auth identity, affected fields via diff, status transitions).`,location:{ruleIndex:r,matchPath:i.path},fix:s?"Replace the always-true predicate with a request-shape check (e.g. request.auth != null && request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*')).":"Replace the always-true predicate with a request-shape check (e.g. request.auth != null && request.resource.data.ownerId == request.auth.uid)."})}}function ld(t,e,n){const s=[...e,...t.path.segments],r=Hp(s);r&&t.allows.forEach((i,o)=>n.set(i,{...r,ruleIndex:o}));for(const i of t.children)ld(i,s,n);return n}function Wy(t,e){for(const[n,s]of t)s.kind!=="subtree"||Bt(n.condition)!==!0||e.push({rule:"RECURSIVE_WILDCARD_OPEN",severity:"error",message:`match ${s.fullPath} allows ${n.operations.join(", ")} on ${s.description} with an always-true condition.`,location:{ruleIndex:s.ruleIndex,matchPath:s.fullPath},fix:"Narrow the match path to the collections that must be open, for example match /{path=**}/<collection>/{id} for one collection group, or replace `if true` with a real predicate (auth identity, ownership, role)."})}function Vy(t){return t.type==="literal"?t.value??"":t.type==="wildcard"?"{*}":t.type==="recursive"?"{**}":""}function Gy(t){return t.map(Vy).join("/")}function Wi(t,e){const n=Gy(t.path.segments),s=e?`${e}/${n}`:n,r=[{block:t,normalizedPath:s}];for(const i of t.children)r.push(...Wi(i,s));return r}function Hy(t,e,n){const s=Wi(t,""),r=Wi(e,""),i=new Map;for(const{block:o,normalizedPath:a}of s)i.has(a)||i.set(a,o);for(const{block:o,normalizedPath:a}of r){const c=i.get(a);if(!c){o.allows.length>0&&n.push({rule:"RULES_WEAKENED",severity:"warning",message:`Match block removed: ${a}`,location:{matchPath:a}});continue}for(const u of o.allows){const l=[...u.operations].sort().join(","),d=c.allows.find(m=>[...m.operations].sort().join(",")===l),f=u.operations.join(", ");if(!d){n.push({rule:"RULES_WEAKENED",severity:"warning",message:`Allow rule removed: ${a} allow ${f}`,location:{matchPath:a}});continue}const p=rr(u.condition).map(fe),h=new Set(rr(d.condition).map(fe));for(const m of p)h.has(m)||n.push({rule:"RULES_WEAKENED",severity:"warning",message:`Predicate removed from ${a} allow ${f}: ${m}`,location:{matchPath:a}})}}}function Vi(t,e={}){const n=[];n.push(...km(t)),xy(t,n);const s=Rs(t);if(!s.ok)return{warnings:n,metrics:dc(t),parseError:s.error};try{return Zy(s.ast,t,e,n)}catch(r){if(!(r instanceof RangeError))throw r;return n.push(Ky()),{warnings:n,metrics:dc(t)}}}function dc(t){return{sourceSize:t.length,functionCount:0,allowRuleCount:0,maxChainDepth:0,maxChainOp:"",maxLetBindings:0,maxLetBindingsFunction:"",maxCallDepth:0,maxEstimatedExpressions:0,getCallCount:0}}function Ky(){return{rule:"EXPRESSION_TOO_DEEP",severity:"error",message:"An expression chains or nests more terms, counting the bodies of the functions it calls, than the linter can analyze, so the remaining checks did not run. This is a limit of the linter; production's limit for this expression is not measured.",fix:"Shorten the chain: bind a value partway along it to a `let` or a function parameter, and read the rest of the chain from that name."}}function Zy(t,e,n,s){const r=t.service?.name==="firebase.storage",i=mm(t),o=Wo(t.service.match),a=zl(t),c=new Map(a.functions.map(w=>[w.fn,w.functions])),u=new Map(a.rules.map(w=>[w.rule,w.functions]));Ly(t,i,s);const l=xl(t);Oy(l,s),Ty(l,s),Ry(l,s),Ny(t,l,s),Cy(i,s),Dy(o,s);const d=Um(t);$y(d.rules,s),Py(t,s);const f=Fy(a,s);jy(o,u,c,s,r),qy(o,u,c,s),s.push(...$m(t,{allowDebug:n.allowDebug}));const p=new Map;for(const w of t.service.match.children)ld(w,[],p);if(zy(o,p,s,r),Wy(p,s),n.testCases&&n.testCases.length>0&&Uy(o,u,c,n.testCases,s),n.previousSource){const w=Rs(n.previousSource);w.ok&&Hy(t.service.match,w.ast.service.match,s)}let h={depth:0,op:""},m={count:0,fn:""};for(const w of i){const k=hm(w.body);k.depth>h.depth&&(h={depth:k.depth,op:k.op}),w.lets.length>m.count&&(m={count:w.lets.length,fn:w.name})}let g=0;for(const w of f.values())w>g&&(g=w);const y=new Map;let b=0;for(const w of d.rules)w.grantCost!==null&&w.grantCost>b&&(b=w.grantCost);let v=0;for(const w of o){const k=u.get(w.rule)??y,O=Ul(w.rule.condition,k,new Set,c);O>v&&(v=O)}return{warnings:s,metrics:{sourceSize:e.length,functionCount:i.length,allowRuleCount:o.length,maxChainDepth:h.depth,maxChainOp:h.op,maxLetBindings:m.count,maxLetBindingsFunction:m.fn,maxCallDepth:g,maxEstimatedExpressions:b,getCallCount:v}}}class dd{message;constructor(e){this.message=e}}const fc=new Set(["diff","get","keys","values"]),fd=new WeakMap;function Jy(t){const e={},n=[];for(const[s,r]of t)Object.hasOwn(e,s)||n.push(s),Object.defineProperty(e,s,{value:r,enumerable:!0,writable:!0,configurable:!0});return fd.set(e,n),e}function Qy(t,e,n){return n.length!==0?new dd(`Incorrect number of arguments. Received: ${n.length}. Expected: map.${t}().`):t==="keys"?Yy(e):Xy(e)}function Yy(t){return Object.keys(t).sort(eb)}function Xy(t){return(fd.get(t)??Object.keys(t)).map(n=>t[n])}function eb(t,e){const n=Math.min(t.length,e.length);for(let s=0;s<n;s+=1)if(t.charCodeAt(s)!==e.charCodeAt(s))return t.codePointAt(s)-e.codePointAt(s);return t.length-e.length}function tb(t,e,n){for(const s of[t,e-1])if(s<0||s>=n)return jr(s,n);return t>e?`Illegal range error. From index: [${t}] , To index: [${e}].`:null}class Oe{message;constructor(e){this.message=e}}function Gi(t){return`Property ${t} is undefined on object.`}function jr(t,e){return`Index out of bound error. Index: [${t}] , size: [${e}].`}function nb(t,e){return typeof e!="number"||!Number.isInteger(e)?new Oe(`Unsupported operation error. Received: list[${J(e)}]. Expected: list[int].`):e<0||e>=t.length?new Oe(jr(e,t.length)):t[e]}function hd(t,e){if(!Object.hasOwn(t,e))return new Oe(Gi(e));const n=t[e];return n===void 0?new Oe(Gi(e)):n}function sb(t,e){return typeof e!="number"||!Number.isInteger(e)?new Oe(`Unsupported operation error. Received: string[${J(e)}]. Expected: string[int].`):e<0||e>=t.length?new Oe(jr(e,t.length)):t[e]}function pd(t){return t instanceof oe&&t.typeName==="path"}const rb="Function not found error: Name: [[]].";function md(t,e){if(Array.isArray(t))return nb(t,e);if(typeof t=="string")return sb(t,e);if(pd(t)){if(typeof e=="number"&&Number.isInteger(e))return e>=0&&e<t.segments.length?t.segments[e]:new Oe(jr(e,t.segments.length));const n=String(e);return Object.hasOwn(t.bindings,n)?t.bindings[n]:new Oe(Gi(n))}return t instanceof oe?new Oe(rb):hd(t,String(e))}function ib(t,e){return Ge(t)?hd(t,e):pd(t)?md(t,e):new Oe(`Type error. Received: [${J(t)}] Expected: [map,path].`)}function ob(t,e,n){if(typeof e!="number"||!Number.isInteger(e))return new Oe(`Slice start must be an integer, got ${J(e)}`);if(typeof n!="number"||!Number.isInteger(n))return new Oe(`Slice end must be an integer, got ${J(n)}`);if(typeof t=="string"||Array.isArray(t)){const s=tb(e,n,t.length);return s?new Oe(s):t.slice(e,n)}return new Oe(`Slice not supported on ${J(t)}`)}class Gs{message;constructor(e){this.message=e}}function ab(t,e){return e==null?new Gs("Null value error."):Array.isArray(e)?e.some(n=>Lo(n,t)):e instanceof ue?e.has(t):Ge(e)?typeof t!="string"?new Gs(`Unsupported operation error. Received: map.in(${J(t)}). Expected: map.in(string).`):Object.hasOwn(e,t):new Gs("Function not found error: Name: [in].")}const hc="0123456789ABCDEF";function cb(t){let e="";for(let n=0;n<t.length;n++){const s=t[n];e+=hc[s>>>4]+hc[s&15]}return e}function ub(t){let e="";for(let s=0;s<t.length;s++)e+=String.fromCharCode(t[s]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_")}function lb(t,e){const n=Math.min(t.length,e.length);for(let s=0;s<n;s++)if(t[s]!==e[s])return t[s]<e[s]?-1:1;return t.length===e.length?0:t.length<e.length?-1:1}let He=class ss extends oe{typeName="bytes";data;constructor(e){super(),this.data=e}static fromUtf8(e){return new ss(new TextEncoder().encode(e))}static fromHex(e){if(e.length%2!==0)throw new Error(`Invalid hex string length: ${e.length}`);const n=new Uint8Array(e.length/2);for(let s=0;s<n.length;s++)n[s]=parseInt(e.substr(s*2,2),16);return new ss(n)}size(){return this.data.length}toBase64(){return ub(this.data)}toHexString(){return cb(this.data)}valueOf(){return this.data.length}toString(){return this.toBase64()}toJSON(){return{__type:"bytes",base64:this.toBase64()}}equals(e){if(!(e instanceof ss)||this.data.length!==e.data.length)return!1;for(let n=0;n<this.data.length;n++)if(this.data[n]!==e.data[n])return!1;return!0}callMethod(e,n){switch(e){case"size":case"toBase64":case"toHexString":if(n.length!==0)throw new RangeError(`Incorrect number of arguments. Received: ${n.length}. Expected: bytes.${e}().`);return e==="size"?this.size():e==="toBase64"?this.toBase64():this.toHexString()}return me}binaryOp(e,n){if(!(n instanceof ss))return me;const s=lb(this.data,n.data);switch(e){case"<":return s<0;case"<=":return s<=0;case">":return s>0;case">=":return s>=0}return me}};const db=/^\{([A-Za-z_][A-Za-z0-9_]*)\}$/;class st extends oe{typeName="path";segments;bindings;constructor(e,n={}){super(),this.segments=e,this.bindings=n}static fromString(e){const n=e.startsWith("/")?e.slice(1):e;return n.length===0?new st([]):new st(n.split("/"))}bind(e){const n=[],s={...this.bindings};for(const r of this.segments){const i=r.match(db);if(!i){n.push(r);continue}const o=i[1];if(Object.hasOwn(e,o)){const a=e[o];if(a==null)throw new TypeError(`Path.bind(): binding '${o}' must not be null`);const c=String(a);n.push(c),s[o]=c}else n.push(r)}return new st(n,s)}valueOf(){return NaN}toString(){return"/"+this.segments.join("/")}toJSON(){return{__type:"path",segments:[...this.segments]}}equals(e){if(!(e instanceof st)||this.segments.length!==e.segments.length)return!1;for(let n=0;n<this.segments.length;n++)if(this.segments[n]!==e.segments[n])return!1;return!0}callMethod(e,n){switch(e){case"bind":{if(n.length!==1)throw new TypeError(`Incorrect number of arguments. Received: ${n.length}. Expected: path.bind(map).`);const s=n[0];if(s==null||typeof s!="object"||Array.isArray(s)||s instanceof oe)throw new TypeError(`Path.bind() requires a Map argument, got ${s===null?"null":typeof s}`);return this.bind(s)}default:return me}}}class Jt extends I{constructor(e,n){super(e,n),this.name="UnsupportedError"}}class fb{entries=[];parents=[];frames=[];capture(e,n){const s=this.entries.length,r=this.parents.length>0?this.parents[this.parents.length-1]:null,i={source:Se(e),kind:e.type,parent:r};e.type==="binaryOp"&&(i.operator=e.op),this.stampFrame(i),this.entries.push(i),this.parents.push(s);try{const o=n();return this.entries[s].value=o,o}catch(o){throw this.entries[s].error=o instanceof Error?o.message:String(o),o}finally{this.parents.pop()}}skip(e){const n=this.parents.length>0?this.parents[this.parents.length-1]:null,s={source:Se(e),kind:e.type,parent:n,skipped:!0};e.type==="binaryOp"&&(s.operator=e.op),this.stampFrame(s),this.entries.push(s)}enterFrame(e){this.frames.push(e)}exitFrame(){this.frames.pop()}markEntryAsLetBinding(e,n){e<0||e>=this.entries.length||(this.entries[e].letBinding={name:n})}stampFrame(e){this.frames.length!==0&&(e.inlinedFrom={name:this.frames[this.frames.length-1]})}}function hb(t,e){const n=Do("split",e,e,"g"),s=kl(n)+1,r=t.split(n).filter((i,o)=>o%s===0);return pb(r)}function pb(t){let e=t.length;for(;e>1&&t[e-1]==="";)e-=1;return t.slice(0,e)}function mb(t){let e=0,n=t.length;for(;e<n&&pc(t.charCodeAt(e));)e++;for(;n>e&&pc(t.charCodeAt(n-1));)n--;return t.slice(e,n)}function pc(t){return t<=32}function gb(t,e,n,s){const i=f=>f*Math.PI/180,o=i(t),a=i(n),c=i(n-t),u=i(s-e),l=Math.sin(c/2)**2+Math.cos(o)*Math.cos(a)*Math.sin(u/2)**2;return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}class lt extends oe{typeName="latlng";lat;lng;constructor(e,n){super(),this.lat=e,this.lng=n}valueOf(){return NaN}toString(){return`${this.lat},${this.lng}`}toJSON(){return{__type:"latlng",lat:this.lat,lng:this.lng}}equals(e){return e instanceof lt&&this.lat===e.lat&&this.lng===e.lng}callMethod(e,n){switch(e){case"latitude":case"longitude":if(n.length!==0)throw new TypeError(`Incorrect number of arguments. Received: ${n.length}. Expected: latlng.${e}().`);return e==="latitude"?this.lat:this.lng;case"distance":{if(n.length!==1)throw new TypeError(`Incorrect number of arguments. Received: ${n.length}. Expected: latlng.distance(latlng).`);const s=n[0];if(!(s instanceof lt))throw new TypeError(`latlng.distance() requires a LatLng argument, got ${typeof s}`);return gb(this.lat,this.lng,s.lat,s.lng)}default:return me}}}const Cn=1e9,yb=315576e6,bb="Duration is not valid. Seconds must be in range [-315,576,000,000, +315,576,000,000]. Nanos must be in range [-999,999,999, +999,999,999]. Nanos must have the same sign as seconds.",mc={w:10080*60,d:1440*60,h:3600,m:60,s:1};function vb(t,e){let n=t+Math.trunc(e/Cn),s=e%Cn;return n>0&&s<0?(n-=1,s+=Cn):n<0&&s>0&&(n+=1,s-=Cn),{seconds:n,nanos:s}}function wb(t){return Number.isFinite(t)&&Math.abs(t)<=yb}class Ae extends oe{typeName="duration";seconds;nanos;constructor(e,n){super();const s=vb(e,n);if(!wb(s.seconds))throw new Di(bb);this.seconds=s.seconds,this.nanos=s.nanos}static fromValue(e,n){if(n in mc)return new Ae(e*mc[n],0);if(n==="ms"){const s=Math.trunc(e/1e3),r=e-s*1e3;return new Ae(s,r*1e6)}if(n==="ns"){const s=Math.trunc(e/Cn),r=e-s*Cn;return new Ae(s,r)}throw new Error(`Unknown duration unit '${n}' (expected one of: w, d, h, m, s, ms, ns)`)}static fromTime(e,n,s,r){return new Ae(e*3600+n*60+s,r)}static abs(e){return new Ae(Math.abs(e.seconds),Math.abs(e.nanos))}valueOf(){return this.seconds*1e3+Math.round(this.nanos/1e6)}toString(){const e=this.seconds<0||this.nanos<0,n=Math.abs(this.seconds),s=Math.abs(this.nanos);return`${e?"-":""}${n}.${s.toString().padStart(9,"0")}s`}toJSON(){return{__type:"duration",seconds:this.seconds,nanos:this.nanos}}equals(e){return e instanceof Ae&&this.seconds===e.seconds&&this.nanos===e.nanos}callMethod(e,n){switch(e){case"seconds":case"nanos":if(n.length!==0)throw new RangeError(`Incorrect number of arguments. Received: ${n.length}. Expected: duration.${e}().`);return e==="seconds"?this.seconds:this.nanos;default:return me}}binaryOp(e,n){if(!(n instanceof Ae))return me;switch(e){case"+":return new Ae(this.seconds+n.seconds,this.nanos+n.nanos);case"-":return new Ae(this.seconds-n.seconds,this.nanos-n.nanos);case"<":return this.compareTo(n)<0;case"<=":return this.compareTo(n)<=0;case">":return this.compareTo(n)>0;case">=":return this.compareTo(n)>=0;default:return me}}compareTo(e){return this.seconds!==e.seconds?this.seconds-e.seconds:this.nanos-e.nanos}}const gc=1e9,Sb=864e5,di=86400,fi=60,Ab=-62135596800,kb=253402300799,yc="Timestamp is not valid. Seconds must be in range [-62,135,596,800, +253,402,300,799]. Nanos must be in range [0, +999,999,999].";function Eb(t,e){const n=Math.floor(e/gc);return{seconds:t+n,nanos:e-n*gc}}function Ib(t){return Number.isFinite(t)&&t>=Ab&&t<=kb}let ye=class It extends oe{typeName="timestamp";seconds;nanos;constructor(e,n){super();const s=Eb(e,n);if(!Ib(s.seconds))throw new Di(yc);this.seconds=s.seconds,this.nanos=s.nanos}static fromMillis(e){if(!Number.isFinite(e))throw new Di(yc);const n=Math.floor(e/1e3),s=e-n*1e3;return new It(n,s*1e6)}static fromYMD(e,n,s){if(!Number.isInteger(e)||!Number.isInteger(n)||!Number.isInteger(s)||e<1||e>9999||n<1||n>12||s<1||s>31)throw new RangeError(`Date is not valid. year: ${e}, month: ${n} day: ${s}.`);const r=new Date(0);if(r.setUTCFullYear(e,n-1,s),r.setUTCHours(0,0,0,0),r.getUTCFullYear()!==e||r.getUTCMonth()!==n-1||r.getUTCDate()!==s)throw new RangeError(`Date is not valid. year: ${e}, month: ${n} day: ${s}.`);return It.fromMillis(r.getTime())}static fromIsoString(e){return It.fromMillis(Date.parse(e))}toMillis(){return this.seconds*1e3+Math.floor(this.nanos/1e6)}toDate(){return new Date(this.toMillis())}valueOf(){return this.toMillis()}toString(){const e=new Date(this.toMillis()).toISOString(),n=this.nanos.toString().padStart(9,"0");return e.replace(/\.\d{3}Z$/,`.${n}Z`)}toJSON(){return{__type:"timestamp",seconds:this.seconds,nanos:this.nanos}}equals(e){return e instanceof It&&this.seconds===e.seconds&&this.nanos===e.nanos}callMethod(e,n){const s=()=>{if(n.length!==0)throw new RangeError(`Incorrect number of arguments. Received: ${n.length}. Expected: timestamp.${e}().`)};switch(e){case"seconds":return s(),(this.seconds%fi+fi)%fi;case"nanos":return s(),this.nanos;case"toMillis":return s(),this.toMillis();case"year":return s(),this.asDate().getUTCFullYear();case"month":return s(),this.asDate().getUTCMonth()+1;case"day":return s(),this.asDate().getUTCDate();case"hours":return s(),this.asDate().getUTCHours();case"minutes":return s(),this.asDate().getUTCMinutes();case"dayOfWeek":{s();const r=this.asDate().getUTCDay();return r===0?7:r}case"dayOfYear":{s();const r=this.asDate(),i=Date.UTC(r.getUTCFullYear(),0,1);return Math.floor((this.toMillis()-i)/Sb)+1}case"date":return s(),It.fromYMD(this.asDate().getUTCFullYear(),this.asDate().getUTCMonth()+1,this.asDate().getUTCDate());case"time":{s();const r=(this.seconds%di+di)%di,i=Math.floor(r/3600),o=Math.floor(r%3600/60),a=r%60;return Ae.fromTime(i,o,a,this.nanos)}default:return me}}asDate(){return new Date(this.toMillis())}binaryOp(e,n){if(n instanceof It)switch(e){case"-":return new Ae(this.seconds-n.seconds,this.nanos-n.nanos);case"<":return this.compareTo(n)<0;case"<=":return this.compareTo(n)<=0;case">":return this.compareTo(n)>0;case">=":return this.compareTo(n)>=0;default:return me}if(n instanceof Ae)switch(e){case"+":return new It(this.seconds+n.seconds,this.nanos+n.nanos);case"-":return new It(this.seconds-n.seconds,this.nanos-n.nanos);default:return me}return me}compareTo(e){return this.seconds!==e.seconds?this.seconds-e.seconds:this.nanos-e.nanos}};class Ns{message;constructor(e){this.message=e}}const bc=-9223372036854776e3,vc=2**63,_b=-(2n**63n),xb=2n**63n-1n,Cb=/^[+-]?\d+$/,Ob=/^[+-]?(?:NaN|Infinity|(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?[fFdD]?)$/,Tb=/^([+-]?)0[xX]([0-9a-fA-F]*)(?:\.([0-9a-fA-F]*))?[pP]([+-]?\d+)[fFdD]?$/;function Hi(t,e){return new Ns(`Type conversion error. Argument: [${t}], From type: [string], To type: [${e}].`)}function Zo(t,e,n){return new Ns(`Unsupported operation error. Received: ${t}(${J(e)}). Expected: ${n}.`)}function Rb(t){return Number.isNaN(t)?0:t<=bc?bc:t>=vc?vc:Math.trunc(t)+0}function Nb(t){if(!Cb.test(t))return Hi(t,"int");const e=BigInt(t);return e<_b||e>xb?Hi(t,"int"):Number(e)}function Lb(t){const[,e,n,s="",r]=t;if(n.length+s.length===0)return;const o=[...n+s].reduce((a,c)=>a*16+parseInt(c,16),0)*2**(Number(r)-4*s.length);return e==="-"?-o:o}function Mb(t){const e=t.replace(/^[\x00-\x20]+|[\x00-\x20]+$/g,"");if(Ob.test(e))return parseFloat(e.replace(/[fFdD]$/,""));const n=Tb.exec(e),s=n?Lb(n):void 0;return s===void 0?Hi(t,"float"):s}const Db={overloads:"int(int), int(float), int(string)",convert(t){return typeof t=="number"?t:t instanceof te?Rb(t.value):typeof t=="string"?Nb(t):Zo("int",t,this.overloads)}},$b={overloads:"float(int), float(float), float(string)",convert(t){if(t instanceof te)return t;if(typeof t=="number")return new te(t);if(typeof t=="string"){const e=Mb(t);return typeof e=="number"?new te(e):e}return Zo("float",t,this.overloads)}},Pb={overloads:"string(int), string(float), string(null), string(string), string(bool), string(path)",convert(t){return typeof t=="string"?t:typeof t=="number"||typeof t=="boolean"?String(t):t===null?"null":t instanceof te||t instanceof oe&&t.typeName==="path"?t.toString():Zo("string",t,this.overloads)}},Fb=new Map([["int",Db],["float",$b],["string",Pb]]);function gd(t){return Fb.get(t)}function yd(t,e){return e.length!==1?new Ns(`Incorrect number of arguments. Received: ${e.length}. Expected: ${t.overloads}.`):t.convert(e[0])}class Hs{message;constructor(e){this.message=e}}const Ki=-9223372036854776e3,wc=2**63;function jb(t){return Number.isNaN(t)?0:t<=Ki?Ki:t>=wc?wc:Math.round(t)+0}const Hn=t=>new te(t),qb=new Map([["abs",{overloads:"math.abs(int), math.abs(float)",arity:1,apply:([t],[e])=>e?Hn(Math.abs(t)):t===Ki?t:Math.abs(t)}],["ceil",{overloads:"math.ceil(float)",arity:1,apply:([t])=>Hn(Math.ceil(t))}],["floor",{overloads:"math.floor(float)",arity:1,apply:([t])=>Hn(Math.floor(t))}],["round",{overloads:"math.round(float)",arity:1,apply:([t])=>jb(t)}],["sqrt",{overloads:"math.sqrt(float)",arity:1,apply:([t])=>Hn(Math.sqrt(t))}],["pow",{overloads:"math.pow(float, float)",arity:2,apply:([t,e])=>Hn(Math.pow(t,e))}],["isNaN",{overloads:"math.isNaN(float)",arity:1,apply:([t])=>Number.isNaN(t)}]]);function Ub(t){if(t instanceof te)return{value:t.value,isFloat:!0};if(typeof t=="number")return{value:t,isFloat:!Number.isInteger(t)}}function Bb(t,e){const n=qb.get(t);if(!n)return new Hs(`Function not found error: Name: [math.${t}].`);if(e.length!==n.arity)return new Hs(`Incorrect number of arguments. Received: ${e.length}. Expected: ${n.overloads}.`);const s=e.map(Ub);return s.some(r=>r===void 0)?new Hs(`Unsupported operation error. Received: math.${t}(${e.map(J).join(", ")}). Expected: ${n.overloads}.`):n.apply(s.map(r=>r.value),s.map(r=>r.isFloat))}class Mt{message;constructor(e){this.message=e}}const zb=gd("string");function qr(t,e,n){if(n.length!==1)return new Mt(`Incorrect number of arguments. Received: ${n.length}. Expected: list.${t}(${e}).`);const[s]=n;return(e==="list"?Array.isArray(s):typeof s=="string")?s:new Mt(`Unsupported operation error. Received: list.${t}(${J(s)}). Expected: list.${t}(${e}).`)}function Wb(t,e){const n=qr("concat","list",e);return n instanceof Mt?n:[...t,...n]}function Vb(t,e){const n=qr("removeAll","list",e);return n instanceof Mt?n:t.filter(s=>!n.some(r=>Lo(s,r)))}function Gb(t,e,n){const s=qr(t,"list",n);if(s instanceof Mt)return s;const r=(o,a)=>o.some(c=>Lo(c,a)),i=s;return t==="hasAll"?i.every(o=>r(e,o)):t==="hasAny"?i.some(o=>r(e,o)):e.every(o=>r(i,o))}const Sc=new Set(["concat","hasAll","hasAny","hasOnly","join","removeAll","toSet"]);function Hb(t,e){const n=qr("join","string",e);if(n instanceof Mt)return n;const s=[];for(const r of t){const i=yd(zb,[r]);if(i instanceof Ns)return new Mt(i.message);s.push(i)}return s.join(n)}class wt extends oe{typeName="reference";path;constructor(e){super(),this.path=Kb(e)}static fromResourceName(e){return new wt(bd(e))}get id(){const e=this.path.lastIndexOf("/");return e===-1?this.path:this.path.slice(e+1)}get parent(){const e=this.path.lastIndexOf("/");return e===-1?"":this.path.slice(0,e)}valueOf(){return NaN}toString(){return this.path}toJSON(){return{__type:"reference",path:this.path}}equals(e){return e instanceof wt?this.path===e.path:!1}field(e){switch(e){case"path":return this.path;case"id":return this.id;case"parent":return this.parent;default:return null}}callMethod(e,n){return me}}function Kb(t){let e=bd(t);return e.startsWith("/")&&(e=e.slice(1)),e.endsWith("/")&&(e=e.slice(0,-1)),e}function bd(t){const e="/documents/",n=t.indexOf(e);return n===-1?t:t.slice(n+e.length)}class Qt extends oe{typeName="vector";value;constructor(e){if(super(),!Array.isArray(e))throw new TypeError("Vector: value must be a number[]");for(let n=0;n<e.length;n++)if(typeof e[n]!="number")throw new TypeError(`Vector: element at index ${n} is not a number (got ${typeof e[n]})`);this.value=Object.freeze(e.slice())}get dimension(){return this.value.length}valueOf(){return NaN}toString(){return`[${this.value.join(", ")}]`}toJSON(){return{__type__:"__vector__",value:this.value.slice()}}equals(e){if(!(e instanceof Qt)||e.value.length!==this.value.length)return!1;for(let n=0;n<this.value.length;n++)if(e.value[n]!==this.value[n])return!1;return!0}callMethod(e,n){return me}}function Jo(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}const Zb=new Set(["id","path","bypassRules","auth","env"]);function Jb(t){const e=Object.keys(t);if(e.length<2||!e.every(s=>Zb.has(s))||typeof t.id!="string"||typeof t.path!="string")return!1;const n=t.path.split("/");return n.length>=2&&n.length%2===0&&n.every(s=>s.length>0)&&n[n.length-1]===t.id}function Qb(t){const e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e.length%4===0?"":"=".repeat(4-e.length%4),s=atob(e+n),r=new Uint8Array(s.length);for(let i=0;i<s.length;i++)r[i]=s.charCodeAt(i);return r}function Yb(t){const e=atob(t),n=new Uint8Array(e.length);for(let s=0;s<e.length;s++)n[s]=e.charCodeAt(s);return n}function Xb(t){return typeof t=="object"&&t!==null&&(t.__type==="serverTimestamp"||t._methodName==="serverTimestamp"||t._methodName==="FieldValue.serverTimestamp")}function Zi(t,e){const n={};for(const[s,r]of Object.entries(t))n[s]=vd(r,e);return n}function vd(t,e){return Xb(t)?e:Array.isArray(t)?t.map(n=>vd(n,e)):Jo(t)?Zi(t,e):t}function Yt(t){if(typeof t=="number"&&!Number.isInteger(t))return new te(t);if(Array.isArray(t))return t.map(Yt);if(Jo(t)){if(typeof t.__type=="string")switch(t.__type){case"float":if(typeof t.value=="number")return new te(t.value);break;case"timestamp":if(typeof t.seconds=="number"&&typeof t.nanos=="number")return new ye(t.seconds,t.nanos);break;case"bytes":if(typeof t.base64=="string")return new He(Qb(t.base64));break;case"latlng":if(typeof t.lat=="number"&&typeof t.lng=="number")return new lt(t.lat,t.lng);break;case"duration":if(typeof t.seconds=="number"&&typeof t.nanos=="number")return new Ae(t.seconds,t.nanos);break;case"reference":if(typeof t.path=="string")return new wt(t.path);break;case"path":if(Array.isArray(t.segments))return new st(t.segments);break}if(t.__type__==="__vector__"&&Array.isArray(t.value))return new Qt(Object.freeze(t.value.slice()));if(typeof t.type=="string")switch(t.type){case"firestore/timestamp/1.0":if(typeof t.seconds=="number"&&typeof t.nanoseconds=="number")return new ye(t.seconds,t.nanoseconds);break;case"firestore/bytes/1.0":if(typeof t.bytes=="string")return new He(Yb(t.bytes));break;case"firestore/geoPoint/1.0":if(typeof t.latitude=="number"&&typeof t.longitude=="number")return new lt(t.latitude,t.longitude);break;case"firestore/vectorValue/1.0":if(Array.isArray(t.vectorValues))return new Qt(Object.freeze(t.vectorValues.slice()));break}return Jb(t)?new wt(t.path):Object.fromEntries(Object.entries(t).map(([e,n])=>[e,Yt(n)]))}return t}function Ji(t){return typeof t=="number"&&!Number.isInteger(t)?new te(t):Array.isArray(t)?t.map(Ji):Jo(t)?Object.fromEntries(Object.entries(t).map(([e,n])=>[e,Ji(n)])):t}function Ac(t){if(t.method==="list")return{limit:t.query?.limit??null,offset:t.query?.offset??null,orderBy:t.query?.orderBy??null}}function Ur(t){const e=typeof t=="string"?t.split("/").filter(Boolean):t;return e.length===0||e.length%2!==0?!1:!e.some(n=>/^\{.*\}$/.test(n))}function Fn(t){let e=t.replace(/\$\(database\)/g,"(default)");const n="/databases/(default)/documents/";e.startsWith(n)?e=e.slice(n.length):e.startsWith("/databases/(default)/documents")&&(e=e.slice(30)),e.startsWith("/")&&(e=e.slice(1));const s=e.split("/").filter(i=>i.length>0&&i!=="."),r=[];for(const i of s)i===".."?r.length>1&&r.pop():r.push(i);return r.join("/")}function Qi(t,e){const n=t.split("/").filter(Boolean);return{data:Yt(e),id:n.at(-1)??"",__name__:new st(["databases","(default)","documents",...n])}}function kc(t,e){const n=Fn(t),s=n.split("/").filter(Boolean);if(!Ur(s))throw new I(`get() requires a path pointing to a document (even segment count), got '${n}'`);let r=e.mockDocuments.get(n);if(!r&&e.getDoc){const i=e.getDoc(n);if(i){const o=Yt(i);e.mockDocuments.set(n,o),r=o}}if(r){const i=Yt(r);return e.identitylessFunctionMocks?.has(n)?{data:i}:Qi(n,i)}throw new I(`get() of non-existent document '${n}' (guard with exists() first)`)}function Ec(t,e){const n=Fn(t),s=n.split("/").filter(Boolean);if(!Ur(s))throw new I(`exists() requires a path pointing to a document (even segment count), got '${n}'`);const r=e.existsMocks?.get(n);if(r!==void 0)return r;if(e.mockDocuments.has(n))return!0;if(e.getDoc){const i=e.getDoc(n);if(i)return e.mockDocuments.set(n,Yt(i)),!0}return!1}const Yi=10,ev=20,tv=Symbol.for("pyric.firestore.lookupCollector"),Ic=new WeakMap;function nv(t){const e=Ic.get(t);if(e!==void 0)return e;const n=new wd(ev);return Ic.set(t,n),n}class sv extends dn{constructor(e){super(e),this.name="LookupBudgetError"}}class wd{limit;accessed=new Set;constructor(e=Yi){this.limit=e}charge(e,n){const s=`${e}:${n}`;if(this.accessed.has(s))return;const r=this.limit===Yi;if(this.accessed.size>=this.limit){let i=`multi-document batch/transaction (${this.limit} allowed across the atomic operation)`;throw r&&(i="request (production allows 10 per request; the 11th distinct access fails the evaluation)"),new sv(`document access limit exceeded: already read ${this.limit} distinct documents via get()/exists()/getAfter()/existsAfter() in this ${i}`)}this.accessed.add(s)}}function Fs(t,e,n){if(!t.lookupBudget)return;const s=Fn(n);if(!Ur(s))return;if(e==="doc"){const a=globalThis[tv];a!==void 0&&a.add(s)}t.lookupBudget.charge(e,s);const i=t.batchProjection;i!==void 0&&nv(i).charge(e,s)}function rv(t){if(t instanceof He)return t;if(typeof t=="string")return He.fromUtf8(t);throw new I(`hashing.* requires Bytes or String, got ${typeof t}`)}function iv(t,e){if(t!=="md5"&&t!=="sha256"&&t!=="crc32"&&t!=="crc32c")throw new I(os(`hashing.${t}`));if(e.length!==1)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: hashing.${t}(bytes), hashing.${t}(string).`);const n=rv(e[0]);switch(t){case"md5":return new He(fv(n.data));case"sha256":return new He(pv(n.data));case"crc32":{const s=av(n.data);return new He(_c(s))}case"crc32c":{const s=uv(n.data);return new He(_c(s))}}}function _c(t){return new Uint8Array([t&255,t>>>8&255,t>>>16&255,t>>>24&255])}const ov=(()=>{const t=new Uint32Array(256);for(let e=0;e<256;e++){let n=e;for(let s=0;s<8;s++)n=n&1?3988292384^n>>>1:n>>>1;t[e]=n>>>0}return t})();function av(t){let e=4294967295;for(let n=0;n<t.length;n++)e=ov[(e^t[n])&255]^e>>>8;return(e^4294967295)>>>0}const cv=(()=>{const t=new Uint32Array(256);for(let e=0;e<256;e++){let n=e;for(let s=0;s<8;s++)n=n&1?2197175160^n>>>1:n>>>1;t[e]=n>>>0}return t})();function uv(t){let e=4294967295;for(let n=0;n<t.length;n++)e=cv[(e^t[n])&255]^e>>>8;return(e^4294967295)>>>0}function Sd(t,e){const n=(t.length+8>>>6)+1<<6,s=new Uint8Array(n);s.set(t),s[t.length]=128;const r=new DataView(s.buffer),i=t.length<<3>>>0,o=Math.floor(t.length/536870912);return e?(r.setUint32(n-8,i,!0),r.setUint32(n-4,o,!0)):(r.setUint32(n-8,o,!1),r.setUint32(n-4,i,!1)),r}const lv=[7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21],dv=new Uint32Array([3614090360,3905402710,606105819,3250441966,4118548399,1200080426,2821735955,4249261313,1770035416,2336552879,4294925233,2304563134,1804603682,4254626195,2792965006,1236535329,4129170786,3225465664,643717713,3921069994,3593408605,38016083,3634488961,3889429448,568446438,3275163606,4107603335,1163531501,2850285829,4243563512,1735328473,2368359562,4294588738,2272392833,1839030562,4259657740,2763975236,1272893353,4139469664,3200236656,681279174,3936430074,3572445317,76029189,3654602809,3873151461,530742520,3299628645,4096336452,1126891415,2878612391,4237533241,1700485571,2399980690,4293915773,2240044497,1873313359,4264355552,2734768916,1309151649,4149444226,3174756917,718787259,3951481745]);function fv(t){const e=Sd(t,!0);let n=1732584193,s=4023233417,r=2562383102,i=271733878;const o=new Uint32Array(16);for(let u=0;u<e.byteLength;u+=64){for(let h=0;h<16;h++)o[h]=e.getUint32(u+h*4,!0);let l=n,d=s,f=r,p=i;for(let h=0;h<64;h++){let m,g;h<16?(m=d&f|~d&p,g=h):h<32?(m=p&d|~p&f,g=5*h+1&15):h<48?(m=d^f^p,g=3*h+5&15):(m=f^(d|~p),g=7*h&15);const y=l+m+dv[h]+o[g]|0,b=lv[h];l=p,p=f,f=d,d=d+(y<<b|y>>>32-b)|0}n=n+l|0,s=s+d|0,r=r+f|0,i=i+p|0}const a=new Uint8Array(16),c=new DataView(a.buffer);return c.setUint32(0,n>>>0,!0),c.setUint32(4,s>>>0,!0),c.setUint32(8,r>>>0,!0),c.setUint32(12,i>>>0,!0),a}const hv=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function ft(t,e){return t>>>e|t<<32-e}function pv(t){const e=Sd(t,!1),n=new Int32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),s=new Int32Array(64);for(let o=0;o<e.byteLength;o+=64){for(let m=0;m<16;m++)s[m]=e.getInt32(o+m*4,!1);for(let m=16;m<64;m++){const g=s[m-15],y=s[m-2],b=ft(g,7)^ft(g,18)^g>>>3,v=ft(y,17)^ft(y,19)^y>>>10;s[m]=s[m-16]+b+s[m-7]+v|0}let a=n[0],c=n[1],u=n[2],l=n[3],d=n[4],f=n[5],p=n[6],h=n[7];for(let m=0;m<64;m++){const g=ft(d,6)^ft(d,11)^ft(d,25),y=d&f^~d&p,b=h+g+y+hv[m]+s[m]|0,v=ft(a,2)^ft(a,13)^ft(a,22),w=a&c^a&u^c&u,k=v+w|0;h=p,p=f,f=d,d=l+b|0,l=u,u=c,c=a,a=b+k|0}n[0]=n[0]+a|0,n[1]=n[1]+c|0,n[2]=n[2]+u|0,n[3]=n[3]+l|0,n[4]=n[4]+d|0,n[5]=n[5]+f|0,n[6]=n[6]+p|0,n[7]=n[7]+h|0}const r=new Uint8Array(32),i=new DataView(r.buffer);for(let o=0;o<8;o++)i.setInt32(o*4,n[o],!1);return r}function Br(t){return t==="1"?1:0}const xc=new WeakSet,Ad=new WeakMap;function mv(t){if(xc.has(t))return;xc.add(t);const e=zl(t);for(const n of e.functions)Ad.set(n.fn,n)}function gv(t){return Ad.get(t)}function Qo(t){return`/${t.path.segments.map(n=>n.type==="literal"?n.value:n.type==="wildcard"?`{${n.name}}`:`{${n.name}=**}`).join("/")}`}function zr(t,e,n,s,r){const i=Br(s),o=[...n,...t.functions],a=t.path.segments,c={},u=[];let l=0,d,f;for(let y=0;y<a.length;y++){const b=a[y];if(b.type==="literal"){if(l>=e.length){d="request-shorter";break}if(e[l]!==b.value){d="literal-mismatch";break}l++}else if(b.type==="wildcard"){if(l>=e.length){d="request-shorter";break}c[b.name]=e[l],l===e.length-1&&u.push(b.name),l++}else{const v=a.length-y-1,w=e.length-l-v;if(w<i){d="request-shorter";break}c[b.name]=e.slice(l,l+w).join("/"),v===0&&(f={name:b.name,start:l},w>0&&u.push(b.name)),l+=w}}const p=y=>({...t.loc?{line:t.loc.line}:{},blockPath:Qo(t),matchedSegments:l,totalSegments:a.length,bindings:c,matched:!1,...y});if(d!==void 0)return r?.push(p({reason:d})),[];if(f){const y=[{block:t,pathVariables:c,candidateVariables:u,functions:o},...yv(t,e,o,c,f,s,r)];return r?.push(p({matched:!0})),y}const h=e.slice(l),m=[],g=h.length>0?t.children:t.children.filter(y=>y.path.segments.every(b=>b.type==="recursive"));h.length===0&&m.push({block:t,pathVariables:c,candidateVariables:u,functions:o});for(const y of g)for(const b of zr(y,h,o,s,r))b.pathVariables={...c,...b.pathVariables},b.candidateVariables=[...u,...b.candidateVariables],m.push(b);return r?.push(p(m.length>0?{matched:!0}:{reason:"no-matching-child"})),m}function yv(t,e,n,s,r,i,o){if(t.children.length===0)return[];const a=r.start+Br(i),c=[],u=new Set;let l;for(let d=e.length-1;d>=a;d--){const f=e.slice(d),p={...s,[r.name]:e.slice(r.start,d).join("/")},h=[];let m=!1;for(const g of t.children)for(const y of zr(g,f,n,i,{push:b=>h.push(b)}))u.has(y.block)||(u.add(y.block),m=!0,y.pathVariables={...p,...y.pathVariables},c.push(y));if(l??=h,m)for(const g of h)o?.push(g)}if(c.length===0)for(const d of l??[])o?.push(d);return c}function js(t,e,n,s){if(e.length!==1)throw ct(e,n,s),new I(`Incorrect number of arguments. Received: ${e.length}. Expected: ${t}(path).`);const r=_e(e[0],n,s);if(!(r instanceof st)||r.segments.some(i=>/^\{.*\}$/.test(i)))throw new I(`Function not found error: Name: [${t}].`);return String(r)}function Cc(t,e){if(e.split("/").some(s=>s==="."||s===".."))throw new I(`${t}() path '${e}' has a '.' or '..' segment, which is not a valid document id`);const n=Fn(e);if(!Ur(n.split("/").filter(Boolean)))throw new I(`${t}() requires a path pointing to a document (even segment count), got '${n}'`);return n}function Oc(t){return Fn(t.afterStatePath.toString())}function bv(t,e,n,s){const r=n.functions?.get(t);if(r)return vv(t,r,e,n,s);switch(t){case"get":{const i=js("get",e,n,s);return Fs(n,"doc",i),kc(i,n)}case"exists":{const i=js("exists",e,n,s);return Fs(n,"doc",i),Ec(i,n)}case"getAfter":{const i=js("getAfter",e,n,s),o=Cc("getAfter",i);if(Fs(n,"after",o),o===Oc(n)){if(n.afterState===null)throw new I(`getAfter() of non-existent document '${i}' (guard with existsAfter() first)`);return Qi(o,n.afterState)}if(n.batchProjection?.has(o)){const a=n.batchProjection.get(o);if(a===null)throw new I(`getAfter() of non-existent document '${i}' (guard with existsAfter() first)`);return Qi(o,a)}return kc(i,n)}case"existsAfter":{const i=js("existsAfter",e,n,s),o=Cc("existsAfter",i);return Fs(n,"after",o),o===Oc(n)?n.existsAfter:n.batchProjection?.has(o)?n.batchProjection.get(o)!==null:Ec(i,n)}case"string":case"int":case"float":{const i=yd(gd(t),ct(e,n,s));if(i instanceof Ns)throw new I(i.message);return i}case"path":{if(e.length!==1)throw ct(e,n,s),new I(`Incorrect number of arguments. Received: ${e.length}. Expected: path(string).`);const i=_e(e[0],n,s);if(typeof i=="string")return st.fromString(i);throw new I(`path() requires a string argument, got ${typeof i}`)}}throw new I(`Unknown function: ${t}`)}function vv(t,e,n,s,r){if(n.length!==e.parameters.length)throw ct(n,s,r),new I(`Incorrect number of arguments. Received: ${n.length}. Expected: ${t}(${e.parameters.join(", ")}).`);const i=Object.create(null);for(let c=0;c<e.parameters.length;c++)i[e.parameters[c]]=Lc(n[c],s,r);const o=gv(e);let a=s;if(o){const c={};for(const u of o.captures)Object.hasOwn(s.pathVariables,u)&&(c[u]=s.pathVariables[u]);a={...s,functions:o.functions,pathVariables:c,database:o.captures.has("database")?s.database:""}}s.trace?.enterFrame(t);try{for(const c of e.lets){const u=s.trace?s.trace.entries.length:-1;i[c.name]=Lc(c.value,a,i),s.expressionBudget?.letBinding(c),u>=0&&s.trace?.markEntryAsLetBinding(u,c.name)}return _e(e.body,a,i)}finally{s.trace?.exitFrame()}}function wv(t,e,n,s,r){if(t.type==="identifier"){const a=t.name;if(Tc(a)&&!Object.hasOwn(r,a)&&!Object.hasOwn(s.pathVariables,a)){const c=ct(n,s,r);return s.expressionBudget?.node(t),Av(a,e,c)}if(!Tc(a)&&!Object.hasOwn(r,a)&&!Object.hasOwn(s.pathVariables,a)&&!Tv(a))throw new Jt(`Unknown namespace or method '${a}.${e}()'`)}const[i,...o]=ct([t,...n],s,r);if(i instanceof oe){let a;try{a=i.callMethod(e,o)}catch(c){throw c instanceof I?c:new I(c.message)}if(a===me)throw e==="size"||e==="toSet"||Sc.has(e)||$i.has(e)||fc.has(e)?new I(os(e)):new Jt(`Unknown method '${e}' on ${i.typeName}`);return i instanceof lt&&typeof a=="number"?new te(a):a}if(e==="diff"&&Ge(i)){if(o.length!==1)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: map.diff(map).`);const a=o[0];if(Ge(a))return new tr(a,i);throw new I("diff() requires a map argument")}if(typeof i=="function")return i(...o);if(i instanceof ue){const a=ep(i,e,o);if(a instanceof on)throw new I(a.message);return a}if(i instanceof tr){switch(e){case"addedKeys":case"removedKeys":case"changedKeys":case"affectedKeys":case"unchangedKeys":if(o.length!==0)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: map_diff.${e}().`);return i[e]()}throw new I(os(e))}if(Ge(i)){const a=i;switch(e){case"keys":case"values":{const c=Qy(e,a,o);if(c instanceof dd)throw new I(c.message);return c}case"size":if(o.length!==0)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: map.size().`);return Object.keys(a).length;case"get":{if(o.length!==2)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: map.get(string, any), map.get(list, any).`);const c=o[0],u=o[1];if(Array.isArray(c)){let l=a;for(const d of c){if(l==null||typeof l!="object"||Array.isArray(l)||l instanceof oe)return u;const f=String(d);if(!Object.hasOwn(l,f))return u;l=l[f]}return l}if(typeof c!="string")throw new I(`Unsupported operation error. Received: map.get(${J(c)}, ${J(u)}). Expected: map.get(string, any), map.get(list, any).`);return Object.hasOwn(a,c)?a[c]:u}}}if(Array.isArray(i))switch(e){case"size":if(o.length!==0)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: list.size().`);return i.length;case"hasAll":case"hasAny":case"hasOnly":{const a=Gb(e,i,o);if(a instanceof Mt)throw new I(a.message);return a}case"concat":case"join":case"removeAll":{let a;if(e==="concat"?a=Wb(i,o):e==="join"?a=Hb(i,o):a=Vb(i,o),a instanceof Mt)throw new I(a.message);return a}case"toSet":if(o.length!==0)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: list.toSet().`);return new ue(i)}if(typeof i=="string")switch(e){case"size":case"lower":case"upper":case"trim":case"toUtf8":if(o.length!==0)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: string.${e}().`);return e==="size"?i.length:e==="lower"?i.toLowerCase():e==="upper"?i.toUpperCase():e==="trim"?mb(i):He.fromUtf8(i);case"split":case"matches":{if(o.length!==1)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: string.${e}(string).`);const a=o[0];if(typeof a!="string")throw new I(`Unsupported operation error. Received: string.${e}(${J(a)}). Expected: string.${e}(string).`);try{return e==="matches"?lp(a,i):hb(i,a)}catch(c){throw new I(c.message)}}case"replace":{if(o.length!==2)throw new I(`Incorrect number of arguments. Received: ${o.length}. Expected: string.replace(string, string).`);const[a,c]=o;if(typeof a!="string"||typeof c!="string")throw new I(`Unsupported operation error. Received: string.replace(${J(a)}, ${J(c)}). Expected: string.replace(string, string).`);try{return dp(i,a,c)}catch(u){throw new I(u.message)}}}throw Sc.has(e)||$i.has(e)||fc.has(e)?new I(os(e)):new I(`Unknown method '${e}' on ${typeof i}`)}const Sv=new Set(["math","timestamp","duration","latlng","hashing"]);function Tc(t){return Sv.has(t)}function Av(t,e,n){switch(t){case"math":return Ev(e,n);case"timestamp":return xv(e,n);case"duration":return Cv(e,n);case"latlng":return kv(e,n);case"hashing":return iv(e,n)}throw new Jt(`Unknown namespace '${t}'`)}function Rc(t){return t instanceof te?t.value:t}function kv(t,e){switch(t){case"value":{if(e.length!==2)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: latlng.value(float, float).`);const n=Rc(e[0]),s=Rc(e[1]);if(typeof n!="number"||typeof s!="number"||!Number.isFinite(n)||!Number.isFinite(s))throw new I(`Unsupported operation error. Received: latlng.value(${J(e[0])}, ${J(e[1])}). Expected: latlng.value(float, float).`);if(n<-90||n>90||s<-180||s>180)throw new I(" Latitude must be in range [-90.0, +90.0] and longitude must be in range [-180.0, +180.0]");return new lt(n,s)}}throw new Jt(`Unknown latlng method '${t}'`)}function Ev(t,e){const n=Bb(t,e);if(n instanceof Hs)throw new I(n.message);return n}const Iv=-621355968e5,_v=0xe677d21fdbff;function xv(t,e){switch(t){case"date":{if(e.length!==3)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: timestamp.date(int, int, int).`);if(!e.every(i=>typeof i=="number"&&Number.isInteger(i)))throw new I(`Unsupported operation error. Received: timestamp.date(${e.map(J).join(", ")}). Expected: timestamp.date(int, int, int).`);const[n,s,r]=e;try{return ye.fromYMD(n,s,r)}catch(i){throw new I(i.message)}}case"value":{if(e.length!==1)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: timestamp.value(int).`);const n=e[0];if(typeof n!="number"||!Number.isInteger(n))throw new I(`Unsupported operation error. Received: timestamp.value(${J(n)}). Expected: timestamp.value(int).`);if(n<Iv||n>_v)throw new I("Timestamp out of range");return ye.fromMillis(n)}}throw new Jt(`Unknown timestamp method '${t}'`)}function Cv(t,e){switch(t){case"value":{if(e.length!==2)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: duration.value(int, string).`);const[n,s]=e;if(typeof n!="number"||!Number.isInteger(n)||typeof s!="string")throw new I(`Unsupported operation error. Received: duration.value(${J(n)}, ${J(s)}). Expected: duration.value(int, string).`);try{return Ae.fromValue(n,s)}catch(r){throw new I(r.message)}}case"time":{if(e.length!==4)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: duration.time(int, int, int, int).`);if(!e.every(o=>typeof o=="number"&&Number.isInteger(o)))throw new I(`Unsupported operation error. Received: duration.time(${e.map(J).join(", ")}). Expected: duration.time(int, int, int, int).`);const[n,s,r,i]=e;return Ae.fromTime(n,s,r,i)}case"abs":{if(e.length!==1)throw new I(`Incorrect number of arguments. Received: ${e.length}. Expected: duration.abs(duration).`);const n=e[0];if(!(n instanceof Ae))throw new I(`duration.abs() requires a Duration argument, got ${typeof n}`);return Ae.abs(n)}}throw new Jt(`Unknown duration method '${t}'`)}function _e(t,e,n={}){return e.trace?e.trace.capture(t,()=>Nc(t,e,n)):Nc(t,e,n)}function Nc(t,e,n){const s=e.expressionBudget;if(!s)return hi(t,e,n);if(t.type==="functionCall")return s.call(t),hi(t,e,n);let r;try{r=hi(t,e,n)}catch(i){throw i instanceof dn||s.node(t),i}return s.node(t),r}function hi(t,e,n){switch(t.type){case"literal":return typeof t.value=="number"&&t.raw.includes(".")?new te(t.value):t.value instanceof Uint8Array?new He(t.value):t.value;case"identifier":return Ov(t.name,e,n);case"binaryOp":return Nv(t,e,n);case"unaryOp":{if(t.op==="!")return!bs(_e(t.operand,e,n),t.operand);if(t.op==="-"){const s=_e(t.operand,e,n);if(s instanceof te)return new te(-s.value);if(typeof s=="number")return-s;throw new I(`Unsupported operation error. Received: -${J(s)}. Expected: -int, -float, -duration.`,t)}throw new I(`Unknown unary op: ${t.op}`,t)}case"ternary":return e.expressionBudget?.ternary(t),bs(_e(t.condition,e,n),t.condition)?_e(t.consequent,e,n):(e.expressionBudget?.ternaryElse(t),_e(t.alternate,e,n));case"memberAccess":{const s=_e(t.object,e,n);if(s==null)throw new I(`Property '${t.property}' accessed on ${s===null?"null":"undefined"} value`,t);if(s instanceof oe&&s.typeName!=="path")return s.field(t.property);if(!Ge(s)){const r=ib(s,t.property);if(r instanceof Oe)throw new I(r.message,t);return r}if(Object.hasOwn(s,t.property))return s[t.property];throw new I(`No field '${t.property}' on map (use 'in' or .get() to read a possibly-absent field)`,t)}case"bracketAccess":{const[s,r]=ct([t.index,t.object],e,n);if(r==null)throw new I(`Index access on ${r===null?"null":"undefined"} value`,t);const i=md(r,s);if(i instanceof Oe)throw new I(i.message,t);return i}case"sliceAccess":{const[s,r,i]=ct([t.object,t.start,t.end],e,n),o=ob(s,r,i);if(o instanceof Oe)throw new I(o.message,t);return o}case"inExpr":{const[s,r]=ct([t.collection,t.element],e,n),i=ab(r,s);if(i instanceof Gs)throw new I(i.message,t);return i}case"isExpr":{const s=_e(t.value,e,n);switch(t.typeName){case"string":return typeof s=="string";case"int":return s instanceof oe?!1:typeof s=="number";case"float":return s instanceof te;case"number":return s instanceof te?!0:s instanceof oe?!1:typeof s=="number";case"bool":return typeof s=="boolean";case"null":return s===null;case"list":return Array.isArray(s);case"set":return s instanceof ue;case"map":return s instanceof oe||s instanceof tr||s instanceof ue?!1:typeof s=="object"&&s!==null&&!Array.isArray(s);default:return s instanceof oe?s.typeName===t.typeName:!1}}case"listLiteral":return ct(t.elements,e,n);case"mapLiteral":{const s=ct(t.entries.flatMap(i=>[i.key,i.value]),e,n),r=[];for(let i=0;i<s.length;i+=2){const o=s[i];if(typeof o!="string")throw new I(`Type error. Received: [${J(o)}] Expected: [string].`,t);r.push([o,s[i+1]])}return Jy(r)}case"functionCall":return bv(t.name,t.args,e,n);case"methodCall":return wv(t.object,t.method,t.args,e,n);case"pathLiteral":{const s=[];let r;for(const i of t.segments)if(typeof i=="string")e.expressionBudget?.pathSegment(t),s.push(i);else try{const o=_e(i,e,n);if(typeof o!="string"&&(typeof o!="number"||!Number.isInteger(o)))throw new I(`Type error. Received: [${J(o)}] Expected: [string].`,i);s.push(String(o))}catch(o){r=Xo(r,o)}if(r)throw r;return new st(s)}default:throw new I(`Unknown expression type: ${t.type}`,t)}}function Ov(t,e,n){if(Object.hasOwn(n,t)){const s=n[t];if(s instanceof I)throw s;return s}if(Object.hasOwn(e.pathVariables,t))return e.pathVariables[t];switch(t){case"request":return e.request;case"resource":if(e.resource===null)throw new I("Null value error.");return e.resource;case"true":return!0;case"false":return!1;case"null":return null}throw new I(`Undefined variable '${t}'`)}function Tv(t){return t==="request"||t==="resource"||t==="true"||t==="false"||t==="null"}function Rv(t){return t instanceof I&&!(t instanceof dn)&&!(t instanceof Jt)}function Yo(t){if(Rv(t))return t;throw t}function Xo(t,e){const n=Yo(e);return t??n}function ct(t,e,n){const s=new Array(t.length);let r;for(let i=0;i<t.length;i++)try{s[i]=_e(t[i],e,n)}catch(o){r=Xo(r,o)}if(r)throw r;return s}function Lc(t,e,n){try{return _e(t,e,n)}catch(s){return Yo(s)}}function Mc(t,e,n,s,r,i){let o,a;try{o=bs(_e(n,r,i),n)}catch(l){a=l}if(a instanceof dn)throw a;if(a===void 0&&o===e)return r.trace?.skip(s),e;r.expressionBudget?.logicalRight(t);let c,u;try{c=bs(_e(s,r,i),s)}catch(l){u=l}if(u instanceof dn)throw u;if(u===void 0&&c===e)return e;if(a!==void 0)throw a;if(u!==void 0)throw u;return c}function Nv(t,e,n){const{op:s,left:r,right:i}=t;if(s==="&&")return Mc(t,!1,r,i,e,n);if(s==="||")return Mc(t,!0,r,i,e,n);let o,a,c;try{o=_e(r,e,n)}catch(u){c=Yo(u)}try{a=_e(i,e,n)}catch(u){c=Xo(c,u)}if(c)throw c;if(s!=="=="&&s!=="!="){if(o instanceof oe){const u=o.binaryOp(s,a);if(u!==me)return u}if(typeof o=="number"&&a instanceof te){const u=new te(o).binaryOp(s,a);if(u!==me)return u}if(a instanceof oe&&(s==="+"||s==="*")){const u=a.binaryOp(s,o);if(u!==me)return u}if(o instanceof oe||a instanceof oe)throw new I(`Operator '${s}' is not defined between ${J(o)} and ${J(a)}`)}if((s==="<"||s===">"||s==="<="||s===">=")&&!(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string"))throw new I(`Operator '${s}' is not defined between ${typeof o} and ${typeof a}`);switch(s){case"==":return o===a||Fa(o,a);case"!=":return!(o===a||Fa(o,a));case"<":return o<a;case">":return o>a;case"<=":return o<=a;case">=":return o>=a;case"+":{if(typeof o=="string"&&typeof a=="string"||typeof o=="number"&&typeof a=="number")return o+a;throw new I(`Operator '+' is not defined between ${J(o)} and ${J(a)}`)}case"-":case"*":case"/":case"%":{if(typeof o!="number"||typeof a!="number")throw new I(`Unsupported operation error. Received: ${J(o)} ${s} ${J(a)}.`);if(s==="-")return o-a;if(s==="*")return o*a;if(a===0)throw new I(Kh);return s==="/"?Math.trunc(o/a):o%a}default:throw new I(`Unknown binary op: ${s}`)}}function bs(t,e){if(typeof t=="boolean")return t;throw new I(`Type error. Received: [${J(t)}] Expected: [bool].`,e)}const Lv=`Unable to evaluate the expression as the maximum of ${hs} expressions to evaluate has been reached.`;function Mv(t,e){return e===void 0?t:`${Ip(e)}: ${t}`}class Dv{exhausted;limit;evaluated=0;constructor(e,n=hs){this.exhausted=e,this.limit=n}node(e){this.charge(e===void 0?void 0:Tl(e))}call(e){this.charge(e===void 0?void 0:An(e))}logicalRight(e){this.charge(e===void 0?void 0:An(e))}ternary(e){this.charge(e===void 0?void 0:An(e))}ternaryElse(e){const n=e===void 0?void 0:An(e);this.charge(n),this.charge(n)}pathSegment(e){this.charge(e===void 0?void 0:An(e))}letBinding(e){this.charge(e===void 0?void 0:An(e))}charge(e){if(this.evaluated>=this.limit)throw this.exhausted(Lv,e);this.evaluated++}}const $v=new Set(["__proto__","prototype","constructor"]);function or(t){if($v.has(t))throw new Error(`Invalid field-path segment '${t}': the keys __proto__, prototype, and constructor are reserved and cannot appear in a field path.`)}function kd(t,e){const n={...t};for(const[s,r]of Object.entries(e)){or(s);const i=Object.hasOwn(n,s)?n[s]:void 0;Ge(r)&&Ge(i)?n[s]=kd(i,r):n[s]=r}return n}function Pv(t,e,n){let s=t;for(let i=0;i<e.length-1;i++){const o=e[i];or(o);const a=Object.hasOwn(s,o)?s[o]:void 0,c=Ge(a)?{...a}:{};s[o]=c,s=c}const r=e[e.length-1];or(r),s[r]=n}function Fv(t,e){const n={...t};for(const[s,r]of Object.entries(e))s.includes(".")?Pv(n,s.split("."),r):(or(s),n[s]=r);return n}function jv(t,e,n){switch(t.kind){case"create":return n;case"set":return t.merge?kd(e??{},n):n;case"update":return Fv(e??{},n);case"delete":return null}}const qv="Paths are document-relative, from the first segment after /databases/<database>/documents, such as orders/o2.",Dc=3;function Ed(t){const e=t.split("/").filter(Boolean);return e.length>Dc&&e[0]==="databases"&&e[2]==="documents"?e.slice(Dc).join("/"):e.join("/")}var Q;(function(t){t.assertEqual=r=>{};function e(r){}t.assertIs=e;function n(r){throw new Error}t.assertNever=n,t.arrayToEnum=r=>{const i={};for(const o of r)i[o]=o;return i},t.getValidEnumValues=r=>{const i=t.objectKeys(r).filter(a=>typeof r[r[a]]!="number"),o={};for(const a of i)o[a]=r[a];return t.objectValues(o)},t.objectValues=r=>t.objectKeys(r).map(function(i){return r[i]}),t.objectKeys=typeof Object.keys=="function"?r=>Object.keys(r):r=>{const i=[];for(const o in r)Object.prototype.hasOwnProperty.call(r,o)&&i.push(o);return i},t.find=(r,i)=>{for(const o of r)if(i(o))return o},t.isInteger=typeof Number.isInteger=="function"?r=>Number.isInteger(r):r=>typeof r=="number"&&Number.isFinite(r)&&Math.floor(r)===r;function s(r,i=" | "){return r.map(o=>typeof o=="string"?`'${o}'`:o).join(i)}t.joinValues=s,t.jsonStringifyReplacer=(r,i)=>typeof i=="bigint"?i.toString():i})(Q||(Q={}));var $c;(function(t){t.mergeShapes=(e,n)=>({...e,...n})})($c||($c={}));const T=Q.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),zt=t=>{switch(typeof t){case"undefined":return T.undefined;case"string":return T.string;case"number":return Number.isNaN(t)?T.nan:T.number;case"boolean":return T.boolean;case"function":return T.function;case"bigint":return T.bigint;case"symbol":return T.symbol;case"object":return Array.isArray(t)?T.array:t===null?T.null:t.then&&typeof t.then=="function"&&t.catch&&typeof t.catch=="function"?T.promise:typeof Map<"u"&&t instanceof Map?T.map:typeof Set<"u"&&t instanceof Set?T.set:typeof Date<"u"&&t instanceof Date?T.date:T.object;default:return T.unknown}},E=Q.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]);class Dt extends Error{get errors(){return this.issues}constructor(e){super(),this.issues=[],this.addIssue=s=>{this.issues=[...this.issues,s]},this.addIssues=(s=[])=>{this.issues=[...this.issues,...s]};const n=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,n):this.__proto__=n,this.name="ZodError",this.issues=e}format(e){const n=e||function(i){return i.message},s={_errors:[]},r=i=>{for(const o of i.issues)if(o.code==="invalid_union")o.unionErrors.map(r);else if(o.code==="invalid_return_type")r(o.returnTypeError);else if(o.code==="invalid_arguments")r(o.argumentsError);else if(o.path.length===0)s._errors.push(n(o));else{let a=s,c=0;for(;c<o.path.length;){const u=o.path[c];c===o.path.length-1?(a[u]=a[u]||{_errors:[]},a[u]._errors.push(n(o))):a[u]=a[u]||{_errors:[]},a=a[u],c++}}};return r(this),s}static assert(e){if(!(e instanceof Dt))throw new Error(`Not a ZodError: ${e}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,Q.jsonStringifyReplacer,2)}get isEmpty(){return this.issues.length===0}flatten(e=n=>n.message){const n={},s=[];for(const r of this.issues)if(r.path.length>0){const i=r.path[0];n[i]=n[i]||[],n[i].push(e(r))}else s.push(e(r));return{formErrors:s,fieldErrors:n}}get formErrors(){return this.flatten()}}Dt.create=t=>new Dt(t);const Xi=(t,e)=>{let n;switch(t.code){case E.invalid_type:t.received===T.undefined?n="Required":n=`Expected ${t.expected}, received ${t.received}`;break;case E.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(t.expected,Q.jsonStringifyReplacer)}`;break;case E.unrecognized_keys:n=`Unrecognized key(s) in object: ${Q.joinValues(t.keys,", ")}`;break;case E.invalid_union:n="Invalid input";break;case E.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${Q.joinValues(t.options)}`;break;case E.invalid_enum_value:n=`Invalid enum value. Expected ${Q.joinValues(t.options)}, received '${t.received}'`;break;case E.invalid_arguments:n="Invalid function arguments";break;case E.invalid_return_type:n="Invalid function return type";break;case E.invalid_date:n="Invalid date";break;case E.invalid_string:typeof t.validation=="object"?"includes"in t.validation?(n=`Invalid input: must include "${t.validation.includes}"`,typeof t.validation.position=="number"&&(n=`${n} at one or more positions greater than or equal to ${t.validation.position}`)):"startsWith"in t.validation?n=`Invalid input: must start with "${t.validation.startsWith}"`:"endsWith"in t.validation?n=`Invalid input: must end with "${t.validation.endsWith}"`:Q.assertNever(t.validation):t.validation!=="regex"?n=`Invalid ${t.validation}`:n="Invalid";break;case E.too_small:t.type==="array"?n=`Array must contain ${t.exact?"exactly":t.inclusive?"at least":"more than"} ${t.minimum} element(s)`:t.type==="string"?n=`String must contain ${t.exact?"exactly":t.inclusive?"at least":"over"} ${t.minimum} character(s)`:t.type==="number"?n=`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:t.type==="bigint"?n=`Number must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${t.minimum}`:t.type==="date"?n=`Date must be ${t.exact?"exactly equal to ":t.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(t.minimum))}`:n="Invalid input";break;case E.too_big:t.type==="array"?n=`Array must contain ${t.exact?"exactly":t.inclusive?"at most":"less than"} ${t.maximum} element(s)`:t.type==="string"?n=`String must contain ${t.exact?"exactly":t.inclusive?"at most":"under"} ${t.maximum} character(s)`:t.type==="number"?n=`Number must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:t.type==="bigint"?n=`BigInt must be ${t.exact?"exactly":t.inclusive?"less than or equal to":"less than"} ${t.maximum}`:t.type==="date"?n=`Date must be ${t.exact?"exactly":t.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(t.maximum))}`:n="Invalid input";break;case E.custom:n="Invalid input";break;case E.invalid_intersection_types:n="Intersection results could not be merged";break;case E.not_multiple_of:n=`Number must be a multiple of ${t.multipleOf}`;break;case E.not_finite:n="Number must be finite";break;default:n=e.defaultError,Q.assertNever(t)}return{message:n}};let Uv=Xi;function Bv(){return Uv}const zv=t=>{const{data:e,path:n,errorMaps:s,issueData:r}=t,i=[...n,...r.path||[]],o={...r,path:i};if(r.message!==void 0)return{...r,path:i,message:r.message};let a="";const c=s.filter(u=>!!u).slice().reverse();for(const u of c)a=u(o,{data:e,defaultError:a}).message;return{...r,path:i,message:a}};function C(t,e){const n=Bv(),s=zv({issueData:e,data:t.data,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,n,n===Xi?void 0:Xi].filter(r=>!!r)});t.common.issues.push(s)}class qe{constructor(){this.value="valid"}dirty(){this.value==="valid"&&(this.value="dirty")}abort(){this.value!=="aborted"&&(this.value="aborted")}static mergeArray(e,n){const s=[];for(const r of n){if(r.status==="aborted")return F;r.status==="dirty"&&e.dirty(),s.push(r.value)}return{status:e.value,value:s}}static async mergeObjectAsync(e,n){const s=[];for(const r of n){const i=await r.key,o=await r.value;s.push({key:i,value:o})}return qe.mergeObjectSync(e,s)}static mergeObjectSync(e,n){const s={};for(const r of n){const{key:i,value:o}=r;if(i.status==="aborted"||o.status==="aborted")return F;i.status==="dirty"&&e.dirty(),o.status==="dirty"&&e.dirty(),i.value!=="__proto__"&&(typeof o.value<"u"||r.alwaysSet)&&(s[i.value]=o.value)}return{status:e.value,value:s}}}const F=Object.freeze({status:"aborted"}),rs=t=>({status:"dirty",value:t}),rt=t=>({status:"valid",value:t}),Pc=t=>t.status==="aborted",Fc=t=>t.status==="dirty",Mn=t=>t.status==="valid",ar=t=>typeof Promise<"u"&&t instanceof Promise;var L;(function(t){t.errToObj=e=>typeof e=="string"?{message:e}:e||{},t.toString=e=>typeof e=="string"?e:e?.message})(L||(L={}));class St{constructor(e,n,s,r){this._cachedPath=[],this.parent=e,this.data=n,this._path=s,this._key=r}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}const jc=(t,e)=>{if(Mn(e))return{success:!0,data:e.value};if(!t.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;const n=new Dt(t.common.issues);return this._error=n,this._error}}};function W(t){if(!t)return{};const{errorMap:e,invalid_type_error:n,required_error:s,description:r}=t;if(e&&(n||s))throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);return e?{errorMap:e,description:r}:{errorMap:(o,a)=>{const{message:c}=t;return o.code==="invalid_enum_value"?{message:c??a.defaultError}:typeof a.data>"u"?{message:c??s??a.defaultError}:o.code!=="invalid_type"?{message:a.defaultError}:{message:c??n??a.defaultError}},description:r}}class Z{get description(){return this._def.description}_getType(e){return zt(e.data)}_getOrReturnCtx(e,n){return n||{common:e.parent.common,data:e.data,parsedType:zt(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new qe,ctx:{common:e.parent.common,data:e.data,parsedType:zt(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){const n=this._parse(e);if(ar(n))throw new Error("Synchronous parse encountered promise.");return n}_parseAsync(e){const n=this._parse(e);return Promise.resolve(n)}parse(e,n){const s=this.safeParse(e,n);if(s.success)return s.data;throw s.error}safeParse(e,n){const s={common:{issues:[],async:n?.async??!1,contextualErrorMap:n?.errorMap},path:n?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:zt(e)},r=this._parseSync({data:e,path:s.path,parent:s});return jc(s,r)}"~validate"(e){const n={common:{issues:[],async:!!this["~standard"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:zt(e)};if(!this["~standard"].async)try{const s=this._parseSync({data:e,path:[],parent:n});return Mn(s)?{value:s.value}:{issues:n.common.issues}}catch(s){s?.message?.toLowerCase()?.includes("encountered")&&(this["~standard"].async=!0),n.common={issues:[],async:!0}}return this._parseAsync({data:e,path:[],parent:n}).then(s=>Mn(s)?{value:s.value}:{issues:n.common.issues})}async parseAsync(e,n){const s=await this.safeParseAsync(e,n);if(s.success)return s.data;throw s.error}async safeParseAsync(e,n){const s={common:{issues:[],contextualErrorMap:n?.errorMap,async:!0},path:n?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:zt(e)},r=this._parse({data:e,path:s.path,parent:s}),i=await(ar(r)?r:Promise.resolve(r));return jc(s,i)}refine(e,n){const s=r=>typeof n=="string"||typeof n>"u"?{message:n}:typeof n=="function"?n(r):n;return this._refinement((r,i)=>{const o=e(r),a=()=>i.addIssue({code:E.custom,...s(r)});return typeof Promise<"u"&&o instanceof Promise?o.then(c=>c?!0:(a(),!1)):o?!0:(a(),!1)})}refinement(e,n){return this._refinement((s,r)=>e(s)?!0:(r.addIssue(typeof n=="function"?n(s,r):n),!1))}_refinement(e){return new gn({schema:this,typeName:j.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this["~standard"]={version:1,vendor:"zod",validate:n=>this["~validate"](n)}}optional(){return Lt.create(this,this._def)}nullable(){return yn.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return gt.create(this)}promise(){return pr.create(this,this._def)}or(e){return lr.create([this,e],this._def)}and(e){return dr.create(this,e,this._def)}transform(e){return new gn({...W(this._def),schema:this,typeName:j.ZodEffects,effect:{type:"transform",transform:e}})}default(e){const n=typeof e=="function"?e:()=>e;return new mr({...W(this._def),innerType:this,defaultValue:n,typeName:j.ZodDefault})}brand(){return new Cd({typeName:j.ZodBranded,type:this,...W(this._def)})}catch(e){const n=typeof e=="function"?e:()=>e;return new gr({...W(this._def),innerType:this,catchValue:n,typeName:j.ZodCatch})}describe(e){const n=this.constructor;return new n({...this._def,description:e})}pipe(e){return ta.create(this,e)}readonly(){return yr.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}const Wv=/^c[^\s-]{8,}$/i,Vv=/^[0-9a-z]+$/,Gv=/^[0-9A-HJKMNP-TV-Z]{26}$/i,Hv=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,Kv=/^[a-z0-9_-]{21}$/i,Zv=/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,Jv=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,Qv=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,Yv="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";let pi;const Xv=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,ew=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,tw=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,nw=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,sw=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,rw=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Id="((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))",iw=new RegExp(`^${Id}$`);function _d(t){let e="[0-5]\\d";t.precision?e=`${e}\\.\\d{${t.precision}}`:t.precision==null&&(e=`${e}(\\.\\d+)?`);const n=t.precision?"+":"?";return`([01]\\d|2[0-3]):[0-5]\\d(:${e})${n}`}function ow(t){return new RegExp(`^${_d(t)}$`)}function aw(t){let e=`${Id}T${_d(t)}`;const n=[];return n.push(t.local?"Z?":"Z"),t.offset&&n.push("([+-]\\d{2}:?\\d{2})"),e=`${e}(${n.join("|")})`,new RegExp(`^${e}$`)}function cw(t,e){return!!((e==="v4"||!e)&&Xv.test(t)||(e==="v6"||!e)&&tw.test(t))}function uw(t,e){if(!Zv.test(t))return!1;try{const[n]=t.split(".");if(!n)return!1;const s=n.replace(/-/g,"+").replace(/_/g,"/").padEnd(n.length+(4-n.length%4)%4,"="),r=JSON.parse(atob(s));return!(typeof r!="object"||r===null||"typ"in r&&r?.typ!=="JWT"||!r.alg||e&&r.alg!==e)}catch{return!1}}function lw(t,e){return!!((e==="v4"||!e)&&ew.test(t)||(e==="v6"||!e)&&nw.test(t))}class Ot extends Z{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==T.string){const i=this._getOrReturnCtx(e);return C(i,{code:E.invalid_type,expected:T.string,received:i.parsedType}),F}const s=new qe;let r;for(const i of this._def.checks)if(i.kind==="min")e.data.length<i.value&&(r=this._getOrReturnCtx(e,r),C(r,{code:E.too_small,minimum:i.value,type:"string",inclusive:!0,exact:!1,message:i.message}),s.dirty());else if(i.kind==="max")e.data.length>i.value&&(r=this._getOrReturnCtx(e,r),C(r,{code:E.too_big,maximum:i.value,type:"string",inclusive:!0,exact:!1,message:i.message}),s.dirty());else if(i.kind==="length"){const o=e.data.length>i.value,a=e.data.length<i.value;(o||a)&&(r=this._getOrReturnCtx(e,r),o?C(r,{code:E.too_big,maximum:i.value,type:"string",inclusive:!0,exact:!0,message:i.message}):a&&C(r,{code:E.too_small,minimum:i.value,type:"string",inclusive:!0,exact:!0,message:i.message}),s.dirty())}else if(i.kind==="email")Qv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"email",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="emoji")pi||(pi=new RegExp(Yv,"u")),pi.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"emoji",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="uuid")Hv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"uuid",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="nanoid")Kv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"nanoid",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="cuid")Wv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"cuid",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="cuid2")Vv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"cuid2",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="ulid")Gv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"ulid",code:E.invalid_string,message:i.message}),s.dirty());else if(i.kind==="url")try{new URL(e.data)}catch{r=this._getOrReturnCtx(e,r),C(r,{validation:"url",code:E.invalid_string,message:i.message}),s.dirty()}else i.kind==="regex"?(i.regex.lastIndex=0,i.regex.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"regex",code:E.invalid_string,message:i.message}),s.dirty())):i.kind==="trim"?e.data=e.data.trim():i.kind==="includes"?e.data.includes(i.value,i.position)||(r=this._getOrReturnCtx(e,r),C(r,{code:E.invalid_string,validation:{includes:i.value,position:i.position},message:i.message}),s.dirty()):i.kind==="toLowerCase"?e.data=e.data.toLowerCase():i.kind==="toUpperCase"?e.data=e.data.toUpperCase():i.kind==="startsWith"?e.data.startsWith(i.value)||(r=this._getOrReturnCtx(e,r),C(r,{code:E.invalid_string,validation:{startsWith:i.value},message:i.message}),s.dirty()):i.kind==="endsWith"?e.data.endsWith(i.value)||(r=this._getOrReturnCtx(e,r),C(r,{code:E.invalid_string,validation:{endsWith:i.value},message:i.message}),s.dirty()):i.kind==="datetime"?aw(i).test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{code:E.invalid_string,validation:"datetime",message:i.message}),s.dirty()):i.kind==="date"?iw.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{code:E.invalid_string,validation:"date",message:i.message}),s.dirty()):i.kind==="time"?ow(i).test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{code:E.invalid_string,validation:"time",message:i.message}),s.dirty()):i.kind==="duration"?Jv.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"duration",code:E.invalid_string,message:i.message}),s.dirty()):i.kind==="ip"?cw(e.data,i.version)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"ip",code:E.invalid_string,message:i.message}),s.dirty()):i.kind==="jwt"?uw(e.data,i.alg)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"jwt",code:E.invalid_string,message:i.message}),s.dirty()):i.kind==="cidr"?lw(e.data,i.version)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"cidr",code:E.invalid_string,message:i.message}),s.dirty()):i.kind==="base64"?sw.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"base64",code:E.invalid_string,message:i.message}),s.dirty()):i.kind==="base64url"?rw.test(e.data)||(r=this._getOrReturnCtx(e,r),C(r,{validation:"base64url",code:E.invalid_string,message:i.message}),s.dirty()):Q.assertNever(i);return{status:s.value,value:e.data}}_regex(e,n,s){return this.refinement(r=>e.test(r),{validation:n,code:E.invalid_string,...L.errToObj(s)})}_addCheck(e){return new Ot({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...L.errToObj(e)})}url(e){return this._addCheck({kind:"url",...L.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...L.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...L.errToObj(e)})}nanoid(e){return this._addCheck({kind:"nanoid",...L.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...L.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...L.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...L.errToObj(e)})}base64(e){return this._addCheck({kind:"base64",...L.errToObj(e)})}base64url(e){return this._addCheck({kind:"base64url",...L.errToObj(e)})}jwt(e){return this._addCheck({kind:"jwt",...L.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...L.errToObj(e)})}cidr(e){return this._addCheck({kind:"cidr",...L.errToObj(e)})}datetime(e){return typeof e=="string"?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:e}):this._addCheck({kind:"datetime",precision:typeof e?.precision>"u"?null:e?.precision,offset:e?.offset??!1,local:e?.local??!1,...L.errToObj(e?.message)})}date(e){return this._addCheck({kind:"date",message:e})}time(e){return typeof e=="string"?this._addCheck({kind:"time",precision:null,message:e}):this._addCheck({kind:"time",precision:typeof e?.precision>"u"?null:e?.precision,...L.errToObj(e?.message)})}duration(e){return this._addCheck({kind:"duration",...L.errToObj(e)})}regex(e,n){return this._addCheck({kind:"regex",regex:e,...L.errToObj(n)})}includes(e,n){return this._addCheck({kind:"includes",value:e,position:n?.position,...L.errToObj(n?.message)})}startsWith(e,n){return this._addCheck({kind:"startsWith",value:e,...L.errToObj(n)})}endsWith(e,n){return this._addCheck({kind:"endsWith",value:e,...L.errToObj(n)})}min(e,n){return this._addCheck({kind:"min",value:e,...L.errToObj(n)})}max(e,n){return this._addCheck({kind:"max",value:e,...L.errToObj(n)})}length(e,n){return this._addCheck({kind:"length",value:e,...L.errToObj(n)})}nonempty(e){return this.min(1,L.errToObj(e))}trim(){return new Ot({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new Ot({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new Ot({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(e=>e.kind==="datetime")}get isDate(){return!!this._def.checks.find(e=>e.kind==="date")}get isTime(){return!!this._def.checks.find(e=>e.kind==="time")}get isDuration(){return!!this._def.checks.find(e=>e.kind==="duration")}get isEmail(){return!!this._def.checks.find(e=>e.kind==="email")}get isURL(){return!!this._def.checks.find(e=>e.kind==="url")}get isEmoji(){return!!this._def.checks.find(e=>e.kind==="emoji")}get isUUID(){return!!this._def.checks.find(e=>e.kind==="uuid")}get isNANOID(){return!!this._def.checks.find(e=>e.kind==="nanoid")}get isCUID(){return!!this._def.checks.find(e=>e.kind==="cuid")}get isCUID2(){return!!this._def.checks.find(e=>e.kind==="cuid2")}get isULID(){return!!this._def.checks.find(e=>e.kind==="ulid")}get isIP(){return!!this._def.checks.find(e=>e.kind==="ip")}get isCIDR(){return!!this._def.checks.find(e=>e.kind==="cidr")}get isBase64(){return!!this._def.checks.find(e=>e.kind==="base64")}get isBase64url(){return!!this._def.checks.find(e=>e.kind==="base64url")}get minLength(){let e=null;for(const n of this._def.checks)n.kind==="min"&&(e===null||n.value>e)&&(e=n.value);return e}get maxLength(){let e=null;for(const n of this._def.checks)n.kind==="max"&&(e===null||n.value<e)&&(e=n.value);return e}}Ot.create=t=>new Ot({checks:[],typeName:j.ZodString,coerce:t?.coerce??!1,...W(t)});function dw(t,e){const n=(t.toString().split(".")[1]||"").length,s=(e.toString().split(".")[1]||"").length,r=n>s?n:s,i=Number.parseInt(t.toFixed(r).replace(".","")),o=Number.parseInt(e.toFixed(r).replace(".",""));return i%o/10**r}class Dn extends Z{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==T.number){const i=this._getOrReturnCtx(e);return C(i,{code:E.invalid_type,expected:T.number,received:i.parsedType}),F}let s;const r=new qe;for(const i of this._def.checks)i.kind==="int"?Q.isInteger(e.data)||(s=this._getOrReturnCtx(e,s),C(s,{code:E.invalid_type,expected:"integer",received:"float",message:i.message}),r.dirty()):i.kind==="min"?(i.inclusive?e.data<i.value:e.data<=i.value)&&(s=this._getOrReturnCtx(e,s),C(s,{code:E.too_small,minimum:i.value,type:"number",inclusive:i.inclusive,exact:!1,message:i.message}),r.dirty()):i.kind==="max"?(i.inclusive?e.data>i.value:e.data>=i.value)&&(s=this._getOrReturnCtx(e,s),C(s,{code:E.too_big,maximum:i.value,type:"number",inclusive:i.inclusive,exact:!1,message:i.message}),r.dirty()):i.kind==="multipleOf"?dw(e.data,i.value)!==0&&(s=this._getOrReturnCtx(e,s),C(s,{code:E.not_multiple_of,multipleOf:i.value,message:i.message}),r.dirty()):i.kind==="finite"?Number.isFinite(e.data)||(s=this._getOrReturnCtx(e,s),C(s,{code:E.not_finite,message:i.message}),r.dirty()):Q.assertNever(i);return{status:r.value,value:e.data}}gte(e,n){return this.setLimit("min",e,!0,L.toString(n))}gt(e,n){return this.setLimit("min",e,!1,L.toString(n))}lte(e,n){return this.setLimit("max",e,!0,L.toString(n))}lt(e,n){return this.setLimit("max",e,!1,L.toString(n))}setLimit(e,n,s,r){return new Dn({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:s,message:L.toString(r)}]})}_addCheck(e){return new Dn({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:L.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:L.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:L.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:L.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:L.toString(e)})}multipleOf(e,n){return this._addCheck({kind:"multipleOf",value:e,message:L.toString(n)})}finite(e){return this._addCheck({kind:"finite",message:L.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:L.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:L.toString(e)})}get minValue(){let e=null;for(const n of this._def.checks)n.kind==="min"&&(e===null||n.value>e)&&(e=n.value);return e}get maxValue(){let e=null;for(const n of this._def.checks)n.kind==="max"&&(e===null||n.value<e)&&(e=n.value);return e}get isInt(){return!!this._def.checks.find(e=>e.kind==="int"||e.kind==="multipleOf"&&Q.isInteger(e.value))}get isFinite(){let e=null,n=null;for(const s of this._def.checks){if(s.kind==="finite"||s.kind==="int"||s.kind==="multipleOf")return!0;s.kind==="min"?(n===null||s.value>n)&&(n=s.value):s.kind==="max"&&(e===null||s.value<e)&&(e=s.value)}return Number.isFinite(n)&&Number.isFinite(e)}}Dn.create=t=>new Dn({checks:[],typeName:j.ZodNumber,coerce:t?.coerce||!1,...W(t)});class vs extends Z{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce)try{e.data=BigInt(e.data)}catch{return this._getInvalidInput(e)}if(this._getType(e)!==T.bigint)return this._getInvalidInput(e);let s;const r=new qe;for(const i of this._def.checks)i.kind==="min"?(i.inclusive?e.data<i.value:e.data<=i.value)&&(s=this._getOrReturnCtx(e,s),C(s,{code:E.too_small,type:"bigint",minimum:i.value,inclusive:i.inclusive,message:i.message}),r.dirty()):i.kind==="max"?(i.inclusive?e.data>i.value:e.data>=i.value)&&(s=this._getOrReturnCtx(e,s),C(s,{code:E.too_big,type:"bigint",maximum:i.value,inclusive:i.inclusive,message:i.message}),r.dirty()):i.kind==="multipleOf"?e.data%i.value!==BigInt(0)&&(s=this._getOrReturnCtx(e,s),C(s,{code:E.not_multiple_of,multipleOf:i.value,message:i.message}),r.dirty()):Q.assertNever(i);return{status:r.value,value:e.data}}_getInvalidInput(e){const n=this._getOrReturnCtx(e);return C(n,{code:E.invalid_type,expected:T.bigint,received:n.parsedType}),F}gte(e,n){return this.setLimit("min",e,!0,L.toString(n))}gt(e,n){return this.setLimit("min",e,!1,L.toString(n))}lte(e,n){return this.setLimit("max",e,!0,L.toString(n))}lt(e,n){return this.setLimit("max",e,!1,L.toString(n))}setLimit(e,n,s,r){return new vs({...this._def,checks:[...this._def.checks,{kind:e,value:n,inclusive:s,message:L.toString(r)}]})}_addCheck(e){return new vs({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:L.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:L.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:L.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:L.toString(e)})}multipleOf(e,n){return this._addCheck({kind:"multipleOf",value:e,message:L.toString(n)})}get minValue(){let e=null;for(const n of this._def.checks)n.kind==="min"&&(e===null||n.value>e)&&(e=n.value);return e}get maxValue(){let e=null;for(const n of this._def.checks)n.kind==="max"&&(e===null||n.value<e)&&(e=n.value);return e}}vs.create=t=>new vs({checks:[],typeName:j.ZodBigInt,coerce:t?.coerce??!1,...W(t)});class eo extends Z{_parse(e){if(this._def.coerce&&(e.data=!!e.data),this._getType(e)!==T.boolean){const s=this._getOrReturnCtx(e);return C(s,{code:E.invalid_type,expected:T.boolean,received:s.parsedType}),F}return rt(e.data)}}eo.create=t=>new eo({typeName:j.ZodBoolean,coerce:t?.coerce||!1,...W(t)});class cr extends Z{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==T.date){const i=this._getOrReturnCtx(e);return C(i,{code:E.invalid_type,expected:T.date,received:i.parsedType}),F}if(Number.isNaN(e.data.getTime())){const i=this._getOrReturnCtx(e);return C(i,{code:E.invalid_date}),F}const s=new qe;let r;for(const i of this._def.checks)i.kind==="min"?e.data.getTime()<i.value&&(r=this._getOrReturnCtx(e,r),C(r,{code:E.too_small,message:i.message,inclusive:!0,exact:!1,minimum:i.value,type:"date"}),s.dirty()):i.kind==="max"?e.data.getTime()>i.value&&(r=this._getOrReturnCtx(e,r),C(r,{code:E.too_big,message:i.message,inclusive:!0,exact:!1,maximum:i.value,type:"date"}),s.dirty()):Q.assertNever(i);return{status:s.value,value:new Date(e.data.getTime())}}_addCheck(e){return new cr({...this._def,checks:[...this._def.checks,e]})}min(e,n){return this._addCheck({kind:"min",value:e.getTime(),message:L.toString(n)})}max(e,n){return this._addCheck({kind:"max",value:e.getTime(),message:L.toString(n)})}get minDate(){let e=null;for(const n of this._def.checks)n.kind==="min"&&(e===null||n.value>e)&&(e=n.value);return e!=null?new Date(e):null}get maxDate(){let e=null;for(const n of this._def.checks)n.kind==="max"&&(e===null||n.value<e)&&(e=n.value);return e!=null?new Date(e):null}}cr.create=t=>new cr({checks:[],coerce:t?.coerce||!1,typeName:j.ZodDate,...W(t)});class qc extends Z{_parse(e){if(this._getType(e)!==T.symbol){const s=this._getOrReturnCtx(e);return C(s,{code:E.invalid_type,expected:T.symbol,received:s.parsedType}),F}return rt(e.data)}}qc.create=t=>new qc({typeName:j.ZodSymbol,...W(t)});class to extends Z{_parse(e){if(this._getType(e)!==T.undefined){const s=this._getOrReturnCtx(e);return C(s,{code:E.invalid_type,expected:T.undefined,received:s.parsedType}),F}return rt(e.data)}}to.create=t=>new to({typeName:j.ZodUndefined,...W(t)});class ur extends Z{_parse(e){if(this._getType(e)!==T.null){const s=this._getOrReturnCtx(e);return C(s,{code:E.invalid_type,expected:T.null,received:s.parsedType}),F}return rt(e.data)}}ur.create=t=>new ur({typeName:j.ZodNull,...W(t)});class Uc extends Z{constructor(){super(...arguments),this._any=!0}_parse(e){return rt(e.data)}}Uc.create=t=>new Uc({typeName:j.ZodAny,...W(t)});class no extends Z{constructor(){super(...arguments),this._unknown=!0}_parse(e){return rt(e.data)}}no.create=t=>new no({typeName:j.ZodUnknown,...W(t)});class Xt extends Z{_parse(e){const n=this._getOrReturnCtx(e);return C(n,{code:E.invalid_type,expected:T.never,received:n.parsedType}),F}}Xt.create=t=>new Xt({typeName:j.ZodNever,...W(t)});class Bc extends Z{_parse(e){if(this._getType(e)!==T.undefined){const s=this._getOrReturnCtx(e);return C(s,{code:E.invalid_type,expected:T.void,received:s.parsedType}),F}return rt(e.data)}}Bc.create=t=>new Bc({typeName:j.ZodVoid,...W(t)});class gt extends Z{_parse(e){const{ctx:n,status:s}=this._processInputParams(e),r=this._def;if(n.parsedType!==T.array)return C(n,{code:E.invalid_type,expected:T.array,received:n.parsedType}),F;if(r.exactLength!==null){const o=n.data.length>r.exactLength.value,a=n.data.length<r.exactLength.value;(o||a)&&(C(n,{code:o?E.too_big:E.too_small,minimum:a?r.exactLength.value:void 0,maximum:o?r.exactLength.value:void 0,type:"array",inclusive:!0,exact:!0,message:r.exactLength.message}),s.dirty())}if(r.minLength!==null&&n.data.length<r.minLength.value&&(C(n,{code:E.too_small,minimum:r.minLength.value,type:"array",inclusive:!0,exact:!1,message:r.minLength.message}),s.dirty()),r.maxLength!==null&&n.data.length>r.maxLength.value&&(C(n,{code:E.too_big,maximum:r.maxLength.value,type:"array",inclusive:!0,exact:!1,message:r.maxLength.message}),s.dirty()),n.common.async)return Promise.all([...n.data].map((o,a)=>r.type._parseAsync(new St(n,o,n.path,a)))).then(o=>qe.mergeArray(s,o));const i=[...n.data].map((o,a)=>r.type._parseSync(new St(n,o,n.path,a)));return qe.mergeArray(s,i)}get element(){return this._def.type}min(e,n){return new gt({...this._def,minLength:{value:e,message:L.toString(n)}})}max(e,n){return new gt({...this._def,maxLength:{value:e,message:L.toString(n)}})}length(e,n){return new gt({...this._def,exactLength:{value:e,message:L.toString(n)}})}nonempty(e){return this.min(1,e)}}gt.create=(t,e)=>new gt({type:t,minLength:null,maxLength:null,exactLength:null,typeName:j.ZodArray,...W(e)});function xn(t){if(t instanceof we){const e={};for(const n in t.shape){const s=t.shape[n];e[n]=Lt.create(xn(s))}return new we({...t._def,shape:()=>e})}else return t instanceof gt?new gt({...t._def,type:xn(t.element)}):t instanceof Lt?Lt.create(xn(t.unwrap())):t instanceof yn?yn.create(xn(t.unwrap())):t instanceof pn?pn.create(t.items.map(e=>xn(e))):t}class we extends Z{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;const e=this._def.shape(),n=Q.objectKeys(e);return this._cached={shape:e,keys:n},this._cached}_parse(e){if(this._getType(e)!==T.object){const u=this._getOrReturnCtx(e);return C(u,{code:E.invalid_type,expected:T.object,received:u.parsedType}),F}const{status:s,ctx:r}=this._processInputParams(e),{shape:i,keys:o}=this._getCached(),a=[];if(!(this._def.catchall instanceof Xt&&this._def.unknownKeys==="strip"))for(const u in r.data)o.includes(u)||a.push(u);const c=[];for(const u of o){const l=i[u],d=r.data[u];c.push({key:{status:"valid",value:u},value:l._parse(new St(r,d,r.path,u)),alwaysSet:u in r.data})}if(this._def.catchall instanceof Xt){const u=this._def.unknownKeys;if(u==="passthrough")for(const l of a)c.push({key:{status:"valid",value:l},value:{status:"valid",value:r.data[l]}});else if(u==="strict")a.length>0&&(C(r,{code:E.unrecognized_keys,keys:a}),s.dirty());else if(u!=="strip")throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{const u=this._def.catchall;for(const l of a){const d=r.data[l];c.push({key:{status:"valid",value:l},value:u._parse(new St(r,d,r.path,l)),alwaysSet:l in r.data})}}return r.common.async?Promise.resolve().then(async()=>{const u=[];for(const l of c){const d=await l.key,f=await l.value;u.push({key:d,value:f,alwaysSet:l.alwaysSet})}return u}).then(u=>qe.mergeObjectSync(s,u)):qe.mergeObjectSync(s,c)}get shape(){return this._def.shape()}strict(e){return L.errToObj,new we({...this._def,unknownKeys:"strict",...e!==void 0?{errorMap:(n,s)=>{const r=this._def.errorMap?.(n,s).message??s.defaultError;return n.code==="unrecognized_keys"?{message:L.errToObj(e).message??r}:{message:r}}}:{}})}strip(){return new we({...this._def,unknownKeys:"strip"})}passthrough(){return new we({...this._def,unknownKeys:"passthrough"})}extend(e){return new we({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new we({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:j.ZodObject})}setKey(e,n){return this.augment({[e]:n})}catchall(e){return new we({...this._def,catchall:e})}pick(e){const n={};for(const s of Q.objectKeys(e))e[s]&&this.shape[s]&&(n[s]=this.shape[s]);return new we({...this._def,shape:()=>n})}omit(e){const n={};for(const s of Q.objectKeys(this.shape))e[s]||(n[s]=this.shape[s]);return new we({...this._def,shape:()=>n})}deepPartial(){return xn(this)}partial(e){const n={};for(const s of Q.objectKeys(this.shape)){const r=this.shape[s];e&&!e[s]?n[s]=r:n[s]=r.optional()}return new we({...this._def,shape:()=>n})}required(e){const n={};for(const s of Q.objectKeys(this.shape))if(e&&!e[s])n[s]=this.shape[s];else{let i=this.shape[s];for(;i instanceof Lt;)i=i._def.innerType;n[s]=i}return new we({...this._def,shape:()=>n})}keyof(){return xd(Q.objectKeys(this.shape))}}we.create=(t,e)=>new we({shape:()=>t,unknownKeys:"strip",catchall:Xt.create(),typeName:j.ZodObject,...W(e)});we.strictCreate=(t,e)=>new we({shape:()=>t,unknownKeys:"strict",catchall:Xt.create(),typeName:j.ZodObject,...W(e)});we.lazycreate=(t,e)=>new we({shape:t,unknownKeys:"strip",catchall:Xt.create(),typeName:j.ZodObject,...W(e)});class lr extends Z{_parse(e){const{ctx:n}=this._processInputParams(e),s=this._def.options;function r(i){for(const a of i)if(a.result.status==="valid")return a.result;for(const a of i)if(a.result.status==="dirty")return n.common.issues.push(...a.ctx.common.issues),a.result;const o=i.map(a=>new Dt(a.ctx.common.issues));return C(n,{code:E.invalid_union,unionErrors:o}),F}if(n.common.async)return Promise.all(s.map(async i=>{const o={...n,common:{...n.common,issues:[]},parent:null};return{result:await i._parseAsync({data:n.data,path:n.path,parent:o}),ctx:o}})).then(r);{let i;const o=[];for(const c of s){const u={...n,common:{...n.common,issues:[]},parent:null},l=c._parseSync({data:n.data,path:n.path,parent:u});if(l.status==="valid")return l;l.status==="dirty"&&!i&&(i={result:l,ctx:u}),u.common.issues.length&&o.push(u.common.issues)}if(i)return n.common.issues.push(...i.ctx.common.issues),i.result;const a=o.map(c=>new Dt(c));return C(n,{code:E.invalid_union,unionErrors:a}),F}}get options(){return this._def.options}}lr.create=(t,e)=>new lr({options:t,typeName:j.ZodUnion,...W(e)});const _t=t=>t instanceof ro?_t(t.schema):t instanceof gn?_t(t.innerType()):t instanceof hr?[t.value]:t instanceof mn?t.options:t instanceof io?Q.objectValues(t.enum):t instanceof mr?_t(t._def.innerType):t instanceof to?[void 0]:t instanceof ur?[null]:t instanceof Lt?[void 0,..._t(t.unwrap())]:t instanceof yn?[null,..._t(t.unwrap())]:t instanceof Cd||t instanceof yr?_t(t.unwrap()):t instanceof gr?_t(t._def.innerType):[];class ea extends Z{_parse(e){const{ctx:n}=this._processInputParams(e);if(n.parsedType!==T.object)return C(n,{code:E.invalid_type,expected:T.object,received:n.parsedType}),F;const s=this.discriminator,r=n.data[s],i=this.optionsMap.get(r);return i?n.common.async?i._parseAsync({data:n.data,path:n.path,parent:n}):i._parseSync({data:n.data,path:n.path,parent:n}):(C(n,{code:E.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]}),F)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,n,s){const r=new Map;for(const i of n){const o=_t(i.shape[e]);if(!o.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(const a of o){if(r.has(a))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(a)}`);r.set(a,i)}}return new ea({typeName:j.ZodDiscriminatedUnion,discriminator:e,options:n,optionsMap:r,...W(s)})}}function so(t,e){const n=zt(t),s=zt(e);if(t===e)return{valid:!0,data:t};if(n===T.object&&s===T.object){const r=Q.objectKeys(e),i=Q.objectKeys(t).filter(a=>r.indexOf(a)!==-1),o={...t,...e};for(const a of i){const c=so(t[a],e[a]);if(!c.valid)return{valid:!1};o[a]=c.data}return{valid:!0,data:o}}else if(n===T.array&&s===T.array){if(t.length!==e.length)return{valid:!1};const r=[];for(let i=0;i<t.length;i++){const o=t[i],a=e[i],c=so(o,a);if(!c.valid)return{valid:!1};r.push(c.data)}return{valid:!0,data:r}}else return n===T.date&&s===T.date&&+t==+e?{valid:!0,data:t}:{valid:!1}}class dr extends Z{_parse(e){const{status:n,ctx:s}=this._processInputParams(e),r=(i,o)=>{if(Pc(i)||Pc(o))return F;const a=so(i.value,o.value);return a.valid?((Fc(i)||Fc(o))&&n.dirty(),{status:n.value,value:a.data}):(C(s,{code:E.invalid_intersection_types}),F)};return s.common.async?Promise.all([this._def.left._parseAsync({data:s.data,path:s.path,parent:s}),this._def.right._parseAsync({data:s.data,path:s.path,parent:s})]).then(([i,o])=>r(i,o)):r(this._def.left._parseSync({data:s.data,path:s.path,parent:s}),this._def.right._parseSync({data:s.data,path:s.path,parent:s}))}}dr.create=(t,e,n)=>new dr({left:t,right:e,typeName:j.ZodIntersection,...W(n)});class pn extends Z{_parse(e){const{status:n,ctx:s}=this._processInputParams(e);if(s.parsedType!==T.array)return C(s,{code:E.invalid_type,expected:T.array,received:s.parsedType}),F;if(s.data.length<this._def.items.length)return C(s,{code:E.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),F;!this._def.rest&&s.data.length>this._def.items.length&&(C(s,{code:E.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),n.dirty());const i=[...s.data].map((o,a)=>{const c=this._def.items[a]||this._def.rest;return c?c._parse(new St(s,o,s.path,a)):null}).filter(o=>!!o);return s.common.async?Promise.all(i).then(o=>qe.mergeArray(n,o)):qe.mergeArray(n,i)}get items(){return this._def.items}rest(e){return new pn({...this._def,rest:e})}}pn.create=(t,e)=>{if(!Array.isArray(t))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new pn({items:t,typeName:j.ZodTuple,rest:null,...W(e)})};class fr extends Z{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:n,ctx:s}=this._processInputParams(e);if(s.parsedType!==T.object)return C(s,{code:E.invalid_type,expected:T.object,received:s.parsedType}),F;const r=[],i=this._def.keyType,o=this._def.valueType;for(const a in s.data)r.push({key:i._parse(new St(s,a,s.path,a)),value:o._parse(new St(s,s.data[a],s.path,a)),alwaysSet:a in s.data});return s.common.async?qe.mergeObjectAsync(n,r):qe.mergeObjectSync(n,r)}get element(){return this._def.valueType}static create(e,n,s){return n instanceof Z?new fr({keyType:e,valueType:n,typeName:j.ZodRecord,...W(s)}):new fr({keyType:Ot.create(),valueType:e,typeName:j.ZodRecord,...W(n)})}}class zc extends Z{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){const{status:n,ctx:s}=this._processInputParams(e);if(s.parsedType!==T.map)return C(s,{code:E.invalid_type,expected:T.map,received:s.parsedType}),F;const r=this._def.keyType,i=this._def.valueType,o=[...s.data.entries()].map(([a,c],u)=>({key:r._parse(new St(s,a,s.path,[u,"key"])),value:i._parse(new St(s,c,s.path,[u,"value"]))}));if(s.common.async){const a=new Map;return Promise.resolve().then(async()=>{for(const c of o){const u=await c.key,l=await c.value;if(u.status==="aborted"||l.status==="aborted")return F;(u.status==="dirty"||l.status==="dirty")&&n.dirty(),a.set(u.value,l.value)}return{status:n.value,value:a}})}else{const a=new Map;for(const c of o){const u=c.key,l=c.value;if(u.status==="aborted"||l.status==="aborted")return F;(u.status==="dirty"||l.status==="dirty")&&n.dirty(),a.set(u.value,l.value)}return{status:n.value,value:a}}}}zc.create=(t,e,n)=>new zc({valueType:e,keyType:t,typeName:j.ZodMap,...W(n)});class ws extends Z{_parse(e){const{status:n,ctx:s}=this._processInputParams(e);if(s.parsedType!==T.set)return C(s,{code:E.invalid_type,expected:T.set,received:s.parsedType}),F;const r=this._def;r.minSize!==null&&s.data.size<r.minSize.value&&(C(s,{code:E.too_small,minimum:r.minSize.value,type:"set",inclusive:!0,exact:!1,message:r.minSize.message}),n.dirty()),r.maxSize!==null&&s.data.size>r.maxSize.value&&(C(s,{code:E.too_big,maximum:r.maxSize.value,type:"set",inclusive:!0,exact:!1,message:r.maxSize.message}),n.dirty());const i=this._def.valueType;function o(c){const u=new Set;for(const l of c){if(l.status==="aborted")return F;l.status==="dirty"&&n.dirty(),u.add(l.value)}return{status:n.value,value:u}}const a=[...s.data.values()].map((c,u)=>i._parse(new St(s,c,s.path,u)));return s.common.async?Promise.all(a).then(c=>o(c)):o(a)}min(e,n){return new ws({...this._def,minSize:{value:e,message:L.toString(n)}})}max(e,n){return new ws({...this._def,maxSize:{value:e,message:L.toString(n)}})}size(e,n){return this.min(e,n).max(e,n)}nonempty(e){return this.min(1,e)}}ws.create=(t,e)=>new ws({valueType:t,minSize:null,maxSize:null,typeName:j.ZodSet,...W(e)});class ro extends Z{get schema(){return this._def.getter()}_parse(e){const{ctx:n}=this._processInputParams(e);return this._def.getter()._parse({data:n.data,path:n.path,parent:n})}}ro.create=(t,e)=>new ro({getter:t,typeName:j.ZodLazy,...W(e)});class hr extends Z{_parse(e){if(e.data!==this._def.value){const n=this._getOrReturnCtx(e);return C(n,{received:n.data,code:E.invalid_literal,expected:this._def.value}),F}return{status:"valid",value:e.data}}get value(){return this._def.value}}hr.create=(t,e)=>new hr({value:t,typeName:j.ZodLiteral,...W(e)});function xd(t,e){return new mn({values:t,typeName:j.ZodEnum,...W(e)})}class mn extends Z{_parse(e){if(typeof e.data!="string"){const n=this._getOrReturnCtx(e),s=this._def.values;return C(n,{expected:Q.joinValues(s),received:n.parsedType,code:E.invalid_type}),F}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(e.data)){const n=this._getOrReturnCtx(e),s=this._def.values;return C(n,{received:n.data,code:E.invalid_enum_value,options:s}),F}return rt(e.data)}get options(){return this._def.values}get enum(){const e={};for(const n of this._def.values)e[n]=n;return e}get Values(){const e={};for(const n of this._def.values)e[n]=n;return e}get Enum(){const e={};for(const n of this._def.values)e[n]=n;return e}extract(e,n=this._def){return mn.create(e,{...this._def,...n})}exclude(e,n=this._def){return mn.create(this.options.filter(s=>!e.includes(s)),{...this._def,...n})}}mn.create=xd;class io extends Z{_parse(e){const n=Q.getValidEnumValues(this._def.values),s=this._getOrReturnCtx(e);if(s.parsedType!==T.string&&s.parsedType!==T.number){const r=Q.objectValues(n);return C(s,{expected:Q.joinValues(r),received:s.parsedType,code:E.invalid_type}),F}if(this._cache||(this._cache=new Set(Q.getValidEnumValues(this._def.values))),!this._cache.has(e.data)){const r=Q.objectValues(n);return C(s,{received:s.data,code:E.invalid_enum_value,options:r}),F}return rt(e.data)}get enum(){return this._def.values}}io.create=(t,e)=>new io({values:t,typeName:j.ZodNativeEnum,...W(e)});class pr extends Z{unwrap(){return this._def.type}_parse(e){const{ctx:n}=this._processInputParams(e);if(n.parsedType!==T.promise&&n.common.async===!1)return C(n,{code:E.invalid_type,expected:T.promise,received:n.parsedType}),F;const s=n.parsedType===T.promise?n.data:Promise.resolve(n.data);return rt(s.then(r=>this._def.type.parseAsync(r,{path:n.path,errorMap:n.common.contextualErrorMap})))}}pr.create=(t,e)=>new pr({type:t,typeName:j.ZodPromise,...W(e)});class gn extends Z{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===j.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){const{status:n,ctx:s}=this._processInputParams(e),r=this._def.effect||null,i={addIssue:o=>{C(s,o),o.fatal?n.abort():n.dirty()},get path(){return s.path}};if(i.addIssue=i.addIssue.bind(i),r.type==="preprocess"){const o=r.transform(s.data,i);if(s.common.async)return Promise.resolve(o).then(async a=>{if(n.value==="aborted")return F;const c=await this._def.schema._parseAsync({data:a,path:s.path,parent:s});return c.status==="aborted"?F:c.status==="dirty"||n.value==="dirty"?rs(c.value):c});{if(n.value==="aborted")return F;const a=this._def.schema._parseSync({data:o,path:s.path,parent:s});return a.status==="aborted"?F:a.status==="dirty"||n.value==="dirty"?rs(a.value):a}}if(r.type==="refinement"){const o=a=>{const c=r.refinement(a,i);if(s.common.async)return Promise.resolve(c);if(c instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return a};if(s.common.async===!1){const a=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});return a.status==="aborted"?F:(a.status==="dirty"&&n.dirty(),o(a.value),{status:n.value,value:a.value})}else return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then(a=>a.status==="aborted"?F:(a.status==="dirty"&&n.dirty(),o(a.value).then(()=>({status:n.value,value:a.value}))))}if(r.type==="transform")if(s.common.async===!1){const o=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!Mn(o))return F;const a=r.transform(o.value,i);if(a instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:n.value,value:a}}else return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then(o=>Mn(o)?Promise.resolve(r.transform(o.value,i)).then(a=>({status:n.value,value:a})):F);Q.assertNever(r)}}gn.create=(t,e,n)=>new gn({schema:t,typeName:j.ZodEffects,effect:e,...W(n)});gn.createWithPreprocess=(t,e,n)=>new gn({schema:e,effect:{type:"preprocess",transform:t},typeName:j.ZodEffects,...W(n)});class Lt extends Z{_parse(e){return this._getType(e)===T.undefined?rt(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}Lt.create=(t,e)=>new Lt({innerType:t,typeName:j.ZodOptional,...W(e)});class yn extends Z{_parse(e){return this._getType(e)===T.null?rt(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}}yn.create=(t,e)=>new yn({innerType:t,typeName:j.ZodNullable,...W(e)});class mr extends Z{_parse(e){const{ctx:n}=this._processInputParams(e);let s=n.data;return n.parsedType===T.undefined&&(s=this._def.defaultValue()),this._def.innerType._parse({data:s,path:n.path,parent:n})}removeDefault(){return this._def.innerType}}mr.create=(t,e)=>new mr({innerType:t,typeName:j.ZodDefault,defaultValue:typeof e.default=="function"?e.default:()=>e.default,...W(e)});class gr extends Z{_parse(e){const{ctx:n}=this._processInputParams(e),s={...n,common:{...n.common,issues:[]}},r=this._def.innerType._parse({data:s.data,path:s.path,parent:{...s}});return ar(r)?r.then(i=>({status:"valid",value:i.status==="valid"?i.value:this._def.catchValue({get error(){return new Dt(s.common.issues)},input:s.data})})):{status:"valid",value:r.status==="valid"?r.value:this._def.catchValue({get error(){return new Dt(s.common.issues)},input:s.data})}}removeCatch(){return this._def.innerType}}gr.create=(t,e)=>new gr({innerType:t,typeName:j.ZodCatch,catchValue:typeof e.catch=="function"?e.catch:()=>e.catch,...W(e)});class Wc extends Z{_parse(e){if(this._getType(e)!==T.nan){const s=this._getOrReturnCtx(e);return C(s,{code:E.invalid_type,expected:T.nan,received:s.parsedType}),F}return{status:"valid",value:e.data}}}Wc.create=t=>new Wc({typeName:j.ZodNaN,...W(t)});class Cd extends Z{_parse(e){const{ctx:n}=this._processInputParams(e),s=n.data;return this._def.type._parse({data:s,path:n.path,parent:n})}unwrap(){return this._def.type}}class ta extends Z{_parse(e){const{status:n,ctx:s}=this._processInputParams(e);if(s.common.async)return(async()=>{const i=await this._def.in._parseAsync({data:s.data,path:s.path,parent:s});return i.status==="aborted"?F:i.status==="dirty"?(n.dirty(),rs(i.value)):this._def.out._parseAsync({data:i.value,path:s.path,parent:s})})();{const r=this._def.in._parseSync({data:s.data,path:s.path,parent:s});return r.status==="aborted"?F:r.status==="dirty"?(n.dirty(),{status:"dirty",value:r.value}):this._def.out._parseSync({data:r.value,path:s.path,parent:s})}}static create(e,n){return new ta({in:e,out:n,typeName:j.ZodPipeline})}}class yr extends Z{_parse(e){const n=this._def.innerType._parse(e),s=r=>(Mn(r)&&(r.value=Object.freeze(r.value)),r);return ar(n)?n.then(r=>s(r)):s(n)}unwrap(){return this._def.innerType}}yr.create=(t,e)=>new yr({innerType:t,typeName:j.ZodReadonly,...W(e)});var j;(function(t){t.ZodString="ZodString",t.ZodNumber="ZodNumber",t.ZodNaN="ZodNaN",t.ZodBigInt="ZodBigInt",t.ZodBoolean="ZodBoolean",t.ZodDate="ZodDate",t.ZodSymbol="ZodSymbol",t.ZodUndefined="ZodUndefined",t.ZodNull="ZodNull",t.ZodAny="ZodAny",t.ZodUnknown="ZodUnknown",t.ZodNever="ZodNever",t.ZodVoid="ZodVoid",t.ZodArray="ZodArray",t.ZodObject="ZodObject",t.ZodUnion="ZodUnion",t.ZodDiscriminatedUnion="ZodDiscriminatedUnion",t.ZodIntersection="ZodIntersection",t.ZodTuple="ZodTuple",t.ZodRecord="ZodRecord",t.ZodMap="ZodMap",t.ZodSet="ZodSet",t.ZodFunction="ZodFunction",t.ZodLazy="ZodLazy",t.ZodLiteral="ZodLiteral",t.ZodEnum="ZodEnum",t.ZodEffects="ZodEffects",t.ZodNativeEnum="ZodNativeEnum",t.ZodOptional="ZodOptional",t.ZodNullable="ZodNullable",t.ZodDefault="ZodDefault",t.ZodCatch="ZodCatch",t.ZodPromise="ZodPromise",t.ZodBranded="ZodBranded",t.ZodPipeline="ZodPipeline",t.ZodReadonly="ZodReadonly"})(j||(j={}));const yt=Ot.create,oo=Dn.create,Wr=eo.create,Od=ur.create,Ss=no.create;Xt.create;const na=gt.create,pt=we.create,Ls=lr.create,fw=ea.create;dr.create;pn.create;const As=fr.create,qs=hr.create,br=mn.create;pr.create;Lt.create;yn.create;const hw=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/,sa="an ISO-8601 instant with Z or an explicit offset, such as 2026-01-01T00:00:00Z";function Td(t){return hw.test(t)?!Number.isNaN(Date.parse(t)):!1}function pw(t){if(!(t===void 0||typeof t=="string"&&Td(t)))return`Case refused: requestTime is ${JSON.stringify(t)}, which is not ${sa}.`}const mw="Case refused: a create case has no existing resource; use 'update' or remove 'resource'.";function gw(t){return t.method==="create"&&t.resource!==void 0&&t.resource!==null?mw:void 0}const yw=["get","list","create","update","delete"],bw=pt({uid:yt(),token:As(Ss()).optional()}),vw=pt({function:br(["get","exists"]).describe("Firestore function to mock"),path:yt().describe('Document path, e.g. "users/alice"'),result:Ls([As(Ss()),Wr()]).describe("Document data for get, boolean for exists")}),ww=fw("kind",[pt({kind:qs("create")}),pt({kind:qs("set"),merge:Wr()}),pt({kind:qs("update")}),pt({kind:qs("delete")})]),Vc=Ls([yt(),oo(),Wr(),Od()]),Sw=pt({field:yt(),op:yt(),value:Ls([Vc,na(Vc)])}),Aw=pt({where:na(Sw).optional(),limit:oo().optional(),offset:oo().optional(),orderBy:yt().optional()}),Rd=pt({description:yt().describe("Human-readable description of what this test verifies"),expectation:br(["ALLOW","DENY"]).describe("Expected outcome"),method:br(yw).describe("Firestore method to test"),path:yt().describe('Document path, e.g. "users/alice"'),auth:Ls([bw,Od()]).optional().describe("Auth context; null or omitted for unauthenticated"),data:As(Ss()).optional().describe("request.resource.data for write operations"),resource:As(Ss()).optional().describe("Existing document data (resource.data)"),functionMocks:na(vw).optional().describe("Mock get()/exists() calls in rules"),query:Aw.optional().describe("request.query payload (list ops only): limit/offset/orderBy."),requestTime:yt().refine(Td,{message:`requestTime must be ${sa}`}).optional().describe("Override for request.time (ISO-8601 with Z or an offset). Defaults to wallclock."),writeMode:ww.optional().describe("Optional write-mode override; controls update merge semantics and getAfter() projection.")}).strict();function en(t){if(t.decision==="UNSUPPORTED")return;const n=t.decision==="ALLOW";let s="deny",r;if(n)s="allow",r=t.trace.find(y=>y.verdict==="ALLOW");else if(t.resourceLimit!==void 0&&t.trace.length>0)s="deny",r=t.trace[t.trace.length-1];else if(s="deny",r=t.trace.find(b=>b.verdict==="DENY"?!0:b.verdict==="ERROR"),r===void 0){const b=t.trace.length;b>0&&(r=t.trace[b-1])}if(r===void 0)return;const o={verdict:s};r.line!==void 0&&(o.line=r.line),r.col!==void 0&&(o.col=r.col,o.column=r.col),r.column!==void 0&&(o.col=r.column,o.column=r.column),r.file!==void 0&&(o.file=r.file),r.citation!==void 0&&(o.citation=r.citation),r.conditionText!==void 0&&(o.expression=r.conditionText),r.expressionTrace!==void 0&&(o.expressionTrace=r.expressionTrace);const h=o.line!==void 0,m=o.expression!==void 0,g=o.expressionTrace!==void 0;if(h||m||g)return o}function ke(t){const e=[];for(const n of t.notes)e.push(n);for(const n of t.trace){const s=n.operations.join(","),r=`Rule #${n.ruleIndex} (${s})`;n.verdict==="ALLOW"?e.push(`${r} → ALLOW`):n.verdict==="DENY"?e.push(`${r} → deny`):n.verdict==="UNSUPPORTED"?e.push(`${r} → unsupported: ${n.message??""}`):e.push(`${r} → error: ${n.message??""}`)}return e.push(`Simulated: ${t.decision}`),e}pt({function:br(["get","exists"]).describe("Cross-service Firestore function to mock"),path:yt().describe('Firestore document path in collection/doc form, e.g. "users/alice"'),result:Ls([As(Ss()),Wr()]).describe("Document fields for get, boolean for exists")});function kw(t){if(t.code==="unrecognized_keys"){const s=t.keys.map(i=>`'${i}'`).join(", "),r=Object.keys(Rd.shape).join(", ");return`unknown field ${s}; a Firestore rules case takes ${r}.`}const e=t.path.join(".");return e==="requestTime"?`requestTime is not ${sa}.`:`${e===""?"the case":e}: ${t.message}.`}function Ew(t){const e=Rd.safeParse(t);return e.success?gw(e.data):`Case refused: ${e.error.issues.map(kw).join(" ")}`}const Nd=["databases","(default)","documents"];function Iw(t){return`/${[...Nd,...Md(t)].join("/")}`}function ra(t,e){const n=[...Nd,...Md(e)];return Ld(t.service.match.path.segments,n,Br(t.version))}function Ld(t,e,n){const s={};let r=0;for(let i=0;i<t.length;i++){const o=t[i];if(o.type==="recursive")return i===t.length-1?{bindings:s,remaining:e.slice(r),recursiveTail:{name:o.name}}:_w(o.name,t.slice(i+1),e,r,s,n);if(!(r<e.length))return null;const c=e[r];if(o.type==="literal"&&o.value!==c)return null;o.type==="wildcard"&&(s[o.name]=c),r++}return{bindings:s,remaining:e.slice(r)}}function _w(t,e,n,s,r,i){for(let o=s+i;o<=n.length;o++){const a=Ld(e,n.slice(o),i);if(a)return{...a,bindings:{...r,[t]:n.slice(s,o).join("/"),...a.bindings}}}return null}function ao(t,e,n,s){const r=ra(t,e);if(!r)return[];const i=r.recursiveTail,o=i?xw(t.service.match,i.name,r.remaining,n,t.version,s):t.service.match.children.flatMap(a=>zr(a,r.remaining,n,t.version,s));for(const a of o)a.pathVariables={...r.bindings,...a.pathVariables};return o}function xw(t,e,n,s,r,i){const o=`/{${e}=**}`,a={path:{raw:o,segments:[{type:"recursive",name:e}]},functions:[],allows:[],children:t.children};return zr(a,n,s,r,i&&{push(u){u.blockPath===o&&u.line===void 0||i.push(u)}}).filter(u=>u.block!==a)}function Cw(t){const e=ra(t,"");if(!e)return!1;const n=e.recursiveTail===void 0&&e.remaining.length===0,s=e.remaining.length>=Br(t.version),r=e.recursiveTail!==void 0&&s;return n||r}function Ow(t,e){return ra(t,e)!==null?[`No match block found for path '${e}', so the request is denied by default.`,qv]:[`The root match '${Qo(t.service.match)}' does not match '${Iw(e)}', so no match block applies and the request is denied.`]}function Md(t){return t.split("/").filter(Boolean)}const co=t=>t===null||typeof t=="string"||typeof t=="boolean"||typeof t=="number"&&Number.isFinite(t),Ut=t=>({type:"literal",value:t,raw:JSON.stringify(t)});function vr(t){return t.type==="memberAccess"?{object:t.object,property:t.property}:t.type==="bracketAccess"&&t.index.type==="literal"&&typeof t.index.value=="string"?{object:t.object,property:t.index.value}:null}function Tw(t){const e=vr(t);return!e||e.property!=="data"?!1:e.object.type==="identifier"&&e.object.name==="resource"}function Wt(t){const e=vr(t);return!e||e.property.length===0||e.property.includes(".")||!Tw(e.object)?null:e.property}function Dd(t){const e=vr(t);if(!e||e.property!=="uid")return!1;const n=vr(e.object);return!n||n.property!=="auth"?!1:n.object.type==="identifier"&&n.object.name==="request"}function ia(t){const e=new Map;for(const n of t.where??[]){let s;if(n.op==="=="&&co(n.value)?s=[n.value]:n.op==="in"&&Array.isArray(n.value)&&n.value.length>0&&n.value.length<=30&&n.value.every(co)&&(s=Array.from(new Set(n.value))),s===void 0)continue;const r=e.get(n.field);r===void 0?e.set(n.field,[s]):r.push(s)}return e}function oa(t){const e=new Map;for(const[n,s]of ia(t)){let r=s[0];for(let i=1;i<s.length;i++){const o=s[i];r=r.filter(a=>o.includes(a))}e.set(n,r)}return e}function Rw(t,e,n=new Set){let s=500;const r=(i,o)=>{if(--s<0)return null;if(i.type==="functionCall"&&e.has(i.name)){if(o.has(i.name))return null;const a=e.get(i.name);if(a.parameters.length!==i.args.length)return null;const c=new Map;for(let l=0;l<a.parameters.length;l++){const d=r(i.args[l],o);if(!d)return null;c.set(a.parameters[l],d)}const u=new Set(o).add(i.name);for(const l of a.lets){const d=r(tn(l.value,c),u);if(!d)return null;c.set(l.name,d)}return r(tn(a.body,c),u)}switch(i.type){case"literal":case"identifier":return i;case"memberAccess":{const a=r(i.object,o);return a?{...i,object:a}:null}case"bracketAccess":{const a=r(i.object,o),c=r(i.index,o);return!a||!c?null:{...i,object:a,index:c}}case"binaryOp":{const a=r(i.left,o),c=r(i.right,o);return!a||!c?null:{...i,left:a,right:c}}default:return i}};return r(t,n)}function Us(t,e,n){return{type:"binaryOp",op:n,left:t,right:e}}function En(t){return{type:"unaryOp",op:"!",operand:t}}function aa(t,e){if(t.type==="literal"&&co(t.value))return t.value;if(Dd(t))return e}function mi(t,e,n,s){const r=aa(e,s);return r===void 0?!1:(n.where??[]).some(i=>i.field===t&&i.op==="array-contains"&&i.value===r)}function Nw(t,e,n,s){const r=(i,o)=>{const a=Wt(i);if(a===null)return!1;const c=n.get(a);if(!c)return!1;const u=aa(o,s);return u===void 0?!1:c.some(l=>l.length===1&&l[0]===u)};return r(t,e)||r(e,t)}function Lw(t,e,n,s){const r=Wt(t);if(r===null||e.type!=="listLiteral")return!1;const i=n.get(r);if(!i)return!1;const o=[];for(const a of e.elements){const c=aa(a,s);if(c===void 0)return!1;o.push(c)}return i.some(a=>a.every(c=>o.includes(c)))}function Mw(t,e,n,s){let r=!1;const i=ia(e),o=oa(e),a=new Map;for(const[l,d]of o)d.length>0&&a.set(l,d);let c=[new Map];for(const[l,d]of a){if(c.length*d.length>30)return;c=c.flatMap(f=>d.map(p=>new Map([...f,[l,p]])))}const u=[];for(const l of c){let f=function(h,m=new Set){if(--d<0)throw new Error("proof expansion budget");const g=Wt(h);if(g!==null&&l.has(g))return Ut(l.get(g));if(h.type==="functionCall"&&n.has(h.name)){if(cn(h,n))return h;if(m.has(h.name))throw new Error("recursive proof helper");const b=n.get(h.name);if(b.parameters.length!==h.args.length)throw new Error("proof arity");const v=new Map(b.parameters.map((w,k)=>[w,h.args[k]]));for(const w of b.lets)v.set(w.name,tn(w.value,v));return f(tn(b.body,v),new Set([...m,h.name]))}if(h.type==="inExpr"){const b=f(h.element,m),v=f(h.collection,m),w=Wt(v);return w!==null&&mi(w,b,e,s)||Lw(b,v,i,s)?Ut(!0):{...h,element:b,collection:v}}const y=b=>f(b,m);switch(h.type){case"literal":case"identifier":return h;case"memberAccess":{const b={...h,object:y(h.object)},v=Wt(b);return v!==null&&l.has(v)?Ut(l.get(v)):b}case"bracketAccess":{const b={...h,object:y(h.object),index:y(h.index)},v=Wt(b);return v!==null&&l.has(v)?Ut(l.get(v)):b}case"sliceAccess":return{...h,object:y(h.object),start:y(h.start),end:y(h.end)};case"binaryOp":{const b=y(h.left),v=y(h.right);return h.op==="=="&&Nw(b,v,i,s)?Ut(!0):{...h,left:b,right:v}}case"unaryOp":return{...h,operand:y(h.operand)};case"ternary":return{...h,condition:y(h.condition),consequent:y(h.consequent),alternate:y(h.alternate)};case"isExpr":return{...h,value:y(h.value)};case"methodCall":{const b=y(h.object),v=h.args.map(y),w=Wt(b);if(w!==null&&v.length===1&&v[0].type==="listLiteral"&&v[0].elements.every(k=>cn(k,n))){const k=v[0].elements;if(h.method==="hasAny"&&k.some(O=>mi(w,O,e,s))||h.method==="hasAll"&&k.length>0&&k.every(O=>mi(w,O,e,s)))return Ut(!0)}return{...h,object:b,args:v}}case"functionCall":return{...h,args:h.args.map(y)};case"listLiteral":return{...h,elements:h.elements.map(y)};case"mapLiteral":return{...h,entries:h.entries.map(b=>({key:y(b.key),value:y(b.value)}))};case"pathLiteral":return{...h,segments:h.segments.map(b=>typeof b=="string"?b:y(b))}}},p=function(h){if(cn(h,n))return h;if(h.type==="unaryOp"&&h.op==="!"){const y=h.operand;if(y.type==="binaryOp"&&y.op==="&&")return p(Us(En(y.left),En(y.right),"||"));if(y.type==="binaryOp"&&y.op==="||")return p(Us(En(y.left),En(y.right),"&&"));if(y.type==="unaryOp"&&y.op==="!"){const b=p(y.operand);return b?En(En(b)):void 0}return}if(h.type!=="binaryOp"||h.op!=="&&"&&h.op!=="||")return;const m=p(h.left),g=p(h.right);if(m&&g)return Us(m,g,h.op);if(h.op==="||")return r=!0,m??g},d=2e3;try{const h=p(f(t));if(!h)return;u.push(h)}catch{return}}return{condition:u.reduce((l,d)=>Us(l,d,"&&")),partial:r}}function Dw(t,e,n=new Map,s){const r=$w(t,e,n,s);if(r.provable||r.kind==="constraints-not-satisfied")return r;const i=Mw(t,e,n,s);return i?{provable:!0,reason:"query-guaranteed facts reduce every candidate alternative to a document-independent residual",residualCondition:i.condition,proofFailure:i.partial?r:void 0}:r}function $w(t,e,n=new Map,s){if(cn(t,n))return{provable:!0,reason:"list rule does not depend on per-document data; every doc is equally readable"};const r=Fw(t,n,s);if(!r.ok||r.required.length===0){const f="list rule depends on per-document data through a predicate the query cannot discharge (unconstrained candidate fields or unsupported query facts remain after helper expansion)";return{provable:!1,kind:"unsupported-predicate",reason:`${f} — Pyric cannot establish whether Firebase would allow this query`,residual:{missing:[],mismatched:[],outOfScope:f,...r.ok?{}:{predicate:Se(r.predicate),predicateLoc:r.predicateLoc}}}}const i=r.required,o=e.where??[],a=ia(e),c=oa(e),u=[],l=[];let d=!1;for(const f of i){const p=c.get(f.field),h=a.get(f.field),m=p!==void 0&&p.length===1&&gi(p[0],f.value),g=h!==void 0&&h.some(v=>v.length===1&&gi(v[0],f.value));if(m||g){(p?.length??0)===0&&(d=!0);continue}const b=o.find(v=>v.field===f.field&&v.op==="=="&&!gi(v.value,f.value));b?l.push({field:f.field,expectedValue:f.value,actualValue:b.value}):u.push({field:f.field,expectedValue:f.value,fromAuthUid:f.fromAuthUid})}if(u.length===0&&l.length===0){const f={provable:!0,reason:"every per-document predicate the rule requires is guaranteed by a query where(...) constraint"};return d&&(f.residualCondition=r.residual),f}return{provable:!1,kind:"constraints-not-satisfied",reason:Pw(u,l),residual:{missing:u,mismatched:l}}}function Pw(t,e){const n=[];if(t.length>0){const s=t.map(r=>`resource.data.${r.field} == ${r.fromAuthUid?"request.auth.uid":JSON.stringify(r.expectedValue)}`).join(", ");n.push(`the query has no matching where(...) equality for [${s}]`)}if(e.length>0){const s=e.map(r=>`resource.data.${r.field} == ${JSON.stringify(r.expectedValue)} but the query pins ${JSON.stringify(r.actualValue)}`).join(", ");n.push(`the query where(...) value does not match [${s}]`)}return`${n.join("; ")} — Pyric cannot prove the query safe ("rules are not filters")`}function cn(t,e=new Map,n=new Set){const s=r=>{switch(r.type){case"literal":return!0;case"identifier":return r.name!=="resource";case"memberAccess":return s(r.object);case"bracketAccess":return s(r.object)&&s(r.index);case"sliceAccess":return s(r.object)&&s(r.start)&&s(r.end);case"binaryOp":return s(r.left)&&s(r.right);case"unaryOp":return s(r.operand);case"ternary":return s(r.condition)&&s(r.consequent)&&s(r.alternate);case"inExpr":return s(r.element)&&s(r.collection);case"isExpr":return s(r.value);case"listLiteral":return r.elements.every(s);case"mapLiteral":return r.entries.every(i=>s(i.key)&&s(i.value));case"pathLiteral":return r.segments.every(i=>typeof i=="string"||s(i));case"methodCall":return s(r.object)&&r.args.every(s);case"functionCall":{if(!r.args.every(s))return!1;const i=e.get(r.name);if(!i)return!0;if(n.has(r.name))return!1;const o=new Set(n).add(r.name),a=new Map;i.parameters.forEach((c,u)=>{const l=r.args[u];l&&a.set(c,l)});for(const c of i.lets){const u=tn(c.value,a);if(!cn(u,e,o))return!1;a.set(c.name,u)}return cn(tn(i.body,a),e,o)}default:return!1}};return s(t)}function Fw(t,e,n){const s=[];let r=t,i=t.loc;const o=(c,u,l=t.loc)=>{if(c.type==="binaryOp"&&c.op==="&&"){const p=o(c.left,u,l);if(!p)return null;const h=o(c.right,u,l);return h?{type:"binaryOp",op:"&&",left:p,right:h}:null}if(c.type==="functionCall"&&e.has(c.name)&&!u.has(c.name)){const p=e.get(c.name),h=new Map;p.parameters.forEach((y,b)=>{const v=c.args[b];v&&h.set(y,v)});for(const y of p.lets)h.set(y.name,tn(y.value,h));const m=tn(p.body,h),g=new Set(u).add(c.name);return o(m,g,p.loc??l)}const d=jw(c,e,n,u);return d?(s.push(d),{type:"literal",value:!0,raw:"true"}):cn(c,e)?c:(r=c,i=c.loc??l,null)},a=o(t,new Set);return a?{ok:!0,required:s,residual:a}:{ok:!1,predicate:r,predicateLoc:i}}function jw(t,e,n,s){const r=Rw(t,e,s);if(!r||r.type!=="binaryOp"||r.op!=="==")return null;const i=(o,a)=>{const c=Wt(o);return c===null?null:a.type==="literal"?{field:c,value:a.value,fromAuthUid:!1}:n!==void 0&&Dd(a)?{field:c,value:n,fromAuthUid:!0}:null};return i(r.left,r.right)??i(r.right,r.left)}function tn(t,e){const n=s=>{switch(s.type){case"identifier":return e.get(s.name)??s;case"literal":return s;case"memberAccess":return{...s,object:n(s.object)};case"methodCall":return{...s,object:n(s.object),args:s.args.map(n)};case"bracketAccess":return{...s,object:n(s.object),index:n(s.index)};case"sliceAccess":return{...s,object:n(s.object),start:n(s.start),end:n(s.end)};case"binaryOp":return{...s,left:n(s.left),right:n(s.right)};case"unaryOp":return{...s,operand:n(s.operand)};case"ternary":return{...s,condition:n(s.condition),consequent:n(s.consequent),alternate:n(s.alternate)};case"inExpr":return{...s,element:n(s.element),collection:n(s.collection)};case"isExpr":return{...s,value:n(s.value)};case"listLiteral":return{...s,elements:s.elements.map(n)};case"mapLiteral":return{...s,entries:s.entries.map(r=>({key:n(r.key),value:n(r.value)}))};case"pathLiteral":return{...s,segments:s.segments.map(r=>typeof r=="string"?r:n(r))};case"functionCall":return{...s,args:s.args.map(n)}}};return n(t)}function gi(t,e){return t===e}function $d(t){const e=new Map,n=new Set;for(const s of t)e.has(s.name)&&n.add(s.name),e.set(s.name,s);return{functions:e,ambiguousNames:n}}function Pd(t,e,n,s=qw){const r=new Set;return{pathInvariant:!Ks(t,e,n,s,new Set,r),requiredFunctions:r}}function Ks(t,e,n,s,r,i){const o=a=>Ks(a,e,n,s,r,i);switch(t.type){case"literal":return!1;case"identifier":return e.has(t.name)||t.name==="request";case"memberAccess":return t.object.type==="identifier"&&t.object.name==="request"?!Hc.has(t.property):o(t.object);case"methodCall":return o(t.object)||t.args.some(o);case"bracketAccess":return t.object.type==="identifier"&&t.object.name==="request"?!(t.index.type==="literal"&&typeof t.index.value=="string"&&Hc.has(t.index.value)):o(t.object)||o(t.index);case"sliceAccess":return o(t.object)||o(t.start)||o(t.end);case"binaryOp":return o(t.left)||o(t.right);case"unaryOp":return o(t.operand);case"ternary":return o(t.condition)||o(t.consequent)||o(t.alternate);case"inExpr":return o(t.element)||o(t.collection);case"isExpr":return o(t.value);case"listLiteral":return t.elements.some(o);case"mapLiteral":return t.entries.some(a=>o(a.key)||o(a.value));case"pathLiteral":return t.segments.some(a=>typeof a!="string"&&o(a));case"functionCall":{for(const l of t.args)if(!yi(l)&&o(l))return!0;if(s.has(t.name))return!0;const a=n.get(t.name);if(!a)return t.args.some(yi);if(t.args.length!==a.parameters.length||(i.add(a.name),r.has(a.name)))return!0;const c=new Set(r).add(a.name),u=new Map;for(let l=0;l<a.parameters.length;l++)u.set(a.parameters[l],t.args[l]);for(const l of a.lets){const d=Gc(l.value,u);if(!yi(d)&&Ks(d,e,n,s,c,i))return!0;u.set(l.name,d)}return Ks(Gc(a.body,u),e,n,s,c,i)}}}function yi(t){return t.type==="identifier"&&t.name==="request"}function Gc(t,e){const n=s=>{switch(s.type){case"identifier":return e.get(s.name)??s;case"literal":return s;case"memberAccess":return{...s,object:n(s.object)};case"methodCall":return{...s,object:n(s.object),args:s.args.map(n)};case"bracketAccess":return{...s,object:n(s.object),index:n(s.index)};case"sliceAccess":return{...s,object:n(s.object),start:n(s.start),end:n(s.end)};case"binaryOp":return{...s,left:n(s.left),right:n(s.right)};case"unaryOp":return{...s,operand:n(s.operand)};case"ternary":return{...s,condition:n(s.condition),consequent:n(s.consequent),alternate:n(s.alternate)};case"inExpr":return{...s,element:n(s.element),collection:n(s.collection)};case"isExpr":return{...s,value:n(s.value)};case"listLiteral":return{...s,elements:s.elements.map(n)};case"mapLiteral":return{...s,entries:s.entries.map(r=>({key:n(r.key),value:n(r.value)}))};case"pathLiteral":return{...s,segments:s.segments.map(r=>typeof r=="string"?r:n(r))};case"functionCall":return{...s,args:s.args.map(n)}}};return n(t)}const Hc=new Set(["auth","method","query","time"]),qw=new Set;function Fd(t,e,n,s,r){if(t!==null===!1)return{kind:"no-rule"};const o=[...t.functions??[],...t.service.functions??[],...t.service.match.functions],a=ao(t,e,o);if(a.length===0)return{kind:"no-rule"};const u=[],l=new Map;let d=0;for(const h of a){const m=$d(h.functions),g=m.functions;for(const y of h.block.allows){if(y.operations.some(V=>V==="list"?!0:V==="read")===!1)continue;if(d++,Pd(y.condition,new Set(h.candidateVariables),g,m.ambiguousNames).pathInvariant===!0===!1){u.push({kind:"unsupported-path",reason:"list rule depends on the candidate document path",residual:{missing:[],mismatched:[]},rule:Kc(y,r)});continue}const k=Dw(y.condition,s,g,n?.uid);k.provable===!0&&l.set(y,k.residualCondition?{...y,condition:k.residualCondition}:y);const R=k.provable?k.proofFailure:k;R&&u.push({kind:R.kind,reason:R.reason,residual:R.residual,rule:Kc(y,r),...R.residual.predicate?{predicate:jd(R.residual.predicate,R.residual.predicateLoc??y.loc,r)}:{}})}}if(d===0)return{kind:"no-rule"};if(l.size===0){const h=u[0];return{kind:"unprovable",failures:u,reason:h.reason,residual:h.residual,...h.rule?{rule:{...h.rule,verdict:"deny"}}:{}}}return{kind:"provable",failures:u,evaluationAst:Uw(t,l),syntheticResource:Bw(s)}}function Kc(t,e=""){return jd(Se(t.condition),t.loc,e)}function jd(t,e,n=""){if(!e)return{expression:t};const{line:s,col:r,file:i}=e,o=$g(n,s,r,i,t);return o?{...o,column:o.col,expression:o.expression??t}:{line:s,col:r,column:r,file:i??"firestore.rules",citation:`${i??"firestore.rules"}:${s}:${r}`,expression:t}}function Uw(t,e){const n=s=>({...s,allows:s.allows.filter(r=>e.has(r)).map(r=>e.get(r)),children:s.children.map(n)});return{...t,service:{...t.service,match:n(t.service.match)}}}function Bw(t){const e={};for(const[n,s]of oa(t))s.length===1&&(e[n]=s[0]);return e}function zw(t){return t?{...t.where!==void 0?{where:t.where}:{},...t.limit!==void 0?{limit:t.limit}:{},...t.offset!==void 0?{offset:t.offset}:{},...t.orderBy!==void 0?{orderBy:t.orderBy}:{}}:{}}function qd(t){const e=t.where!==void 0&&t.where.length>0;if(!(!e&&t.limit==null&&t.offset==null&&t.orderBy==null))return{...e?{where:t.where.map(n=>({field:n.field,op:n.op,value:Array.isArray(n.value)?[...n.value]:n.value}))}:{},...t.limit!=null?{limit:t.limit}:{},...t.offset!=null?{offset:t.offset}:{},...t.orderBy!=null?{orderBy:t.orderBy}:{}}}function uo(t){const e=[];for(const s of t.missing)s.fromAuthUid?e.push(` .where('${s.field}', '==', request.auth.uid) // request.auth.uid is ${JSON.stringify(s.expectedValue)}`):e.push(` .where('${s.field}', '==', ${JSON.stringify(s.expectedValue)})`);for(const s of t.mismatched)e.push(` .where('${s.field}', '==', ${JSON.stringify(s.expectedValue)}) // the query pins ${JSON.stringify(s.actualValue)}, but the rule requires ${JSON.stringify(s.expectedValue)}`);return e.length===0?void 0:`The list rule requires per-document equalities the query does not guarantee. Add the matching where(...) constraint(s) so every returned document satisfies the rule:
|
|
1707
|
+
${e.join(`
|
|
1708
|
+
`)}`}function Zc(t){return/^[A-Za-z0-9_./:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function Ud(t){const e=qd(t.constraints),n=t.auth?{uid:t.auth.uid,...t.auth.token&&Object.keys(t.auth.token).length>0?{token:t.auth.token}:{}}:null,s={description:`list ${t.path}`,expectation:"ALLOW",method:"list",path:t.path,auth:n,...e?{query:e}:{}};return{command:["pyric rules simulate --service firestore --operation list",`--path ${Zc(t.path)}`,...n?[`--uid ${Zc(n.uid)}`]:[],...e?[`--query '${JSON.stringify(e).replace(/'/g,"'\\''")}'`]:[]].join(" "),testCase:s}}function Ww(t){const e=Ud(t);return["Reproduce with:",` ${e.command}`,` Fixture case: ${JSON.stringify(e.testCase)}`].join(`
|
|
1709
|
+
`)}class Vw{attempts=[];push(e){this.attempts.push(e)}}function Gw(t){switch(t){case"get":return["get","read"];case"list":return["list","read"];case"create":return["create","write"];case"update":return["update","write"];case"delete":return["delete","write"];default:return[t]}}function Hw(t){return t instanceof gl?{kind:"expressions",limit:hs,message:t.message,...t.position===void 0?{}:{line:t.position.line,column:t.position.column}}:{kind:"document-lookups",limit:Yi,message:t.message}}function Kw(t,e,n,s){const r=Gw(e),i=[],o=[],a=[];for(let p=0;p<t.allows.length;p++){const h=t.allows[p];h.operations.some(g=>r.includes(g))&&a.push({rule:h,index:p})}if(a.length===0)return o.push(`No allow rules found for operation '${e}'`),{decision:"DENY",trace:i,notes:o};let u=!1;const l=n.trace,d=p=>{n.expressionBudget&&(p.evaluatedExpressions=n.expressionBudget.evaluated),i.push(p)};for(const{rule:p,index:h}of a){const m=Zw(p,h,s),g=new fb;n.trace=g;try{const y=bs(_e(p.condition,n),p.condition);if(m.expressionTrace=g.entries,y)return m.verdict="ALLOW",d(m),n.trace=l,{decision:"ALLOW",trace:i,notes:o};m.verdict="DENY",d(m)}catch(y){if(m.expressionTrace=g.entries,y instanceof dn){m.verdict="ERROR",m.message=y.message,d(m),n.trace=l;const w=Hw(y),k=w.line===void 0||w.column===void 0?void 0:{line:w.line,column:w.column},O=Mv(w.message,k);return o.push(`Request denied by a rules resource limit: ${O.endsWith(".")?O:`${O}.`} The limit is per request, so no other allow rule or match block was evaluated.`),{decision:"DENY",trace:i,notes:o,resourceLimit:w}}y instanceof Jt?(u=!0,m.verdict="UNSUPPORTED",m.message=y.message):(m.verdict="ERROR",y instanceof Error?m.message=y.message:m.message=String(y)),d(m)}}n.trace=l;let f="DENY";return u&&(f="UNSUPPORTED"),{decision:f,trace:i,notes:o}}function Zw(t,e,n){const s=Se(t.condition),r={ruleIndex:e,operations:[...t.operations],verdict:"DENY",conditionText:s};if(t.loc!==void 0){const o=t.loc;if(r.line=o.line,r.col=o.col,r.column=o.col,o.file!==void 0?(r.file=o.file,r.citation=`${o.file}:${o.line}:${o.col}`):(r.file="firestore.rules",r.citation=`firestore.rules:${o.line}:${o.col}`),n!==void 0){const u=ad(n,o.line,o.col,o.file,s);u!==void 0&&(r.line=u.line,r.col=u.col,r.column=u.col,r.file=u.file,r.citation=u.citation,u.expression!==void 0&&(r.conditionText=u.expression))}}return r}function Jw(t,e,n,s,r,i,o,a=Yt){const c=new Map;for(const R of e)c.set(R.name,R);const u=new Map,l=new Set,d=new Map;for(const R of t.functionMocks??[]){const V=Fn(R.path);R.function==="get"&&typeof R.result=="object"&&R.result!==null?(u.set(V,a(R.result)),l.add(V)):R.function==="exists"&&d.set(V,R.result===!0)}const f=t.requestTime?ye.fromIsoString(t.requestTime):ye.fromMillis(Date.now()),h=["databases","(default)","documents",...Ed(t.path).split("/").filter(Boolean)],m=new st(h,n),g=a(t.data??{}),y=t.resource===void 0||t.resource===null?null:a(t.resource);let b,v;if(t.writeMode)b=jv(t.writeMode,y,g),v=b!==null;else switch(t.method){case"create":case"update":b=g,v=!0;break;case"delete":b=null,v=!1;break;case"get":case"list":default:b=y,v=y!==null;break}const w=b!==null?a(Zi(b,f)):null;let k;t.method==="create"||t.method==="update"?k={data:w??{}}:t.data!==void 0&&(k={data:a(Zi(t.data,f))});const O={auth:t.auth?{uid:t.auth.uid,token:t.auth.token??{}}:null,method:t.method,path:m,...Ac(t)?{query:Ac(t)}:{},time:f};return k!==void 0&&(O.resource=k),{request:O,resource:t.method==="create"||y===null?null:{data:a(y)},mockDocuments:u,identitylessFunctionMocks:l,existsMocks:d,getDoc:s,pathVariables:n,functions:c,database:"(default)",afterStatePath:m,afterState:w,existsAfter:v,...r?{batchProjection:r}:{},lookupBudget:i,expressionBudget:o}}function Qw(t,e){return e?Ew(t):pw(t.requestTime)}function Yw(t,e){const n=typeof t=="object"&&t!==null?t:{};return{description:typeof n.description=="string"?n.description:"",expectation:n.expectation==="ALLOW"?"ALLOW":"DENY",state:"UNSUPPORTED",decision:"UNSUPPORTED",evaluatedExpressions:0,trace:[],notes:[e]}}class Xw{simulate(e,n,s){if(!e||e.trim().length===0)return{success:!1,error:{code:"PARSE_FAILED",message:"Empty rules source — call setRules(sandbox, rules) from pyric/sandbox/firestore before operating, or initialize without rules to use the open-by-default ruleset. See pyric/sandbox docs.",recoverable:!0}};const r=zo(e);return r.ok?this.simulateParsed(r.ast,e,n,s):{success:!1,error:{code:"PARSE_FAILED",message:`Firestore ${r.rejection.message}`,recoverable:!0}}}simulateParsed(e,n,s,r){mv(e);const i=r?.sourceMap??Ko(n),o=[];let a=0,c=0,u=0;const l={database:"(default)"},d=r?.publicCases===!0,f=d?Ji:Yt;for(const p of s){const h=Qw(p,d);if(h!==void 0){u++,o.push(Yw(p,h));continue}const m=Ed(p.path),g=m.split("/").filter(Boolean),y=p.method==="list",b=g.length%2===1;let v,w=e,k=p;if(y&&!r?.skipQueryProof){const pe=g.length===0?"__listPlaceholder__":b?`${m}/__listPlaceholder__`:m,et=zw(p.query),be=Fd(e,pe,p.auth??null,et,n);if(be.kind==="no-rule")v={verdict:"NO_RULE",provable:!1,kind:"no-rule",failures:[]};else if(be.kind==="unprovable"){const We=be.failures.find(sn=>sn.kind!=="constraints-not-satisfied")??be.failures[0],ie=uo(We.residual);v={verdict:"UNPROVABLE",provable:!1,kind:We.kind,failures:be.failures,reason:We.reason,residual:We.residual,...ie?{remediation:ie}:{},...We.rule?{rule:{...We.rule,verdict:"deny"}}:{}}}else{let We=!1;if(be.failures.length>0){const ie=this.simulateParsed(be.evaluationAst,n,[{...p,path:pe,resource:be.syntheticResource,expectation:"ALLOW"}],{...r,sourceMap:i,skipQueryProof:!0});ie.success&&ie.data.results[0]?.decision!=="ALLOW"&&(We=!0)}if(We){const ie=be.failures.find(Yr=>Yr.kind!=="constraints-not-satisfied")??be.failures[0],sn=uo(ie.residual);v={verdict:"UNPROVABLE",provable:!1,kind:ie.kind,failures:be.failures,reason:ie.reason,residual:ie.residual,...sn?{remediation:sn}:{},...ie.rule?{rule:{...ie.rule,verdict:"deny"}}:{}}}else v={verdict:"PROVABLE",provable:!0,kind:"provable",failures:be.failures};p.resource===void 0&&(p.query?.where?.length??0)>0&&(w=be.evaluationAst,k={...p,resource:be.syntheticResource})}}const O=[...w.functions??[],...w.service.functions??[],...w.service.match.functions];let R=[];const V=new Vw;R.push(...ao(w,m,O,V));let G=!1;if(y&&b){const pe=[...g,"__hypothetical_doc__"],et=ao(w,pe.join("/"),O,V);et.length>0&&(R=et,G=!0)}const D={requestPath:m,attempts:V.attempts};if(R.length===0){const pe=p.expectation==="DENY"?"PASSED":"FAILED";pe==="PASSED"?a++:c++,o.push({description:p.description,expectation:p.expectation,state:pe,decision:"DENY",evaluatedExpressions:0,trace:[],notes:Ow(w,m),pathResolution:D,...v?{queryProof:v}:{}});continue}let q="DENY";const x=[],S=[];let _=!1,P,$,z=!1;const ee=new wd,ne=new Dv((pe,et)=>new gl(pe,et));for(const pe of R){const et={...l,...pe.pathVariables},be=Jw(k,pe.functions,et,r?.getDoc,r?.batchProjection,ee,ne,f),We=Qo(pe.block),ie=Kw(pe.block,p.method,be,i);for(const M of ie.trace)M.matchPath=We;if(x.push(...ie.trace),S.push(...ie.notes),ie.resourceLimit!==void 0){q="DENY",z=!0;const M=x.slice(0,-1).find(se=>se.verdict==="ERROR");ie.resourceLimit.kind==="expressions"&&M?S.push(`The request reached the limit (${ie.resourceLimit.message}) after an earlier allow rule raised an error; production reports that earlier error: ${M.message??"evaluation error"}`):$=ie.resourceLimit;break}if(ie.decision==="ALLOW"){q="ALLOW",P=We;break}ie.decision==="UNSUPPORTED"&&(_=!0)}q!=="ALLOW"&&!z&&_&&(q="UNSUPPORTED"),q==="ALLOW"&&P!==void 0&&S.push(`Allowed by match block '${P}'`),G===!0&&S.push(`list on collection path '${p.path}' evaluated against the document-level match block (document wildcard hypothetical, resource undefined) — emulator-faithful`);let Le;q==="UNSUPPORTED"?(Le="UNSUPPORTED",u++):q===p.expectation?(Le="PASSED",a++):(Le="FAILED",c++),o.push({description:p.description,expectation:p.expectation,state:Le,decision:q,evaluatedExpressions:ne.evaluated,...$?{resourceLimit:$}:{},...v?{queryProof:v}:{},trace:x,notes:S,pathResolution:D})}return{success:!0,data:{passed:a,failed:c,unsupported:u,results:o}}}}const eS=new TextEncoder;function Zs(t){try{const e=JSON.stringify(t);return typeof Buffer=="function"?Buffer.byteLength(e):eS.encode(e).byteLength}catch{return 1/0}}class tS{entries=new Set;record(e){const n=e.event;if(!(n.kind==="request"&&n.rulesEvidence!==void 0)||(this.entries.add(e),this.entries.size<=64))return;const o=this.entries.values().next().value;return o!==void 0&&this.entries.delete(o),o}forget(e){this.entries.delete(e)}clear(){this.entries.clear()}}class nS{limits;entries=[];bytes=0;liveCount=0;liveBytes=0;activeRequests=new Map;completedRequests=new Set;activeListeners=new Map;retainedIds=new Set;rulesEvidence=new tS;sourceGapCount=0;gap;constructor(e){this.limits=e}get length(){return this.snapshot().length}append(e){const n=e.kind==="operation"?e.observation:void 0,s=this.limits!==void 0,r=s?Zs(e)+1:0;if(n?.status==="pending"){if(this.completedRequests.has(n.id))return;const u=this.activeRequests.get(n.id);u&&this.releaseLive(u);const l={event:e,bytes:r};this.activeRequests.set(n.id,l),this.reserveLive(l),this.prune();return}if(n){const u=this.activeRequests.get(n.id);u&&this.releaseLive(u),this.activeRequests.delete(n.id),this.completedRequests.add(n.id)}if(this.trackListener(e,r),this.retainedIds.has(e.id))return;this.retainedIds.add(e.id);const i="listenerId"in e?this.activeListeners.get(e.listenerId):void 0;i?.event.id===e.id&&this.releaseLive(i);const a=s&&e.kind==="observation_gap"&&e.reason==="history-limit";if(a||!Number.isFinite(r))if(this.forgetId(e),a){const u=Math.max(0,e.omittedCount-this.sourceGapCount);this.sourceGapCount=Math.max(this.sourceGapCount,e.omittedCount),u&&this.omit({...e,omittedCount:u})}else this.omit(e);else{const u={event:e,bytes:r};this.entries.push(u),this.bytes+=r;const l=this.rulesEvidence.record(u);l!==void 0&&this.expireRulesEvidence(l)}this.prune()}snapshot(){const e=[...this.entries.map(r=>r.event),...[...this.activeRequests.values()].map(r=>r.event),...[...this.activeListeners.values()].map(r=>r.event).filter(r=>!this.retainedIds.has(r.id))],n=this.gap;return n!==void 0?[{...n},...e]:e}clear(){this.entries=[],this.activeRequests.clear(),this.activeListeners.clear(),this.completedRequests.clear(),this.retainedIds.clear(),this.rulesEvidence.clear(),this.bytes=0,this.liveCount=0,this.liveBytes=0,this.gap=void 0,this.sourceGapCount=0}forgetId(e){this.retainedIds.delete(e.id);const n="listenerId"in e?this.activeListeners.get(e.listenerId):void 0;n?.event.id===e.id&&this.reserveLive(n);const r=e.kind==="operation"?e.observation:void 0;r&&this.completedRequests.delete(r.id)}trackListener(e,n){if(!("listenerId"in e))return;const s=e.kind==="listener_attach"||e.kind==="listener"&&e.phase==="attach",r=e.kind==="listener_detach"||e.kind==="listener_errored"||e.kind==="listener"&&(e.phase==="detach"||e.phase==="errored");if(!(s||r))return;const o=this.activeListeners.get(e.listenerId),a=o!==void 0&&!this.retainedIds.has(o.event.id);if(a&&this.releaseLive(o),s){const c={event:e,bytes:n};this.activeListeners.set(e.listenerId,c),!this.retainedIds.has(e.id)&&this.reserveLive(c)}else this.activeListeners.delete(e.listenerId);a&&this.omit(o.event)}expireRulesEvidence(e){const n=e.event;if(n.kind!=="request")return;const{rulesEvidence:r,...i}=n;e.event={...i,rulesEvidenceExpired:!0};const a=this.limits!==void 0?Zs(e.event)+1:0;this.bytes+=a-e.bytes,e.bytes=a}reserveLive(e){this.liveCount++,this.liveBytes+=e.bytes}releaseLive(e){this.liveCount--,this.liveBytes-=e.bytes}prune(){let e=this.exceedsLimits();for(;e;){const n=this.entries.shift();if(n===void 0)break;this.forgetId(n.event),this.rulesEvidence.forget(n),this.bytes-=n.bytes,this.omit(n.event),e=this.exceedsLimits()}}exceedsLimits(){const e=this.limits;if(e===void 0)return!1;const r=this.gap===void 0?0:Zs(this.gap)+1,i=Math.min(this.liveCount,Math.floor(e.maxEvents/2)),o=Math.min(this.liveBytes,Math.floor(e.maxBytes/2)),c=this.entries.length+i>e.maxEvents,u=this.bytes+o+r+2>e.maxBytes;return c||u}omit(e){if(("listenerId"in e?this.activeListeners.get(e.listenerId):void 0)?.event.id===e.id)return;const r=e.kind==="observation_gap",i=r?e.omittedCount:1,o=r?e.firstEventId:e.id,a=r?e.lastEventId:e.id;this.gap={kind:"observation_gap",reason:"history-limit",id:"history-gap",at:this.gap?.at??e.at,firstEventId:this.gap?.firstEventId??o,lastEventId:a,omittedCount:(this.gap?.omittedCount??0)+i}}}function sS(t){return typeof t=="object"&&t!==null&&t.__type==="serverTimestamp"}const rS={name:"date-to-timestamp",convert(t){return t instanceof Date?ye.fromMillis(t.getTime()):Xe}},iS={name:"server-timestamp-sentinel",convert(t,e){return sS(t)?e.serverTime instanceof ye?e.serverTime:ye.fromMillis(Date.now()):Xe}};function oS(t){if(t===null||typeof t!="object"||t instanceof ye)return!1;const e=t;return typeof e.seconds=="number"&&typeof e.nanoseconds=="number"&&typeof e.toMillis=="function"}const aS={name:"user-timestamp-to-rules-timestamp",convert(t){if(t instanceof ye){const s=Math.floor(t.nanos/1e3)*1e3;return s===t.nanos?Xe:new ye(t.seconds,s)}if(oS(t)){const s=Math.floor(t.nanoseconds/1e3)*1e3;return new ye(t.seconds,s)}return Xe}},Jc=Symbol.for("pyric.firestore.query-value-registry"),Qc=globalThis,ks=Qc[Jc]??(Qc[Jc]=new WeakMap),Yc=Symbol.for("pyric.firestore.query-value-execution-registry"),Xc=globalThis,wr=Xc[Yc]??(Xc[Yc]=new WeakMap),eu=Symbol.for("pyric.firestore.query-value-owner-registry"),tu=globalThis,Sr=tu[eu]??(tu[eu]=new WeakMap);function jn(t,e,n=()=>t){ks.set(t,e),wr.set(t,n)}function Bd(t){return ks.get(t)}function wk(t){return Sr.get(t)}function Sk(t){return wr.get(t)?.()??t}function Ak(t,e){const n=ks.get(t),s=wr.get(t);n!==void 0&&ks.set(e,n),s!==void 0&&wr.set(e,s);const r=Sr.get(t);r!==void 0&&Sr.set(e,r)}const lo=Symbol.for("pyric.firestore.reference-query-value");class cS{path;[lo]=!0;constructor(e){this.path=e}isEqual(e){return typeof e=="object"&&e!==null&&lo in e&&e.path===this.path}}function ca(t){const e=ks.get(t);if(typeof e!="object"||e===null||!(lo in e))return;const n=e.path;return typeof n=="string"?n:void 0}function uS(t,e,n,s=t){jn(t,new cS(e),()=>s),n!==void 0&&Sr.set(t,n)}function nu(t){return typeof t=="object"&&t!==null&&"isEqual"in t&&typeof t.isEqual=="function"}function fo(t){if(typeof t!="object"||t===null||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function lS(t){const e=Bd(t);if(e?.type==="timestamp"&&typeof e.seconds=="number"&&typeof e.nanoseconds=="number")return{kind:"timestamp",seconds:e.seconds,nanoseconds:e.nanoseconds}}function Es(t){if(typeof t!="object"||t===null)return;if(fo(t))return lS(t);if(t instanceof Uint8Array)return{kind:"bytes",values:Array.from(t)};const e=t;if(typeof e.seconds=="number"){const n=typeof e.nanoseconds=="number"?e.nanoseconds:e.nanos;if(typeof n=="number")return{kind:"timestamp",seconds:e.seconds,nanoseconds:n}}if(e.data instanceof Uint8Array)return{kind:"bytes",values:Array.from(e.data)};if(typeof e.toUint8Array=="function")return{kind:"bytes",values:Array.from(e.toUint8Array())};if(typeof e.latitude=="number"&&typeof e.longitude=="number")return{kind:"geo-point",latitude:e.latitude,longitude:e.longitude};if(typeof e.lat=="number"&&typeof e.lng=="number")return{kind:"geo-point",latitude:e.lat,longitude:e.lng};if(typeof e.path=="string")return{kind:"reference",path:e.path};if(e.typeName==="vector"&&Array.isArray(e.value))return{kind:"vector",values:e.value};if(typeof e.toArray=="function")return{kind:"vector",values:e.toArray()}}function Gt(t,e){if(Object.is(t,e))return!0;const n=Es(t),s=Es(e);if(n!==void 0||s!==void 0){if(n===void 0||s===void 0||n.kind!==s.kind)return!1;switch(n.kind){case"timestamp":return s.kind==="timestamp"&&n.seconds===s.seconds&&n.nanoseconds===s.nanoseconds;case"bytes":return s.kind==="bytes"&&n.values.length===s.values.length&&n.values.every((o,a)=>o===s.values[a]);case"vector":return s.kind==="vector"&&n.values.length===s.values.length&&n.values.every((o,a)=>o===s.values[a]);case"geo-point":return s.kind==="geo-point"&&n.latitude===s.latitude&&n.longitude===s.longitude;case"reference":return s.kind==="reference"&&n.path===s.path}}if(nu(t))return t.isEqual(e);if(nu(e))return e.isEqual(t);if(Array.isArray(t)||Array.isArray(e))return!Array.isArray(t)||!Array.isArray(e)||t.length!==e.length?!1:t.every((o,a)=>Gt(o,e[a]));if(!fo(t)||!fo(e))return!1;const r=Object.keys(t),i=Object.keys(e);return r.length!==i.length?!1:r.every(o=>o in e&&Gt(t[o],e[o]))}function dS(t){return typeof t=="object"&&t!==null&&t.__type==="increment"&&typeof t.value=="number"}function fS(t){return typeof t=="object"&&t!==null&&t.__type==="arrayUnion"&&Array.isArray(t.values)}function hS(t){return typeof t=="object"&&t!==null&&t.__type==="arrayRemove"&&Array.isArray(t.values)}function pS(t){return typeof t=="object"&&t!==null&&t.__type==="deleteField"}function ua(t){if(t.prior===null)return;let e=t.prior;for(const n of t.fieldSegments){if(typeof n=="number"){if(!Array.isArray(e))return;e=e[n];continue}if(typeof e!="object"||e===null||Array.isArray(e)||!Object.hasOwn(e,n))return;e=e[n]}return e}const mS={name:"increment-sentinel",convert(t,e){if(!dS(t))return Xe;const n=ua(e);return(typeof n=="number"?n:0)+t.value}},gS={name:"array-union-sentinel",convert(t,e){if(!fS(t))return Xe;const n=ua(e),s=Array.isArray(n)?n.slice():[];for(const r of t.values)s.some(o=>Gt(o,r))||s.push(r);return s}},yS={name:"array-remove-sentinel",convert(t,e){if(!hS(t))return Xe;const n=ua(e);return Array.isArray(n)?n.filter(s=>!t.values.some(r=>Gt(s,r))):[]}},bS={name:"delete-field-sentinel",convert(t){return pS(t)?bt:Xe}};function vS(t){if(t===null||typeof t!="object"||t instanceof wt)return!1;const e=t;return typeof e.path=="string"&&typeof e.id=="string"&&e._path!==void 0&&e._firestore!==void 0}const wS={name:"document-reference",convert(t){if(typeof t=="object"&&t!==null){const e=ca(t);if(e!==void 0)return new wt(e)}return vS(t)?new wt(t.path):Xe}};function SS(t){return Array.isArray(t)&&t.every(e=>typeof e=="number")}function AS(t){if(t===null||typeof t!="object"||t instanceof Qt)return null;const e=t;return SS(e._values)&&typeof e.toArray=="function"?e._values:null}const kS={name:"vector-value",convert(t){const e=AS(t);return e===null?Xe:new Qt(e)}};function ES(t){if(t===null||typeof t!="object"||t instanceof He)return!1;const e=t;return typeof e.toBase64=="function"&&typeof e.toUint8Array=="function"&&typeof e.isEqual=="function"}function IS(t){if(t===null||typeof t!="object"||t instanceof lt)return!1;const e=t;return typeof e.latitude=="number"&&typeof e.longitude=="number"&&typeof e.isEqual=="function"}const _S={name:"fb-bytes-to-rules-bytes",convert(t){return ES(t)?new He(t.toUint8Array()):Xe}},xS={name:"fb-geopoint-to-rules-latlng",convert(t){return IS(t)?new lt(t.latitude,t.longitude):Xe}};function it(t){if(t===null||typeof t!="object")return!1;const n=Object.getPrototypeOf(t);return n===Object.prototype||n===null}class At extends Error{code;customData;name="FirebaseError";constructor(e,n,s){super(n),this.code=e,this.customData=s,Object.setPrototypeOf(this,new.target.prototype)}}Object.defineProperty(At,"name",{value:"FirebaseError"});function CS(t){return t.length===0||/[.`\\]/.test(t)}function zd(t){return t.map(e=>CS(e)?`\`${e.replace(/\\/g,"\\\\").replace(/`/g,"\\`")}\``:e).join(".")}function Vr(t){if(!t.includes("`"))return t.split(".");const e=[];let n="",s=!1;for(let r=0;r<t.length;r++){const i=t[r];if(s){i==="\\"&&r+1<t.length?n+=t[++r]:i==="`"?s=!1:n+=i;continue}i==="`"?s=!0:i==="."?(e.push(n),n=""):n+=i}return e.push(n),e}function kk(t){const e={};for(const n of t)e[zd(n.path)]=n.value;return e}function su(t,e,n){Object.defineProperty(t,e,{value:n,enumerable:!0,writable:!0,configurable:!0})}function OS(t){const e={};for(const[n,s]of Object.entries(t)){const r=Vr(n);let i=e;for(const o of r.slice(0,-1)){const a=Object.hasOwn(i,o)?i[o]:void 0;it(a)||su(i,o,{}),i=i[o]}su(i,r[r.length-1],s)}return e}function TS(t){return Object.keys(t).map(Vr)}function RS(t){return t.method==="update"&&(t.merge===void 0||t.merge===!1)}function is(t,e){return RS(t)?{resourceData:OS(e),updateMask:TS(e)}:{resourceData:e}}function la(t){if(typeof t!="object"||t===null)return;const n=t._internalPath?.segments;if(Array.isArray(n)&&n.every(r=>typeof r=="string"))return[...n]}function Wd(t){return typeof t=="string"||la(t)!==void 0}const NS=/[~*/[\]]/,LS=/^[_a-zA-Z][_a-zA-Z0-9]*$/;function Vd(t){return t.map(e=>{const n=e.replace(/\\/g,"\\\\").replace(/`/g,"\\`");return LS.test(n)?n:`\`${n}\``}).join(".")}function Ar(t,e,n,s){if(n===void 0){const r=s!==void 0&&s.length>0?` in field ${Vd(s)}`:"";throw new At("invalid-argument",`Function ${t}() called with invalid data. Unsupported field value: undefined (found${r} in document ${e})`)}if(Array.isArray(n)){for(const r of n)Ar(t,e,r,void 0);return}if(it(n))for(const[r,i]of Object.entries(n))Ar(t,e,i,s===void 0?void 0:[...s,r])}function kr(t,e,n){const s=n===void 0?"":` (found in document ${n})`;return new At("invalid-argument",`Function ${t}() called with invalid data. ${e}${s}`)}function Gd(t,e,n){if(NS.test(e))throw kr(t,`Invalid field path (${e}). Paths must not contain '~', '*', '/', '[', or ']'`,n);const s=e.split(".");if(s.some(r=>r.length===0))throw kr(t,`Invalid field path (${e}). Paths must not be empty, begin with '.', end with '.', or contain '..'`,n);return s}function ru(t,e,n){const s=la(e);if(s!==void 0)return s;if(typeof e=="string")return Gd(t,e);throw kr(t,"Field path arguments must be of type string or ",n)}function Ek(t,e,n,s){if(!Wd(n)){if(!it(n))throw kr(t,"Data must be an object, but it was: "+MS(n),e);return Object.entries(n).map(([c,u])=>{const l=Gd(t,c,e);return Ar(t,e,u,l),{path:l,value:u}})}const[r,...i]=s,o=[{path:ru(t,n,e),value:r}];if(i.length%2!==0)throw new At("invalid-argument",`Function ${t}() needs to be called with an even number of arguments that alternate between field names and values.`);for(let c=0;c<i.length;c+=2)o.push({path:ru(t,i[c]),value:i[c+1]});const a=[];for(let c=o.length-1;c>=0;c--){const u=zd(o[c].path);a.includes(u)||(a.push(u),Ar(t,e,o[c].value,o[c].path))}return o}function MS(t){return t===void 0?"undefined":t===null?"null":typeof t=="string"?`"${t.length>20?`${t.substring(0,20)}...`:t}"`:typeof t=="object"?Array.isArray(t)?"an array":"a custom object":typeof t=="function"?"a function":String(t)}const Xe=Symbol("value-resolver:KEEP"),bt=Symbol("value-resolver:DELETE_MARKER"),ho=[];function ot(t){ho.some(e=>e.name===t.name)||ho.push(t)}function ht(t,e){const n={},s=e.method==="update";for(const[r,i]of Object.entries(t)){const o=s?Vr(r):[r];n[r]=po(i,{...e,fieldPath:r,fieldSegments:o})}return n}function po(t,e){for(const n of ho){const s=n.convert(t,e);if(s!==Xe)return s}if(Array.isArray(t))return t.map((n,s)=>po(n,{...e,fieldPath:`${e.fieldPath}[${s}]`,fieldSegments:[...e.fieldSegments,s]}));if(it(t)){const n={};for(const[s,r]of Object.entries(t)){const i=e.fieldPath?`${e.fieldPath}.${s}`:s;n[s]=po(r,{...e,fieldPath:i,fieldSegments:[...e.fieldSegments,s]})}return n}return t}function un(t){const e={},n=[];for(const[s,r]of Object.entries(t)){if(r===bt){n.push(s);continue}e[s]=Er(r)}return{writes:e,deletedKeys:n}}function Er(t){if(t!==bt){if(Array.isArray(t))return t.filter(e=>e!==bt).map(Er);if(it(t)){const e={};for(const[n,s]of Object.entries(t))s!==bt&&(e[n]=Er(s));return e}return t}}function DS(){ot(rS),ot(iS),ot(aS),ot(mS),ot(gS),ot(yS),ot(bS),ot(wS),ot(kS),ot(_S),ot(xS)}const iu=Symbol.for("pyric.firestore.activity-value-registry"),ou=globalThis,Hd=ou[iu]??(ou[iu]=new WeakMap);function Kd(){let t=2166136261,e=2654435769,n=2246822507,s=3266489909;const r=i=>{t=Math.imul(t^i,16777619),e=Math.imul(e^i,2246822507),n=Math.imul(n^i,3266489909),s=Math.imul(s^i,668265263)};return{update:i=>{if(typeof i=="string")for(let o=0;o<i.length;o+=1){const a=i.charCodeAt(o);r(a&255),r(a>>>8)}else for(const o of i)r(o)},finish:()=>[t,e,n,s].map(i=>(i>>>0).toString(16).padStart(8,"0")).join("")}}function da(...t){const e=Kd();for(const n of t)e.update(n);return e.finish()}function $S(t){return{type:"string-digest",length:t.length,digest:da("string\0",t)}}function Ir(t,...e){return{type:`${t}-digest`,digest:da(`${t}\0`,...e)}}function PS(t){return{type:"bytes-digest",length:t.byteLength,digest:da("bytes\0",t)}}function au(t){const e=Kd(),n=(...r)=>{for(const i of r)e.update(i)},s=r=>{if(r===null){n("null;");return}switch(typeof r){case"string":n(`s${r.length}:`,r,";");return;case"number":n(`n${Object.is(r,-0)?"-0":String(r)};`);return;case"boolean":n(r?"b1;":"b0;");return;case"undefined":n("u;");return;case"bigint":n(`i${r.toString()};`);return;case"object":break;default:n(`x${typeof r};`);return}if(Array.isArray(r)){n(`a${r.length}[`);for(const a of r)s(a);n("];");return}const i=r,o=Object.keys(i).sort();n(`o${o.length}{`);for(const a of o)n(`k${a.length}:`,a,"="),s(i[a]);n("};")};return s(t),{type:"wire-value-digest",digest:e.finish()}}function Is(t,e){Hd.set(t,e)}function FS(t){return Hd.get(t)}const cu=-62135596800,jS=253402300800;class mt{seconds;nanoseconds;constructor(e,n){if(this.seconds=e,this.nanoseconds=n,n<0||n>=1e9)throw new At("invalid-argument",`Timestamp nanoseconds out of range: ${n}`);if(e<cu||e>=jS)throw new At("invalid-argument",`Timestamp seconds out of range: ${e}`);Is(this,Ir("timestamp",String(e),"\0",String(n))),jn(this,Object.freeze({type:"timestamp",seconds:e,nanoseconds:n}),()=>new mt(e,n))}static now(){return mt.fromMillis(Date.now())}static fromDate(e){return mt.fromMillis(e.getTime())}static fromMillis(e){const n=Math.floor(e/1e3),s=Math.floor((e-n*1e3)*1e6);return new mt(n,s)}toDate(){return new Date(this.toMillis())}toMillis(){return this.seconds*1e3+this.nanoseconds/1e6}isEqual(e){return e.seconds===this.seconds&&e.nanoseconds===this.nanoseconds}toString(){return`Timestamp(seconds=${this.seconds}, nanoseconds=${this.nanoseconds})`}toJSON(){return{type:"firestore/timestamp/1.0",seconds:this.seconds,nanoseconds:this.nanoseconds}}valueOf(){const e=this.seconds-cu,n=String(e).padStart(12,"0"),s=String(this.nanoseconds).padStart(9,"0");return`${n}.${s}`}}function _s(t){const e={};for(const[n,s]of Object.entries(t))e[n]=Zd(s);return e}function Zd(t){return t instanceof Date?mt.fromDate(t).toDate():Array.isArray(t)?t.map(Zd):it(t)?ca(t)!==void 0?t:_s(t):t}function qS(t){return t.split(".")}const US=new Set(["__proto__","prototype","constructor"]);function uu(t){if(US.has(t))throw new Error(`Invalid field-path segment '${t}': the keys __proto__, prototype, and constructor are reserved and cannot appear in a field path.`)}function Jd(t,e,n){let s=t;for(let i=0;i<e.length-1;i++){const o=e[i];uu(o);const a=Object.hasOwn(s,o)?s[o]:void 0;it(a)||(s[o]={}),s=s[o]}const r=e[e.length-1];uu(r),n===bt?delete s[r]:s[r]=Er(n)}function Gr(t,e){const n=_s(t);for(const[s,r]of Object.entries(e)){if(r!==bt&&_r(r))throw new Qd;Jd(n,Vr(s),r)}return n}class Qd extends Error{constructor(){super("FieldValue.delete() can only appear at the top level of your update data"),this.name="DeleteFieldNestedError"}}function _r(t){return t===bt?!0:Array.isArray(t)?t.some(_r):it(t)?Object.values(t).some(_r):!1}function BS(t){for(const e of Object.values(t))if(e!==bt&&_r(e))throw new Qd}function Hr(t,e,n){const s=_s(t),r=[];if(n!==void 0)for(const o of n){const a=qS(o),c=zS(e,a);if(c===Yd)throw new At("invalid-argument",`Field '${o}' is specified in your field mask but missing from your input data.`);r.push({segments:a,value:c})}else Xd(e,[],r);for(const{segments:o,value:a}of r)Jd(s,o,a);return s}const Yd=Symbol("field-merge:ABSENT");function zS(t,e){let n=t;for(const s of e){if(!it(n)||!Object.hasOwn(n,s))return Yd;n=n[s]}return n}function Xd(t,e,n){const s=Object.keys(t);if(s.length===0&&e.length>0){n.push({segments:e,value:{}});return}for(const r of s){const i=t[r],o=[...e,r];it(i)&&i!==bt?Xd(i,o,n):n.push({segments:o,value:i})}}function WS(t,e,n){const s=[],r=new Map;for(const[a,c]of e.entries()){const u=r.get(c.path)??t.has(c.path);switch(c.method){case"create":u&&s.push({index:a,error:`Document '${c.path}' already exists`}),r.set(c.path,!0);break;case"update":{!u&&s.push({index:a,error:`Document '${c.path}' does not exist`});break}case"delete":r.set(c.path,!1);break;case"set":r.set(c.path,!0);break}}if(s.length>0)return{success:!1,errors:s};const o=new Map;for(const a of e)if(!o.has(a.path)){const u=t.has(a.path);let l=null;u&&(l={...t.get(a.path)}),o.set(a.path,l)}for(const a of e){switch(a.method){case"create":{const c=ht({...a.data},{path:a.path,method:"create",prior:null}),{writes:u}=un(c);t.set(a.path,u);break}case"update":{const c=t.get(a.path);if(c===void 0)throw new Error(`Validated document '${a.path}' disappeared during atomic application`);const l=ht({...a.data},{path:a.path,method:"update",prior:c});t.set(a.path,Gr(c,l));break}case"set":{const c=o.get(a.path)??null,u=ht({...a.data},{path:a.path,method:"set",prior:c}),{writes:l}=un(u);t.set(a.path,l);break}case"delete":t.delete(a.path);break}n(a.path)}return{success:!0,priorStates:o}}function VS(t,e){if(e===void 0)throw new TypeError("Projection fields are not iterable");const s={};for(const r of e)Object.prototype.hasOwnProperty.call(t,r)&&(s[r]=t[r]);return s}class bi{onChange;documents;versions=new Map;nextVersion=1;constructor(e={},n,s){this.onChange=s,this.documents=n??new Map;for(const[r,i]of Object.entries(e)){const o=ht({...i},{path:r,method:"seed",prior:null}),{writes:a}=un(o);this.documents.set(r,a),this.bumpVersion(r)}}get(e){return this.documents.get(e)??null}version(e){return this.versions.get(e)??0}currentVersion(){return this.nextVersion-1}exists(e){return this.documents.has(e)}scan(e,n={}){const r=e===""||e.endsWith("/")?e:e+"/",i=!!n.projection;let o=d=>d;i&&(o=d=>VS(d,n.projection));const a=[],c=new Set,u=[];for(const[d,f]of this.documents){if(r!==""&&!d.startsWith(r))continue;if(!n.directOnly){a.push({path:d,data:o(f)});continue}const m=d.slice(r.length),g=m.indexOf("/");if(g===-1){a.push({path:d,data:o(f)}),c.add(m);continue}if(!!n.phantoms){const v=m.slice(0,g);v.length>0&&!u.includes(v)&&u.push(v)}}if(!!(n.directOnly&&n.phantoms))for(const d of u)c.has(d)||a.push({path:r+d,data:{},phantom:!0});return a}list(e){return this.scan(e,{directOnly:!0,phantoms:!0})}listRootCollections(){const e=new Set,n=[];for(const s of this.documents.keys()){const r=s.split("/",1)[0]??"";if(r.length===0)continue;!e.has(r)&&(e.add(r),n.push(r))}return n}listSubcollections(e){const s=e.endsWith("/")?e:e+"/",r=new Set,i=[];for(const o of this.documents.keys()){if(!o.startsWith(s))continue;const u=o.slice(s.length).split("/",1)[0]??"";if(u.length===0)continue;!r.has(u)&&(r.add(u),i.push(u))}return i}snapshot(){const e={};for(const[n,s]of this.documents)e[n]={...s};return e}size(){return this.documents.size}create(e,n){if(this.documents.has(e))return{success:!1,error:`Document '${e}' already exists`};let r;try{const i=ht({...n},{path:e,method:"create",prior:null});r=un(i).writes}catch(i){return{success:!1,error:i.message}}return this.documents.set(e,r),this.bumpVersion(e),{success:!0}}update(e,n){const s=this.documents.get(e);if(!s)return{success:!1,error:`Document '${e}' does not exist`};let i;try{const o=ht({...n},{path:e,method:"update",prior:s});i=Gr(s,o)}catch(o){return{success:!1,error:o.message}}return this.documents.set(e,i),this.bumpVersion(e),{success:!0,priorData:{...s}}}setMerge(e,n,s){const r=this.documents.has(e);let i=null;r&&(i={...this.documents.get(e)});const o=ht({...n},{path:e,method:"set",prior:i}),a=Hr(i??{},o,s);return this.documents.set(e,a),this.bumpVersion(e),{success:!0,priorData:i,created:i===null}}set(e,n){const s=this.documents.has(e);let r=null;s&&(r={...this.documents.get(e)});const i=ht({...n},{path:e,method:"set",prior:r}),{writes:o}=un(i);return this.documents.set(e,o),this.bumpVersion(e),{success:!0,priorData:r,created:r===null}}delete(e){const n=this.documents.get(e);return n?(this.documents.delete(e),this.bumpVersion(e),{success:!0,priorData:{...n}}):{success:!1,error:`Document '${e}' does not exist`}}applyBatch(e){return WS(this.documents,e,n=>this.bumpVersion(n))}restore(e){const n=new Set([...this.documents.keys(),...Object.keys(e)]);this.documents.clear();for(const[s,r]of Object.entries(e))this.documents.set(s,{...r});for(const s of n)this.bumpVersion(s)}restorePaths(e){for(const[n,s]of Object.entries(e))s===null?this.documents.delete(n):this.documents.set(n,{...s}),this.bumpVersion(n)}bumpVersion(e){this.versions.set(e,this.nextVersion++),this.onChange?.(e)}}class GS{base;overlay=new Map;tombstones=new Set;baseCache=new Map;cleared=!1;constructor(e){this.base=e}inBase(e){return Object.prototype.hasOwnProperty.call(this.base,e)}baseDoc(e){let n=this.baseCache.get(e);return n===void 0&&(n=structuredClone(this.base[e]),this.baseCache.set(e,n)),n}get(e){if(this.overlay.has(e))return this.overlay.get(e);if(!(this.cleared||this.tombstones.has(e)))return this.inBase(e)?this.baseDoc(e):void 0}set(e,n){this.overlay.set(e,n),this.tombstones.delete(e)}has(e){return this.overlay.has(e)?!0:this.cleared||this.tombstones.has(e)?!1:this.inBase(e)}delete(e){const n=this.has(e);return this.overlay.delete(e),!this.cleared&&this.inBase(e)&&this.tombstones.add(e),n}clear(){this.overlay.clear(),this.tombstones.clear(),this.baseCache.clear(),this.cleared=!0}get size(){let e=0;for(const n of this)e++;return e}*keys(){for(const[e]of this)yield e}*[Symbol.iterator](){const e=new Set;if(!this.cleared)for(const n of Object.keys(this.base))this.tombstones.has(n)||(e.add(n),yield[n,this.overlay.has(n)?this.overlay.get(n):this.baseDoc(n)]);for(const[n,s]of this.overlay)e.has(n)||(yield[n,s])}}const HS={maxEvents:1e4,maxBytes:8*1024*1024};class ut extends Error{code;denialContext;remediation;constructor(e,n,s){const r=typeof e=="object",i=r?e.code:e,o=r?e.message:n,a=r?e.denialContext:s,c=r?e.remediation:void 0,u=c!==void 0?`${o}
|
|
1710
|
+
|
|
1711
|
+
Remediation:
|
|
1712
|
+
${c}`:o;super(u),this.name="SandboxError",this.code=i,a!==void 0&&(this.denialContext=a),c!==void 0&&(this.remediation=c)}}const ef=Symbol.for("pyric.sandbox.clock");function lu(t){const e=t[ef];if(e===void 0)throw new ut("invalid-argument","Sandbox handle was not produced by initializeSandbox(); custom Sandbox implementations are not supported.");return e}function tf(){return{mode:"wall",fixedAt:0,offsetMs:0}}function du(t,e){if(!Number.isFinite(t))throw new RangeError(`${e} must be a finite number of milliseconds; received ${String(t)}.`)}function fu(t){return t.mode!=="fixed"}function Js(t){return t.mode==="offset"?t.offsetMs:0}class KS{current=tf();floor=Number.NEGATIVE_INFINITY;get state(){return{...this.current}}adopt(e){this.current={...e},this.floor=Number.NEGATIVE_INFINITY}shift(e,n){this.current={...e},this.floor+=n}follow(e){if(fu(this.current)&&fu(e)){this.shift(e,Js(e)-Js(this.current));return}this.adopt(e)}now(){return this.current.mode==="fixed"?this.current.fixedAt:(this.floor=Math.max(this.floor,Date.now()+Js(this.current)),this.floor)}}class Pt{reading=new KS;listeners=new Set;onChange(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}move(e){this.reading.adopt(e),this.announce()}announce(){const e=this.capture();for(const n of[...this.listeners])n(e)}get mode(){return this.reading.state.mode}now(){return this.reading.now()}date(){return new Date(this.now())}set(e){du(e,"A clock instant"),this.move({mode:"fixed",fixedAt:e,offsetMs:0})}advance(e){du(e,"A clock advance");const n=this.reading.state;if(n.mode==="fixed"){this.move({...n,fixedAt:n.fixedAt+e});return}this.reading.shift({mode:"offset",fixedAt:0,offsetMs:Js(n)+e},e),this.announce()}reset(){this.move(tf())}capture(){return this.reading.state}restore(e){this.move(e)}}class ZS{clock;limits;events=[];nextId=1;undoneEvents=[];eventBytes=new Map;retainedBytes=0;omittedCount=0;constructor(e=new Pt,n=HS){this.clock=e,this.limits=n}append(e,n=!1){const s={...e,id:this.nextId++,timestamp:new Date(this.clock.now()).toISOString()};if(!n){for(const i of this.undoneEvents)this.release(i);this.undoneEvents=[]}this.events.push(s);const r=Zs(s)+1;return this.eventBytes.set(s.id,r),this.retainedBytes+=r,this.prune(),s}getEvents(){return[...this.events]}getWriteEvents(){return this.events.filter(e=>e.allowed&&e.method!=="get"&&e.method!=="list")}lastWriteEvent(){const e=this.getWriteEvents();return e.length>0?e[e.length-1]:null}popLastWrite(){for(let e=this.events.length-1;e>=0;e--){const n=this.events[e];if(!n.aborted&&n.allowed&&n.method!=="get"&&n.method!=="list")return this.events.splice(e,1),this.undoneEvents.push(n),n}return null}popLastUndo(){const e=this.undoneEvents.pop();return e?(this.release(e),e):null}getRetention(){return{retainedEvents:this.eventBytes.size,retainedBytes:this.retainedBytes,omittedCount:this.omittedCount}}release(e){this.retainedBytes-=this.eventBytes.get(e.id)??0,this.eventBytes.delete(e.id),this.eventBytes.size===0&&(this.retainedBytes=0)}prune(){const e=()=>this.eventBytes.size>this.limits.maxEvents||this.retainedBytes>this.limits.maxBytes;for(;e();){const n=this.eventBytes.keys().next().value,s=this.events[0]?.id!==n,r=s?this.undoneEvents:this.events,i=s?r.findIndex(a=>a.id===n):0,[o]=r.splice(i,1);if(!o)break;this.release(o),this.omittedCount++}}size(){return this.events.length}clear(){this.events=[],this.undoneEvents=[],this.nextId=1,this.eventBytes.clear(),this.retainedBytes=0,this.omittedCount=0}}function JS(t){return new Date(t.toMillis()).toISOString()}class qn extends Error{method;path;debugMessages;constructor(e,n,s,r){super(e),this.method=n,this.path=s,this.debugMessages=r,this.name="SimulatorUnsupportedError"}}function Un(t,e,n){const s=n.filter(i=>i.includes("unsupported:")).map(i=>i.replace(/^.*unsupported:\s*/,"")).join("; "),r=s?` Reason(s): ${s}.`:"";return`Simulator cannot decide ${t} on ${e} — the rule uses a feature the local simulator does not yet implement.${r} Verify this rule against production using TestFirestoreRulesHandler, or file a sim-gap entry in REBUILD_PLAN.md.`}function QS(t=""){return{description:t,expectation:"ALLOW",state:"PASSED",decision:"ALLOW",trace:[],notes:["admin lens — rules bypassed (Studio Gap #2)"]}}const YS=`rules_version = '2';
|
|
1713
|
+
service cloud.firestore {
|
|
1714
|
+
match /databases/{database}/documents {
|
|
1715
|
+
match /{document=**} {
|
|
1716
|
+
allow read, write: if true;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
`;class rn{swallowAsyncRejections;subscribers=new Set;constructor(e=!1){this.swallowAsyncRejections=e}get hasSubscribers(){return this.subscribers.size>0}subscribe(e){return this.subscribers.add(e),()=>{this.subscribers.delete(e)}}emit(...e){for(const n of this.subscribers)try{const s=n(...e);this.swallowAsyncRejections&&s&&typeof s.then=="function"&&s.catch(()=>{})}catch{}}clear(){this.subscribers.clear()}}class XS{denial=new rn;request=new rn(!0);write=new rn(!0);delivery=new rn;suppressed=new rn;lifecycle=new rn;snapshotError=new rn;clear(){this.denial.clear(),this.request.clear(),this.write.clear(),this.delivery.clear(),this.suppressed.clear(),this.lifecycle.clear(),this.snapshotError.clear()}}class e0{currentTrigger;run(e,n){const s=this.currentTrigger;this.currentTrigger=e;try{return n()}finally{this.currentTrigger=s}}current(){return this.currentTrigger}}class xs extends Error{code;simError;constructor(e){super(e.message),this.name="FirestoreError",this.code=e.code,this.simError=e}}function mo(t){return t instanceof ye?new mt(t.seconds,t.nanos):t instanceof wt?(uS(t,t.path),t):t instanceof He||t instanceof lt||t instanceof Qt?t:Array.isArray(t)?t.map(mo):t!==null&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([o,a])=>[o,mo(a)])):t}function nf(t){return mo(t)}function t0(t){return(e,n)=>{for(const s of t)e.call(n,s)}}const n0=/[*~/[\]]/;class go{_internalPath;constructor(...e){if(Array.isArray(e[0]))throw new Error("The FieldPath constructor no longer supports an array as its first argument. Please unpack your array and call FieldPath() with individual arguments.");if(e.length===0)throw new Error('Function "FieldPath()" requires at least 1 argument.');e.forEach((n,s)=>{if(typeof n!="string")throw new Error(`Element at index ${s} is not a valid string.`);if(n.length===0)throw new Error(`Element at index ${s} should not be an empty string.`)}),this._internalPath={segments:[...e],offset:0,len:e.length}}static DOCUMENT_ID=new go("__name__");static documentId(){return go.DOCUMENT_ID}isEqual(e){const n=sf(e),s=this._internalPath.segments;return s.length===n.length&&s.every((r,i)=>r===n[i])}toString(){return Vd(this._internalPath.segments)}}function yo(t,e){const n=la(e);if(n!==void 0)return n;const r=`${typeof t=="string"?`Value for argument "${t}"`:`Element at index ${t}`} is not a valid field path.`;if(e===void 0)throw new Error(`${r} The path cannot be omitted.`);if(typeof e!="string")throw new Error(`${r} Paths can only be specified as strings or via a FieldPath object.`);if(e.includes(".."))throw new Error(`${r} Paths must not contain ".." in them.`);if(e.startsWith(".")||e.endsWith("."))throw new Error(`${r} Paths must not start or end with ".".`);if(e.length===0||n0.test(e))throw new Error(`${r} Paths can't be empty and must not contain
|
|
1721
|
+
"*~/[]".`);return e.split(".")}function sf(t){return yo("field",t)}function s0(t){if(typeof t!="object"||t===null||Array.isArray(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}const hu="Update() requires either a single JavaScript object or an alternating list of field/value pairs that can be followed by an optional precondition.";function Ik(t,e){const n=[];let s;if(Wd(t)){const r=[t,...e];try{for(let i=0;i<r.length;i+=2)if(i===r.length-1){const a=r[i];if(typeof a!="object"||a===null)throw new Error("Input is not an object.");s=a}else n.push({path:yo(i+1,r[i]),value:r[i+1]})}catch(i){throw new Error(`${hu} ${i.message}`)}}else{try{if(!(typeof t=="object"&&t!==null&&!Array.isArray(t)))throw new Error('Value for argument "dataOrField" is not a valid Firestore document. Input is not a plain JavaScript object.');for(const[i,o]of Object.entries(t))n.push({path:yo(i,i),value:o})}catch(r){throw new Error(`${hu} ${r.message}`)}s=e[0]}return{fields:n,options:s}}function rf(t,e){const n=sf(e);let s=t;for(const r of n){if(!s0(s))return;s=Object.prototype.hasOwnProperty.call(s,r)?s[r]:void 0}return s}function Bs(t){return t.collectionGroup?{kind:"collection-group",collectionId:t.collection}:{kind:"collection",path:t.collection}}const Cs=Object.freeze({hasPendingWrites:!1,fromCache:!1}),pu=Object.freeze({hasPendingWrites:!0,fromCache:!1});function of(t){const e=t.lastIndexOf("/");return e===-1?t:t.slice(e+1)}function Kn(t,e,n=Cs){const s={id:of(t),path:t},r=e!==null,i=r?nf(e):void 0;return{id:s.id,ref:s,metadata:n,exists:()=>r,data:()=>i,get:o=>rf(i,o)}}function mu(t,e,n=Cs){const s={id:of(t),path:t},r=nf(e);return{id:s.id,ref:s,metadata:n,exists:()=>!0,data:()=>r,get:i=>rf(r,i)}}function Zn(t,e,n,s,r=Cs){const i=e.map(a=>mu(a.path,a.data,r)),o=o0(s,e,i,(a,c)=>JSON.stringify(a.data)===JSON.stringify(c.data),a=>mu(a.path,a.data,r));return{query:t,metadata:r,size:i.length,empty:i.length===0,docs:i,forEach:t0(i),docChanges:i0(o,n.excludesMetadataChanges)}}const r0="To include metadata changes with your document changes, you must also pass { includeMetadataChanges: true } to onSnapshot().";function i0(t,e){let n=null,s=null;return r=>{const i=r?.includeMetadataChanges===!0;if(i&&e)throw new Error(r0);return i?(s??=t.slice(),s):(n??=t.slice(),n)}}function o0(t,e,n,s,r){if(t===void 0)return n.map((c,u)=>({type:"added",doc:c,oldIndex:-1,newIndex:u}));const i=new Map;t.forEach((c,u)=>i.set(c.path,u));const o=new Set(e.map(c=>c.path)),a=[];for(let c=0;c<t.length;c++){const u=t[c];o.has(u.path)||a.push({type:"removed",doc:r(u),oldIndex:c,newIndex:-1})}for(let c=0;c<e.length;c++){const u=e[c],l=i.get(u.path);l===void 0?a.push({type:"added",doc:n[c],oldIndex:-1,newIndex:c}):s(t[l],u)||a.push({type:"modified",doc:n[c],oldIndex:l,newIndex:c})}return a}function gu(t,e){return t===null&&e===null?!0:t===null||e===null?!1:JSON.stringify(t)===JSON.stringify(e)}function yu(t,e){for(const n of t){if(e.kind==="collection-group"){const i=n.split("/");if(i.length%2===0&&i[i.length-2]===e.collectionId)return!0;continue}const s=`${e.path}/`;if(!n.startsWith(s))continue;const r=n.slice(s.length);if(r.length>0&&!r.includes("/"))return!0}return!1}let vi=0;function cs(){return vi=vi+1>>>0,`req-${vi.toString(36)}-${Math.random().toString(36).slice(2,7)}`}function a0(t,e){const n=e==="allow";let s;for(const r of t){const i=/^Rule #(\d+) \(([^)]+)\) → (ALLOW|deny|unsupported)/.exec(r);if(!i)continue;const o={ruleIndex:Number(i[1]),operations:i[2].split(",").map(a=>a.trim())};if(n&&i[3]==="ALLOW")return o;s=o}return s}function Kr(t){const e={kind:"request",id:cs(),at:t.at,evalMs:t.evalMs,method:t.method,path:t.path,auth:t.auth?{uid:t.auth.uid,...t.auth.token?{token:t.auth.token}:{}}:null,result:t.result,reasons:t.debugMessages,origin:t.origin};t.resourceData!==void 0&&(e.request={resourceData:t.resourceData},t.updateMask!==void 0&&(e.request.updateMask=t.updateMask)),t.resourceBefore!==void 0&&(e.resourceBefore=t.resourceBefore),t.resourceAfter!==void 0&&(e.resourceAfter=t.resourceAfter),t.rulesEvidence!==void 0&&(e.rulesEvidence=t.rulesEvidence),t.queryProof!==void 0&&(e.queryProof=t.queryProof);const n=a0(t.debugMessages,t.result);return n&&(e.matchedRule=n),t.result!=="unsupported"&&t.evaluatedRule&&(e.evaluatedRule=t.evaluatedRule),t.groupId!==void 0&&(e.groupId=t.groupId,t.origin==="batch"?e.groupKind="batch":t.origin==="transaction"&&(e.groupKind="transaction")),t.triggeredBy!==void 0&&(e.triggeredBy=t.triggeredBy),t.detail!==void 0&&(e.detail=t.detail),t.provenance!==void 0&&Object.assign(e,t.provenance),e}const c0="production";function u0(){try{return c0==="production"}catch{return!1}}function af(){return!u0()}const l0=3,d0=()=>!1;let f0={frames:l0,skips:d0};function h0(){return f0}function p0(){const t=Error,e=t.stackTraceLimit,n=typeof e=="number"&&e<bu;n&&(t.stackTraceLimit=bu);try{const s=new Error().stack;return typeof s=="string"?s:void 0}finally{n&&(t.stackTraceLimit=e)}}const bu=50,xr="data-pyric-owner";let vu=0;function Cr(t){if(t===null||typeof t!="object")return!1;const e=t;return typeof e.getAttribute!="function"?!1:typeof e.tagName=="string"}function Zr(t){const e=t.tagName;return typeof e!="string"||e.length===0?"element":e.toLowerCase()}function fa(t){const e=t.id;if(typeof e=="string"&&e.length>0)return`#${e}`;const n=t.getAttribute(xr);if(typeof n=="string"&&n.length>0)return`[${xr}="${n}"]`}function m0(t){const e=t.parentElement;if(!e)return 1;const n=e.children;if(!n)return 1;for(let s=0;s<n.length;s+=1)if(n[s]===t)return s+1;return 1}function g0(t){const e=[];let n=t,s=0;for(;n&&s<8;){const r=fa(n);if(r!==void 0)return e.unshift(r),e.join(" > ");e.unshift(`${Zr(n)}:nth-child(${m0(n)})`),n=n.parentElement,s+=1}return e.join(" > ")}function cf(t){const e=fa(t);if(e!==void 0)return e;vu+=1;const n=`${Zr(t)}-${vu.toString(36)}`;return t.setAttribute(xr,n),`[${xr}="${n}"]`}function y0(t){const e=fa(t);return e!==void 0?e:g0(t)}function b0(t){return t===null||typeof t!="object"?!1:"kind"in t&&typeof t.kind=="string"}function v0(t){if(t.kind!=="component")return t;const e={kind:"component",name:t.name};t.path!==void 0&&t.path.length>0&&(e.path=t.path);const n=t.element;return typeof n=="string"?e.element=n:n!==void 0&&Cr(n)&&(e.element=cf(n),e.tag=Zr(n)),e}const In=w0();function w0(){const t=S0();if(t===void 0)return"";const e=t.slice(0,t.lastIndexOf("/")),n=e.slice(0,e.lastIndexOf("/")),s=n.slice(0,n.lastIndexOf("/"));return uf(s)}function S0(){try{const t=import.meta.url;return typeof t!="string"?void 0:t}catch{return}}function uf(t){return t.startsWith("file://")?t.slice(7):t}function A0(t){if(t.includes("/node_modules/")||t==="native"||t.startsWith("node:")||In.length>0&&t.startsWith(`${In}/`))return!0;const e=In.endsWith("/src")?`${In.slice(0,-4)}/dist`:In.endsWith("/dist")?`${In.slice(0,-5)}/src`:"";return!!(e&&t.startsWith(`${e}/`))}const k0=/^\s*at\s+(.+?)\s+\((.+):(\d+):(\d+)\)\s*$/,E0=/^\s*at\s+(.+):(\d+):(\d+)\s*$/,I0=/^\s*(.*?)@(.+):(\d+):(\d+)\s*$/;function _0(t){const e=k0.exec(t);if(e)return wi(e[2],e[3],e[4],e[1]);const n=E0.exec(t);if(n)return wi(n[1],n[2],n[3],"");const s=I0.exec(t);if(s)return wi(s[2],s[3],s[4],s[1])}function wi(t,e,n,s){const r={kind:"frame",file:uf(t),line:Number(e),column:Number(n)};return s.length>0&&(r.function=s),r}function x0(t){const{frames:e,skips:n}=h0(),s=[];let r;for(const a of t.split(`
|
|
1722
|
+
`)){const c=_0(a);if(c?.kind!=="frame"||A0(c.file))continue;const{kind:u,...l}=c;if(r===void 0&&!n(c.file)&&(r=s.length),s.push(l),r!==void 0&&s.length-r>=e)break}if(s.length===0)return;const i=r===void 0?s.slice(0,e):s,o={kind:"frame",...i[r??0]};return i.length>1&&(o.stack=i),o}function C0(){if(!af())return;const t=p0();if(t!==void 0)return x0(t)}function O0(t){if(t!==void 0){if(typeof t=="string")return t.length===0?void 0:{kind:"tag",name:t};if(b0(t))return v0(t);if(Cr(t))return{kind:"tag",name:Zr(t),element:cf(t)}}}function T0(t,e){if(e!==void 0&&e.length>0)return[...e];const n=[],s=C0();s!==void 0&&n.push(s);const r=O0(t);if(r!==void 0&&n.push(r),n.length!==0)return n}const R0={childList:!0,attributes:!0,characterData:!0,subtree:!0};function N0(){const t=globalThis,e=t.MutationObserver,n=t.document;if(typeof e=="function"&&n!=null)return{Observer:e,document:n}}function L0(t){if(Cr(t))return t;if(t===null||typeof t!="object")return;const e=t.parentElement;if(Cr(e))return e}function M0(t){if(!af()){t();return}const e=N0();if(e===void 0){t();return}const n=new e.Observer(()=>{});let s=[];try{n.observe(e.document,R0),t()}finally{s=n.takeRecords(),n.disconnect()}return D0(s)}function D0(t){const e=[],n=new Set,s=r=>{const i=L0(r);if(i===void 0)return;const o=y0(i);o.length!==0&&(n.has(o)||(n.add(o),e.push(o)))};for(const r of t){s(r.target);const i=r.addedNodes;if(i)for(let o=0;o<i.length;o+=1)s(i[o])}if(e.length!==0)return{kind:"regions",selectors:e}}function Jn(t,e=!1){return{kind:"query",collection:t.collection,...t.collectionGroup?{collectionGroup:!0}:{},...e&&t.constraints?.activityQuery?{query:t.constraints.activityQuery}:{}}}const _n=Symbol.for("pyric.firestore.lookupCollector");class $0{events;triggerScope;host;clock;snapshotListeners=new Map;nextListenerId=0;listenerLookupDeps=new Map;deliveryQueue=[];deliveryScheduled=!1;deliveryOwners=new Map;constructor(e,n,s,r=new Pt){this.events=e,this.triggerScope=n,this.host=s,this.clock=r}instrumentCallback(e,n){return s=>{this.deliveryOwners.delete(e);const r=M0(()=>n(s));r!==void 0&&this.deliveryOwners.set(e,[r])}}takeDeliveryOwners(e){const n=this.deliveryOwners.get(e);return this.deliveryOwners.delete(e),n}emitSnapshotDelivery(e){const n=this.takeDeliveryOwners(e.listenerId);if(!this.events.delivery.hasSubscribers)return;const s={kind:"snapshot_delivery",id:cs().replace(/^req-/,"snd-"),at:this.clock.now(),listenerId:e.listenerId,target:e.target,auth:e.auth?{uid:e.auth.uid,...e.auth.token?{token:e.auth.token}:{}}:null,addedCount:e.addedCount,modifiedCount:e.modifiedCount,removedCount:e.removedCount,size:e.size,...e.sample?{sample:e.sample}:{},...e.triggeredBy?{triggeredBy:e.triggeredBy}:{}};n!==void 0&&(s.owners=n),this.events.delivery.emit(s)}emitSnapshotSuppressed(e){if(!this.events.suppressed.hasSubscribers)return;const n={kind:"snapshot_suppressed",id:cs().replace(/^req-/,"sup-"),at:this.clock.now(),listenerId:e.listenerId,target:e.target,auth:e.auth?{uid:e.auth.uid,...e.auth.token?{token:e.auth.token}:{}}:null,reason:"no-op",...e.triggeredBy?{triggeredBy:e.triggeredBy}:{}};this.events.suppressed.emit(n)}emitLifecycle(e){if(!this.events.lifecycle.hasSubscribers)return;const n={kind:e.phase,id:cs().replace(/^req-/,"lc-"),at:this.clock.now(),listenerId:e.listenerId,target:e.target,auth:e.auth?{uid:e.auth.uid,...e.auth.token?{token:e.auth.token}:{}}:null};e.owners!==void 0&&(n.owners=e.owners),this.events.lifecycle.emit(n)}emitSnapshotError(e,n,s){this.events.snapshotError.emit(e,n,s)}addSnapshotListener(e,n,s={},r=null,i,o=!1,a=!1,c){const u=String(this.nextListenerId++),l=T0(s.owner,s.owners),d={id:u,target:e,callback:this.instrumentCallback(u,n),auth:r,bypassRules:a,followsCurrentUser:o,...c?{authScope:c}:{},options:s,currentSnapshot:void 0,errored:!1,...i?{errorCallback:i}:{}};return this.snapshotListeners.set(u,d),this.emitLifecycle({phase:"listener_attach",listenerId:u,target:e.kind==="doc"?{kind:"doc",path:e.path}:Jn(e,!0),auth:r,owners:l}),this.scheduleDelivery(()=>{this.snapshotListeners.has(u)&&this.fireInitialSnapshot(d)}),()=>{const f=this.snapshotListeners.has(u);this.snapshotListeners.delete(u),this.deliveryOwners.delete(u),this.listenerLookupDeps.delete(u),f&&this.emitLifecycle({phase:"listener_detach",listenerId:u,target:e.kind==="doc"?{kind:"doc",path:e.path}:Jn(e,!0),auth:r})}}readDocWithLookupDeps(e,n){const s=new Set,r=globalThis,i=r[_n];r[_n]=s;try{return this.host.silentReadDoc(n,e.auth,e.bypassRules)}finally{r[_n]=i,this.listenerLookupDeps.set(e.id,s)}}readCollectionWithLookupDeps(e,n,s){const r=new Set,i=globalThis,o=i[_n];i[_n]=r;try{return this.host.silentReadCollection(n,e.auth,s,e.bypassRules)}finally{i[_n]=o,this.listenerLookupDeps.set(e.id,r)}}touchesLookupDependency(e,n){const s=this.listenerLookupDeps.get(e);if(s===void 0||s.size===0)return!1;for(const i of n)if(s.has(i))return!0;return!1}fireInitialSnapshot(e){if(e.target.kind==="doc"){const r=this.readDocWithLookupDeps(e,e.target.path);if(!r.allowed){this.markErrored(e,r.error);return}const i=Kn(e.target.path,r.data);e.currentSnapshot=i,e.currentDocData=r.data;try{e.callback(i)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:{kind:"doc",path:e.target.path},auth:e.auth,addedCount:r.data!==null?1:0,modifiedCount:0,removedCount:0,size:r.data!==null?1:0,sample:{docs:[{path:e.target.path,data:r.data}]}});return}const n=this.readCollectionWithLookupDeps(e,Bs(e.target),e.target.constraints);if(!n.allowed){this.markErrored(e,n.error);return}const s=Zn({path:e.target.collection},n.docs,{excludesMetadataChanges:!e.options.includeMetadataChanges});e.currentSnapshot=s,e.currentDocs=n.docs;try{e.callback(s)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:Jn(e.target),auth:e.auth,addedCount:n.docs.length,modifiedCount:0,removedCount:0,size:n.docs.length,sample:{docs:n.docs.map(r=>({path:r.path,data:r.data}))}})}scheduleDelivery(e){this.deliveryQueue.push(e),!this.deliveryScheduled&&(this.deliveryScheduled=!0,queueMicrotask(()=>this.drainDeliveries()))}scheduleTriggeredDelivery(e,n){this.scheduleDelivery(()=>this.triggerScope.run(e,n))}drainDeliveries(){for(this.deliveryScheduled=!1;this.deliveryQueue.length>0;)this.deliveryQueue.shift()()}flushListeners(){this.drainDeliveries()}notifyListenersForPaths(e,n){if(e.size===0||this.snapshotListeners.size===0)return;const s=this.triggerScope.current(),r=Array.from(this.snapshotListeners.values());for(const i of r){const o=n?this.attributeToOp(i,n)??s:s;this.scheduleTriggeredDelivery(o,()=>{this.snapshotListeners.has(i.id)&&(i.errored||(i.target.kind==="doc"?this.notifyDocListener(i,e):this.notifyQueryListener(i,e)))})}}attributeToOp(e,n){const s=e.target;for(const r of n.paths)if(s.kind==="doc"?s.path===r:yu(new Set([r]),Bs(s)))return{method:n.method,path:r}}notifyDocListener(e,n){if(e.target.kind!=="doc")return;const s=n.has(e.target.path),r=this.touchesLookupDependency(e.id,n);if(!s&&!r)return;const i=this.readDocWithLookupDeps(e,e.target.path);if(!i.allowed){this.markErrored(e,i.error);return}if(!s)return;const o=e.currentDocData??null;if(gu(o,i.data)){this.emitSnapshotSuppressed({listenerId:e.id,target:{kind:"doc",path:e.target.path},auth:e.auth,...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}});return}const a=e.target.path,c=Kn(a,i.data,pu);e.currentSnapshot=c,e.currentDocData=i.data;const u=o!==null,l=i.data!==null,d=!u&&l?1:0,f=u&&!l?1:0,p=u&&l?1:0;try{e.callback(c)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:{kind:"doc",path:a},auth:e.auth,addedCount:d,modifiedCount:p,removedCount:f,size:l?1:0,sample:{docs:[{path:a,data:i.data}]},...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}}),this.scheduleDocMetadataAck(e,a,i.data)}scheduleDocMetadataAck(e,n,s){e.options.includeMetadataChanges&&this.scheduleTriggeredDelivery(this.triggerScope.current(),()=>{if(!this.snapshotListeners.has(e.id)||e.errored)return;const r=Kn(n,s,Cs);e.currentSnapshot=r;try{e.callback(r)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:{kind:"doc",path:n},auth:e.auth,addedCount:0,modifiedCount:0,removedCount:0,size:s!==null?1:0,sample:{docs:[{path:n,data:s}]},...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}})})}notifyQueryListener(e,n){if(e.target.kind!=="query")return;const s=Bs(e.target),r=yu(n,s),i=this.touchesLookupDependency(e.id,n);if(!r&&!i)return;const o=this.readCollectionWithLookupDeps(e,s,e.target.constraints);if(!o.allowed){this.markErrored(e,o.error);return}if(!r)return;const a=e.target.collection,c=Jn(e.target),u=e.currentDocs??[],l=Zn({path:a},o.docs,{excludesMetadataChanges:!e.options.includeMetadataChanges},u,pu),d=l.docChanges();if(d.length===0){if(e.options.includeMetadataChanges){e.currentSnapshot=l,e.currentDocs=o.docs;try{e.callback(l)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:c,auth:e.auth,addedCount:0,modifiedCount:0,removedCount:0,size:o.docs.length,sample:{docs:o.docs.map(m=>({path:m.path,data:m.data}))},...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}}),this.scheduleQueryMetadataAck(e,e.target,o.docs);return}this.emitSnapshotSuppressed({listenerId:e.id,target:c,auth:e.auth,...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}});return}e.currentSnapshot=l,e.currentDocs=o.docs;let f=0,p=0,h=0;for(const m of d)m.type==="added"?f++:m.type==="modified"?p++:m.type==="removed"&&h++;try{e.callback(l)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:c,auth:e.auth,addedCount:f,modifiedCount:p,removedCount:h,size:o.docs.length,sample:{docs:o.docs.map(m=>({path:m.path,data:m.data}))},...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}}),this.scheduleQueryMetadataAck(e,e.target,o.docs)}scheduleQueryMetadataAck(e,n,s){if(!e.options.includeMetadataChanges)return;const r=Jn(n);this.scheduleTriggeredDelivery(this.triggerScope.current(),()=>{if(!this.snapshotListeners.has(e.id)||e.errored)return;const i=Zn({path:n.collection},s,{excludesMetadataChanges:!1},s,Cs);e.currentSnapshot=i;try{e.callback(i)}catch{}this.emitSnapshotDelivery({listenerId:e.id,target:r,auth:e.auth,addedCount:0,modifiedCount:0,removedCount:0,size:s.length,sample:{docs:s.map(o=>({path:o.path,data:o.data}))},...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}})})}markErrored(e,n){if(e.errored=!0,this.emitSnapshotError(n,e.target,e.id),!!e.errorCallback)try{e.errorCallback(n)}catch{}}reEvaluateAllListeners(){if(this.snapshotListeners.size===0)return;const e=Array.from(this.snapshotListeners.values());for(const n of e)this.snapshotListeners.has(n.id)&&(n.target.kind==="doc"?this.reEvaluateDocListener(n):this.reEvaluateQueryListener(n))}reevaluateLiveListeners(e,n){if(this.snapshotListeners.size===0)return;const s=Array.from(this.snapshotListeners.values());for(const r of s)r.followsCurrentUser&&r.authScope===n&&this.snapshotListeners.has(r.id)&&(r.errored||(r.auth=e,r.target.kind==="doc"?this.reEvaluateDocListener(r):this.reEvaluateQueryListener(r)))}reEvaluateDocListener(e){if(e.target.kind!=="doc")return;const n=this.readDocWithLookupDeps(e,e.target.path);if(!n.allowed){if(e.errored)return;this.markErrored(e,n.error);return}if(e.errored){e.errored=!1;const i=Kn(e.target.path,n.data);e.currentSnapshot=i,e.currentDocData=n.data;try{e.callback(i)}catch{}return}const s=e.currentDocData??null;if(gu(s,n.data))return;const r=Kn(e.target.path,n.data);e.currentSnapshot=r,e.currentDocData=n.data;try{e.callback(r)}catch{}}reEvaluateQueryListener(e){if(e.target.kind!=="query")return;const n=this.readCollectionWithLookupDeps(e,Bs(e.target),e.target.constraints);if(!n.allowed){if(e.errored)return;this.markErrored(e,n.error);return}if(e.errored){e.errored=!1;const o=Zn({path:e.target.collection},n.docs,{excludesMetadataChanges:!e.options.includeMetadataChanges});e.currentSnapshot=o,e.currentDocs=n.docs;try{e.callback(o)}catch{}return}const s=e.currentDocs??[],r=Zn({path:e.target.collection},n.docs,{excludesMetadataChanges:!e.options.includeMetadataChanges},s);if(r.docChanges().length!==0){e.currentSnapshot=r,e.currentDocs=n.docs;try{e.callback(r)}catch{}}}getSnapshotListenerCount(){return this.snapshotListeners.size}dispose(){this.snapshotListeners.clear(),this.deliveryOwners.clear(),this.listenerLookupDeps.clear(),this.deliveryQueue.length=0,this.deliveryScheduled=!1}}class P0{eventLog;host;constructor(e,n){this.eventLog=e,this.host=n}undo(){const e=this.eventLog.popLastWrite();if(!e)return null;if(e.priorDocs)this.host.state.restorePaths(e.priorDocs);else if(e.snapshot)this.host.state.restore(e.snapshot);else return null;return e}redo(){const e=this.eventLog.popLastUndo();if(!e)return null;const n=e.type==="batch"&&e.operations?e.operations.map(a=>a.path):e.path?[e.path]:[],s=!!e.snapshot,r=s?void 0:this.host.capturePriors(n),i=s?this.host.state.snapshot():void 0;if(e.type==="batch"&&e.operations)for(const a of e.operations)a.allowed&&this.host.applyWrite(a.method,a.path,a.data);else e.allowed&&this.host.applyWrite(e.method,e.path,e.data);const o=this.eventLog.append({...e,snapshot:i,priorDocs:r},!0);return{allowed:e.allowed,debugMessages:["Redo: "+(e.allowed?"applied":"skipped (was denied)")],event:o}}getEvents(){return this.eventLog.getEvents()}getEventCount(){return this.eventLog.size()}}class lf{truncated=!1;remainingChecks=128;text(e){return e.length<=256?e:(this.truncated=!0,`${e.slice(0,256)}…`)}take(e,n){return e.length>n&&(this.truncated=!0),e.slice(0,n)}}function F0(t,e){const n={expression:e.text(t.source),parent:t.parent,operator:t.operator,kind:t.kind,helper:t.inlinedFrom?.name,binding:t.letBinding?.name};if(n.helper!==void 0&&(n.helper=e.text(n.helper)),n.binding!==void 0&&(n.binding=e.text(n.binding)),t.skipped)return{...n,state:"skipped"};if(t.error!==void 0)return{...n,state:"error",error:e.text(t.error)};const s=t.value;return s===null||typeof s=="boolean"||typeof s=="number"?{...n,state:"value",value:s}:typeof s=="string"?{...n,state:"value",value:e.text(s)}:{...n,state:"unavailable"}}function j0(t,e){const n=t.expressionTrace??[],s=e.take(n,e.remainingChecks);e.remainingChecks-=s.length;const r=t.conditionText??"",i={expression:e.text(r),verdict:t.verdict,checks:s.map(o=>F0(o,e))};return t.line!==void 0&&(i.line=t.line),t.matchPath!==void 0&&(i.path=e.text(t.matchPath)),t.message!==void 0&&(i.error=e.text(t.message)),i}function q0(t,e,n="request"){const s=new lf,r=s.take(t.trace,32).map(a=>j0(a,s)),i=t.pathResolution?.attempts??[],o=s.take(i,32).map(a=>({path:s.text(a.blockPath),matched:a.matched,line:a.line}));return{version:e,scope:n,decision:t.decision,rules:r,paths:o,truncated:s.truncated}}function U0(t,e,n){const s=new lf,r=s.take(t.failures,32).map(c=>{const u={reason:s.text(c.reason)};return c.rule?.expression!==void 0&&(u.expression=s.text(c.rule.expression)),c.rule?.line!==void 0&&(u.line=c.rule.line),u});let i="DENY";(t.kind==="unsupported-path"||t.kind==="unsupported-predicate")&&(i="UNSUPPORTED");const a=n??{version:e,scope:"query-residual",decision:i,truncated:!1,rules:[],paths:[]};return{...a,queryProof:{kind:t.kind,failures:r},truncated:a.truncated||s.truncated}}function wu(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`rules-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}class B0{version=wu();captureEvidence(e,n="request"){return q0(e,this.version,n)}captureQueryEvidence(e,n){return U0(e,this.version,n)}currentSource;parsedCache=null;sourceMapCache=null;constructor(e){this.currentSource=e}get source(){return this.currentSource}set(e){this.currentSource!==e&&(this.version=wu()),this.currentSource=e}ast(){if(this.parsedCache?.source!==this.currentSource){const e=zo(this.currentSource);this.parsedCache={source:this.currentSource,ast:e.ok?e.ast:null}}return this.parsedCache.ast}sourceMap(){return this.sourceMapCache?.source!==this.currentSource&&(this.sourceMapCache={source:this.currentSource,sourceMap:Ko(this.currentSource)}),this.sourceMapCache.sourceMap}}const _k=["permission-denied","not-found","already-exists","failed-precondition","aborted","invalid-argument","unauthenticated","unimplemented"];function he(t,e,n){const s={code:t,message:e};return n!==void 0&&(n.queryProof!==void 0&&(s.queryProof=n.queryProof),n.request!==void 0&&(s.request=n.request),n.resource!==void 0&&(s.resource=n.resource),n.remediation!==void 0&&(s.remediation=n.remediation),n.query!==void 0&&(s.query=n.query),n.rule!==void 0&&(s.rule=n.rule),n.repro!==void 0&&(s.repro=n.repro)),s}function z0(t,e){const{method:n,data:s,merge:r}=t;if(n==="get"||n==="list")return;if(!s)return s;if(r!==void 0&&r!==!1&&(n==="create"||n==="update")){const o=r===!0?void 0:r.mergeFields;return Hr(e??{},s,o)}return n==="update"?Gr(e??{},s):un(s).writes}function Jr(t,e,n){const s=t.get(e.path),r=e.method==="set"?s!==null?"update":"create":e.method;return{description:`${e.method} ${e.path}`,expectation:"ALLOW",method:r,path:e.path,auth:e.auth?{uid:e.auth.uid,token:e.auth.token}:null,data:z0(e,s),resource:s??void 0,...n?{requestTime:JS(n)}:{}}}function df(t,e,n,s){const r=t.ast();return r?e.simulateParsed(r,t.source,n,{...s,sourceMap:t.sourceMap()}):e.simulate(t.source,n,s)}function ff(t,e,n,s,r,i){if(r){const o=s.map(a=>QS(a.description));return{success:!0,data:{passed:o.length,failed:0,unsupported:0,results:o}}}return df(e,n,s,{getDoc:o=>t.get(o),...i?{batchProjection:i}:{}})}class W0{events;rules;simulator;host;eventLog;clock;constructor(e,n,s,r,i,o=new Pt){this.events=e,this.rules=n,this.simulator=s,this.host=r,this.eventLog=i,this.clock=o}get state(){return this.host.state}emitRequest(e){this.events.request.hasSubscribers&&this.events.request.emit(Kr(e))}emitDenial(e){this.events.denial.emit(e)}execute(e){const{method:n,path:s,auth:r,bypassRules:i}=e;let o;i===!0&&(o={admin:!0});const c=ye.fromMillis(this.clock.now()),u=Jr(this.state,e,c),l=this.clock.now(),d=performance.now(),f=ff(this.state,this.rules,this.simulator,[u],i),p=performance.now()-d;let h=null;if(r!==void 0&&r!==null&&(h={uid:r.uid}),f.success===!0===!1){const x=this.eventLog.append({type:"single",method:n,path:s,auth:h,allowed:!1,debugMessages:[`Simulation error: ${f.error.message}`]}),S={at:l,evalMs:p,method:n,path:s,auth:r,result:"deny",debugMessages:[`Simulation error: ${f.error.message}`],origin:"user"};return o!==void 0&&(S.detail=o),this.emitRequest(S),{allowed:!1,debugMessages:[f.error.message],event:x}}const b=f.data.results[0],v=this.rules.captureEvidence(b);if(b.state==="UNSUPPORTED"){const x={at:l,evalMs:p,method:n,path:s,auth:r,result:"unsupported",rulesEvidence:v,debugMessages:ke(b),origin:"user"};throw o!==void 0&&(x.detail=o),this.emitRequest(x),new qn(Un(n,s,ke(b)),n,s,ke(b))}const k=b.state==="PASSED";let O;k&&(n==="get"?O=this.state.get(s):O=this.state.list(s));const R=this.eventLog.append({type:"single",method:n,path:s,auth:h,allowed:k,debugMessages:ke(b)}),V={allowed:k,debugMessages:ke(b),event:R};k&&(V.data=O);const G=en(b);if(k===!1){const S={request:{method:n,path:s,auth:r}};if(n==="get"){const $=this.state.get(s),z=$!==null;S.resource={data:$,exists:z}}G!==void 0&&(S.rule=G),V.error=he("permission-denied",`${n} ${s} denied by rules`,S),this.emitDenial(V.error)}let N="deny";k&&(N="allow");const D={at:l,evalMs:p,method:n,path:s,auth:r,result:N,debugMessages:ke(b),evaluatedRule:G,rulesEvidence:v,origin:"user"};if(n==="get"){const x=this.state.get(s),S=x!==null;D.resourceBefore={data:x,exists:S}}return o!==void 0&&(D.detail=o),this.emitRequest(D),V}}const Su=new WeakMap;let V0=1;function Au(t){let e=Su.get(t);return e===void 0&&(e=V0++,Su.set(t,e)),e}function Si(t){if(t===null||typeof t=="boolean")return t;if(typeof t=="string")return $S(t);if(typeof t>"u")return{type:"undefined"};if(typeof t=="bigint")return Ir("bigint",t.toString());if(typeof t=="number"){const n=Number.isNaN(t)?"NaN":t===1/0?"Infinity":t===-1/0?"-Infinity":Object.is(t,-0)?"-0":String(t);return Ir("number",n)}if(typeof t!="object"&&typeof t!="function")return{type:typeof t,value:String(t)};const e=FS(t);if(e!==void 0)return e;try{if(Array.isArray(t))return{type:"array",id:Au(t)}}catch{}return{type:"opaque-object",id:Au(t)}}function G0(t,e,n){if(e<=0)return[];const s=[];for(const r of t)s.length<e?ku(s,r,n):n(r,s[s.length-1])<0&&(s.pop(),ku(s,r,n));return s}function ku(t,e,n){let s=0,r=t.length;for(;s<r;){const i=s+r>>1;n(e,t[i])<0?r=i:s=i+1}t.splice(s,0,e)}const H0={timestamp:3,bytes:5,reference:6,"geo-point":7,vector:9};function K0(t){if(t==null)return 0;const e=typeof t;if(e==="boolean")return 1;if(e==="number"||e==="bigint")return 2;if(e==="string")return 4;if(Array.isArray(t))return 8}function Or(t){const e=K0(t);if(e!==void 0)return e;const n=Es(t);return n===void 0?10:H0[n.kind]}function Ht(t,e){return t<e?-1:t>e?1:0}function Qs(t,e){const n=Number.isNaN(t),s=Number.isNaN(e);return n&&s?0:n?-1:s?1:Ht(t,e)}function ha(t,e){return Ht(t,e)}function Tr(t,e,n){const s=Math.min(t.length,e.length);for(let r=0;r<s;r++){const i=n(t[r],e[r]);if(i!==0)return i}return Ht(t.length,e.length)}function Eu(t){return t.split("/").filter(e=>e.length>0)}function Z0(t,e){return Tr(Eu(t),Eu(e),ha)}function J0(t,e){return t.kind==="timestamp"&&e.kind==="timestamp"?Ht(t.seconds,e.seconds)||Ht(t.nanoseconds,e.nanoseconds):t.kind==="bytes"&&e.kind==="bytes"?Tr(t.values,e.values,Ht):t.kind==="reference"&&e.kind==="reference"?Z0(t.path,e.path):t.kind==="geo-point"&&e.kind==="geo-point"?Qs(t.latitude,e.latitude)||Qs(t.longitude,e.longitude):t.kind==="vector"&&e.kind==="vector"?Ht(t.values.length,e.values.length)||Tr(t.values,e.values,Qs):0}function Q0(t,e){const n=Object.keys(t).sort(),s=Object.keys(e).sort(),r=Math.min(n.length,s.length);for(let i=0;i<r;i++){const o=ha(n[i],s[i]);if(o!==0)return o;const a=Ft(t[n[i]],e[s[i]]);if(a!==0)return a}return Ht(n.length,s.length)}function Ft(t,e){const n=Or(t),s=Or(e);if(n!==s)return n<s?-1:1;switch(n){case 0:return 0;case 1:return t===e?0:t?1:-1;case 2:return Qs(Number(t),Number(e));case 4:return ha(t,e);case 8:return Tr(t,e,Ft);case 10:return Q0(t,e);default:return J0(Es(t),Es(e))}}const Ai="__name__";function Y0(t,e){const n=t.split("."),s=e.split("."),r=Math.min(n.length,s.length);for(let i=0;i<r;i++){const o=n[i],a=s[i];if(o!==a)return o<a?-1:1}return n.length-s.length}function X0(t,e){const n=[...t],s=new Set(n.map(o=>o.field)),r=t.length>0?t[t.length-1].direction:"asc",i=[...new Set(e)].filter(o=>o!==Ai&&!s.has(o));for(const o of i.sort(Y0))s.add(o),n.push({field:o,direction:r});return s.has(Ai)||n.push({field:Ai,direction:r}),n}function Iu(t){const e=t.kind;if(e==="collection"){const n=t.path;return Object.freeze({kind:e,path:n})}if(e==="collection-group"){const n=t.collectionId;return Object.freeze({kind:e,collectionId:n})}throw new xs({code:"invalid-argument",message:`Unknown query scope kind: ${String(e)}`})}function _u(t){const e=u=>{const l=u.kind;if(l==="where"){const f=u.field,p=u.op,h=u.value;return Object.freeze({kind:l,field:f,op:p,value:h})}if(l!=="and"&&l!=="or")throw new xs({code:"invalid-argument",message:`Unknown query filter kind: ${String(l)}`});const d=u.filters;return Object.freeze({kind:l,filters:Object.freeze(Array.from(d,e))})},n=u=>{if(u===void 0)return;const l=u.values,d=u.inclusive,f=u.fromSnapshot;return Object.freeze({values:Object.freeze(Array.from(l)),inclusive:d,fromSnapshot:f})},s=t.filters,r=t.orders,i=t.limitCount,o=t.limitFromEnd,a=t.start,c=t.end;return Object.freeze({filters:Object.freeze(Array.from(s,e)),orders:Object.freeze(Array.from(r,u=>{const l=u.field,d=u.direction;return Object.freeze({field:l,direction:d})})),limitCount:i,limitFromEnd:o,start:n(a),end:n(c)})}function xu(t){const e=[],n=s=>{if(s.kind==="where"){if(s.field===Ms)return;const r=s.value;(r===null||typeof r=="string"||typeof r=="number"||typeof r=="boolean"||s.op==="in"&&Array.isArray(r)&&r.length>0&&r.length<=30&&r.every(i=>i===null||typeof i=="string"||typeof i=="boolean"||typeof i=="number"&&Number.isFinite(i)))&&e.push(Object.freeze({field:s.field,op:s.op,value:Array.isArray(r)?Object.freeze([...r]):r}));return}s.kind==="and"&&s.filters.forEach(n)};return t.filters.forEach(n),Object.freeze({where:Object.freeze(e),limit:t.limitCount??null,offset:null,orderBy:t.orders.length>0?t.orders[0].field:null})}function eA(t){const e=n=>n.kind==="where"?{kind:n.kind,field:n.field,op:n.op,value:Si(n.value)}:{kind:n.kind,filters:n.filters.map(e)};return{filters:t.filters.map(e),orders:t.orders,limitCount:t.limitCount,limitFromEnd:t.limitFromEnd,...t.start?{start:{...t.start,values:t.start.values.map(Si)}}:{},...t.end?{end:{...t.end,values:t.end.values.map(Si)}}:{}}}function Cu(t,e){if(e.kind==="collection")return t.scan(e.path,{directOnly:!0});const n=[];for(const[s,r]of Object.entries(t.snapshot())){const i=s.split("/").filter(o=>o.length>0);i.length>0&&i.length%2===0&&i[i.length-2]===e.collectionId&&n.push({path:s,data:r})}return n}const Ms="__name__";function pa(t,e){let n=t;for(const s of e.split(".")){if(!it(n)||!Object.hasOwn(n,s))return;n=n[s]}return n}const tA=new Set(["<","<=",">",">=","!=","not-in"]);class Rr{path;constructor(e){this.path=e}}function bo(t,e){return e===Ms?new Rr(t.path):pa(t.data,e)}function hf(t){return t.kind==="where"?tA.has(t.op)?[t.field]:[]:t.filters.flatMap(hf)}function Ds(t,e){return Or(t)===Or(e)}function nA(t,e){return Ds(t,e)&&Ft(t,e)<0}function sA(t,e){return Ds(t,e)&&Ft(t,e)<=0}function rA(t,e){return Ds(t,e)&&Ft(t,e)>0}function iA(t,e){return Ds(t,e)&&Ft(t,e)>=0}function Ou(t,e){return Ds(t,e)&&Ft(t,e)===0}function oA(t,e,n){const s=t!==void 0;switch(e){case"==":return s&&Ou(t,n);case"!=":return s&&t!==null&&!Ou(t,n);case"<":return s&&nA(t,n);case"<=":return s&&sA(t,n);case">":return s&&rA(t,n);case">=":return s&&iA(t,n);case"in":return s&&Array.isArray(n)&&n.some(r=>Gt(t,r));case"not-in":return!Array.isArray(n)||n.some(r=>r===null)?!1:s&&t!==null&&!n.some(r=>Gt(t,r));case"array-contains":return Array.isArray(t)&&t.some(r=>Gt(r,n));case"array-contains-any":return Array.isArray(t)&&Array.isArray(n)&&n.some(r=>t.some(i=>Gt(i,r)))}}function aA(t,e){return e===Ms?new Rr(t.path):pa(t.data,e)}function cA(t){const e=t.lastIndexOf("/");return e<0?"":t.slice(0,e)}function pf(t,e){if(Array.isArray(t))return t.map(s=>pf(s,e));if(typeof t=="string"){const s=t.includes("/");return new Rr(s?t:`${cA(e)}/${t}`)}return t!==null&&typeof t=="object"&&typeof t.path=="string"?new Rr(t.path):t}function vo(t,e){if(e.kind==="where"){const n=aA(t,e.field),s=e.field===Ms?pf(e.value,t.path):e.value;return oA(n,e.op,s)}return e.kind==="and"?e.filters.every(n=>vo(t,n)):e.filters.some(n=>vo(t,n))}function uA(t,e){return t.filter(n=>e.every(s=>vo(n,s)))}function Tu(t,e,n){for(let s=0;s<e.length;s++){const r=Ft(bo(t,n[s].field),e[s]);if(r!==0)return n[s].direction==="desc"?-r:r}return 0}function lA(t,e,n,s){return t.filter(r=>{if(n){const i=Tu(r,n.values,e);if(n.inclusive?i<0:i<=0)return!1}if(s){const i=Tu(r,s.values,e);if(s.inclusive?i>0:i>=0)return!1}return!0})}function mf(t,e){return t.filter(n=>e.every(s=>s.field===Ms||pa(n.data,s.field)!==void 0))}function gf(t){return(e,n)=>{for(const s of t){const r=Ft(bo(e,s.field),bo(n,s.field));if(r!==0)return s.direction==="desc"?-r:r}return 0}}function dA(t,e){return e.length===0?t:mf(t,e).sort(gf(e))}function fA(t){return X0(t.orders,t.filters.flatMap(hf))}function Ru(t,e){let n=uA(t,[...e.filters]);const s=fA(e),r=e.limitCount;if(r!==void 0&&!e.limitFromEnd&&e.start===void 0&&e.end===void 0)return G0(mf(n,s),r,gf(s));if(n=dA(n,s),!!(e.start||e.end)){for(const u of[e.start,e.end])if(!!(u&&!u.fromSnapshot&&u.values.length>e.orders.length))throw new xs({code:"invalid-argument",message:"Too many arguments provided to a cursor (startAt / startAfter / endAt / endBefore). The number of cursor values must be less than or equal to the number of orderBy() clauses."});n=lA(n,s,e.start,e.end)}const a=e.limitCount;if(a!==void 0)if(e.limitFromEnd){if(e.orders.length===0)throw new xs({code:"unimplemented",message:"limitToLast() queries require at least one orderBy clause."});n=a===0?[]:n.slice(-a)}else n=n.slice(0,a);return n}function hA(t,e){if(!t||!Cw(t))return null;const n=[...t.functions??[],...t.service.functions??[],...t.service.match.functions],s=new Set,r=t.service.match.children.flatMap(o=>{const a=mA(o,e,n,s);return a?[a]:[]});if(r.length===0)return null;const i=o=>o?.filter(a=>s.has(a.name));return{...t,functions:i(t.functions),service:{...t.service,functions:i(t.service.functions),match:{...t.service.match,functions:i(t.service.match.functions)??[],children:r}}}}function pA(t,e){const[n,s,r,...i]=t.path.segments;return n?.type!=="recursive"?null:s?s.type==="literal"&&s.value===e&&r?.type==="wildcard"&&i.length===0?new Set([n.name,r.name]):null:new Set([n.name])}function mA(t,e,n,s){const r=pA(t,e);if(!r)return null;const i=$d([...n,...t.functions]),o=t.allows.filter(a=>{if(!a.operations.some(u=>u==="list"||u==="read"))return!1;const c=Pd(a.condition,r,i.functions,i.ambiguousNames);if(c.pathInvariant)for(const u of c.requiredFunctions)s.add(u);return c.pathInvariant});return o.length===0?null:{...t,functions:t.functions.filter(a=>s.has(a.name)),allows:o,children:[]}}function gA(t){return qd(t)}class yA{events;rules;simulator;host;clock;constructor(e,n,s,r,i=new Pt){this.events=e,this.rules=n,this.simulator=s,this.host=r,this.clock=i}authorize(e){const{path:n,auth:s,constraints:r,origin:i,triggeredBy:o}=e,a=gA(r),c={...e.bypassRules?{admin:!0}:{},...a?{query:a}:{},...e.activityQuery!==void 0?{activityQuery:e.activityQuery}:{}},u=Object.keys(c).length>0?c:void 0,l=e.timing?.requestTime??(e.bypassRules?void 0:ye.fromMillis(this.clock.now())),d=e.timing?.at??this.clock.now();if(e.bypassRules)return this.emitRequest({at:d,evalMs:0,method:"list",path:n,auth:s,result:"allow",debugMessages:[i==="listener"?"admin lens — rules bypassed":"admin lens — rules bypassed (Studio Gap #2)"],origin:i,...u?{detail:u}:{},...o?{triggeredBy:o}:{}}),{allowed:!0};const f=this.rules.ast(),p=e.collectionGroup?hA(f,n):f;if(e.collectionGroup&&!p){const D=`list ${n} denied: no rule governs every '${n}' collection. A collection-group query needs a list or read rule at match /{path=**}/${n}/{id} or match /{document=**} whose condition reads no path binding`;this.emitRequest({at:d,evalMs:0,method:"list",path:n,auth:s,result:"deny",debugMessages:[D],origin:i,...u?{detail:u}:{},...o?{triggeredBy:o}:{}});const K=he("permission-denied",D,{request:{method:"list",path:n,auth:s},query:r});return this.emitUserDenial(i,K),{allowed:!1,error:K}}const h=`${n}/__listPlaceholder__`,m=performance.now(),g=Fd(p,h,s,r,this.rules.source);if(g.kind==="unprovable")return this.denyQuery(e,g,d,performance.now()-m,u);const b=g.kind==="provable"?g.evaluationAst:p,v=Jr(this.host.state,{method:"list",path:h,auth:s},l);this.applyProof(v,g,r);const w=D=>this.host.state.get(D),k=b?this.simulator.simulateParsed(b,this.rules.source,[v],{getDoc:w,sourceMap:this.rules.sourceMap(),skipQueryProof:!0}):this.simulator.simulate(this.rules.source,[v],{getDoc:w}),O=performance.now()-m;if(!k.success)return this.emitRequest({at:d,evalMs:O,method:"list",path:n,auth:s,result:"deny",debugMessages:[`Simulation error: ${k.error.message}`],origin:i,...u?{detail:u}:{},...o?{triggeredBy:o}:{}}),{allowed:!1,error:he("permission-denied",`list ${n} simulator error`,{request:{method:"list",path:n,auth:s}})};const R=k.data.results[0],V=this.rules.captureEvidence(R,"query-residual"),G=ke(R);if(R.state==="UNSUPPORTED")throw this.emitRequest({at:d,evalMs:O,method:"list",path:n,auth:s,result:"unsupported",rulesEvidence:V,debugMessages:G,origin:i,...u?{detail:u}:{},...o?{triggeredBy:o}:{}}),new qn(Un("list",n,G),"list",n,G);return R.state!=="PASSED"?this.denyQuery(e,g,d,O,u,{reasons:G,rule:en(R),evidence:V}):(this.emitRequest({at:d,evalMs:O,method:"list",path:n,auth:s,result:"allow",debugMessages:G,evaluatedRule:en(R),rulesEvidence:V,origin:i,...u?{detail:u}:{},...o?{triggeredBy:o}:{}}),{allowed:!0})}denyQuery(e,n,s,r,i,o={reasons:[]}){const{reasons:a,rule:c}=o,u=n.kind==="no-rule"?[]:n.failures,l=u.find(w=>w.kind!=="constraints-not-satisfied")??u[0],d={kind:l?.kind??(n.kind==="no-rule"?"no-rule":"residual-denied"),failures:u,query:e.activityQuery??(e.execution?eA(e.execution):void 0)},f=l?`list ${e.path} denied: Pyric found the query statically unprovable — ${l.reason}`:`list ${e.path} denied by rules`,p=l?[f,...a.filter(w=>!w.startsWith("No allow rules found"))]:a,h=l?uo(l.residual):void 0,m={path:e.path,auth:e.auth,constraints:e.constraints},g=l?Ud(m):void 0,y=l?Ww(m):void 0,b=h&&y?`${h}
|
|
1723
|
+
|
|
1724
|
+
${y}`:h??y,v=he("permission-denied",f,{request:{method:"list",path:e.path,auth:e.auth},query:e.constraints,queryProof:d,...b?{remediation:b}:{},...g?{repro:g}:{},...l?.rule||c?{rule:l?.rule??c}:{}});return this.emitRequest({at:s,evalMs:r,method:"list",path:e.path,auth:e.auth,result:"deny",debugMessages:p,queryProof:d,rulesEvidence:this.rules.captureQueryEvidence(d,o.evidence),...c?{evaluatedRule:c}:{},origin:e.origin,...i?{detail:i}:{},...e.triggeredBy?{triggeredBy:e.triggeredBy}:{}}),this.emitUserDenial(e.origin,v),{allowed:!1,error:v}}applyProof(e,n,s){n.kind==="provable"&&(e.resource=n.syntheticResource),(s.limit!=null||s.offset!=null||s.orderBy!=null)&&(e.query={...s.limit!=null?{limit:s.limit}:{},...s.offset!=null?{offset:s.offset}:{},...s.orderBy!=null?{orderBy:s.orderBy}:{}})}emitRequest(e){this.events.request.hasSubscribers&&this.events.request.emit(Kr(e))}emitUserDenial(e,n){e==="user"&&this.events.denial.emit(n)}}class bA{events;triggerScope;rules;simulator;host;clock;operationReader;listAuthorizer;constructor(e,n,s,r,i,o,a=new Pt){this.events=e,this.triggerScope=n,this.rules=s,this.simulator=r,this.host=i,this.clock=a,this.operationReader=new W0(e,s,r,i,o,a),this.listAuthorizer=new yA(e,s,r,i,a)}get state(){return this.host.state}emitRequest(e){this.events.request.hasSubscribers&&this.events.request.emit(Kr(e))}execute(e){return this.operationReader.execute(e)}silentReadDoc(e,n,s=!1){if(s){const w=this.state.get(e);return this.emitRequest({at:this.clock.now(),evalMs:0,method:"get",path:e,auth:n,result:"allow",debugMessages:["admin lens — rules bypassed"],origin:"listener",resourceBefore:{data:w,exists:w!==null},detail:{admin:!0},...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}}),{allowed:!0,data:w}}const r=ye.fromMillis(this.clock.now()),i=Jr(this.state,{method:"get",path:e,auth:n},r),o=this.clock.now(),a=performance.now(),c=df(this.rules,this.simulator,[i],{getDoc:w=>this.state.get(w)}),u=performance.now()-a;if(!c.success)return this.emitRequest({at:o,evalMs:u,method:"get",path:e,auth:n,result:"deny",debugMessages:[`Simulation error: ${c.error.message}`],origin:"listener",...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}}),{allowed:!1,error:he("permission-denied",`get ${e} simulator error`,{request:{method:"get",path:e,auth:n}})};const l=c.data.results[0],d=this.rules.captureEvidence(l);if(l.state==="UNSUPPORTED")throw this.emitRequest({at:o,evalMs:u,method:"get",path:e,auth:n,result:"unsupported",rulesEvidence:d,debugMessages:ke(l),origin:"listener",...this.triggerScope.current()?{triggeredBy:this.triggerScope.current()}:{}}),new qn(Un("get",e,ke(l)),"get",e,ke(l));const f=l.state==="PASSED",p=this.state.get(e),h=en(l);let m="deny";f&&(m="allow");const g=p!==null,y={at:o,evalMs:u,method:"get",path:e,auth:n,result:m,debugMessages:ke(l),evaluatedRule:h,rulesEvidence:d,origin:"listener",resourceBefore:{data:p,exists:g}},b=this.triggerScope.current();if(b!==void 0&&(y.triggeredBy=b),this.emitRequest(y),f===!1){const w={request:{method:"get",path:e,auth:n},resource:{data:p,exists:g}};return h!==void 0&&(w.rule=h),{allowed:!1,error:he("permission-denied",`get ${e} denied by rules`,w)}}return{allowed:!0,data:p}}silentReadCollection(e,n,s,r=!1){if(typeof s=="function")return{allowed:!1,error:he("invalid-argument","Callable query constraints are no longer executable; pass an immutable QueryConstraintPlan.")};const i=s?_u(s.execution):void 0,o=i?xu(i):{},a={requestTime:ye.fromMillis(this.clock.now()),at:this.clock.now()},c=this.triggerScope.current(),u=Iu(e),l=this.listAuthorizer.authorize({path:u.kind==="collection"?u.path:u.collectionId,collectionGroup:u.kind==="collection-group",auth:n,constraints:o,bypassRules:r,...s?.activityQuery?{activityQuery:s.activityQuery}:{},execution:i,origin:"listener",...c?{triggeredBy:c}:{},timing:a});if(!l.allowed)return l;const d=Cu(this.state,u);return{allowed:!0,docs:i?Ru(d,i):d}}runQuery(e){const n=Iu(e.scope),s=_u(e.execution),r=e.auth,i=e.bypassRules,o=e.activityQuery,a=Cu(this.state,n),c=n.kind==="collection"?n.path:n.collectionId,u=xu(s),l=this.listAuthorizer.authorize({path:c,collectionGroup:n.kind==="collection-group",auth:r,constraints:u,bypassRules:i,...o!==void 0?{activityQuery:o}:{},execution:s,origin:"user"});return l.allowed?{allowed:!0,docs:Ru(a,s)}:l}}const Nu="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",Lu=20;function vA(){const t=new Uint8Array(Lu);globalThis.crypto.getRandomValues(t);let e="";for(let n=0;n<Lu;n++)e+=Nu[t[n]%Nu.length];return e}function yf(t,e=""){const n=[],s=new WeakSet;return r(t,e),n;function r(i,o){if(i==null||typeof i!="object"||s.has(i)||(s.add(i),Bd(i)!==void 0))return;if(Array.isArray(i)){i.forEach((u,l)=>r(u,`${o}[${l}]`));return}const a=i,c=wA(a);if(c){n.push({field:o,kind:c});return}for(const[u,l]of Object.entries(a)){const d=o?`${o}.${u}`:u;r(l,d)}}}function wA(t){const e=t.__type;return e==="serverTimestamp"?"serverTimestamp":e==="increment"?"increment":e==="arrayUnion"?"arrayUnion":e==="arrayRemove"?"arrayRemove":e==="deleteField"?"delete":null}DS();class SA{host;rules;simulator;eventLog;events;triggerScope;clock;constructor(e,n,s,r,i,o,a=new Pt){this.host=e,this.rules=n,this.simulator=s,this.eventLog=r,this.events=i,this.triggerScope=o,this.clock=a}get state(){return this.host.state}emitDenial(e){this.events.denial.emit(e)}emitRequest(e){this.events.request.hasSubscribers&&this.events.request.emit(Kr(e))}emitWrite(e){if(!this.events.write.hasSubscribers)return;const s={kind:"write",id:cs().replace(/^req-/,"wr-"),at:this.clock.now(),method:e.method,path:e.path,auth:null,priorState:e.priorState,nextState:e.nextState,requestTime:{seconds:e.requestTime.seconds,nanoseconds:e.requestTime.nanos}},{auth:r}=e;r!==null&&(s.auth={uid:r.uid},r.token&&(s.auth.token=r.token)),e.data!==void 0&&(s.data=e.data),e.updateMask!==void 0&&(s.updateMask=e.updateMask);const{merge:c}=e;c===!0?s.merge=!0:c!==void 0&&c!==!1&&(s.merge={mergeFields:[...c.mergeFields]}),e.groupId!==void 0&&(s.groupId=e.groupId),e.groupKind!==void 0&&(s.groupKind=e.groupKind),e.sentinels!==void 0&&e.sentinels.length>0&&(s.sentinels=e.sentinels),e.autoId!==void 0&&(s.autoId=e.autoId),e.detail!==void 0&&(s.detail=e.detail),this.events.write.emit({...s,...e.provenance})}capturePriors(e){const n={};for(const s of e){const r=this.state.get(s),i=r!==null;n[s]=i?{...r}:null}return n}captureEvidence(e){return this.rules.captureEvidence(e)}runSimulate(e,n,s){return ff(this.state,this.rules,this.simulator,e,n,s)}resolvePriorDocumentState(e,n,s){return n.has(e)?n.get(e)??null:s.exists(e)?s.get(e)??null:null}computeProjectedUpdate(e,n){return Gr(e??{},n??{})}computeProjectedOverwrite(e,n){return Hr(e??{},n??{})}buildBatchProjection(e,n=new Map){for(const s of e){if(s.method==="set"){n.set(s.path,un(s.data??{}).writes);continue}if(s.method==="delete"){n.set(s.path,null);continue}const o=this.resolvePriorDocumentState(s.path,n,this.state);if(s.method==="update"){const c=this.computeProjectedUpdate(o,s.data);n.set(s.path,c)}else{const c=this.computeProjectedOverwrite(o,s.data);n.set(s.path,c)}}return n}buildTestCase(e,n){return Jr(this.state,e,n)}notify(e,n){this.triggerScope.run({method:e,path:n[0]??""},()=>this.host.notifyListenersForPaths(new Set(n),{method:e,paths:n}))}}class bf{runtime;constructor(e){this.runtime=e}prepare(e,n){const s=ye.fromMillis(this.runtime.clock.now()),r=[],i=new Map;for(const[o,a]of e.entries())try{if(a.method==="update"&&i.get(a.path)===null)throw new Error(`Cannot delete then update document '${a.path}' in the same atomic write.`);const u=a.data!==void 0;let l=a.data;if(u){const f=i.has(a.path);let p;f?p=i.get(a.path)??null:p=this.runtime.state.get(a.path),l=ht({...a.data},{path:a.path,method:a.method,prior:p,serverTime:s});const{merge:h}=a;if(h!==void 0&&h!==!1){const y=h===!0?void 0:h.mergeFields;l=Hr(p??{},l,y)}}const d={method:a.method,path:a.path,data:l};r.push(d),this.runtime.buildBatchProjection([d],i)}catch(c){const u=c.message,l=he("invalid-argument",u),d=n.snapshot[a.path]??null,f={at:this.runtime.clock.now(),evalMs:0,method:a.ruleMethod,path:a.path,auth:n.auth,result:"deny",debugMessages:[`Write preparation error: ${u}`],resourceBefore:{data:d,exists:d!==null},origin:n.origin,groupId:n.groupId};return this.includesRequestData(n,a)&&Object.assign(f,is(a,a.preData)),n.bypassRules===!0&&(f.detail={admin:!0}),n.provenance!==void 0&&(f.provenance=n.provenance),{index:o,input:a,message:u,error:l,request:f}}return{context:n,inputs:e,resolvedOps:r,serverTime:s}}evaluateAndApply(e,n){const{context:s,resolvedOps:r,serverTime:i}=e,o=this.runtime.buildBatchProjection(r,n),a=e.inputs.map(f=>{if(f.method!=="set")return f;const h=o.get(f.path)===null;let m;return h?m="delete":m=this.runtime.state.get(f.path)!==null?"update":"create",{...f,ruleMethod:m}}),c=r.map((f,p)=>{const h=this.runtime.buildTestCase({method:a[p].ruleMethod,path:f.path,auth:s.auth,data:f.data},i);return h.data=o.get(f.path)??void 0,h}),u=[];let l=!0;for(const[f]of r.entries()){const p=a[f],h=s.snapshot[p.path]??null,m=this.runtime.clock.now(),g=performance.now(),y=this.runtime.runSimulate([c[f]],s.bypassRules,o),b=performance.now()-g;if(!y.success){const D=he("invalid-argument",y.error.message);u.push({path:p.path,method:p.ruleMethod,allowed:!1,debugMessages:[y.error.message],error:D,request:this.request(e,p,h,m,b,"deny",[`Simulation error: ${y.error.message}`])}),l=!1;continue}const w=y.data.results[0],k=ke(w);if(w.state==="UNSUPPORTED"){const D=this.request(e,p,h,m,b,"unsupported",k);throw D.rulesEvidence=this.runtime.captureEvidence(w),this.runtime.emitRequest(D),new qn(Un(p.ruleMethod,p.path,k),p.ruleMethod,p.path,k)}const R=w.state==="PASSED";let V="deny";R&&(V="allow");const G={path:p.path,method:p.ruleMethod,allowed:R,debugMessages:k,request:this.request(e,p,h,m,b,V,k)};if(G.request.rulesEvidence=this.runtime.captureEvidence(w),!R){const D=en(w),K=h!==null,q={request:{method:p.ruleMethod,path:p.path,auth:s.auth},resource:{data:h,exists:K}};this.includesRequestData(s,p)&&Object.assign(q.request,is(p,p.preData)),D!==void 0&&(q.rule=D),G.error=he("permission-denied",`${p.ruleMethod} ${p.path} denied by rules`,q),this.runtime.emitDenial(G.error),l=!1}u.push(G)}let d=null;if(l){const f=this.runtime.state.applyBatch(r);if(!f.success){l=!1;const h=f.errors?.[0];if(h!==void 0){const y=r[h.index]?.method==="create";d=he(y?"already-exists":"not-found",h.error);const b=u[h.index];b!==void 0&&(b.allowed=!1,b.error=d)}}}return{...e,inputs:a,outcomes:u,allowed:l,structuralError:d}}emitAndNotify(e){const{context:n,inputs:s,outcomes:r,serverTime:i}=e;e.allowed&&this.runtime.notify(n.origin,s.map(o=>o.path));for(const[o,a]of r.entries()){const c=s[o],u=e.allowed&&a.allowed,l=n.snapshot[c.path]??null;if(u){const d=c.ruleMethod==="delete";a.request.resourceAfter=d?{data:null,exists:!1}:{data:this.runtime.state.get(c.path),exists:this.runtime.state.get(c.path)!==null}}else a.request.resourceAfter={data:l,exists:l!==null};if(this.runtime.emitRequest(a.request),u){const f=c.preData!==void 0?is(c,c.preData):void 0,p=f?yf(f.resourceData):void 0,h=c.ruleMethod==="delete",m={method:c.ruleMethod,path:c.path,auth:n.auth,priorState:l,nextState:h?null:this.runtime.state.get(c.path),groupId:n.groupId,groupKind:n.origin,requestTime:i,merge:c.merge};!h&&f!==void 0&&(m.data=f.resourceData,f.updateMask!==void 0&&(m.updateMask=f.updateMask)),p!==void 0&&p.length>0&&(m.sentinels=p),n.bypassRules===!0&&(m.detail={admin:!0}),n.provenance!==void 0&&(m.provenance=n.provenance),this.runtime.emitWrite(m)}}}request(e,n,s,r,i,o,a){const{context:c}=e,u={at:r,evalMs:i,method:n.ruleMethod,path:n.path,auth:c.auth,result:o,debugMessages:a,resourceBefore:{data:s,exists:s!==null},origin:c.origin,groupId:c.groupId};return this.includesRequestData(c,n)&&Object.assign(u,is(n,n.preData)),c.bypassRules===!0&&(u.detail={admin:!0}),c.provenance!==void 0&&(u.provenance=c.provenance),u}includesRequestData(e,n){return n.preData!==void 0&&(e.origin==="batch"||n.ruleMethod!=="delete")}}class AA{runtime;pipeline;constructor(e){this.runtime=e,this.pipeline=new bf(e)}batch(e,n,s){const r=this.runtime.capturePriors(e.map(v=>v.path)),i=`batch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o=e.map(v=>{const{method:w}=v,k=w==="set";let O;return k?O=r[v.path]!==null?"update":"create":O=w,{...v,ruleMethod:O,preData:v.data}}),a=this.pipeline.prepare(o,{origin:"batch",groupId:i,auth:n,bypassRules:s,snapshot:r}),u=n!==null?{uid:n.uid}:null;if(!("resolvedOps"in a)){const v=this.runtime.eventLog.append({type:"batch",method:"batch",path:"",auth:u,allowed:!1,operations:e.map(w=>({method:w.method,path:w.path,data:w.data,allowed:!1})),debugMessages:[`Write preparation error on '${a.input.path}': ${a.message}`]});return this.runtime.emitRequest(a.request),{allowed:!1,results:e.map(w=>{const k={path:w.path,allowed:!1,debugMessages:[a.message]};return w.path===a.input.path&&(k.error=a.error),k}),event:v,error:a.error}}const d=this.pipeline.evaluateAndApply(a),f=d.outcomes.map(v=>{const w={path:v.path,allowed:v.allowed,debugMessages:v.debugMessages};return v.error!==void 0&&(w.error=v.error),w}),{allowed:p}=d,h=this.runtime.eventLog.append({type:"batch",method:"batch",path:"",auth:u,allowed:p,priorDocs:p?r:void 0,operations:d.resolvedOps.map((v,w)=>({method:v.method,path:v.path,data:v.data,allowed:f[w]?.allowed??!1})),debugMessages:p?["Batch committed"]:["Batch rolled back — one or more operations denied"]});this.pipeline.emitAndNotify(d);let m;!p&&(m=d.structuralError??f.find(v=>v.error)?.error??he("permission-denied","Batch denied"));const y={allowed:p,results:f,event:h};return m!==void 0&&(y.error=m),y}}const Mu="Firestore transactions require all reads to be executed before all writes.";class kA extends Error{simError;constructor(){super(Mu),this.name="ReadAfterWriteError",this.simError=he("failed-precondition",Mu)}}class Du extends Error{constructor(){super("A document read in the transaction changed before commit."),this.name="RetryableTransactionConflictError"}}class EA extends Error{simError=he("failed-precondition","Transaction failed all retries.");constructor(){super("Transaction failed all retries."),this.name="TransactionAttemptsExhaustedError"}}class ki extends Error{code;simError;constructor(e){super(e.message),this.name="TransactionReadDeniedError",this.code=e.code,this.simError=e}}class IA{versionReader;reader;reads=[];writes=[];readVersions=new Map;writeStarted=!1;constructor(e,n=()=>0){this.versionReader=n,this.reader=e}get(e){this.assertReadsAllowed();const n=this.reader(e);!this.readVersions.has(e)&&this.readVersions.set(e,this.versionReader(e)),this.reads.push({path:e,data:n});const i=n===null?null:_s(n);return{path:e,exists:i!==null,data:()=>i===null?void 0:i}}getAll(...e){return this.assertReadsAllowed(),e.map(n=>this.get(n))}set(e,n,s){const r={method:"set",path:e,data:n};if(s!==void 0){const o=typeof s=="object";r.merge=o?{mergeFields:[...s.mergeFields]}:s}this.queue(r)}create(e,n){this.queue({method:"create",path:e,data:n})}update(e,n){this.queue({method:"update",path:e,data:n})}delete(e){this.queue({method:"delete",path:e})}consume(){return{reads:this.reads,writes:this.writes,readVersions:this.readVersions}}hadWrites(){return this.writeStarted}queue(e){const{data:n}=e;n!==void 0&&(e.data=_s(n)),this.writeStarted=!0,this.writes.push(e)}assertReadsAllowed(){if(this.writeStarted)throw new kA}}class _A{runtime;pipeline;constructor(e){this.runtime=e,this.pipeline=new bf(e)}transaction(e,n){return this.runAttempt(e,n,1)}runAttempt(e,n,s){const r=this.runtime.state.snapshot(),i=this.runtime.state.currentVersion(),o=new Map(Object.keys(r).map(h=>[h,this.runtime.state.version(h)])),a=`tx-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,c=new Map;let u;const l=h=>{const m=r[h]??null;if(n.bypassRules!==!0){const y=this.evaluateTransactionRead(h,m,n,a,c);if(y!==null)throw u=y,new ki(y)}return m},d=new IA(l,h=>{const m=o.get(h);if(m!==void 0)return m;const y=this.runtime.state.version(h);return y<=i?y:-1});let f;try{f=e(d)}catch(h){if(h instanceof ki)return this.buildReadDeniedResult(d,n,h.simError);if(u!==void 0)return this.buildReadDeniedResult(d,n,u);throw this.logAbortedTransaction(d,n.auth,h),h}if(f!==null&&typeof f?.then=="function")return f.then(h=>{try{return this.commitTransaction(d,r,n,h,i,a,c,u)}catch(m){return this.retryOrThrow(m,e,n,s)}},h=>{if(h instanceof ki)return this.buildReadDeniedResult(d,n,h.simError);if(u!==void 0)return this.buildReadDeniedResult(d,n,u);throw this.logAbortedTransaction(d,n.auth,h),h});try{return this.commitTransaction(d,r,n,f,i,a,c,u)}catch(h){return this.retryOrThrow(h,e,n,s)}}retryOrThrow(e,n,s,r){if(!(e instanceof Du))throw e;const o=s.maxAttempts??5;if(r>=o)throw new EA;return this.runAttempt(n,s,r+1)}commitTransaction(e,n,s,r,i,o,a,c){if(c!==void 0)return this.buildReadDeniedResult(e,s,c);const{reads:l,writes:d,readVersions:f}=e.consume();for(const[x,S]of f)if(this.runtime.state.version(x)!==S)throw new Du;if(s.bypassRules!==!0&&l.length>0&&this.runtime.state.currentVersion()!==i){const x=new Map(a);for(const S of l){const _=this.runtime.state.get(S.path),P=this.evaluateTransactionRead(S.path,_,s,o,x);if(P!==null)return this.buildReadDeniedResult(e,s,P,l)}}const h=s.auth;if(d.length===0){const x=h!==null,S=this.runtime.eventLog.append({type:"transaction",method:"transaction",path:"",auth:x?{uid:h.uid}:null,allowed:!0,reads:l.map(_=>({path:_.path,data:_.data})),operations:[],snapshot:n,debugMessages:["Transaction committed (read-only — no writes queued)"]});return{allowed:!0,reads:[...l],writes:[],returnValue:r,event:S}}const g=Object.fromEntries(d.map(x=>[x.path,n[x.path]??null])),y=d.map(x=>{const{method:S}=x,_=S==="set";let P;return _?P=this.runtime.state.get(x.path)!==null?"update":"create":P=S,{...x,ruleMethod:P,preData:x.data}}),b=this.pipeline.prepare(y,{origin:"transaction",groupId:o,auth:h,bypassRules:s.bypassRules,provenance:s.provenance,snapshot:g});if(!("resolvedOps"in b)){const x=h!==null,S=this.runtime.eventLog.append({type:"transaction",method:"transaction",path:"",auth:x?{uid:h.uid}:null,allowed:!1,aborted:!0,error:{name:"FirebaseError",message:b.message,code:b.error.code},reads:l.map(_=>({path:_.path,data:_.data})),operations:d.map(_=>({method:_.method,path:_.path,data:_.data,allowed:!1})),debugMessages:[`Write preparation error on '${b.input.path}': ${b.message}`]});return this.runtime.emitRequest(b.request),{allowed:!1,reads:[...l],writes:this.summarizeWrites(y.map((_,P)=>{const $=P===b.index,z={path:_.path,method:_.ruleMethod,allowed:!1,debugMessages:$?[b.message]:[]};return $&&(z.error=b.error),z})),returnValue:r,event:S,error:b.error}}const w=this.pipeline.evaluateAndApply(b,a),k=w.outcomes.map(x=>{const S={path:x.path,method:x.method,allowed:x.allowed,debugMessages:x.debugMessages};return x.error!==void 0&&(S.error=x.error),S}),{allowed:O}=w,R=h!==null,V=this.runtime.eventLog.append({type:"transaction",method:"transaction",path:"",auth:R?{uid:h.uid}:null,allowed:O,reads:l.map(x=>({path:x.path,data:x.data})),operations:w.resolvedOps.map((x,S)=>({method:x.method,path:x.path,data:x.data,allowed:k[S]?.allowed??!1})),snapshot:O?n:void 0,debugMessages:O?["Transaction committed"]:["Transaction rolled back — one or more operations denied"]});this.pipeline.emitAndNotify(w);let G;!O&&(G=w.structuralError??k.find(x=>x.error)?.error??he("permission-denied","Transaction denied"));const D={allowed:O,reads:[...l],writes:this.summarizeWrites(k),returnValue:r,event:V};return G!==void 0&&(D.error=G),s.readOnly===!0&&e.hadWrites()&&(D.readOnlyViolation=!0),D}summarizeWrites(e){const n=new Map;for(const s of e){const r=n.get(s.path);if(r===void 0){n.set(s.path,s);continue}const o=r.allowed&&s.allowed,a={path:s.path,method:s.method,allowed:o,debugMessages:[...r.debugMessages,...s.debugMessages]},c=r.error??s.error;c!==void 0&&(a.error=c),n.set(s.path,a)}return[...n.values()]}evaluateTransactionRead(e,n,s,r,i){const o=this.runtime.clock.now(),a=performance.now(),c=this.runtime.buildTestCase({method:"get",path:e,auth:s.auth}),u=this.runtime.runSimulate([c],s.bypassRules,i),l=performance.now()-a,d=n!==null;if(!u.success){const R={at:o,evalMs:l,method:"get",path:e,auth:s.auth,result:"deny",debugMessages:[`Simulation error: ${u.error.message}`],resourceBefore:{data:n,exists:d},origin:"transaction",groupId:r};return s.provenance!==void 0&&(R.provenance=s.provenance),this.runtime.emitRequest(R),he("invalid-argument",u.error.message)}const p=u.data.results[0],h=ke(p);if(p.state==="UNSUPPORTED"){const R={at:o,evalMs:l,method:"get",path:e,auth:s.auth,result:"unsupported",debugMessages:h,resourceBefore:{data:n,exists:d},origin:"transaction",groupId:r,rulesEvidence:this.runtime.captureEvidence(p)};throw s.provenance!==void 0&&(R.provenance=s.provenance),this.runtime.emitRequest(R),new qn(Un("get",e,h),"get",e,h)}if(p.state==="PASSED")return null;const y={at:o,evalMs:l,method:"get",path:e,auth:s.auth,result:"deny",debugMessages:h,resourceBefore:{data:n,exists:d},origin:"transaction",groupId:r,rulesEvidence:this.runtime.captureEvidence(p)};s.provenance!==void 0&&(y.provenance=s.provenance),this.runtime.emitRequest(y);const v=en(p),w={request:{method:"get",path:e,auth:s.auth},resource:{data:n,exists:d}};v!==void 0&&(w.rule=v);const O=he("permission-denied",`get ${e} denied by rules`,w);return this.runtime.emitDenial(O),O}buildReadDeniedResult(e,n,s,r){const i=r??e.consume().reads,o=n.auth,a=o!==null,c=this.runtime.eventLog.append({type:"transaction",method:"transaction",path:"",auth:a?{uid:o.uid}:null,allowed:!1,reads:i.map(u=>({path:u.path,data:u.data})),operations:[],debugMessages:["Transaction rolled back — read denied by rules"]});return{allowed:!1,reads:[...i],writes:[],returnValue:void 0,event:c,error:s}}logAbortedTransaction(e,n,s){const r=s,{reads:i}=e.consume(),o=n!==null,a={name:s.name,message:s.message};r.code!==void 0&&(a.code=String(r.code)),this.runtime.eventLog.append({type:"transaction",method:"transaction",path:"",auth:o?{uid:n.uid}:null,allowed:!1,aborted:!0,reads:i.map(u=>({path:u.path,data:u.data})),error:a,debugMessages:[`Transaction aborted: ${s.message}`]})}}class xA{runtime;batches;transactions;constructor(e,n,s,r,i,o,a=new Pt){this.runtime=new SA(e,n,s,r,i,o,a),this.batches=new AA(this.runtime),this.transactions=new _A(this.runtime)}capturePriors(e){return this.runtime.capturePriors(e)}applyWrite(e,n,s,r){if(r!==void 0&&r!==!1&&(e==="create"||e==="update")){const i=r===!0?void 0:r.mergeFields;return this.runtime.state.setMerge(n,s??{},i),null}switch(e){case"create":{const i=this.runtime.state.create(n,s??{});return i.success?null:he("already-exists",i.error??`Document '${n}' already exists`)}case"update":{const i=this.runtime.state.update(n,s??{});return i.success?null:he("not-found",i.error??`Document '${n}' does not exist`)}case"set":return this.runtime.state.set(n,s??{}),null;case"delete":return this.runtime.state.delete(n),null;default:return null}}execute(e){const{method:n,path:s,auth:r,data:i,autoId:o,requestTime:a,merge:c,bypassRules:u}=e,l=i?is(e,i):void 0,d=u?{admin:!0}:void 0,f=this.runtime.capturePriors([s]),p=a??ye.fromMillis(this.runtime.clock.now());let h;try{h=i&&ht({...i},{path:s,method:n,prior:this.runtime.state.get(s),serverTime:p}),n==="update"&&h&&BS(h)}catch(K){const q=K.message,x=this.runtime.eventLog.append({type:"single",method:n,path:s,auth:r?{uid:r.uid}:null,data:i,allowed:!1,priorDocs:f,debugMessages:[`FieldValue resolve error: ${q}`]});return this.runtime.emitRequest({at:this.runtime.clock.now(),evalMs:0,method:n,path:s,auth:r,result:"deny",debugMessages:[`FieldValue resolve error: ${q}`],...l??{},resourceBefore:{data:f[s]??null,exists:(f[s]??null)!==null},origin:"user",...d?{detail:d}:{}}),{allowed:!1,debugMessages:[q],event:x,error:he("invalid-argument",q)}}const m=this.runtime.buildTestCase({...e,data:h},p),g=this.runtime.clock.now(),y=performance.now(),b=this.runtime.runSimulate([m],u),v=performance.now()-y;if(!b.success){const K=this.runtime.eventLog.append({type:"single",method:n,path:s,auth:r?{uid:r.uid}:null,data:h,allowed:!1,priorDocs:f,debugMessages:[`Simulation error: ${b.error.message}`]});return this.runtime.emitRequest({at:g,evalMs:v,method:n,path:s,auth:r,result:"deny",debugMessages:[`Simulation error: ${b.error.message}`],...l??{},resourceBefore:{data:f[s]??null,exists:(f[s]??null)!==null},origin:"user",...d?{detail:d}:{}}),{allowed:!1,debugMessages:[b.error.message],event:K,error:he("invalid-argument",b.error.message)}}const w=b.data.results[0],k=this.runtime.captureEvidence(w);if(w.state==="UNSUPPORTED")throw this.runtime.emitRequest({at:g,evalMs:v,method:n,path:s,auth:r,result:"unsupported",rulesEvidence:k,debugMessages:ke(w),...l??{},resourceBefore:{data:f[s]??null,exists:(f[s]??null)!==null},origin:"user",...d?{detail:d}:{}}),new qn(Un(n,s,ke(w)),n,s,ke(w));let O=w.state==="PASSED",R=null;O&&(R=this.applyWrite(n,s,h,c),R&&(O=!1));const V=this.runtime.eventLog.append({type:"single",method:n,path:s,auth:r?{uid:r.uid}:null,data:h,allowed:O,priorDocs:O?f:void 0,debugMessages:ke(w)}),G={allowed:O,debugMessages:ke(w),event:V};if(O===!1){let K=!1;if(R!==void 0&&R!==null&&(K=!0),K)G.error=R;else{let x=null;const S=f[s];S!==void 0&&(x=S);let P=n;n==="set"&&(x!==null?P="update":P="create");const z=en(w),ne={request:{method:P,path:s,auth:r},resource:{data:x,exists:x!==null}};i!==void 0&&Object.assign(ne.request,l),z!==void 0&&(ne.rule=z),G.error=he("permission-denied",`${n} ${s} denied by rules`,ne),this.runtime.emitDenial(G.error)}}O&&this.runtime.notify(n,[s]);const N=f[s]??null,D=O?this.runtime.state.get(s):N;if(this.runtime.emitRequest({at:g,evalMs:v,method:n,path:s,auth:r,result:O?"allow":"deny",debugMessages:ke(w),evaluatedRule:en(w),rulesEvidence:k,...l??{},resourceBefore:{data:N,exists:N!==null},...n!=="delete"?{resourceAfter:{data:D,exists:D!==null}}:{resourceAfter:{data:null,exists:!1}},origin:"user",...d?{detail:d}:{}}),O){const K=l?yf(l.resourceData):void 0,q=o&&n==="create"?s.split("/").pop():void 0;this.runtime.emitWrite({method:n,path:s,auth:r,...n!=="delete"&&l?{data:l.resourceData,...l.updateMask?{updateMask:l.updateMask}:{}}:{},merge:c,priorState:N,nextState:n==="delete"?null:D,...K&&K.length>0?{sentinels:K}:{},...q?{autoId:q}:{},requestTime:p,...d?{detail:d}:{}})}return G}createWithAutoId(e,n,s,r){const i=e.endsWith("/")?e.slice(0,-1):e,o=vA(),a=`${i}/${o}`,c=this.execute({method:"create",path:a,auth:s,data:n,autoId:!0,bypassRules:r});return{path:a,result:c}}batch(e,n,s){return this.batches.batch(e,n,s)}transaction(e,n){return this.transactions.transaction(e,n)}}class $u{state;stateChanges=new Set;onStateChange(e){return this.stateChanges.add(e),()=>{this.stateChanges.delete(e)}}stateChanged=e=>{for(const n of this.stateChanges)n(e)};eventLog;history;simulator;rules;seedSnapshot;events=new XS;triggerScope=new e0;reads;writes;listeners;constructor(e=new Pt){this.state=new bi({},void 0,this.stateChanged),this.eventLog=new ZS(e);const n=this;this.simulator=new Xw,this.rules=new B0(YS),this.reads=new bA(this.events,this.triggerScope,this.rules,this.simulator,{get state(){return n.state}},this.eventLog,e),this.listeners=new $0(this.events,this.triggerScope,this.reads,e),this.writes=new xA({get state(){return n.state},notifyListenersForPaths:(s,r)=>n.listeners.notifyListenersForPaths(s,r)},this.rules,this.simulator,this.eventLog,this.events,this.triggerScope,e),this.history=new P0(this.eventLog,{get state(){return n.state},capturePriors:s=>this.writes.capturePriors(s),applyWrite:(s,r,i,o)=>this.writes.applyWrite(s,r,i,o)}),this.seedSnapshot={}}onDenial(e){return this.events.denial.subscribe(e)}onRequest(e){return this.events.request.subscribe(e)}onWrite(e){return this.events.write.subscribe(e)}onSnapshotDelivery(e){return this.events.delivery.subscribe(e)}onSnapshotSuppressed(e){return this.events.suppressed.subscribe(e)}onListenerLifecycle(e){return this.events.lifecycle.subscribe(e)}onSnapshotError(e){return this.events.snapshotError.subscribe(e)}addSnapshotListener(e,n,s={},r=null,i,o=!1,a=!1,c){return this.listeners.addSnapshotListener(e,n,s,r,i,o,a,c)}flushListeners(){this.listeners.flushListeners()}getSnapshotListenerCount(){return this.listeners.getSnapshotListenerCount()}dispose(){this.listeners.dispose(),this.events.clear(),this.stateChanges.clear()}seed(e){return this.rules.set(e.rules),this.state=e.baseDocuments?new bi({},new GS(e.baseDocuments),this.stateChanged):new bi(e.documents??{},void 0,this.stateChanged),this.stateChanged(null),this.seedSnapshot=e.baseDocuments??this.state.snapshot(),this.eventLog.clear(),Vi(e.rules)}deployRules(e){const n=Vi(e);return this.rules.set(e),this.listeners.reEvaluateAllListeners(),n}reevaluateLiveListeners(e,n){this.listeners.reevaluateLiveListeners(e,n)}getRules(){return this.rules.source}getDocument(e){return this.state.get(e)}listDocuments(e){return this.state.list(e)}runQuery(e){return this.reads.runQuery(e)}listRootCollections(){return this.state.listRootCollections()}listSubcollections(e){return this.state.listSubcollections(e)}snapshot(){return this.state.snapshot()}adminSetDocument(e,n){this.state.set(e,n??{}),this.listeners.notifyListenersForPaths(new Set([e]))}adminDeleteDocument(e){const n=this.state.delete(e);return n.success&&this.listeners.notifyListenersForPaths(new Set([e])),{deleted:n.success}}execute(e){return e.method==="get"||e.method==="list"?this.reads.execute(e):this.writes.execute(e)}createWithAutoId(e,n,s,r){return this.writes.createWithAutoId(e,n,s,r)}batch(e,n,s){return this.writes.batch(e,n,s)}transaction(e,n){return this.writes.transaction(e,n)}undo(){return this.history.undo()}redo(){return this.history.redo()}getEvents(){return this.history.getEvents()}getEventRetention(){return this.eventLog.getRetention()}getEventCount(){return this.history.getEventCount()}}function CA(t,e,n){const s=t.execute({method:"set",path:e,data:n??{},auth:null,bypassRules:!0});s.allowed||vf(s,e)}function OA(t,e){if(t.getDocument(e)===null)return{deleted:!1};const s=t.execute({method:"delete",path:e,auth:null,bypassRules:!0});return s.allowed||vf(s,e),{deleted:!0}}function vf(t,e){const n=he("failed-precondition",`admin write to '${e}' was not applied: ${t.debugMessages.join("; ")}`);throw new xs(t.error??n)}const TA=/password|credential|secret|token|authorization|cookie|api[-_]?key/i;function RA(t){return t.replace(/\bBearer\s+[A-Za-z0-9._~+\/-]+=*/gi,"Bearer [redacted]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g,"[redacted token]").replace(/((?:password|api[-_]?key|access[-_]?token|refresh[-_]?token|secret)["']?\s*[:=]\s*["']?)[^\s"',;}]+/gi,"$1[redacted]")}function NA(t,e=16384){try{const n=JSON.stringify(t,(s,r)=>TA.test(s)?"[redacted]":typeof r=="string"?RA(r):r,2);return n===void 0?void 0:{text:n.slice(0,e),truncated:n.length>e}}catch{return}}function wo(t){return t.kind==="request"||t.kind==="operation"||t.kind==="listener"&&t.phase==="errored"}function $s(t){const e=Object.freeze({...t.source}),n=Object.freeze({...t.authLens});return Object.freeze({source:e,authLens:n,...t.planId===void 0?{}:{planId:t.planId}})}function xk(t){const e=$s(t);return{actor:e.source,authLens:e.authLens,operationContext:e,...e.planId===void 0?{}:{planId:e.planId}}}function Pu(t){const e=t?.operationContext?.source;if(e&&e.kind!=="unattributed")return e;if(t?.actor&&t.actor.kind!=="unattributed")return t.actor}function ma(t,e){const n=t?.operationContext?.source??t?.actor,s=e?.operationContext?.source??e?.actor;return $s({source:Pu(t)??Pu(e)??n??s??{kind:"unattributed"},authLens:e?.operationContext?.authLens??e?.authLens??t?.operationContext?.authLens??t?.authLens??{mode:"app-session"},...(t?.operationContext?.planId??t?.planId??e?.operationContext?.planId??e?.planId)===void 0?{}:{planId:t?.operationContext?.planId??t?.planId??e?.operationContext?.planId??e?.planId}})}function wf(t){return ma(void 0,t)}function LA(t){if(t.result==="deny")return!0;if(!("error"in t)||!t.error||typeof t.error!="object")return!1;const e=t.error.code;if(typeof e!="string")return!1;const n=e.toLowerCase();return n==="permission_denied"||n==="permission-denied"||n==="auth/permission-denied"}function Sf(t){return"rulesDisposition"in t&&t.rulesDisposition?t.rulesDisposition:t.kind==="operation"&&t.origin==="admin"?{kind:"bypassed",reason:"admin"}:t.detail?.admin===!0?{kind:"bypassed",reason:"admin"}:LA(t)?{kind:"evaluated",verdict:"deny"}:t.result==="unsupported"?{kind:"not-evaluated",reason:"unsupported"}:t.kind==="operation"&&t.result==="error"?{kind:"not-evaluated",reason:"runtime-error"}:t.kind==="operation"&&t.result==="not-applicable"?{kind:"not-evaluated",reason:"not-a-rules-operation"}:t.kind==="listener"?t.rules?{kind:"evaluated",verdict:"deny"}:{kind:"not-evaluated",reason:"runtime-error"}:t.kind==="request"?{kind:"evaluated",verdict:"allow"}:"rules"in t&&t.rules?{kind:"evaluated",verdict:"allow"}:{kind:"not-evaluated",reason:"no-rules"}}function MA(t){if(t===null)return null;let e;return t.token!==void 0&&(e=Af(t.token)),Object.freeze({uid:t.uid,...e===void 0?{}:{token:e}})}function Af(t){const e={};for(const[n,s]of Object.entries(t))e[n]=ga(s);return Object.freeze(e)}function ga(t){return Array.isArray(t)?Object.freeze(t.map(ga)):t&&typeof t=="object"?Af(t):t}function DA(t){if(wo(t))return t;if(!(t.kind==="service_mutation"&&t.service==="auth"))return null;const n=s=>{const r=NA(s);if(!(!r||r.truncated))return JSON.parse(r.text)};return{kind:"operation",id:t.id,at:t.at,service:"auth",method:t.op,path:t.path,auth:t.auth,origin:"user",result:"not-applicable",rulesDisposition:{kind:"not-evaluated",reason:"not-a-rules-operation"},operationContext:wf(t),detail:{transition:t.op,evidence:n(t.detail)},resourceBefore:t.before===void 0?void 0:{data:n(t.before),exists:!0},resourceAfter:t.after===void 0?void 0:{data:n(t.after),exists:!0}}}function Ck(t){const e=DA(t);if(!e)return null;let n="listen",s;e.kind==="request"||e.kind==="operation"?(n=e.method,e.path!==void 0&&(s=e.path)):e.kind==="listener"&&(n="listen",e.target.path!==void 0&&(s=e.target.path));let r="firestore";e.service!==void 0&&(r=e.service);let i;return"queryProof"in e&&e.queryProof&&(i=ga(e.queryProof)),Object.freeze({id:e.kind==="operation"?e.observation?.id??e.id:e.id,at:e.kind==="operation"?e.observation?.startedAt??e.at:e.at,...e.kind==="operation"&&e.observation?{observation:e.observation}:{},eventKind:e.kind,service:r,method:n,...s===void 0?{}:{path:s},auth:MA(e.auth),result:e.result,context:wf(e),rules:Object.freeze({...Sf(e)}),queryProof:i})}function Fu(t){if(t===null)return null;if(t.tenant===void 0)return t.token===void 0?{uid:t.uid}:{uid:t.uid,token:structuredClone(t.token)};const e=t.token!==void 0?structuredClone(t.token):{},n=e.firebase;let s;if(typeof n=="object"&&n!==null&&!Array.isArray(n)){const r=n;s={...r,tenant:r.tenant!==void 0?r.tenant:t.tenant}}else s={tenant:t.tenant};return e.firebase=s,{uid:t.uid,tenant:t.tenant,token:e}}function ju(t){if(t===null)return{mode:"anon"};const e={mode:"as",uid:t.uid};return t.token!==void 0&&(e.token=t.token),t.tenant!==void 0&&(e.tenant=t.tenant),e}class Qr{sandbox;auth;operationContext;constructor(e,n,s){this.sandbox=e,Nr(n);const r=Fu(n);this.auth=r,this.operationContext=$s(s??{source:{kind:"unattributed"},authLens:ju(r)})}withAuth(e){Nr(e);const n=Fu(e);return new Qr(this.sandbox,n,{source:this.operationContext.source,authLens:ju(n),...this.operationContext.planId===void 0?{}:{planId:this.operationContext.planId}})}}function Ok(t,e){return new Qr(t.sandbox,t.auth,e)}function Nr(t){if(t===null)return;if(t===void 0)throw new ut({code:"invalid-argument",message:"withAuth() requires an explicit AuthState argument.",remediation:["For anonymous (unauthenticated) access: withAuth(null)",'For authenticated access: withAuth({ uid: "someUid" })','For custom claims: withAuth({ uid: "someUid", token: { role: "admin" } })'].join(`
|
|
1725
|
+
`)});if(typeof t!="object")throw new ut("invalid-argument","withAuth() expected null or an object with a `uid` field.");const e=t;if(typeof e.uid!="string"||e.uid.length===0)throw new ut("invalid-argument","withAuth() requires `uid` to be a non-empty string.");if("tenant"in e&&e.tenant!==void 0&&(typeof e.tenant!="string"||e.tenant.length===0))throw new ut("invalid-argument","withAuth() requires `tenant` (when present) to be a non-empty string.");if("token"in e&&e.token!==void 0&&(e.token===null||typeof e.token!="object"||Array.isArray(e.token)))throw new ut("invalid-argument","withAuth() requires `token` (when present) to be a plain object.")}class Vt{bytes;constructor(e){this.bytes=e,Is(this,PS(e)),jn(this,Object.freeze({type:"bytes",values:Object.freeze(Array.from(e))}),()=>new Vt(e.slice()))}static fromBase64String(e){const n=atob(e),s=Uint8Array.from(n,r=>r.charCodeAt(0));return new Vt(s)}static fromUint8Array(e){return new Vt(e.slice())}toBase64(){let e="";for(const n of this.bytes)e+=String.fromCharCode(n);return btoa(e)}toUint8Array(){return this.bytes.slice()}toString(){return`Bytes(base64: ${this.toBase64()})`}isEqual(e){return e instanceof Vt&&this.bytes.length===e.bytes.length&&this.bytes.every((n,s)=>n===e.bytes[s])}toJSON(){return{type:"firestore/bytes/1.0",bytes:this.toBase64()}}static fromJSON(e){const n=e;if(n.type!=="firestore/bytes/1.0"||typeof n.bytes!="string")throw new TypeError("Invalid Bytes JSON value.");return Vt.fromBase64String(n.bytes)}}class Tn{lat;lng;constructor(e,n){if(this.lat=e,this.lng=n,!Number.isFinite(e)||e<-90||e>90)throw new TypeError("Latitude must be a number between -90 and 90.");if(!Number.isFinite(n)||n<-180||n>180)throw new TypeError("Longitude must be a number between -180 and 180.");Is(this,Ir("geo-point",String(e),"\0",String(n))),jn(this,Object.freeze({type:"geo-point",latitude:e,longitude:n}),()=>new Tn(e,n))}get latitude(){return this.lat}get longitude(){return this.lng}isEqual(e){return e instanceof Tn&&this.lat===e.lat&&this.lng===e.lng}toJSON(){return{latitude:this.lat,longitude:this.lng,type:"firestore/geoPoint/1.0"}}static fromJSON(e){const n=e;if(n.type!=="firestore/geoPoint/1.0"||typeof n.latitude!="number"||typeof n.longitude!="number")throw new TypeError("Invalid GeoPoint JSON value.");return new Tn(n.latitude,n.longitude)}}class Tt{_values;constructor(e){this._values=e,jn(this,Object.freeze({type:"vector",values:Object.freeze(e.slice())}),()=>new Tt(e.slice()))}static create(e){if(!e.every(s=>typeof s=="number"))throw new TypeError("Vector values must be numbers.");return new Tt(e.slice())}toArray(){return this._values.slice()}isEqual(e){if(!(e instanceof Tt))return!1;const s=e._values;return s!==void 0&&this._values.length===s.length&&this._values.every((r,i)=>r===s[i])}toJSON(){return{type:"firestore/vectorValue/1.0",vectorValues:this.toArray()}}static fromJSON(e){const n=e;if(n.type!=="firestore/vectorValue/1.0"||!Array.isArray(n.vectorValues)||!n.vectorValues.every(i=>typeof i=="number"))throw new TypeError("Invalid VectorValue JSON value.");return Tt.create(n.vectorValues)}}function Tk(t=[]){return Tt.create(t)}const $A=64;function ya(t){kf(t,0)}function kf(t,e){if(t===null||typeof t!="object")return;const s=e+1;if(s>$A)throw new At("invalid-argument","Encoded document nesting exceeds 64 containers.");for(const i of Object.values(t))kf(i,s)}function Ef(t){if(it(t))return t;throw new At("invalid-argument","Document data must be a plain object.")}const ba="pyric/firestore-values/1";function If(t){const e=t===void 0,n=t===ba;if(!e&&!n)throw new At("invalid-argument","Unsupported Firestore value encoding.");return n}function So(t){if(t===null||typeof t!="object")return t;if(t instanceof mt)return t.toJSON();if(t instanceof Date)return mt.fromDate(t).toJSON();if(t instanceof Vt||t instanceof Tn||t instanceof Tt)return t.toJSON();const a=ca(t);if(a!==void 0)return{__type:"reference",path:a};if(Array.isArray(t))return t.map(So);const l=Object.getPrototypeOf(t);if(l===Object.prototype||l===null){const f=Object.fromEntries(Object.entries(t).map(([h,m])=>[h,So(m)]));return Object.hasOwn(f,"type")||Object.hasOwn(f,"__type")||Object.hasOwn(f,"__type__")?{type:"pyric/map/1.0",fields:f}:f}return t}const _f={bytes:t=>new He(t),geoPoint:(t,e)=>new lt(t,e),reference:t=>new wt(t),timestamp:(t,e)=>new ye(t,e),vector:t=>new Qt(t)};function PA(t){const e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e.length%4===0?"":"=".repeat(4-e.length%4),s=atob(e+n),r=new Uint8Array(s.length);for(let i=0;i<s.length;i++)r[i]=s.charCodeAt(i);return r}function FA(t){const e=atob(t),n=new Uint8Array(e.length);for(let s=0;s<e.length;s++)n[s]=e.charCodeAt(s);return n}function jA(t){return Rn(t,!0,_f,!1)}function qA(t,e){ya(t);const n=If(e);return Rn(t,!0,_f,n)}function Rk(t,e,n){ya(t);const s=If(n);return Rn(t,!0,{bytes:r=>Vt.fromUint8Array(r),geoPoint:(r,i)=>new Tn(r,i),reference:r=>e.create(r),timestamp:(r,i)=>new mt(r,i),vector:r=>Tt.create(r.slice())},s)}function Rn(t,e,n,s){if(t===null||typeof t!="object")return t;if(Array.isArray(t)){const h=t.map(m=>Rn(m,!1,n,s));return e&&Is(h,au(t)),h}const o=t,a=h=>(e&&Is(h,au(t)),h),c=(h,m)=>(jn(h,Object.freeze(m),()=>h),a(h));if(o.__type__==="__vector__"&&Array.isArray(o.value)){const h=Object.freeze(o.value.slice());return c(n.vector(h),{type:"vector",values:h})}if(typeof o.__type=="string")switch(o.__type){case"timestamp":return c(n.timestamp(o.seconds,o.nanos),{type:"timestamp",seconds:o.seconds,nanoseconds:o.nanos});case"bytes":{const h=PA(o.base64);return c(n.bytes(h),{type:"bytes",values:Object.freeze(Array.from(h))})}case"latlng":return c(n.geoPoint(o.lat,o.lng),{type:"geo-point",latitude:o.lat,longitude:o.lng});case"duration":return a(new Ae(o.seconds,o.nanos));case"reference":{const h=o.path;return a(n.reference(h))}case"path":return a(new st(o.segments))}if(s&&o.type==="pyric/map/1.0"){const h=o.fields;if(h===null||typeof h!="object"||Array.isArray(h))throw new TypeError("Invalid encoded map fields.");const g=Object.fromEntries(Object.entries(h).map(([y,b])=>[y,Rn(b,!1,n,s)]));return a(g)}if(typeof o.type=="string")switch(o.type){case"firestore/timestamp/1.0":{const h=o.seconds,m=o.nanoseconds;return c(n.timestamp(h,m),{type:"timestamp",seconds:h,nanoseconds:m})}case"firestore/bytes/1.0":{const h=FA(o.bytes);return c(n.bytes(h),{type:"bytes",values:Object.freeze(Array.from(h))})}case"firestore/geoPoint/1.0":return c(n.geoPoint(o.latitude,o.longitude),{type:"geo-point",latitude:o.latitude,longitude:o.longitude});case"firestore/vectorValue/1.0":{const h=Tt.fromJSON(o),m=Object.freeze(h.toArray());return c(n.vector(m),{type:"vector",values:m})}}const p={};for(const[h,m]of Object.entries(o))p[h]=Rn(m,!1,n,s);return a(p)}function xf(t){return Ef(JSON.parse(JSON.stringify(So(t))))}class zs extends Error{constructor(e){super(e),this.name="PersistenceSchemaError"}}function UA(t){let e;try{e=JSON.parse(t)}catch(u){const l=u instanceof Error;throw new zs(`Persisted blob is not valid JSON: ${l?u.message:String(u)}`)}if(typeof e!="object"||e===null)throw new zs("Persisted blob is not an object");if(e.version!==1&&e.version!==2)throw new zs(`Persisted blob has version ${String(e.version)}, expected 1 or 2`);if(typeof e.firestore!="object"||e.firestore===null)throw new zs("Persisted blob has no firestore field");const i={};for(const[u,l]of Object.entries(e.firestore))ya(l),i[u]=jA(l);const o=e.services;return{firestore:i,services:o!==void 0&&typeof o=="object"&&o!==null?o:{}}}const Cf=3,BA=256,Os="meta";function Of(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=e+((e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24))>>>0;return(e%BA).toString(16).padStart(2,"0")}function va(t){const e=JSON.stringify(t);let n=2166136261,s=0,r=s<e.length;for(;r;)n^=e.charCodeAt(s),n=Math.imul(n,16777619)>>>0,s+=1,r=s<e.length;return n}function Tf(t,e,n){const s=new Map;s.set(Os,{version:Cf,savedAt:n,services:e});for(const[r,i]of Object.entries(t)){const o=Of(r),c=s.get(o)??{docs:{},encoding:ba};s.set(o,c),c.docs[r]=xf(i)}for(const[r,i]of s)r!==Os&&(i.checksum=va(i.docs));return s}const Rf="pyric-v3-records";function Nk(t){return JSON.stringify({format:Rf,records:Object.fromEntries(t)})}function Lk(t){let e;try{e=JSON.parse(t)}catch{return new Map}const n=e;return n&&typeof n=="object"&&n.format===Rf&&typeof n.records=="object"&&n.records!==null?new Map(Object.entries(n.records)):Nf(t)??new Map}function Nf(t){let e;try{e=UA(t)}catch{return null}return Tf(e.firestore,e.services,0)}function zA(t,e={}){const n={};let s={};for(const[r,i]of t){if(r===Os){const f=i?.services;typeof f=="object"&&f!==null&&(s=f);continue}const a=i,c=a?.docs;if(typeof c!="object"||c===null)continue;if(typeof a?.checksum=="number"&&va(c)!==a.checksum){console.warn(`[sandbox/persistence] checksum mismatch for bucket '${r}'; skipping corrupt bucket`);continue}for(const[d,f]of Object.entries(c))try{n[d]=Ef(qA(f,a?.encoding))}catch(p){if(e.skipInvalidDocuments!==!0)throw p;console.warn(`[sandbox/persistence] skipping unreadable Firestore document '${d}' in bucket '${r}':`,p)}}return{firestore:n,services:s}}class WA{snapshot;read;paths=new Map;dirty;needsSnapshot=!0;constructor(e,n,s){this.snapshot=e,this.read=n,this.dirty=new Set(s)}mark(e){if(e===null){this.needsSnapshot=!0;return}const s=Of(e),r=this.paths.get(s)??new Set;r.add(e),this.paths.set(s,r),this.dirty.add(s)}prepare(){if(this.needsSnapshot){const i=this.snapshot();for(const o of this.paths.keys())this.dirty.add(o);this.paths.clear();for(const o of Object.keys(i))this.mark(o);this.needsSnapshot=!1}const e=this.dirty;this.dirty=new Set;const n=()=>{for(const i of e)this.dirty.add(i)},s=new Map,r=[];try{for(const i of e){const o={},a=this.paths.get(i)??new Set;for(const u of a){const l=this.read(u);l===null?a.delete(u):o[u]=xf(l)}a.size===0?(this.paths.delete(i),r.push(i)):s.set(i,{docs:o,encoding:ba,checksum:va(o)})}return{records:s,removed:r,retry:n}}catch(i){throw n(),i}}}const $n="snapshots";function qu(){const t=new Map,e=n=>{let s=t.get(n);return s||(s=new Map,t.set(n,s)),s};return{async getRecord(n,s){const r=t.get(n)?.get(s);return r===void 0?null:structuredClone(r)},async listRecords(n){return[...t.get(n)?.keys()??[]]},async putRecords(n,s){const r=e(n);for(const[i,o]of s)r.set(i,structuredClone(o))},async deleteRecords(n,s){const r=t.get(n);if(r)for(const i of s)r.delete(i)},async clear(n){t.delete(n)}}}function Lf(t){return new Promise((e,n)=>{const s=indexedDB.open(t,1);s.onupgradeneeded=()=>{const r=s.result;r.objectStoreNames.contains($n)||r.createObjectStore($n)},s.onsuccess=()=>e(s.result),s.onerror=()=>n(s.error??new Error(`Failed to open IndexedDB '${t}'`)),s.onblocked=()=>n(new Error(`IndexedDB open blocked for '${t}'`))})}function Ei(t,e,n){return Lf(t).then(s=>new Promise((r,i)=>{const o=s.transaction($n,e),a=o.objectStore($n),c=n(a);let u=null;c&&(c.onsuccess=()=>{u=c.result??null},c.onerror=()=>i(c.error)),o.oncomplete=()=>{s.close(),r(u)},o.onerror=()=>{s.close(),i(o.error)},o.onabort=()=>{s.close(),i(o.error??new Error("IndexedDB transaction aborted"))}}))}function Uu(t,e){return Lf(t).then(n=>new Promise((s,r)=>{const i=n.transaction($n,"readwrite");e(i.objectStore($n)),i.oncomplete=()=>{n.close(),s()},i.onerror=()=>{n.close(),r(i.error)},i.onabort=()=>{n.close(),r(i.error??new Error("IndexedDB transaction aborted"))}}))}function VA(){if(typeof indexedDB>"u")throw new Error('IndexedDB is not available in this environment. Use { backend: "memory" } or supply an injectedBackend.');return{async getRecord(t,e){return await Ei(t,"readonly",s=>s.get(e))??null},async listRecords(t){return(await Ei(t,"readonly",n=>n.getAllKeys())??[]).map(n=>String(n))},async putRecords(t,e){await Uu(t,n=>{for(const[s,r]of e)n.put(r,s)})},async deleteRecords(t,e){await Uu(t,n=>{for(const s of e)n.delete(s)})},async clear(t){await Ei(t,"readwrite",e=>e.clear())},async estimate(){if(typeof navigator>"u"||!navigator.storage?.estimate)return null;const t=await navigator.storage.estimate();return{usage:t.usage??0,quota:t.quota??0}}}}const GA=250,Bu="pyric:sandbox:auth-session";function Ii(t){return t==="auth"||t==="auth-session:[DEFAULT]"?Bu:`${Bu}:${encodeURIComponent(t)}`}function Mf(t){const e=JSON.stringify(t);let n=2166136261;for(let s=0;s<e.length;s++)n^=e.charCodeAt(s),n=Math.imul(n,16777619)>>>0;return n}function HA(t){if(t&&typeof t=="object"){if(t.name==="QuotaExceededError")return!0;const e=t.message;if(typeof e=="string"&&/quota/i.test(e))return!0}return!1}function KA(t){return t.injectedBackend?t.injectedBackend:(t.backend??"indexedDB")==="memory"||typeof indexedDB>"u"?qu():VA()}async function ZA(t,e){const n={...e,flushIntervalMs:e.flushIntervalMs??GA,backend:e.backend??"indexedDB"},s=KA(n),r=new Map,i=await JA(t,s,n.key,r),o=new Map(Object.entries(i??{})),a=new Map;let c=null,u=!1;const l=new Map,d=t instanceof vt?t:null,f=d?new WA(()=>d.getEnv().snapshot(),S=>d.getEnv().getDocument(S),[...r.keys()].filter(S=>S!==Os)):null,p=async()=>{if(u)return;const S=f?.prepare();try{const _={...Object.fromEntries(o)};let P;if(S!==void 0&&d!==null){for(const[le,Le]of d.getServiceRegistry())(!Le.subscribe||!a.has(le))&&a.set(le,structuredClone(Le.snapshot())),_[le]=a.get(le);P=new Map(S.records),P.set(Os,{version:Cf,savedAt:lu(t).now(),services:_})}else{const le=t.snapshot();P=Tf(le.firestore,{..._,...le.services},lu(t).now())}const z=new Map,ee=new Map;for(const[le,Le]of P){const pe=Mf(Le);ee.set(le,pe),r.get(le)!==pe&&z.set(le,Le)}const ne=S?.removed??[...r.keys()].filter(le=>!P.has(le)),Qe=s.applyChanges;Qe!==void 0?await Qe(n.key,z,ne):(z.size>0&&await s.putRecords(n.key,z),ne.length>0&&await s.deleteRecords(n.key,ne));for(const le of ne)r.delete(le);for(const[le,Le]of ee)r.set(le,Le)}catch(_){throw S?.retry(),_}};let h=Promise.resolve();const m=()=>(c&&(clearTimeout(c),c=null),h=h.then(p,p),h),g=()=>{u||c!==null||(c=setTimeout(()=>{c=null,m().catch(_=>{if(HA(_)){console.warn("[sandbox/persistence] storage quota exceeded; recent changes are kept in memory only. Free storage or reduce sandbox data to persist them.");return}if(s.retryFailedFlush===!1){console.warn("[sandbox/persistence] auto-flush failed; repair and restart required.");return}console.warn("[sandbox/persistence] auto-flush failed, will retry:",_),g()})},n.flushIntervalMs))},y=(S,_)=>{if(!_.subscribe||l.has(S))return;const P=_.subscribe(()=>{a.delete(S),g()});l.set(S,P)},b=new Map,v=new Map,w=(S,_)=>{if(!n.sessionStorage)return;const{local:P,session:$}=n.sessionStorage,z=Ii(S),ee=_.currentUid(),ne=_.mode();if(ee===null||ne==="NONE"){P.removeItem(z),$.removeItem(z);return}const Qe=JSON.stringify({uid:ee});ne==="LOCAL"?($.removeItem(z),P.setItem(z,Qe)):(P.removeItem(z),$.setItem(z,Qe))},k=S=>{if(!n.sessionStorage)return null;const _=Ii(S);for(const[P,$]of[["LOCAL",n.sessionStorage.local],["SESSION",n.sessionStorage.session]]){const z=$.getItem(_);if(z)try{const ee=JSON.parse(z);if(typeof ee?.uid=="string")return{uid:ee.uid,mode:P}}catch{$.removeItem(_)}}return null},O=S=>{if(!n.sessionStorage)return;const _=Ii(S);n.sessionStorage.local.removeItem(_),n.sessionStorage.session.removeItem(_)},R=(S,_,P)=>{if(P.session)try{P.session.restore(_.uid,_.mode),v.delete(S)}catch($){console.warn(`[sandbox/persistence] session restore for uid '${_.uid}' failed — clearing stored session:`,$),O(S),v.delete(S)}},V=(S,_)=>{if(!n.sessionStorage||!_.session||b.has(S))return;const P=_.session;b.set(S,P.subscribe(()=>w(S,P)))},G=(S,_)=>{if(!_.session)return;const P=v.get(S)??k(S);P&&R(S,P,_)};if(t instanceof vt){for(const[S,_]of t.getServiceRegistry())o.delete(S),y(S,_),G(S,_),V(S,_);t.setServiceRegistrationHook((S,_)=>{if(a.delete(S),o.has(S))try{_.restore(o.get(S)),o.delete(S)}catch(ee){console.warn(`[sandbox/persistence] late-restore for service '${S}' failed:`,ee)}const $=k(S);$!==null&&v.set(S,$),G(S,_),y(S,_),V(S,_),g()}),t.setServiceUnregistrationHook(S=>{a.delete(S),l.get(S)?.(),l.delete(S),b.get(S)?.(),b.delete(S),v.delete(S),g()})}const D=d?.onDocumentChange(S=>{f?.mark(S),S===null&&a.clear(),g()}),K=t.onEvent(S=>{QA(S)&&g()}),q=()=>{m().catch(()=>{})};return typeof window<"u"&&window.addEventListener("beforeunload",q),{options:n,flush:m,async clear(){c&&(clearTimeout(c),c=null),await s.clear(n.key),r.clear(),f?.mark(null)},dispose(){if(!u){u=!0,c&&(clearTimeout(c),c=null),K(),D?.();for(const S of l.values())S();l.clear();for(const S of b.values())S();b.clear(),t instanceof vt&&(t.setServiceRegistrationHook(null),t.setServiceUnregistrationHook(null)),typeof window<"u"&&window.removeEventListener("beforeunload",q)}}}}async function JA(t,e,n,s){let r;try{r=await e.listRecords(n)}catch(d){return console.warn("[sandbox/persistence] backend list failed:",d),null}if(r.length===0)return null;const i=[];for(const d of r)try{const f=await e.getRecord(n,d);f!==null&&i.push([d,f])}catch(f){console.warn(`[sandbox/persistence] failed to read persisted record '${d}':`,f)}const o=[],a=[];let c=null;for(const[d,f]of i)if(typeof f=="string"){const p=Nf(f);p&&(a.push(d),c=p)}else o.push([d,f]);if(c){try{await e.putRecords(n,c),a.length>0&&await e.deleteRecords(n,a)}catch(d){console.warn("[sandbox/persistence] v2 migration write failed:",d)}for(const[d,f]of c)o.push([d,f])}for(const[d,f]of o)s.set(d,Mf(f));const u=zA(o,{skipInvalidDocuments:!0}),l=t instanceof vt;for(const[d,f]of Object.entries(u.firestore))l?Rt(t).adminSetDocument(d,f):t.admin.setDocument(d,f);if(t instanceof vt){const d=t.getServiceRegistry();for(const[f,p]of Object.entries(u.services)){const h=d.get(f);if(h)try{h.restore(p)}catch(m){console.warn(`[sandbox/persistence] service '${f}' restore failed — Firestore state is intact; auth users may need to be re-created:`,m)}}}return u.services}function QA(t){return t.kind==="write"||t.kind==="session_boundary"}function YA(t){return typeof t=="object"&&t!==null&&typeof t.kind=="string"&&typeof t.origin=="string"}let XA=0;function ek(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`tab-${crypto.randomUUID()}`:`tab-${++XA}-${typeof performance<"u"?performance.now().toFixed(3):String(Date.now())}`}function tk(t,e={}){let n,s=!1;if(e.channel)n=e.channel,s=!1;else if(typeof BroadcastChannel<"u")n=new BroadcastChannel("pyric:tabsync"),s=!0;else return()=>{};const r=e.originId??ek();let i=!1,o=!1;const a=t.onEvent(d=>{if(d.kind!=="write"||i)return;const f={kind:"write",origin:r,event:d};n.postMessage(f)}),c=d=>{if(!YA(d.data))return;const f=d.data;if(f.origin!==r){if(f.kind==="write")l(f.event);else if(f.kind==="hello"){const p={kind:"state",origin:r,to:f.origin,snapshot:t.snapshot()};n.postMessage(p)}else if(f.kind==="state"){if(f.to!==r||o)return;if(Object.keys(Rt(t).snapshot()).length>0){o=!0;return}i=!0;try{for(const[h,m]of Object.entries(f.snapshot.firestore))Rt(t).adminSetDocument(h,m)}finally{i=!1}o=!0}}};n.addEventListener("message",c);const u={kind:"hello",origin:r};return n.postMessage(u),()=>{a(),n.removeEventListener("message",c),s&&n.close()};function l(d){i=!0;try{if(d.method==="delete")Rt(t).adminDeleteDocument(d.path);else{const f=d.nextState;f!=null&&Rt(t).adminSetDocument(d.path,f)}}finally{i=!1}}}function nk(t,e=!1,n=!0){if(!t||typeof t!="object")return{unmeasured:1};const s=t;if(s.metadata?.fromCache)return{documentReads:0};if(Array.isArray(s.docs)){if(!e||n)return{documentReads:Math.max(1,s.docs.length)};if(!s.docChanges)return{unmeasured:1};const r=s.docChanges();return{documentReads:r.filter(i=>i.type==="added"||i.type==="modified").length,...r.some(i=>i.type==="removed")?{unmeasured:1}:{}}}if(s.exists!==void 0){const r=typeof s.exists=="function"?s.exists():s.exists;return{documentReads:!e||n||r?1:0}}return{unmeasured:1}}function sk(t){if(!t||typeof t!="object"||!("val"in t)||typeof t.val!="function")return{unmeasured:1};const e=JSON.stringify(t.val());return e===void 0?{unmeasured:1}:{payloadBytes:new TextEncoder().encode(e).byteLength}}function rk(t){if(["setDoc","updateDoc","addDoc"].includes(t))return{documentWrites:1};if(t==="deleteDoc")return{documentDeletes:1};if(t==="writeBatch.commit"||t==="runTransaction")return{unmeasured:1}}function ik(t){return t==="database"?"rtdb":t}function ok(t,e,n,s){if(t.phase==="progress"||t.phase==="transport"&&!t.record.ai)return;const{record:r,phase:i}=t;return Object.freeze({...t.usage?{usage:Object.freeze({...t.usage})}:{},...r.ai?{ai:r.ai}:{},sequence:s,id:`${r.id}/${i}/${r.deliveryCount}`,activityId:r.id,appId:r.appId,sourceId:r.sourceId,service:ik(r.service),method:r.method,kind:r.kind,status:r.status,phase:i,deliveryNumber:r.deliveryCount,at:e,monotonicAt:n})}function ak(t={}){const e=t.now??Date.now,n=t.monotonicNow??(()=>performance.now()),s=t.correlationWindowMs??250,r=Math.max(t.retentionMs??3e4,s),i=t.maxCompleted??100,o=new WeakMap,a=new Map,c=new Map,u=new Set,l=new Set,d=[];let f=0,p=!1,h=0,m=0,g=0,y,b=!1,v,w=!1,k=!1;function O(N,D,K){const q=ok({phase:N,record:D,usage:K},e(),n(),f+1);if(q&&(f++,d.push({event:q,observers:[...l]})),!p){p=!0;try{for(;d.length;){const x=d.shift();for(const S of x.observers)try{S(x.event)}catch{}}}finally{p=!1}}for(const x of[...u])try{x({phase:N,record:D})}catch{}}function R(N){a.delete(N.id)&&(c.get(N.id)?.(),c.delete(N.id),O("remove",N))}const V=N=>Math.max(N.endedAt??0,N.lastProgressAt??0);function G(){if(!k){k=!0;try{clearTimeout(y),y=void 0;const N=[...a.values()].filter(K=>K.endedAt!==void 0).sort((K,q)=>V(K)-V(q)),D=e()-r;for(;N.length&&(V(N[0])<=D||N.length>i&&V(N[0])<=e()-s);)R(N.shift());if(N.length&&!b){const K=N.length>i?s:r;y=setTimeout(G,Math.max(1,V(N[0])+K-e())),typeof y=="object"&&"unref"in y&&y.unref()}}finally{k=!1}}}return{silence(N){const D=w;w=!0;try{return N()}finally{w=D}},isSilenced(){return w},registering(N,D){const K=v;v=N.id;try{return D()}finally{v=K}},registrationId(){return v},begin(N){if(b||w)return{id:"",delivered(){},progress(){},complete(){},fail(){},close(){},transport(){},ai(){},response(){}};let D=o.get(N.app);D||(D={id:`app-${++h}`,sources:new Map},o.set(N.app,D));const K=JSON.stringify([N.source.service,N.source.key]);let q=D.sources.get(K);q||(q={id:`${D.id}/source-${++m}`,uses:0},D.sources.set(K,q)),++q.uses;const x=`${D.id}/activity-${++g}`,S=Object.freeze({id:x,appId:D.id,sourceId:q.id,service:N.source.service,target:N.source.target,isQuery:N.source.isQuery??!1,...N.source.indexQuery?{indexQuery:structuredClone(N.source.indexQuery)}:{},method:N.method,kind:N.kind,status:N.kind==="operation"?"pending":"active",startedAt:e(),deliveryCount:0,owners:Object.freeze([...N.owners??[]]),...N.transportId===void 0?{}:{transportId:N.transportId}});if(!b){a.set(x,S);const $=D,z=q;c.set(x,()=>{--z.uses===0&&$.sources.delete(K)}),O("start",S)}function _($,z,ee){const ne=a.get(x);if(!ne||ne.endedAt!==void 0&&!($==="progress"&&ne.status==="completed"))return;const Qe=Object.freeze({...ne,...z});a.set(x,Qe),O($,Qe,ee)}function P($,z){_("end",{status:$,endedAt:e()},z),G()}return{id:x,delivered($,z){const ee=a.get(x);if(!ee||ee.kind==="operation"&&ee.deliveryCount>0)return;let ne;try{ne=z??(ee.service==="firestore"?ee.method.endsWith("FromCache")?{documentReads:0}:nk($,ee.kind==="subscription",ee.deliveryCount===0):sk($))}catch{ne={unmeasured:1}}_("delivery",{deliveryCount:ee.deliveryCount+1,lastDeliveryAt:e()},ne)},progress(){_("progress",{lastProgressAt:e()}),G()},complete($){P("completed",$??(S.service==="firestore"?rk(S.method):void 0))},fail($){P("failed",$)},response($){try{const z=JSON.stringify($,null,2);z!==void 0&&_("transport",{response:Object.freeze({text:z.slice(0,65536),truncated:z.length>65536})})}catch{}},ai($){_("transport",{ai:Object.freeze({...$})})},close(){P("closed")},transport($){_("transport",{transportId:$})}}},records(){return G(),[...a.values()]},subscribe(N){return b||u.add(N),()=>{u.delete(N)}},observe(N){return b||l.add(N),()=>{l.delete(N)}},dispose(){b=!0,clearTimeout(y);for(const N of[...a.values()])R(N);u.clear(),l.clear()}}}const zu=Symbol.for("pyric.sdk-activity"),Wu=globalThis,ck=Wu[zu]??(Wu[zu]=ak());function Mk(t,e){return t.delivered(e),t.complete(),e}function uk(t,e){const n={...t};if(t.kind==="listener_attach"||t.kind==="listener"&&t.phase==="attach"){const o=ck.registrationId();o&&(n.activity={...n.activity,listenerId:o})}n.service=t.service??e?.service??"firestore";const r="detail"in t&&t.detail?.admin===!0&&t.operationContext===void 0&&t.authLens===void 0?{...t,authLens:{mode:"admin"}}:t,i=wo(n)||t.operationContext!==void 0?ma(e,r):lk(t,e);return n.operationContext=i,n.actor=i.source,n.authLens=i.authLens,i.planId!==void 0&&(n.planId=i.planId),e?.activity!==void 0&&(n.activity={...n.activity,...e.activity}),wo(n)&&(n.rulesDisposition=Object.freeze({...Sf(n)})),n}function lk(t,e){return $s({source:t.actor??t.operationContext?.source??e?.actor??e?.operationContext?.source??{kind:"unattributed"},authLens:t.authLens??t.operationContext?.authLens??e?.authLens??e?.operationContext?.authLens??{mode:"app-session"},...(t.planId??t.operationContext?.planId??e?.planId??e?.operationContext?.planId)===void 0?{}:{planId:t.planId??t.operationContext?.planId??e?.planId??e?.operationContext?.planId}})}function dk(t,e){if(!t)return e;if(!e)return t;if(e.operationContext!==void 0)return Df(t,e);if(!(t.operationContext!==void 0||t.actor!==void 0||t.authLens!==void 0||t.planId!==void 0||e.actor!==void 0||e.authLens!==void 0||e.planId!==void 0))return{...t,...e};const s=$s({source:e.actor??t.operationContext?.source??t.actor??{kind:"unattributed"},authLens:e.authLens??t.operationContext?.authLens??t.authLens??{mode:"app-session"},...(e.planId??t.operationContext?.planId??t.planId)===void 0?{}:{planId:e.planId??t.operationContext?.planId??t.planId}});return{...t,...e,operationContext:s,actor:s.source,authLens:s.authLens,...s.planId===void 0?{}:{planId:s.planId}}}function Df(t,e){if(!t)return e;if(!e)return t;if(!(t.operationContext!==void 0||t.actor!==void 0||t.authLens!==void 0||t.planId!==void 0||e.operationContext!==void 0||e.actor!==void 0||e.authLens!==void 0||e.planId!==void 0))return{...t,...e};const s=ma(t,e);return{...t,...e,operationContext:s,actor:s.source,authLens:s.authLens,...s.planId===void 0?{}:{planId:s.planId}}}let fk=1;function ln(){const t=(fk++).toString(36),e=Math.random().toString(36).slice(2,7);return`sbe-${t}-${e}`}class vt{_env;eventSubs=new Set;envUnsubs=[];dispatchedCount=0;eventHistory;ambientProvenance;_currentUser=null;currentUserSubs=new Set;documentChanges=new Set;onDocumentChange(e){return this.documentChanges.add(e),()=>{this.documentChanges.delete(e)}}documentChanged=e=>{for(const n of this.documentChanges)n(e)};persistence=null;enablePersistencePromise=null;serviceRegistry=new Map;_onServiceRegistered=null;_onServiceUnregistered=null;clock;constructor(e,n,s){this.eventHistory=new nS(s),this._env=e,this.clock=n,Object.defineProperty(this,ef,{value:n,enumerable:!1}),this.attachToEnv()}static createRoot(e){const n=new Pt;return new vt(new $u(n),n,e)}getEnv(){return this._env}withAuth(e){return Nr(e),new Qr(this,e)}attachToEnv(){this.envUnsubs.push(this._env.onStateChange(this.documentChanged)),this.envUnsubs.push(this._env.onRequest(e=>{this.emitEvent(e)})),this.envUnsubs.push(this._env.onWrite(e=>{this.emitEvent(e)})),this.envUnsubs.push(this._env.onSnapshotDelivery(e=>this.emitEvent(e))),this.envUnsubs.push(this._env.onSnapshotSuppressed(e=>this.emitEvent(e))),this.envUnsubs.push(this._env.onListenerLifecycle(e=>this.emitEvent(e))),this.envUnsubs.push(this._env.onSnapshotError((e,n,s)=>{const r={kind:"listener_errored",id:ln(),at:this.clock.now(),listenerId:s,target:n.kind==="doc"?{kind:"doc",path:n.path}:{kind:"query",collection:n.collection,...n.collectionGroup?{collectionGroup:!0}:{}},auth:e.request?.auth??null,error:{code:"permission-denied",message:e.message}};this.emitEvent(r)}))}emitEvent(e,n){const s=Df(this.ambientProvenance,n);this.dispatch(uk(e,s))}runWithProvenance(e,n){const s=this.ambientProvenance;this.ambientProvenance=dk(s,e);try{return n()}finally{this.ambientProvenance=s}}dispatch(e){if(e={...e,observedAt:Date.now()},this.eventHistory.append(e),this.dispatchedCount++,this.eventSubs.size!==0)for(const s of this.eventSubs)try{const r=s(e);r!=null&&typeof r.then=="function"&&r.catch(()=>{})}catch{}}emitInternal(e,n){this.emitEvent(e,n)}onEvent(e){return this.eventSubs.add(e),()=>{this.eventSubs.delete(e)}}history(){return this.eventHistory.snapshot()}primeEventHistory(e){const n=this.eventHistory.length>0,s=e.length===0;if(n||s)return 0;for(const r of e)if(r.kind==="operation"&&r.observation?.status==="pending"){const o={...r.observation,status:"interrupted",error:{code:"host-restarted"}};this.eventHistory.append({...r,observation:o})}else this.eventHistory.append(r);return e.length}get admin(){return{getDocument:e=>this._env.getDocument(e),listDocuments:e=>this._env.listDocuments(e),setDocument:(e,n)=>CA(this._env,e,n),deleteDocument:e=>OA(this._env,e)}}reset(){const e={kind:"session_boundary",id:ln(),at:this.clock.now(),phase:"reset",priorOpCount:this.dispatchedCount};this.emitEvent(e),this.eventHistory.clear(),this._currentUser!==null&&(this._currentUser=null,this.notifyCurrentUserSubs(null));for(const s of this.envUnsubs)s();this.envUnsubs=[],this._env.dispose(),this._env=new $u(this.clock),this.attachToEnv(),this.documentChanged(null)}async resetAll(){this.reset();const e=[],n=[];for(const[s,r]of this.serviceRegistry)r.reset&&n.push(Promise.resolve().then(()=>r.reset()).catch(i=>{e.push(`${s}: ${i instanceof Error?i.message:String(i)}`)}));return await Promise.all(n),{errors:e}}dispose(){const e={kind:"session_boundary",id:ln(),at:this.clock.now(),phase:"dispose",priorOpCount:this.dispatchedCount};this.emitEvent(e);for(const n of this.envUnsubs)n();this.envUnsubs=[],this._env.dispose(),this.persistence&&(this.persistence.dispose(),this.persistence=null),this.serviceRegistry.clear(),this._onServiceRegistered=null,this._onServiceUnregistered=null,this.eventSubs.clear(),this.currentUserSubs.clear(),this.documentChanges.clear()}snapshot(){const e={};for(const[n,s]of this.serviceRegistry)e[n]=s.snapshot();return{firestore:this._env.snapshot(),services:e}}loadSnapshot(e){this.reset();for(const[n,s]of Object.entries(e.firestore))this._env.adminSetDocument(n,s);for(const[n,s]of this.serviceRegistry)if(n in e.services)try{s.restore(e.services[n])}catch(r){console.warn(`[sandbox] loadSnapshot: service '${n}' restore failed — Firestore is intact; that service's state may be incomplete:`,r)}}get currentUser(){return this._currentUser}set currentUser(e){Nr(e),!hk(this._currentUser,e)&&(this._currentUser=e,this.notifyCurrentUserSubs(e))}onCurrentUserChanged(e){return this.currentUserSubs.add(e),()=>{this.currentUserSubs.delete(e)}}notifyCurrentUserSubs(e){if(this._env.reevaluateLiveListeners(e),this.currentUserSubs.size!==0)for(const n of this.currentUserSubs)try{const s=n(e);s&&typeof s.then=="function"&&s.catch(()=>{})}catch{}}async enablePersistence(e){if(this.persistence){if(this.persistence.options.key!==e.key)throw new ut("failed-precondition",`Persistence already enabled with key '${this.persistence.options.key}'; cannot re-enable with key '${e.key}'. Dispose and recreate the sandbox.`);return}if(this.enablePersistencePromise)return this.enablePersistencePromise;this.enablePersistencePromise=(async()=>{const n=await ZA(this,e);this.persistence=n})();try{await this.enablePersistencePromise}finally{this.enablePersistencePromise=null}}enableTabSync(e){return tk(this,e)}async flush(){if(!this.persistence)throw new ut("failed-precondition","flush() called before enablePersistence()");await this.persistence.flush()}async clearPersistence(){this.persistence&&await this.persistence.clear()}registerPersistableService(e,n){if(this.serviceRegistry.has(e))throw new ut("failed-precondition",`registerPersistableService: a service named '${e}' is already registered on this sandbox. Each service name must be unique — the auth package registers 'auth' exactly once per sandbox.`);return this.serviceRegistry.set(e,n),this._onServiceRegistered&&this._onServiceRegistered(e,n),()=>{this.serviceRegistry.get(e)===n&&(this.serviceRegistry.delete(e),this._onServiceUnregistered?.(e))}}setServiceRegistrationHook(e){this._onServiceRegistered=e}setServiceUnregistrationHook(e){this._onServiceUnregistered=e}getServiceRegistry(){return this.serviceRegistry}}function hk(t,e){if(t===e)return!0;if(t===null||e===null||t.uid!==e.uid)return!1;const n=t.token===void 0?void 0:JSON.stringify(t.token),s=e.token===void 0?void 0:JSON.stringify(e.token);return n===s}function Rt(t){if(!(t instanceof vt))throw new ut("invalid-argument","Sandbox handle was not produced by initializeSandbox(); custom Sandbox implementations are not supported.");return t.getEnv()}function Dk(t,e,n){if(!(t instanceof vt))throw new ut("invalid-argument","Sandbox handle was not produced by initializeSandbox(); custom Sandbox implementations are not supported.");t.emitInternal(e,n)}function $k(t){const{at:e,...n}=t;return{kind:"service_mutation",id:ln(),at:e,...n}}function Pk(t){const{at:e,...n}=t;return{kind:"operation",id:ln(),at:e,...n}}function Fk(t){const{at:e,...n}=t;return{kind:"commit",id:ln(),at:e,...n}}function jk(t){const{at:e,...n}=t;return{kind:"listener",id:ln(),at:e,...n}}function qk(t){return vt.createRoot(t)}function Uk(t,e){return Rt(t).deployRules(e)}function Bk(t,e){const n=Rt(t);return n.seed({rules:n.getRules(),documents:e})}function zk(t){return Rt(t).snapshot()}function Wk(t,e={}){const n=e.recentEventLimit??10,s=Rt(t),r=s.getRules(),i=r?Vi(r):{warnings:[]},o=i.warnings.map(g=>({rule:g.rule,severity:g.severity,message:g.message})),a={errors:0,warnings:0,info:0};for(const g of i.warnings)g.severity==="error"?a.errors++:g.severity==="warning"?a.warnings++:a.info++;const c=r?cm(r):null;c!==null&&(o.unshift({rule:c.kind==="parse"?"PARSE_ERROR":"COMPILE_LIMIT",severity:"error",message:`Firestore ${c.message}`}),a.errors++);const u=s.snapshot(),l={};for(const g of Object.keys(u)){const y=g.split("/")[0]??"";y&&(l[y]=(l[y]??0)+1)}const d=t.history(),f=[];for(const g of d){const y=g.kind==="request",b=g.kind==="operation",v=g.kind==="listener";(y||b||v&&g.phase==="errored")&&f.push(g)}const p=[];for(const g of f)if(g.result==="deny")p.push(g);else{const b=g.error;b!==void 0&&b.code==="PERMISSION_DENIED"&&p.push(g)}const h=f.slice(-n).map(g=>{let y="";if(g.path!==void 0)y=String(g.path);else{const k=g.target;k!==void 0&&k.path!==void 0&&(y=String(k.path))}let b="listen";g.method!==void 0&&(b=String(g.method));let v="error";if(g.result!==void 0)v=String(g.result);else{const k=g.error;k!==void 0&&k.code==="PERMISSION_DENIED"&&(v="deny")}let w=null;return g.auth!==void 0&&(w=g.auth),{path:y,method:b,result:v,auth:w}}),m=p.slice(-n).map(g=>{let y="";if(g.path!==void 0)y=String(g.path);else{const R=g.target;R!==void 0&&R.path!==void 0&&(y=String(R.path))}let b="listen";g.method!==void 0&&(b=String(g.method));let v=null;g.auth!==void 0&&(v=g.auth);let w;typeof g.debugMessage=="string"&&(w=g.debugMessage);const k=g.evaluatedRule??g.rule??void 0,O=Array.isArray(g.debugMessages)?g.debugMessages:typeof g.debugMessage=="string"?[g.debugMessage]:void 0;return{path:y,method:b,auth:v,debugMessage:w,rule:k,reasons:O}});return{rules:{source:r,sizeBytes:new TextEncoder().encode(r).byteLength,isEmpty:r.trim().length===0,lint:{...a,findings:o}},documents:{totalCount:Object.keys(u).length,byCollection:l},events:{totalCount:d.length,recentDenials:m,recentRequests:h}}}export{ma as $,na as A,Ss as B,yt as C,As as D,Ls as E,At as F,Od as G,br as H,Wr as I,Fu as J,ck as K,T0 as L,er as M,bk as N,M0 as O,ut as P,Rs as Q,am as R,Pt as S,xl as T,vp as U,vk as V,te as W,He as X,hp as Y,Ok as Z,Qr as _,Bk as a,i0 as a$,xk as a0,oe as a1,me as a2,os as a3,Ge as a4,ye as a5,$i as a6,Qy as a7,dd as a8,ue as a9,tb as aA,Jy as aB,ab as aC,Gs as aD,md as aE,Oe as aF,ib as aG,gd as aH,yd as aI,Ns as aJ,uS as aK,t0 as aL,Mk as aM,Rt as aN,xs as aO,_k as aP,Lk as aQ,Nk as aR,KS as aS,O0 as aT,af as aU,p0 as aV,x0 as aW,Si as aX,Rk as aY,qA as aZ,o0 as a_,Mt as aa,Gb as ab,J as ac,tr as ad,ep as ae,on as af,Vb as ag,Hb as ah,Wb as ai,lt as aj,st as ak,iv as al,Bb as am,Hs as an,mb as ao,lp as ap,hb as aq,dp as ar,Ae as as,Di as at,Kh as au,Br as av,Dv as aw,hs as ax,Mv as ay,Fa as az,zk as b,rf as b0,vA as b1,ba as b2,So as b3,X0 as b4,Ef as b5,nS as b6,HS as b7,we as b8,Xt as b9,_s as bA,kA as bB,EA as bC,Zn as bD,Kn as bE,Mu as bF,Ak as bG,Tk as bH,wt as bI,Qt as bJ,Ek as bK,go as bL,Lt as ba,Ot as bb,Dn as bc,eo as bd,mn as be,hr as bf,lr as bg,Nr as bh,qu as bi,Ck as bj,wo as bk,Vt as bl,mt as bm,Tn as bn,nf as bo,Bd as bp,wk as bq,Sk as br,jn as bs,Is as bt,Gt as bu,fA as bv,Ir as bw,Ik as bx,kk as by,he as bz,qk as c,cm as d,ml as e,Bh as f,Ph as g,op as h,Wk as i,pk as j,Ua as k,gk as l,yk as m,es as n,mk as o,wf as p,Dk as q,Ug as r,Uk as s,$k as t,lu as u,Pk as v,Fk as w,jk as x,pt as y,oo as z};
|