@mistriwork/mistri 1.0.0-rc.12 → 1.0.0-rc.13
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/README.md +4 -3
- package/dist/client/assets/LayoutBuilder-MPzkVU2e.js.map +1 -1
- package/dist/client/assets/index-D2dHI6hR.js.map +1 -1
- package/dist/client/assets/shell-TreN_uLs.js.map +1 -1
- package/dist/docs/access-model.md +1 -1
- package/dist/docs/build-and-deploy.md +0 -1
- package/dist/docs/cli.md +1 -1
- package/dist/docs/glossary.md +3 -3
- package/dist/docs/query.md +9 -21
- package/dist/docs/status.md +3 -3
- package/dist/embed/react/chunks/LayoutBuilder-Cbxa_wve.js.map +1 -1
- package/dist/embed/react/chunks/app-0UZ1Re1k.js.map +1 -1
- package/dist/embed/react/chunks/page-Bx4o1kpQ.js.map +1 -1
- package/dist/embed/react/chunks/palette-Bb7Lf6eo.js.map +1 -1
- package/dist/embed/react/chunks/shell-DZRACiB9.js.map +1 -1
- package/dist/embed/react/chunks/write-BQO4CFc9.js.map +1 -1
- package/dist/embed/react/index.js +1 -1
- package/dist/server/build/dockerfile.js +1 -1
- package/dist/server/cli/usage.js +2 -2
- package/dist/ui/index.js +2 -2
- package/dist/ui/page.js +2 -2
- package/dist/ui/{shared-N4Ej8yRD.js → shared-1PD7TOTJ.js} +5 -5
- package/dist/ui/{shared-N4Ej8yRD.js.map → shared-1PD7TOTJ.js.map} +1 -1
- package/dist/ui/{shared-D5m86-4o.js → shared-1gMnOu9J.js} +6 -6
- package/dist/ui/{shared-D5m86-4o.js.map → shared-1gMnOu9J.js.map} +1 -1
- package/dist/ui/{shared-Ctaj8mR2.js → shared-5RQMi4BR.js} +3 -3
- package/dist/ui/{shared-Ctaj8mR2.js.map → shared-5RQMi4BR.js.map} +1 -1
- package/dist/ui/{shared-DpLeIATZ.js → shared-B-BUF9fx.js} +2 -2
- package/dist/ui/{shared-DpLeIATZ.js.map → shared-B-BUF9fx.js.map} +1 -1
- package/dist/ui/{shared-DWYnjItP.js → shared-B-MhiPIN.js} +9 -9
- package/dist/ui/{shared-DWYnjItP.js.map → shared-B-MhiPIN.js.map} +1 -1
- package/dist/ui/{shared-0fNuhSbG.js → shared-B07qIMlE.js} +5 -5
- package/dist/ui/{shared-0fNuhSbG.js.map → shared-B07qIMlE.js.map} +1 -1
- package/dist/ui/{shared-lYtMadRU.js → shared-B1SAS_J-.js} +3 -3
- package/dist/ui/{shared-lYtMadRU.js.map → shared-B1SAS_J-.js.map} +1 -1
- package/dist/ui/{shared-CpI0Y8M5.js → shared-B4jgU8h9.js} +6 -6
- package/dist/ui/{shared-CpI0Y8M5.js.map → shared-B4jgU8h9.js.map} +1 -1
- package/dist/ui/{shared-Cxu1c35l.js → shared-B5aBCUi7.js} +30 -30
- package/dist/ui/{shared-Cxu1c35l.js.map → shared-B5aBCUi7.js.map} +1 -1
- package/dist/ui/{shared-CAe-US1q.js → shared-B9H7_Pji.js} +5 -5
- package/dist/ui/{shared-CAe-US1q.js.map → shared-B9H7_Pji.js.map} +1 -1
- package/dist/ui/{shared-Q2bgBaYo.js → shared-BAXr20S-.js} +4 -4
- package/dist/ui/{shared-Q2bgBaYo.js.map → shared-BAXr20S-.js.map} +1 -1
- package/dist/ui/{shared-CyEefFFb.js → shared-BDDUzH-f.js} +19 -19
- package/dist/ui/{shared-CyEefFFb.js.map → shared-BDDUzH-f.js.map} +1 -1
- package/dist/ui/{shared-BdhPI6dq.js → shared-BGmkeDeW.js} +3 -3
- package/dist/ui/{shared-BdhPI6dq.js.map → shared-BGmkeDeW.js.map} +1 -1
- package/dist/ui/{shared-DONIpq2q.js → shared-BHCQ60yN.js} +2 -2
- package/dist/ui/{shared-DONIpq2q.js.map → shared-BHCQ60yN.js.map} +1 -1
- package/dist/ui/{shared-CNmaAv64.js → shared-BHsjawAG.js} +8 -8
- package/dist/ui/{shared-CNmaAv64.js.map → shared-BHsjawAG.js.map} +1 -1
- package/dist/ui/{shared-DgjU9kOy.js → shared-BIQuK_nq.js} +4 -4
- package/dist/ui/{shared-DgjU9kOy.js.map → shared-BIQuK_nq.js.map} +1 -1
- package/dist/ui/{shared-icSQAj21.js → shared-BOe4W2FI.js} +3 -3
- package/dist/ui/{shared-icSQAj21.js.map → shared-BOe4W2FI.js.map} +1 -1
- package/dist/ui/{shared-BlxoOJSk.js → shared-BPpC08ip.js} +3 -3
- package/dist/ui/{shared-BlxoOJSk.js.map → shared-BPpC08ip.js.map} +1 -1
- package/dist/ui/{shared-BtiFL37J.js → shared-BdA3LPCB.js} +2 -2
- package/dist/ui/{shared-BtiFL37J.js.map → shared-BdA3LPCB.js.map} +1 -1
- package/dist/ui/{shared-CvR94vn4.js → shared-Be3nbWsd.js} +11 -11
- package/dist/ui/{shared-CvR94vn4.js.map → shared-Be3nbWsd.js.map} +1 -1
- package/dist/ui/{shared-Bl_nF_IH.js → shared-Bf30ZLoS.js} +8 -4
- package/dist/ui/shared-Bf30ZLoS.js.map +1 -0
- package/dist/ui/{shared-DijrJ_V-.js → shared-BguP_BaR.js} +7 -7
- package/dist/ui/{shared-DijrJ_V-.js.map → shared-BguP_BaR.js.map} +1 -1
- package/dist/ui/{shared-DPAVoWY0.js → shared-BoLbc2WD.js} +17 -2
- package/dist/ui/{shared-DPAVoWY0.js.map → shared-BoLbc2WD.js.map} +1 -1
- package/dist/ui/{shared-BkdBTYwx.js → shared-BttyOW4W.js} +3 -3
- package/dist/ui/{shared-BkdBTYwx.js.map → shared-BttyOW4W.js.map} +1 -1
- package/dist/ui/{shared-CQWLz8uT.js → shared-BumxsBlA.js} +10 -10
- package/dist/ui/{shared-CQWLz8uT.js.map → shared-BumxsBlA.js.map} +1 -1
- package/dist/ui/{shared-Dzu7tFiC.js → shared-Bw73ktBk.js} +3 -3
- package/dist/ui/{shared-Dzu7tFiC.js.map → shared-Bw73ktBk.js.map} +1 -1
- package/dist/ui/{shared-BhAYErSx.js → shared-C1B0GH0e.js} +4 -4
- package/dist/ui/{shared-BhAYErSx.js.map → shared-C1B0GH0e.js.map} +1 -1
- package/dist/ui/{shared-BQJQcGgj.js → shared-C2FsyYr7.js} +4 -4
- package/dist/ui/{shared-BQJQcGgj.js.map → shared-C2FsyYr7.js.map} +1 -1
- package/dist/ui/{shared-B9lw2Ryh.js → shared-C2RU1qjv.js} +4 -4
- package/dist/ui/{shared-B9lw2Ryh.js.map → shared-C2RU1qjv.js.map} +1 -1
- package/dist/ui/{shared-DQYNI9wO.js → shared-C42f07hJ.js} +5 -5
- package/dist/ui/{shared-DQYNI9wO.js.map → shared-C42f07hJ.js.map} +1 -1
- package/dist/ui/{shared-CqCZ8wMY.js → shared-C4LkPCU4.js} +3 -3
- package/dist/ui/{shared-CqCZ8wMY.js.map → shared-C4LkPCU4.js.map} +1 -1
- package/dist/ui/{shared-BhtpgOpa.js → shared-C4wSfz6k.js} +9 -9
- package/dist/ui/{shared-BhtpgOpa.js.map → shared-C4wSfz6k.js.map} +1 -1
- package/dist/ui/{shared-BHc2Izkj.js → shared-C9DZtSFH.js} +2 -2
- package/dist/ui/{shared-BHc2Izkj.js.map → shared-C9DZtSFH.js.map} +1 -1
- package/dist/ui/{shared-DW1YuiNS.js → shared-CA52ClGo.js} +2 -2
- package/dist/ui/{shared-DW1YuiNS.js.map → shared-CA52ClGo.js.map} +1 -1
- package/dist/ui/{shared-BbSbilkh.js → shared-CBciTwm6.js} +9 -9
- package/dist/ui/{shared-BbSbilkh.js.map → shared-CBciTwm6.js.map} +1 -1
- package/dist/ui/{shared-C-J32eBn.js → shared-CL3RLKDA.js} +16 -16
- package/dist/ui/{shared-C-J32eBn.js.map → shared-CL3RLKDA.js.map} +1 -1
- package/dist/ui/{shared-Ck8S4OxW.js → shared-CLq3-_hW.js} +3 -3
- package/dist/ui/{shared-Ck8S4OxW.js.map → shared-CLq3-_hW.js.map} +1 -1
- package/dist/ui/{shared-Q5WefT7G.js → shared-CMjK-Ucd.js} +3 -3
- package/dist/ui/{shared-Q5WefT7G.js.map → shared-CMjK-Ucd.js.map} +1 -1
- package/dist/ui/{shared-D3MAuEA3.js → shared-CPjpSFGh.js} +2 -2
- package/dist/ui/{shared-D3MAuEA3.js.map → shared-CPjpSFGh.js.map} +1 -1
- package/dist/ui/{shared-VshXGwXP.js → shared-CSPhENq3.js} +2 -2
- package/dist/ui/{shared-VshXGwXP.js.map → shared-CSPhENq3.js.map} +1 -1
- package/dist/ui/{shared-DJrJaE73.js → shared-CZJE4Bmp.js} +3 -3
- package/dist/ui/{shared-DJrJaE73.js.map → shared-CZJE4Bmp.js.map} +1 -1
- package/dist/ui/{shared-D7ONOwI7.js → shared-C_BhUL2I.js} +7 -7
- package/dist/ui/{shared-D7ONOwI7.js.map → shared-C_BhUL2I.js.map} +1 -1
- package/dist/ui/{shared-j-2peBIB.js → shared-CbeujwdU.js} +4 -4
- package/dist/ui/{shared-j-2peBIB.js.map → shared-CbeujwdU.js.map} +1 -1
- package/dist/ui/{shared-D5GrOEa2.js → shared-Cbf-o4Dt.js} +4 -4
- package/dist/ui/{shared-D5GrOEa2.js.map → shared-Cbf-o4Dt.js.map} +1 -1
- package/dist/ui/{shared-HwiPIajr.js → shared-CdNmeNHh.js} +3 -3
- package/dist/ui/{shared-HwiPIajr.js.map → shared-CdNmeNHh.js.map} +1 -1
- package/dist/ui/{shared-ZCFt-CPb.js → shared-CdQOMD8J.js} +3 -3
- package/dist/ui/{shared-ZCFt-CPb.js.map → shared-CdQOMD8J.js.map} +1 -1
- package/dist/ui/{shared-ClhXSGGK.js → shared-CdiPYlTh.js} +2 -2
- package/dist/ui/{shared-ClhXSGGK.js.map → shared-CdiPYlTh.js.map} +1 -1
- package/dist/ui/{shared-DA8_pVRZ.js → shared-CepLAhwm.js} +2 -2
- package/dist/ui/{shared-DA8_pVRZ.js.map → shared-CepLAhwm.js.map} +1 -1
- package/dist/ui/{shared-BrYKjrnM.js → shared-Ch82h_Fu.js} +6 -6
- package/dist/ui/{shared-BrYKjrnM.js.map → shared-Ch82h_Fu.js.map} +1 -1
- package/dist/ui/{shared-C4UrE8Fb.js → shared-Chp88all.js} +3 -3
- package/dist/ui/{shared-C4UrE8Fb.js.map → shared-Chp88all.js.map} +1 -1
- package/dist/ui/{shared-CWa80DTO.js → shared-Ci16s2rN.js} +9 -9
- package/dist/ui/{shared-CWa80DTO.js.map → shared-Ci16s2rN.js.map} +1 -1
- package/dist/ui/{shared-tksTLD6Q.js → shared-CiqNkoE1.js} +5 -5
- package/dist/ui/{shared-tksTLD6Q.js.map → shared-CiqNkoE1.js.map} +1 -1
- package/dist/ui/{shared-yt7DjSrq.js → shared-CpMhOq8F.js} +2 -2
- package/dist/ui/{shared-yt7DjSrq.js.map → shared-CpMhOq8F.js.map} +1 -1
- package/dist/ui/{shared-Dm0z5WUl.js → shared-CrWv5JKH.js} +6 -6
- package/dist/ui/{shared-Dm0z5WUl.js.map → shared-CrWv5JKH.js.map} +1 -1
- package/dist/ui/{shared-CQL3FGHc.js → shared-Csfi3Pti.js} +2 -2
- package/dist/ui/{shared-CQL3FGHc.js.map → shared-Csfi3Pti.js.map} +1 -1
- package/dist/ui/{shared-BKNRbm-V.js → shared-CuZt26rm.js} +2 -2
- package/dist/ui/{shared-BKNRbm-V.js.map → shared-CuZt26rm.js.map} +1 -1
- package/dist/ui/{shared-Guq3upiR.js → shared-Cws_z-TS.js} +2 -2
- package/dist/ui/{shared-Guq3upiR.js.map → shared-Cws_z-TS.js.map} +1 -1
- package/dist/ui/{shared-Bw_qZeIj.js → shared-D1KWuCg6.js} +2 -2
- package/dist/ui/{shared-Bw_qZeIj.js.map → shared-D1KWuCg6.js.map} +1 -1
- package/dist/ui/{shared-CuCZKwXW.js → shared-D66ju_Cb.js} +23 -23
- package/dist/ui/{shared-CuCZKwXW.js.map → shared-D66ju_Cb.js.map} +1 -1
- package/dist/ui/{shared-DYfX7NSM.js → shared-DGaQZXnw.js} +2 -2
- package/dist/ui/{shared-DYfX7NSM.js.map → shared-DGaQZXnw.js.map} +1 -1
- package/dist/ui/{shared-B3Hp8tOv.js → shared-DHy41sET.js} +6 -6
- package/dist/ui/{shared-B3Hp8tOv.js.map → shared-DHy41sET.js.map} +1 -1
- package/dist/ui/{shared-CXyd7IKi.js → shared-DKEOMQ6l.js} +2 -2
- package/dist/ui/{shared-CXyd7IKi.js.map → shared-DKEOMQ6l.js.map} +1 -1
- package/dist/ui/{shared-Ccmc8YO0.js → shared-DSUICuaJ.js} +33 -33
- package/dist/ui/{shared-Ccmc8YO0.js.map → shared-DSUICuaJ.js.map} +1 -1
- package/dist/ui/{shared-CL2iw_js.js → shared-DUPMRoO0.js} +13 -13
- package/dist/ui/{shared-CL2iw_js.js.map → shared-DUPMRoO0.js.map} +1 -1
- package/dist/ui/{shared-Dtp4eRul.js → shared-DVfdm6ah.js} +2 -2
- package/dist/ui/{shared-Dtp4eRul.js.map → shared-DVfdm6ah.js.map} +1 -1
- package/dist/ui/{shared-BJ5Ex32G.js → shared-DXM7d7lJ.js} +3 -3
- package/dist/ui/{shared-BJ5Ex32G.js.map → shared-DXM7d7lJ.js.map} +1 -1
- package/dist/ui/{shared-BFr6ld0e.js → shared-DXbMlcev.js} +2 -2
- package/dist/ui/{shared-BFr6ld0e.js.map → shared-DXbMlcev.js.map} +1 -1
- package/dist/ui/{shared-BUp3jv-N.js → shared-D_SkPtJ9.js} +6 -6
- package/dist/ui/{shared-BUp3jv-N.js.map → shared-D_SkPtJ9.js.map} +1 -1
- package/dist/ui/{shared-CdNomVzH.js → shared-Dd21k2ic.js} +4 -4
- package/dist/ui/{shared-CdNomVzH.js.map → shared-Dd21k2ic.js.map} +1 -1
- package/dist/ui/{shared-gRMbxmpu.js → shared-Dh0nHtLZ.js} +8 -8
- package/dist/ui/{shared-gRMbxmpu.js.map → shared-Dh0nHtLZ.js.map} +1 -1
- package/dist/ui/{shared-BKGJgjog.js → shared-DkOdSpSK.js} +3 -3
- package/dist/ui/{shared-BKGJgjog.js.map → shared-DkOdSpSK.js.map} +1 -1
- package/dist/ui/{shared-BMsh72Uq.js → shared-Dkph5ckT.js} +2 -2
- package/dist/ui/{shared-BMsh72Uq.js.map → shared-Dkph5ckT.js.map} +1 -1
- package/dist/ui/{shared-Be1HpDOB.js → shared-Dl1_Nx--.js} +3 -3
- package/dist/ui/{shared-Be1HpDOB.js.map → shared-Dl1_Nx--.js.map} +1 -1
- package/dist/ui/{shared-BQIZWOoJ.js → shared-Dm0IGbAf.js} +2 -2
- package/dist/ui/{shared-BQIZWOoJ.js.map → shared-Dm0IGbAf.js.map} +1 -1
- package/dist/ui/{shared-DSUtcU5S.js → shared-DnIkTpPr.js} +5 -5
- package/dist/ui/{shared-DSUtcU5S.js.map → shared-DnIkTpPr.js.map} +1 -1
- package/dist/ui/{shared-DsxGbYlV.js → shared-Docl_0tq.js} +3 -3
- package/dist/ui/{shared-DsxGbYlV.js.map → shared-Docl_0tq.js.map} +1 -1
- package/dist/ui/{shared-DZskrV26.js → shared-DprrHC72.js} +2 -2
- package/dist/ui/{shared-DZskrV26.js.map → shared-DprrHC72.js.map} +1 -1
- package/dist/ui/{shared-Bmw43Hwf.js → shared-DyKsJTZs.js} +2 -2
- package/dist/ui/{shared-Bmw43Hwf.js.map → shared-DyKsJTZs.js.map} +1 -1
- package/dist/ui/{shared-BLG88Pya.js → shared-FO7vfI3F.js} +4 -4
- package/dist/ui/{shared-BLG88Pya.js.map → shared-FO7vfI3F.js.map} +1 -1
- package/dist/ui/{shared-DLSd80D1.js → shared-HalAVHjv.js} +3 -3
- package/dist/ui/{shared-DLSd80D1.js.map → shared-HalAVHjv.js.map} +1 -1
- package/dist/ui/{shared-D1mMBLdj.js → shared-JvcI-LWp.js} +15 -15
- package/dist/ui/{shared-D1mMBLdj.js.map → shared-JvcI-LWp.js.map} +1 -1
- package/dist/ui/{shared-C6Hv_4O0.js → shared-K7Ym27yg.js} +2 -2
- package/dist/ui/{shared-C6Hv_4O0.js.map → shared-K7Ym27yg.js.map} +1 -1
- package/dist/ui/{shared-B39ln7oi.js → shared-SzlnwfJO.js} +3 -3
- package/dist/ui/{shared-B39ln7oi.js.map → shared-SzlnwfJO.js.map} +1 -1
- package/dist/ui/{shared-DgPn_Jll.js → shared-TrGbd1FY.js} +3 -3
- package/dist/ui/{shared-DgPn_Jll.js.map → shared-TrGbd1FY.js.map} +1 -1
- package/dist/ui/{shared-DrFb-XtA.js → shared-WhbuObEW.js} +2 -2
- package/dist/ui/{shared-DrFb-XtA.js.map → shared-WhbuObEW.js.map} +1 -1
- package/dist/ui/{shared-DiFQljcq.js → shared-XcSKDp6N.js} +11 -11
- package/dist/ui/{shared-DiFQljcq.js.map → shared-XcSKDp6N.js.map} +1 -1
- package/dist/ui/{shared-CMAg58rY.js → shared-Z4uBJU6I.js} +7 -6
- package/dist/ui/shared-Z4uBJU6I.js.map +1 -0
- package/dist/ui/{shared-BnUptuUp.js → shared-bAgeiRa5.js} +2 -2
- package/dist/ui/{shared-BnUptuUp.js.map → shared-bAgeiRa5.js.map} +1 -1
- package/dist/ui/{shared-BxMvSjey.js → shared-cgXG7OgZ.js} +5 -5
- package/dist/ui/{shared-BxMvSjey.js.map → shared-cgXG7OgZ.js.map} +1 -1
- package/dist/ui/{shared-u4CG2kQJ.js → shared-eZ0SB_zm.js} +2 -2
- package/dist/ui/{shared-u4CG2kQJ.js.map → shared-eZ0SB_zm.js.map} +1 -1
- package/dist/ui/{shared-L90bWW8e.js → shared-frKFb79C.js} +2 -2
- package/dist/ui/{shared-L90bWW8e.js.map → shared-frKFb79C.js.map} +1 -1
- package/dist/ui/{shared-Dd34nhkw.js → shared-hAayNSRA.js} +3 -3
- package/dist/ui/{shared-Dd34nhkw.js.map → shared-hAayNSRA.js.map} +1 -1
- package/dist/ui/{shared-DzC64cpp.js → shared-j_J16p2B.js} +2 -2
- package/dist/ui/{shared-DzC64cpp.js.map → shared-j_J16p2B.js.map} +1 -1
- package/dist/ui/{shared-DX7HRIV-.js → shared-tqpl5N3g.js} +6 -6
- package/dist/ui/{shared-DX7HRIV-.js.map → shared-tqpl5N3g.js.map} +1 -1
- package/dist/ui/{shared-BS5dBMpA.js → shared-y-6_ZDts.js} +2 -2
- package/dist/ui/{shared-BS5dBMpA.js.map → shared-y-6_ZDts.js.map} +1 -1
- package/dist/ui/{shared-Cv5v_MP1.js → shared-zG6e1Rhz.js} +13 -13
- package/dist/ui/{shared-Cv5v_MP1.js.map → shared-zG6e1Rhz.js.map} +1 -1
- package/dist/ui/testing.js +1 -1
- package/package.json +4 -4
- package/dist/docs/cli-browser.md +0 -232
- package/dist/docs/database-browser.md +0 -115
- package/dist/docs/keyboard.md +0 -63
- package/dist/docs/mcp.md +0 -86
- package/dist/ui/shared-Bl_nF_IH.js.map +0 -1
- package/dist/ui/shared-CMAg58rY.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-0UZ1Re1k.js","names":["say","say","_Fragment","say","_Fragment","say","QUIET_FRAMES","say","_Fragment","say","_Fragment","say","say","say","say","host","say","say","say","say","shown","__exportAll","prefetchRecord","rowLabel","navState","subscribeSessionIdentity","el","paintVersion","defineMessages","pageView","tenantLeaseActive","subscribeMessages","setPaintHold","sayBrandName","adoptCss","addHostListener","state","setTabTitle","render","primaryKey","installShell","toast","invalidateSession","renderCrumbs","sessionIdentity","portalRoot","onNavigate","removeHostListener","shellQueryAll","RuntimeMetadataError","subscribeWalk","shellQuery","tableView","configureSessionLifecycle","shellRoot","UnknownAppError","invalidateNavigation","api","workMark","connectionGeneration","arrivedPlacement","connectionChanged","shownUnplaced","viewportBox","currentEntry","go","allowMutationExit","beginConnectionTransition","onLanguagePicked","shell","humanName","findTable","$","viewportSize","backTo","workSince","herePath","emptyWord","shellBody","hereSearch","startSessionMonitoring","columnLabel","shown$1","labelPath","roomVersion","navReplace","useQueryClient","ErrorBoundary","useMessageLanguage","Icon","useQuery","queryClient","setListNavigation","mount","unmount","unmountAll","Delayed","safeHref","onDemand","sayUnavailable","prefetchPages","pagesFor","recordPageId","whenPagesChange","forgetPages","formAt","formViewKey","dashPageId","dashViewKey","dashboardAt","homeRoom","activeClauses","ask","withoutCondition","deriveFilterNames","withoutClause","resolveLabels","whileApplying","readdress","applyHash","syncHash","readAddress","toHash","allowSync","splitOf","appListFor","appListQuery","appCrumbLabel","crumbToolsRef","crumbNoteRef","useWalk","viewLink","WorkbenchLanding","canUseDatabaseTools","canManageConnections","rememberVisit","RECORD_REFRESH_FAILED","savedViewsFor","PageView","beginRecordPage","RecordGone","setAppConfigured","loadTemplates","captureRecordSurfaceOwner","forgetPage","usePageSurface","openPrefs","motionStill","TableRoom","openSidebarChoice","setSidebarFilter","RowRoom","DashboardRoom","openPalette","documentAt","AppListRoom","initPalette","Sidebar","initSidebarToggle","moveSidebar","FilterSection","NothingGranted","registerSurface","menuMode","setMenuGroup","setMenuMode","initMenu","addMenuItem","syncWriteMode","initWriteMode","prepareEditingExit","Value","presentationColumns","OverflowMenu","toggleTheme","themeLabel","effectiveTheme","finishStartup","applyDensity","applyTypography","connectionFromHash","Fragment$1","say$7","nameOf","entry","app","dashboard","form","splitSelection","top","stack","list","sameRoom","next","homeWords","name","said","trailSetting","trailOf","walked","crumbBarShown","setting","Crumbs","home","previous","trail","shown","index","onHome","i","last","first","n","previousTable","showsTable","tableWord","ownStep","content","Fragment","say$6","PageSkeleton","spoken","connection","PageRoom","resolved","useState","owner","schema","surfaceOwner","useMemo","surface","def","needsResolution","base","column","rest","pair","version","rootRow","early","planned","useEffect","page","Known","others","onLayout","saved","WithRoot","Rootless","Arriving","spec","Chooser","what","query","setQuery","draw","listEntry","key","probe","gone","plan","Revealed","label","tab","ARRIVING_SHAPE_MS","QUIET_FRAMES$1","REVEAL_CAP","box","useRef","client","useLayoutEffect","own","pane","root","covered","mark","hidden","done","quiet","stirred","frame","hide","finish","cap","drawn","cover","stop","watch","busy","say$5","SavedViewsBar","isPlain","alreadySaved","views","v","active","view","onRename","onRemove","onSave","clause","SavedViewsSection","bar","AppFooter","links","footer","href","link","BreakdownRoom","knownPages","setKnownPages","pages","notice","noticeOnContent","homeHeld","holdHome","held","homeIsHeld","Content","body","ContentBody","framed","withFooter","paint","homeDash","homeEntry","Home","loadError","room","LoadErrorNote","Room","table","appList","document","rooms","CAP","QUIET_FRAMES","REMEMBERED","ENTER_CLASS","hold","traversedAt","TRAVERSAL_WINDOW","lastInput","scrollAt","restoring","address","placeOf","sameThing","a","b","installNavigationHold","host","reads","records","record","warm","node","readLinked","input","event","release","moved","beforePaint","traversal","again","scroll","recent","enter","depth","focused","made","picture","copy","focusable","afterPaint","ending","restoreScroll","TWIN","ROOT_TWIN","built","linked","twins","url","reply","text","mirrorSheets","sourceOf","sheet","sheets","unread","media","twin","inner","chain","at","ancestor","value","child","still","element","from","to","canvas","fields","copies","field","say$4","initialRuntime","bootstrapRequestIdentity","runtime","selected","requested","error","initConnections","onSwitched","refreshConnections","listGeneration","request","generation","isCurrent","data","controls","syncConnectionControls","picker","say$3","SEEN","STOPS","tourSeen","remember","host$1","endTour","remembering","starting","startTour","card","asked","stops","s","anchorFor","createElement","Tour","initTour","opensAsPage","here","tableId","SETTLED_FOCUS","intent","target","prefetchRecordPage","pageId","listening","listenForRecordPresses","pressedAt","focusTimer","press","say$2","SETTLE_MS","FIELDS","fieldsFor","c","PeekLayer","setTarget","timer","onEnter","chip","e","onLeave","onKey","PeekCard","columns","row","suppressed","title","above","align","wanted","left","clearPeekCache","initPeek","viewTabOf","say$1","loading","composer","load","module","sync","attach","say","app_exports","boot","chrome","offeredTools","tools","startTools","kit","showUnopened","unknown","unavailable","listed","ThemeLab","goHome","showWorkspaceOpening","status","clearSurface","me","rebuildSurface","transition","appLoaded","applyBrand","renderTableList","registerPages","businessRetired","focusContent","appMode","filterInput","filterLabel","sideList","filterText","sayShellWords","skip","signIn","inApp","pagesRegistration","registration","p","reloadAppInPlace","before","after","followSaves","switchAndRestore","id","parsed","hash","t","x","err","installed","titles","reload","lock","reason","incoming","incomingLocation","tenantIncoming","requestedApp","signedInStart","landingAt","chosen","changed","setStartupProbe","roomChanged","restored","path","collapse","typing"],"sources":["../../../../../kit/src/client/copy/shell/components/Crumbs.ts","../../../../../kit/src/client/components/Crumbs.tsx","../../../../../kit/src/client/copy/record/components/PageRoom.ts","../../../../../kit/src/client/components/PageRoom.tsx","../../../../../kit/src/client/copy/lists/components/SavedViews.ts","../../../../../kit/src/client/components/SavedViews.tsx","../../../../../kit/src/client/components/AppFooter.css?inline","../../../../../kit/src/client/components/AppFooter.tsx","../../../../../kit/src/client/components/Content.tsx","../../../../../kit/src/client/navigationHold.ts","../../../../../kit/src/client/copy/shell/connectionList.ts","../../../../../kit/src/client/connectionList.js","../../../../../kit/src/client/copy/workbench/tour.ts","../../../../../kit/src/client/tour.js","../../../../../kit/src/client/recordPress.ts","../../../../../kit/src/client/copy/record/components/Peek.ts","../../../../../kit/src/client/components/Peek.tsx","../../../../../kit/src/client/peek.js","../../../../../kit/src/client/composerTab.js","../../../../../kit/src/client/copy/workbench/composerEntry.ts","../../../../../kit/src/client/composerEntry.js","../../../../../kit/src/client/copy/shell/app.ts","../../../../../kit/src/client/app.js"],"sourcesContent":["/** What Crumbs says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages(\n {\n trail: 'Trail',\n theSchemaYourWork: 'The schema, your work, the diagram (h)',\n appHome: '{app} home',\n home: 'Home',\n back: 'Back to {previous}',\n },\n {\n /* The words a visitor sees in the shell; the rest are said in English. */\n es: {\n trail: 'Ruta',\n appHome: 'Inicio de {app}',\n home: 'Inicio',\n back: 'Volver a {previous}',\n },\n },\n);\n","/**\n * The trail.\n *\n * It starts at the schema, and says so: a link opened deep — which is how\n * most links are opened — must offer a way back to the landing, and the\n * wordmark is not where anybody looks for one. A house rather than the\n * word, because the one thing in the trail that is not a step should not\n * look like one. Then one crumb per entry of the walk, the last of them\n * the current room; and at the end, the walk's own Back — up the trail,\n * not to whatever was looked at last, because a trail arrived at by\n * pasted link has crumbs and no browser history behind it.\n */\nimport { crumbNoteRef, crumbToolsRef } from './crumbSlot.js';\nimport { Fragment } from 'react';\nimport { backTo, findTable } from '../core.js';\nimport { shell } from '../shellMode.js';\nimport { humanName } from '@mistriwork/engine/shared/model.js';\nimport { appCrumbLabel, appListFor, splitOf } from './appListModel.js';\nimport { dashboardAt, formAt } from './appRooms.js';\nimport { useWalk, type WalkEntry } from './walk.js';\nimport { say } from '../copy/shell/components/Crumbs.js';\nimport { Icon } from './Icon.js';\nimport { useMessageLanguage } from './useMessageLanguage.js';\n\n/** What a crumb is called: the app's word for a list, a record's name, a page's. */\nfunction nameOf(entry: WalkEntry): string {\n if (entry.kind === 'page' && !entry.table && entry.pageId) {\n const app = shell().app();\n const dashboard = app && dashboardAt(app, entry.pageId);\n if (dashboard) return dashboard.label;\n const form = app && formAt(app, entry.pageId);\n if (form) return form.label;\n }\n if (entry.kind === 'table' || entry.kind === 'breakdown') {\n const app =\n shell().inApp() && entry.kind === 'table'\n ? appCrumbLabel({ table: entry.table ?? '', query: entry.query ?? '', view: entry.view })\n : null;\n return app ?? entry.query ?? '';\n }\n return entry.label ?? (entry.table && shell().inApp() ? humanName(entry.table) : entry.table) ?? entry.pageId ?? '…';\n}\n\n/* A split's selected record is its list's selection: the list and the row\n beside it are one room, and one crumb. Drawn as two, the trail read \"Inbox\n › Inbox\" and offered a Back to the very list on screen. */\nfunction splitSelection(stack: WalkEntry[]): boolean {\n const top = stack.at(-1);\n const list = stack.at(-2);\n if (!shell().inApp() || top?.kind !== 'row' || list?.kind !== 'table' || !list.table || list.table !== top.table) return false;\n return splitOf(appListFor(list.table, list.query, top.view ?? list.view)) !== undefined;\n}\n\n/* A room keeps its place in the address, and a place it pushes (a list\n chosen in the Pick walk) is a step Back returns from — but it is still the\n one room, so it is one crumb: the trail read \"Pick walk › Pick walk\". Of a\n run of steps in the same room, only the newest is drawn. */\nconst sameRoom = (entry: WalkEntry, next: WalkEntry | undefined): boolean =>\n Boolean(\n next && entry.kind === 'page' && next.kind === 'page' && !entry.table && !next.table && entry.pageId && entry.pageId === next.pageId,\n );\n\n/* The home crumb is the schema in the browser and the App's home in an App,\n where a reader was told \"Schema\" for the App's own front room. */\nfunction homeWords(): { title: string; 'aria-label': string } {\n const name = shell().inApp() ? (shell().app() as { name?: string } | null)?.name : undefined;\n if (shell().inApp()) {\n const said = name ? say('appHome', { app: name }) : say('home');\n return { title: said, 'aria-label': said };\n }\n return { title: say('theSchemaYourWork'), 'aria-label': say('common.schema') };\n}\n\n/* What the App asks of its trail (`ui.shell.breadcrumbs`). By default a room reached straight from the menu names\n itself in its own heading row, with no bar over it, and the trail, once there is one, starts at the first room:\n a bar that only said \"home › Leads\" over a list called Leads was chrome, and the house a second way home beside\n the menu. The Workbench keeps the whole trail; its first crumb is the schema, which nothing else offers. */\nfunction trailSetting(): { top: boolean; home: boolean } | false {\n if (!shell().inApp()) return { top: true, home: true };\n const said = shell().app()?.ui?.shell?.breadcrumbs;\n if (said === false) return false;\n if (said === true) return { top: true, home: true };\n return { top: said?.top ?? false, home: said?.home ?? false };\n}\n\n// Indices stay the walk's own: only the selected row is left off the end.\nconst trailOf = (walked: WalkEntry[]): WalkEntry[] => (splitSelection(walked) ? walked.slice(0, -1) : walked);\n\n/**\n * Whether the bar is drawn over this walk. Read from the walk itself, in the same render that draws the room, so a\n * list knows on its first paint whether its title goes in the bar or in its own heading row (crumbSlot.ts): decided\n * any later, the heading moved after the paint and every row under it jumped. A room is deeper than the menu once\n * the walk has a second step, or when it is a record however it was reached (a link straight to one).\n */\nexport function crumbBarShown(walked: WalkEntry[]): boolean {\n const setting = trailSetting();\n if (!setting) return false;\n if (setting.top) return true;\n const stack = trailOf(walked);\n const top = stack.at(-1);\n return stack.length > 1 || top?.kind === 'row' || (top?.kind === 'page' && top.key != null);\n}\n\nexport function Crumbs({ onHome }: { onHome: () => void }) {\n const walked = useWalk();\n /* Said again when a visitor's language arrives with the App. */\n useMessageLanguage();\n const stack = trailOf(walked);\n const setting = trailSetting();\n const home = Boolean(setting && setting.home);\n const previous = stack.length > 1 ? stack[stack.length - 2] : null;\n /* A public reader's record page names itself in its heading straight\n below: the trail ends at the list it came from, which stays a link. */\n const top = stack[stack.length - 1];\n const trail =\n shell().publicVisitor() && stack.length > 1 && top && (top.kind === 'row' || top.kind === 'page') && top.table\n ? stack.slice(0, -1)\n : stack;\n // Each crumb keeps its index in the walk, which is where it goes back to.\n const shown = trail.map((entry, index) => ({ entry, index })).filter(({ entry, index }) => !sameRoom(entry, trail[index + 1]));\n return (\n <nav className=\"crumbs\" aria-label={say('trail')}>\n {home && (\n <button type=\"button\" className=\"crumb-home\" {...homeWords()} onClick={onHome}>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"17\"\n height=\"17\"\n aria-hidden=\"true\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M2 7.2 8 2.4l6 4.8\" />\n <path d=\"M3.4 6.6V13a.6.6 0 0 0 .6.6h8a.6.6 0 0 0 .6-.6V6.6\" />\n </svg>\n </button>\n )}\n {shown.map(({ entry, index: i }, n) => {\n const last = i === stack.length - 1;\n /* Without the house the first step stands at the start of the bar, with nothing before it to separate. */\n const first = n === 0 && !home;\n /* A row crumb names its table when the walk has changed table —\n which is exactly what following a foreign key does. A page crumb\n is a record crumb drawn as a page, on the same rule. */\n const previousTable = i > 0 ? stack[i - 1].table : null;\n const named = entry.kind === 'row' || entry.kind === 'page';\n /* A dashboard's or a form's page crumb has no table, and `undefined` is not the first crumb's `null`: without\n the table itself the trail drew an empty step before the title. */\n const showsTable = named && entry.label != null && !!entry.table && entry.table !== previousTable;\n /* In an App the table is its own step of the trail, said in the resource's label (\"Properties\"), with the\n separator every step has; the Workbench keeps the table's own name as a qualifier of the record. */\n const tableWord = entry.table\n ? shell().inApp()\n ? appCrumbLabel({ table: entry.table, query: '', view: entry.view }) ||\n humanName((findTable(entry.table) as { name?: string } | undefined)?.name ?? entry.table) ||\n entry.table\n : entry.table\n : '';\n const ownStep = showsTable && shell().inApp();\n const content = (\n <>\n {showsTable && !ownStep && (\n <span className=\"crumb-table\" title={entry.table}>\n {tableWord}\n </span>\n )}\n {nameOf(entry)}\n </>\n );\n return (\n <Fragment key={i}>\n {ownStep && (\n <>\n {!first && <span className=\"sep\">›</span>}\n <span className=\"crumb-table-step\">{tableWord}</span>\n </>\n )}\n {(!first || ownStep) && <span className=\"sep\">›</span>}\n {last ? (\n <span className=\"current\">{content}</span>\n ) : (\n <button type=\"button\" onClick={() => backTo(i)}>\n {content}\n </button>\n )}\n </Fragment>\n );\n })}\n {/* A list's title, count and star land here; its verbs, at the end. */}\n <span className=\"crumb-note\" ref={crumbNoteRef} />\n {/* The walk's Back repeats the trail's own last step; a public reader has\n the trail and the browser's Back, and one more button is chrome. */}\n {previous && !shell().publicVisitor() && (\n <button\n type=\"button\"\n className=\"crumb-back\"\n title={say('back', { previous: nameOf(previous) })}\n onClick={() => backTo(stack.length - 2)}\n >\n <Icon name=\"caret-left\" size={16} />\n <span>{say('common.back')}</span>\n </button>\n )}\n <div className=\"crumb-tools\" ref={crumbToolsRef} />\n </nav>\n );\n}\n","/** What PageRoom says, in the record page room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n pickABelow: 'Pick a {thing} below to open this page.',\n pickAnBelow: 'Pick an {thing} below to open this page.',\n});\n","/**\n * A page as a room. The page is a component (components/Page.tsx) and its pure\n * parts are components/pageModel.ts; page.js keeps the registry every module\n * asks — the config's pages, the suggested one every table has, the ones\n * this browser built. This is the walk's business in between: which\n * definition a link names, the root read off the address, the probe that\n * settles whether the record still exists, the plan the server writes for\n * the page, the crumb and the visit remembered for home.\n *\n * Four asks in a row, each a Query enabled by the one before, each keyed by\n * what it depends on and kept only while the room is up. Nothing paints\n * for an entry that is no longer the one on the walk: the key changed with\n * it, and the callbacks check the entry before touching it.\n */\nimport { useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { currentEntry, go, humanName, pageView, primaryKey, renderCrumbs, rowLabel, state, tableView } from '../core.js';\nimport { shell } from '../shellMode.js';\nimport { deriveFilterNames } from '../filterbar.js';\nimport { forgetPage, rememberVisit } from '../pagemarks.js';\nimport { readdress, syncHash } from '../url.js';\nimport type { TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport { appListFor, appListQuery, type ListSpec } from './appListModel.js';\nimport { PageView } from './Page.js';\nimport { type PageEntry } from './pageModel.js';\nimport {\n captureRecordSurfaceOwner,\n RECORD_REFRESH_FAILED,\n usePageSurface,\n type RecordSurfacePage as Def,\n type RecordSurfaceAlternative as Others,\n} from './recordSurface.js';\nimport { AppListRoom } from './Rooms.js';\nimport { FilterSection, TableRoom } from './TableRoom.js';\nimport { say } from '../copy/record/components/PageRoom.js';\nimport { RecordGone } from './RecordGone.js';\nimport { Delayed } from './Skeleton.js';\nimport { onDemand } from './onDemand.js';\nimport { workMark, workSince } from '../pendingWork.js';\nimport { shellRoot } from '../shellHost.js';\n\n/* App mode reads pages in the app's words; the workbench reads them raw. */\n/* Drawn only past the hold's cap, so it is a part of its own: no record's first page carries it. */\nconst PageSkeleton = onDemand(() => import('./PageSkeleton.js'), 'PageSkeleton', { quiet: true });\n\nconst spoken = (name: string): string => (shell().inApp() ? (humanName(name) as string) : name);\nconst connection = () => (state as { activeConnection?: string }).activeConnection ?? '';\n\nexport function PageRoom({ entry }: { entry: PageEntry }) {\n const [, resolved] = useState(0);\n const owner = connection();\n const schema = state.schema;\n // A routed lifetime still requires this exact walk entry. Explicit surfaces\n // supply their own lifetime predicate without changing the routed fence.\n const surfaceOwner = useMemo(() => captureRecordSurfaceOwner(() => currentEntry() === entry), [entry]);\n const surface = usePageSurface(surfaceOwner, entry);\n const { definition: def, page, base, needsResolution } = surface;\n useLayoutEffect(() => {\n if (!needsResolution || !base || currentEntry() !== entry || connection() !== owner || state.schema !== schema || !surface.isCurrent())\n return;\n /* A deep link names the page but not its table — the definition is the\n one source of that. Backfilled after commit, before mounting readers: the\n sidebar highlight, the crumb, and `openRecord`'s root-in-place guard. */\n entry.table = base.id;\n /* A link carries the root as text, because a single-column key is written\n as a bare value and only the base table says which column that is. */\n if (!entry.key && entry.rootBody !== undefined) {\n entry.key = entry.rootBody.includes('=')\n ? Object.fromEntries(\n entry.rootBody.split(',').map((pair) => {\n const [column, ...rest] = pair.split('=');\n return [column, rest.join('=')];\n }),\n )\n : { [(primaryKey(base) as string[])[0]]: entry.rootBody };\n }\n resolved((version) => version + 1);\n renderCrumbs();\n }, [entry, base, needsResolution, owner, schema, surface.isCurrent]);\n const rootRow = surface.rootRow;\n useEffect(() => {\n if (!rootRow || !base || currentEntry() !== entry || !surface.isCurrent()) return;\n const early = rowLabel(base, rootRow) as string | null;\n if (early && entry.label !== early) {\n entry.label = early;\n renderCrumbs();\n }\n }, [rootRow]); // eslint-disable-line react-hooks/exhaustive-deps\n const planned = surface.plan.data;\n /* `page` too: a suggested page asks its plan and root beside its definition, so both can land first, and a visit\n that waited only on them was never recorded once the definition came. */\n useEffect(() => {\n if (planned && rootRow && page && currentEntry() === entry && surface.isCurrent()) {\n rememberVisit({ pageId: page.id, name: page.name, base: page.base, key: entry.key, label: entry.label });\n }\n }, [planned, rootRow, page]); // eslint-disable-line react-hooks/exhaustive-deps\n if (!surface.isCurrent()) return null;\n return (\n <div className=\"panel-pad\">\n {surface.content && surface.refreshFailed && (\n <p role=\"alert\" className=\"note\">\n {RECORD_REFRESH_FAILED}\n </p>\n )}\n {def.isError && !page ? (\n <p className=\"note\">{(def.error as Error).message}</p>\n ) : !page ? null : page.error ? (\n <>\n <div className=\"page-head\">\n <h1 className=\"page-title\">{page.name}</h1>\n </div>\n <div className=\"page-body\">\n <p className=\"note\">{page.error}</p>\n </div>\n </>\n ) : !base ? (\n <p className=\"note\">{say('common.isNotATable', { base: page.base })}</p>\n ) : needsResolution ? null : (\n <Known entry={entry} page={page} base={base} surface={surface} />\n )}\n </div>\n );\n}\n\nfunction Known({\n entry,\n page,\n base,\n surface,\n}: {\n entry: PageEntry;\n page: Def;\n base: TableMeta;\n surface: ReturnType<typeof usePageSurface>;\n}) {\n const others = surface.others;\n /* The builder is the Workbench's (pagebuilder.js), reached through the shell: only the Workbench authors pages (PageHead's `authoring`). */\n const onLayout = () =>\n shell().editPage?.(page, {\n recordKey: entry.key,\n onSaved: (saved: { id: string; base: string }) => go(pageView(saved.id, saved.base, entry.key, entry.label), 'replace'),\n /* Deleting the page you are standing on has to go somewhere: the table it\n was about. Pinned or recently opened, it is neither now. */\n onDeleted: () => {\n forgetPage(page.id);\n go(tableView(page.base), 'replace');\n },\n });\n if (!others.data) return entry.key ? <Arriving page={page} /> : null;\n return entry.key ? (\n <WithRoot entry={entry} page={page} base={base} surface={surface} onLayout={onLayout} />\n ) : (\n <Rootless entry={entry} page={page} base={base} others={others.data} onLayout={onLayout} />\n );\n}\n\n/**\n * No record chosen: the list *is* the chooser. The app's list page in app\n * mode — tabs, named filters, chips, the lot — and the plain grid in the\n * workbench; a row click opens this record as a page, because the walk is\n * already in page view and `openRecord` keeps it there.\n */\nfunction Rootless({\n entry,\n page,\n base,\n others,\n onLayout,\n}: {\n entry: PageEntry;\n page: Def;\n base: TableMeta;\n others: Others[];\n onLayout: () => void;\n}) {\n useEffect(() => {\n if (currentEntry() === entry && entry.label !== page.name) {\n entry.label = page.name;\n renderCrumbs();\n }\n }, [entry, page.name]);\n const spec = shell().inApp() ? (appListFor(base.id) as ListSpec) : null;\n return (\n <PageView\n entry={entry}\n page={page}\n base={base}\n plans={[]}\n others={others}\n onLabel={() => {}}\n onTab={() => {}}\n onLayout={onLayout}\n chooser={<Chooser entry={entry} base={base} spec={spec} />}\n />\n );\n}\n\nfunction Chooser({ entry, base, spec }: { entry: PageEntry & { chooserQuery?: string }; base: TableMeta; spec: ListSpec | null }) {\n const what = spoken(base.name);\n /* Redrawn in place on every tab click and filter: the chooser lives\n inside the page entry, and its questions must not move the walk. The\n query rides on the entry so the pager's re-render comes back to it —\n not in the URL: the link names the page, and the chooser is a moment. */\n const [query, setQuery] = useState<string>(entry.chooserQuery ?? (spec ? appListQuery(spec) : base.id));\n const draw = (next: string) => {\n entry.chooserQuery = next;\n setQuery(next);\n };\n const listEntry = { kind: 'table' as const, table: base.id, query };\n return (\n <>\n <p className=\"note page-empty\">{say(/^[aeiou]/i.test(what) ? 'pickAnBelow' : 'pickABelow', { thing: what.toLowerCase() })}</p>\n <div className=\"page-root-list\">\n {spec ? (\n <AppListRoom entry={listEntry} spec={spec} navigate={draw} />\n ) : (\n <>\n {/* The workbench chooser gets the named boxes too, the key columns\n leading: the one lookup the old root bar guaranteed was \"by id\". */}\n <FilterSection\n entry={listEntry}\n navigate={draw}\n names={[...new Set([...(primaryKey(base) as string[]), ...(deriveFilterNames(base) as string[])])]}\n />\n <TableRoom entry={listEntry} chrome={false} interactive={false} />\n </>\n )}\n </div>\n </>\n );\n}\n\n/**\n * A record chosen. The root first, before any section: a page for a record\n * that is gone used to say so in one box while the metrics around it\n * rendered zeros. One pk-sized fetch settles existence, and brings the\n * label, so the crumb and the pill say the name before the sections\n * resolve. Then one planning call for the whole page, and a run per section.\n */\nfunction WithRoot({\n entry,\n page,\n base,\n surface,\n onLayout,\n}: {\n entry: PageEntry;\n page: Def;\n base: TableMeta;\n surface: ReturnType<typeof usePageSurface>;\n onLayout: () => void;\n}) {\n const key = entry.key as Record<string, unknown>;\n const { probe, gone, plan, content } = surface;\n if (!probe.data) return <Arriving page={page} />;\n if (gone) {\n return (\n <div className=\"page-body\">\n <RecordGone base={base} spoken={spoken(base.name)} />\n </div>\n );\n }\n if (plan.isError && !content) return <p className=\"note\">{(plan.error as Error).message}</p>;\n if (!content) return <Arriving page={page} />;\n return (\n <Revealed>\n <PageView\n {...content}\n onLayout={onLayout}\n onLabel={(label) => {\n /* Written onto the entry as well as shown, so going away and coming\n back through the trail keeps the name rather than dropping to the\n key. Guarded on the entry still being the current one. */\n if (!label || currentEntry() !== entry || !surface.isCurrent()) return;\n /* A public record's slug is its name (publicAddress.ts): written once the\n name is known, however it came to be known — a crumb may have named\n the entry before the page did. */\n if (entry.label === label) {\n readdress();\n return;\n }\n entry.label = label;\n renderCrumbs();\n readdress();\n /* Recorded again now that the record has a name. */\n rememberVisit({ pageId: page.id, name: page.name, base: page.base, key, label });\n }}\n onTab={(tab) => {\n if (currentEntry() !== entry || !surface.isCurrent()) return;\n entry.tab = tab;\n syncHash();\n }}\n />\n </Revealed>\n );\n}\n\n/**\n * The record while its page is on its way: nothing drawn, and the page's\n * height held. Under a held screen (navigationHold.ts) it is never seen;\n * past the hold's cap it keeps what stands below (the footer) where the page\n * will push it, so the page that arrives moves nothing already on screen. A\n * name or a status drawn here from the row that opened it would move as the\n * real head arrives, taller, with its verbs: that is the layout shift this\n * holds off, so it says no words. Past the cap it draws the page's anatomy in\n * placeholders (PageSkeleton) inside the held height, replaced whole: an\n * empty pane under the crumbs read as a page that had failed, not one coming.\n */\nfunction Arriving({ page }: { page: Def }) {\n return (\n <div className=\"page-arriving\" aria-busy=\"true\" style={{ minHeight: '100vh' }}>\n <Delayed ms={ARRIVING_SHAPE_MS}>\n <PageSkeleton sections={page.sections} />\n </Delayed>\n </div>\n );\n}\n\n/* Past the navigation hold's cap (navigationHold.ts, 1.5s) the pane is uncovered: only then is the page's shape worth\n drawing, and under the hold it is never seen, so it never shows on a page that arrives in time. */\nconst ARRIVING_SHAPE_MS = 1500;\n\n/* Frames with nothing asked and nothing drawn before a page is complete: the navigation hold's count. */\nconst QUIET_FRAMES = 3;\n/* The longest a page arriving uncovered is kept out of sight, as the hold's cap. */\nconst REVEAL_CAP = 1500;\n\n/**\n * The record's page as it arrives, shown once it is complete. A section\n * draws when its own read answers, and the header's verbs when their\n * availability does: under the navigation hold (navigationHold.ts) or the\n * startup veil (startupHold.ts) none of that is seen. But each lets go at\n * its cap, and a page still arriving then drew in steps — a head a line\n * taller once its verbs came, sections growing under it — moving what was\n * already on screen (0.43 on the lender's loan when its read outlasted the\n * hold). So a page that is uncovered before it is complete is kept out of\n * sight, at Arriving's height, until nothing asked since it mounted is out,\n * no read is running and nothing is drawn into it for three frames, and is\n * then shown whole. Covered and complete, it changes nothing: no style is\n * written, so the hold sees nothing stir.\n */\nexport function Revealed({ children }: { children: ReactNode }) {\n const box = useRef<HTMLDivElement>(null);\n const client = useQueryClient();\n useLayoutEffect(() => {\n const own = box.current;\n const pane = own?.closest('.content');\n if (!own) return;\n const root = shellRoot();\n const covered = () => Boolean(pane?.classList.contains('nav-holding')) || root.hasAttribute('data-starting');\n const mark = workMark();\n let hidden = false,\n done = false,\n quiet = 0,\n stirred = false,\n frame = 0;\n const hide = () => {\n if (hidden || done || covered()) return;\n hidden = true;\n own.style.visibility = 'hidden';\n own.style.minHeight = '100vh';\n };\n const finish = () => {\n if (done) return;\n done = true;\n cancelAnimationFrame(frame);\n clearTimeout(cap);\n drawn.disconnect();\n cover.disconnect();\n stop();\n if (hidden) {\n own.style.removeProperty('visibility');\n own.style.removeProperty('min-height');\n }\n };\n /* Told as a microtask, so a cover that lifts hides the page before the frame paints it. */\n const cover = new MutationObserver(hide);\n if (pane) cover.observe(pane, { attributes: true, attributeFilter: ['class'] });\n cover.observe(root, { attributes: true, attributeFilter: ['data-starting'] });\n const drawn = new MutationObserver(() => {\n stirred = true;\n });\n drawn.observe(own, { childList: true, subtree: true, characterData: true });\n const stop = client.getQueryCache().subscribe(() => {\n stirred = true;\n });\n const cap = setTimeout(finish, REVEAL_CAP);\n const watch = () => {\n const busy = stirred || workSince(mark) || client.isFetching() > 0;\n stirred = false;\n quiet = busy ? 0 : quiet + 1;\n if (quiet >= QUIET_FRAMES) {\n finish();\n return;\n }\n frame = requestAnimationFrame(watch);\n };\n hide();\n frame = requestAnimationFrame(watch);\n return finish;\n }, [client]);\n return (\n <div ref={box} className=\"page-revealed\">\n {children}\n </div>\n );\n}\n\nexport type { ReactNode };\n","/** What SavedViews says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n removeNameLabel: 'Remove {name}',\n saveThisFilter: '+ Save this filter',\n removeLabelText: 'Remove {label} {text}',\n});\n","/**\n * Saved filters, as named tabs on a table, beside what is narrowing the\n * result right now — each with a way off. The query bar can write clauses\n * but could not un-write them: having sorted by clicking a header, going\n * back to unsorted meant finding `sort contract_id` in a line of text and\n * deleting exactly it. The store and the naming live in `views.js`.\n */\nimport { savedViewsFor } from '../views.js';\nimport { go, tableView } from '../core.js';\nimport { activeClauses, withoutClause, withoutCondition } from '../clauses.js';\nimport { say } from '../copy/lists/components/SavedViews.js';\n\nexport interface SavedView {\n id: string;\n name: string;\n query: string;\n}\ninterface Entry {\n table: string;\n query: string;\n}\ninterface Clause {\n key: 'sort' | 'filter' | 'show' | 'limit';\n label: string;\n text: string;\n index?: number;\n}\n\n/** Drawn into the `div.views` tablist the crossing owns, so the bar's direct-child rules keep holding. */\nexport function SavedViewsBar({\n entry,\n views,\n onSave,\n onRename,\n onRemove,\n}: {\n entry: Entry;\n views: SavedView[];\n onSave: () => void;\n onRename: (view: SavedView) => void;\n onRemove: (view: SavedView) => void;\n}) {\n /* \"All\" is the unfiltered table, and is only meaningful once something else exists to contrast it with. */\n const isPlain = entry.query.trim() === entry.table;\n const alreadySaved = views.some((v) => v.query.trim() === entry.query.trim());\n return (\n <>\n {views.length ? (\n <button type=\"button\" className=\"view-tab\" aria-pressed={isPlain} onClick={() => go(tableView(entry.table), 'replace')}>\n {say('common.all')}\n </button>\n ) : null}\n {views.map((view) => {\n const active = view.query.trim() === entry.query.trim();\n return (\n <span key={view.id} className={`view-tab-wrap${active ? ' active' : ''}`}>\n <button\n type=\"button\"\n className=\"view-tab\"\n aria-pressed={active}\n title={view.query}\n onClick={() => go(tableView(entry.table, view.query), 'replace')}\n onDoubleClick={() => onRename(view)}\n >\n {view.name}\n </button>\n <button\n type=\"button\"\n className=\"view-remove\"\n title={say('common.removeName', { name: view.name })}\n aria-label={say('removeNameLabel', { name: view.name })}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(view);\n }}\n >\n ×\n </button>\n </span>\n );\n })}\n {/* Saving is offered only when there is a filter worth saving. */}\n {!isPlain && !alreadySaved ? (\n <button type=\"button\" className=\"view-save\" onClick={onSave}>\n {say('saveThisFilter')}\n </button>\n ) : null}\n {(activeClauses(entry.query) as Clause[]).map((clause, i) => (\n <span key={`${clause.key}${clause.index ?? ''}${i}`} className={`clause clause-${clause.key}`}>\n <span className=\"clause-label\">{clause.label}</span>\n <span className=\"clause-text\" title={clause.text}>\n {clause.text}\n </span>\n {/* A filter chip removes its own condition; everything else removes the whole clause. */}\n <button\n type=\"button\"\n className=\"clause-remove\"\n title={say('removeLabelText', { label: clause.label, text: clause.text })}\n aria-label={say('removeLabelText', { label: clause.label, text: clause.text })}\n onClick={() =>\n go(\n tableView(\n entry.table,\n clause.index === undefined ? withoutClause(entry.query, clause.key) : withoutCondition(entry.query, clause.index),\n ),\n 'replace',\n )\n }\n >\n ×\n </button>\n </span>\n ))}\n </>\n );\n}\n\n/**\n * The strip over the explorer's table view: the tablist the stylesheet\n * addresses, or nothing at all. The store and the naming are views.js's.\n */\nexport function SavedViewsSection({ entry }: { entry: Entry }) {\n const bar = savedViewsFor(entry) as {\n views: SavedView[];\n onSave: () => void;\n onRename: (v: SavedView) => void;\n onRemove: (v: SavedView) => void;\n } | null;\n if (!bar) return null;\n return (\n /* A group of switches, not a tablist: beside the saved filters it holds\n their removals, \"Save this filter\" and the query's own chips, none of\n which is a tab, and a tablist may hold only tabs. */\n <div className=\"views\" role=\"group\" aria-label={say('common.savedFilters')}>\n <SavedViewsBar entry={entry} views={bar.views} onSave={bar.onSave} onRename={bar.onRename} onRemove={bar.onRemove} />\n </div>\n );\n}\n","/* A component's own rules, brought with it: after the base, before any look (style.css names the order). */\n@layer components {\n/* Under the room, not beside it: the footer takes the content's width and is\n separated by a rule rather than a band of its own colour, so it reads as\n the end of the page instead of a second surface. Quiet by construction —\n dimmed text at 13px, the same step the landing's footer uses. */\n.app-footer {\n display: grid; gap: var(--space-3h);\n margin-top: var(--space-7); padding: 20px var(--space-4h) 28px;\n border-top: 1px solid var(--line);\n color: var(--ink-muted); font-size: var(--text-base);\n}\n.app-footer-text { margin: 0; max-width: 70ch; line-height: 1.6; }\n.app-footer-links { display: flex; flex-wrap: wrap; gap: var(--space-3) 20px; margin: 0; padding: 0; list-style: none; }\n.app-footer-links a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }\n.app-footer-links a:hover { color: var(--ink); }\n}\n","/**\n * The App's footer: a line of small print and a row of links, drawn under\n * every room of an App that declares `ui.footer`.\n *\n * A landing already had a footer of its own, which is where this shape comes\n * from (`appLanding.parseFooter`). What was missing is the one people read: a\n * public-facing App's listing and record pages ended in nothing, while the\n * sites they are modelled on carry their terms, privacy and contact links on\n * every page. The database browser has no footer and gets none — this belongs\n * to an App, the way a look does.\n *\n * Every string the author wrote is drawn as React text, so markup in it is\n * shown and never run, and a link's href was held to https:, mailto: and tel:\n * when the App loaded.\n */\nimport type { LandingLink } from '@mistriwork/engine/shared/servedApp.js';\nimport { safeHref } from './LandingSurface.js';\nimport './AppFooter.css';\n\nexport function AppFooter({ footer }: { footer: { text?: string; links?: LandingLink[] } }) {\n const links = footer.links ?? [];\n if (!footer.text && !links.length) return null;\n return (\n <footer className=\"app-footer\">\n {footer.text && <p className=\"app-footer-text\">{footer.text}</p>}\n {links.length ? (\n <ul className=\"app-footer-links\">\n {links.map((link, index) => {\n const href = safeHref(link.href);\n return (\n <li key={index}>\n {href ? (\n <a href={href} rel=\"noreferrer noopener\">\n {link.label}\n </a>\n ) : (\n <span>{link.label}</span>\n )}\n </li>\n );\n })}\n </ul>\n ) : null}\n </footer>\n );\n}\n","/**\n * The content pane: what is on screen, decided by the walk.\n *\n * Mounted once on `#content` and subscribed to the walk. Nothing on the\n * stack is a landing — the app's screen or its home card, the workbench's\n * shape of the database; otherwise the trail, then the room the top entry\n * names. Each kind is named explicitly: a dispatch whose last branch is\n * \"or else a row\" turns every kind it has not heard of into a record view\n * asking for a key nobody supplied.\n *\n * Three ticks drive it. Every `render()` is a paint: the address bar is\n * written. The room is keyed by the room tick (core.js `roomVersion`), which\n * moves on nearly every paint, so the room's state and its fetches start\n * over the way a repaint always did — except for a refinement of the table\n * room on screen (a page, a page size, a header's sort or filter), which\n * keeps the room and lets its Query re-ask in place — in an App's list as in\n * the Workbench's table. A crumb correction\n * (`renderCrumbs`) ticks the walk alone: the trail re-reads its labels and\n * the room is left be, because re-fetching the row that just resolved its\n * own label would loop.\n */\nimport { Fragment, useLayoutEffect } from 'react';\nimport { currentEntry, paintVersion, renderCrumbs, roomVersion } from '../core.js';\nimport { shell } from '../shellMode.js';\nimport { syncHash } from '../url.js';\nimport { appListFor, type ListSpec } from './appListModel.js';\nimport { ASSISTANT_PAGE, INBOX_PAGE, dashPageId, dashViewKey, formViewKey, homeRoom } from './appRooms.js';\nimport { onDemand } from './onDemand.js';\nimport type { BreakdownEntry } from './Breakdown.js';\nimport { crumbBarShown, Crumbs } from './Crumbs.js';\nimport type { DashboardDef } from './dashboardModel.js';\nimport { LoadErrorNote, NothingGranted, WorkbenchLanding } from './Landing.js';\nimport type { PageEntry } from './pageModel.js';\nimport { PageRoom } from './PageRoom.js';\nimport type { RowEntry } from './Record.js';\nimport { AppListRoom, DashboardRoom, RowRoom } from './Rooms.js';\nimport { SavedViewsSection } from './SavedViews.js';\nimport { TableRoom } from './TableRoom.js';\nimport type { TableEntry } from './TableView.js';\nimport { useWalk } from './walk.js';\nimport type { KnownPage } from './WorkPanel.js';\nimport { AppFooter } from './AppFooter.js';\nimport { documentAt } from '../documents.js';\nimport { ErrorBoundary } from './ErrorBoundary.js';\n\n/* A breakdown is the query language at work, loaded when one is first asked. */\nconst BreakdownRoom = onDemand(() => import('./BreakdownRoom.js'), 'BreakdownRoom');\n/* An App's own rooms — its home, a form, the inbox, the assistant, a record's document — are the App\n framework's, drawn through the shell's rooms slot (shellMode.ts `rooms`); this pane names none of them. */\n\n/* The pages this connection has, as the last read left them. Synchronous,\n because the landing is drawn before anything is fetched — the shell fills\n this once the pages are known, and a first visit has none to show. */\nlet knownPages: KnownPage[] = [];\nexport function setKnownPages(pages: KnownPage[]): void {\n knownPages = pages;\n}\n\n/* A sentence above the landing — the link that could not be followed, and\n the way forward — shown until the next paint takes it away. */\nlet notice: { text: string; paint: number } | null = null;\nexport function noticeOnContent(text: string): void {\n notice = { text, paint: paintVersion() };\n renderCrumbs();\n}\n\n/* Set by boot while an address it has not applied yet names somewhere: the\n walk is still empty then, and an empty walk is home. Drawn in that gap,\n the home dashboard mounted and fired every tile's query — fourteen\n requests on a warm-tab deep link to a list — for a room nobody asked\n for, replaced a moment later. Released the moment the address is\n applied (app.js boot, switchAndRestore), and the paint that follows\n draws the room the address names. */\nlet homeHeld = false;\nexport function holdHome(held: boolean): void {\n homeHeld = held;\n}\nexport function homeIsHeld(): boolean {\n return homeHeld;\n}\n\nexport function Content({ onHome }: { onHome: () => void }) {\n useWalk();\n const frame = shell().inApp() ? shell().app()?.ui.shell : undefined;\n const body = <ContentBody onHome={onHome} />;\n /* The frame draws the content's width, gutter and title. Placement, the\n menu, search and breadcrumbs are drawn elsewhere and need no frame. */\n const framed = frame !== undefined && (frame.width !== undefined || frame.gutter !== undefined || frame.heading === false);\n /* The App's footer belongs to every room, so it is drawn here rather than\n by each room — and inside the frame, so it takes the content's width\n rather than the window's. A landing standing alone draws its own (LandingSurface); one drawn as this\n pane's home is told not to (PublicHome), so there is one footer either way. */\n const footer = shell().inApp() ? shell().app()?.ui.footer : undefined;\n const withFooter = footer ? (\n <>\n {body}\n <AppFooter footer={footer} />\n </>\n ) : (\n body\n );\n return framed ? (\n <div\n className={`app-content-frame${frame?.heading === false ? ' app-content-no-title' : ''}`}\n data-width={frame?.width}\n data-gutter={frame?.gutter}\n >\n {withFooter}\n </div>\n ) : (\n withFooter\n );\n}\n\nfunction ContentBody({ onHome }: { onHome: () => void }) {\n const walked = useWalk();\n const paint = paintVersion();\n const entry = currentEntry() as ((TableEntry | BreakdownEntry | PageEntry | RowEntry) & { kind: string }) | undefined;\n /* Every paint is a state change worth linking to, so the address bar is\n written here rather than at each of the dozen places that call go(). */\n useLayoutEffect(() => {\n syncHash();\n }, [paint]);\n const said = notice && notice.paint === paint ? <p className=\"note\">{notice.text}</p> : null;\n\n const app = shell().inApp() ? shell().app() : null;\n /* Where this visitor starts is the server's answer (the payload's `home`),\n followed and never worked out here: one of the App's rooms, or — when\n it names none — a public view (AppHome.tsx). */\n const home = app ? homeRoom(app) : undefined;\n const homeDash = home && 'sections' in home ? (home as DashboardDef) : undefined;\n const homeEntry =\n entry?.kind === 'page' && (entry as PageEntry).tab === 'home' && homeDash && (entry as PageEntry).pageId === dashPageId(homeDash.id)\n ? (entry as PageEntry)\n : undefined;\n if (!entry && homeHeld) return null;\n if (!entry || homeEntry) {\n /* In an app, home is the app: where its work starts and what is waiting,\n not the anatomy of the database it happens to run on. The schema\n summary and diagram still exist — they are the workbench's landing,\n one \"All tables\" flip away. */\n if (shell().inApp()) {\n const Home = shell().rooms.Home;\n return Home ? <Home paint={paint} said={said} entry={homeEntry} pages={knownPages} /> : null;\n }\n // An App is served, and this account's roles read none of it.\n if (shell().app())\n return (\n <>\n {said}\n <NothingGranted />\n </>\n );\n return (\n <>\n {said}\n <WorkbenchLanding pages={knownPages} />\n </>\n );\n }\n\n const loadError = shell().inApp() ? shell().loadError() : '';\n /* Spelled apart, so a room in one mode is never taken for the same room\n in the other when the mode changes under the same key. An App's list\n keeps its room through a refinement too (a header's sort, a page): it\n was keyed by the paint, so a sort threw the whole grid away and built\n it again inside the click, the slowest interaction measured on a list\n (test/built-client-vitals.mjs). */\n const room = shell().inApp() ? `app:${roomVersion()}` : `room:${roomVersion()}`;\n return (\n <>\n {/* Decided here, from the walk, in the render that draws the room: a list painted without the bar has its\n heading row from the first frame (crumbSlot.ts), and one painted with it never draws that row at all. */}\n {crumbBarShown(walked) && (\n <div className=\"crumbs-host\">\n <Crumbs onHome={onHome} />\n </div>\n )}\n <LoadErrorNote error={loadError} />\n {said}\n {/* A room that throws says so under the trail, which still leads out of it. */}\n <Fragment key={room}>\n <ErrorBoundary scope=\"room\">\n <Room entry={entry} />\n </ErrorBoundary>\n </Fragment>\n </>\n );\n}\n\nfunction Room({ entry }: { entry: (TableEntry | BreakdownEntry | PageEntry | RowEntry) & { kind: string } }) {\n if (entry.kind === 'table') {\n const table = entry as TableEntry;\n /* In app mode every table renders as an app list page — one of the\n App's views when it has one, a synthesized one (humanized name,\n derived filters) when a drill from a page lands outside them. Same\n entry, same URL; which room you are in decides the dress. */\n const appList = shell().inApp() ? (appListFor(table.table, table.query) as ListSpec | null) : null;\n if (appList) return <AppListRoom entry={table} spec={appList} />;\n /* Saved filters sit above the view tabs and below the trail: they are a\n property of the table you are on, not of the walk that got you here. */\n return (\n <>\n <SavedViewsSection entry={table} />\n <TableRoom entry={table} />\n </>\n );\n }\n if (entry.kind === 'breakdown') return <BreakdownRoom entry={entry as BreakdownEntry} />;\n /* A record's document is said where its tab would be (`/orders/12/invoice`): the record's room yields to the sheet. */\n const document = entry.kind === 'page' || entry.kind === 'row' ? documentAt(entry as PageEntry | RowEntry) : undefined;\n const rooms = shell().rooms;\n if (document) return rooms.Document ? <rooms.Document entry={entry as PageEntry | RowEntry} document={document} /> : null;\n if (entry.kind === 'page') {\n const page = entry as PageEntry;\n /* A dashboard rides the page token with a reserved id space: saved pages\n say `saved:`, config pages `config-`, suggestions `suggested:` —\n `dash-` and `form-` are the app's own screens, and branching here\n costs the URL machinery nothing. */\n if (shell().inApp() && dashViewKey(page.pageId) !== undefined) return <DashboardRoom entry={page} />;\n if (shell().inApp() && formViewKey(page.pageId) !== undefined) return rooms.Form ? <rooms.Form entry={page} /> : null;\n if (shell().inApp() && page.pageId === INBOX_PAGE) return rooms.Inbox ? <rooms.Inbox /> : null;\n if (shell().inApp() && page.pageId === ASSISTANT_PAGE) return rooms.Assistant ? <rooms.Assistant conversation={page.tab} /> : null;\n return <PageRoom entry={page} />;\n }\n return <RowRoom entry={entry as RowEntry} />;\n}\n","/**\n * A navigation swaps finished screens (docs/design.md, motion rule 9).\n *\n * Every paint that starts a room over used to take the room it left off the\n * screen at once and draw the new one as its answers came in: an empty pane\n * for a frame, then a skeleton, then the header, the sections, the aside and\n * the related lists one by one, each pushing the next down. Measured on\n * Compass and on the Keystone lender App, list → record painted in four to\n * eight steps over 100–450 ms, with a layout shift at each.\n *\n * So the screen being left is held — a still copy of it, standing where it\n * stood — while the room that replaces it is drawn underneath, laid out but\n * not shown, and asks for what it needs. When nothing asked since the\n * navigation began is still out (pendingWork.ts, and the room's reads), the\n * copy goes and the new room is there, complete. Most rooms are complete\n * well inside BUDGET ms, and the reader sees one screen replace another.\n * Past it the copy is dimmed, still, so the wait is said without anything\n * moving; and a room still not complete at CAP ms is shown as it stands, its\n * own placeholders saying the rest is coming — a server that slow should not\n * keep the reader looking at a screen they left.\n *\n * The copy is a picture and nothing else: drawn in a closed shadow root,\n * under the page's own stylesheets and a twin of every element the pane\n * stands in, so it looks exactly as the screen did — and no lookup by id,\n * no selector, no test's locator and no assistive technology finds a second\n * record title, a second radio group or a second field in it. The room\n * beneath is the only one there is: laid out and focusable, only not yet\n * painted. Any input — a press, a key, a wheel — ends the hold at once, so\n * nothing waits on it (motion rule 7).\n *\n * A step to a new place starts at the top; Back and Forward return to where\n * the reader was on that screen; a refinement of the place on screen (a\n * sort, a tab, a write that repaints) keeps the scroll it had. A step to a\n * new place taken with the pointer may enter with 160 ms of opacity and a\n * few pixels of settle, once the screen is complete; a key, a refinement or\n * Back animates nothing, and reduced motion silences the enter in the\n * stylesheet.\n */\nimport { motionStill } from './motionStill.js';\nimport { workMark, workSince } from './pendingWork.js';\nimport { addHostListener, onNavigate, shellRoot } from './shellHost.js';\nimport { herePath, hereSearch } from './addressMount.js';\n\n/** How long a navigation holds the screen it left without saying so, in ms. */\nexport const BUDGET = 300;\n/** The longest it holds it at all, in ms. */\nexport const CAP = 1500;\n/* Quiet frames, counted from the frame after the paint: a Query that answers\n enables the next one in the render after it, and React draws that render\n in slices between frames, so a frame or two with nothing out can sit\n between two asks. Anything drawn into the room counts as not quiet. */\nconst QUIET_FRAMES = 3;\n/* Scroll positions to return to, by address; bounded, as a walk is. */\nconst REMEMBERED = 100;\nconst ENTER_CLASS = 'nav-enter';\n\ninterface Place {\n kind?: string;\n table?: string;\n pageId?: string;\n key?: unknown;\n view?: string;\n}\n\ninterface Hold {\n copy: HTMLElement;\n picture: HTMLElement;\n mark: number;\n timers: Array<ReturnType<typeof setTimeout>>;\n frame: number;\n quiet: number;\n scroll: 'top' | 'keep' | 'restore';\n enter: boolean;\n}\n\n/** What else says a room is still arriving: its reads (TanStack Query), which may wait on more than a request. */\ninterface HoldProbe {\n /** Whether a read is running now. */\n busy(): boolean;\n /** Told of every change to any read; returns the way to stop listening. */\n watch(changed: () => void): () => void;\n}\n\nlet content: HTMLElement | null = null;\nlet probe: HoldProbe = { busy: () => false, watch: () => () => {} };\nlet stirred = false;\nlet hold: Hold | null = null;\nlet shown: { entry: unknown; place: string; depth: number; address: string } | null = null;\n/* When the last Back or Forward came. A traversal the shell refuses (a\n change still pending) paints nothing, so the mark is read only by a paint\n that follows it closely, and only once. */\nlet traversedAt = -Infinity;\nconst TRAVERSAL_WINDOW = 1000;\nlet lastInput: { pointer: boolean; at: number; target?: EventTarget | null } = { pointer: false, at: 0 };\nconst scrollAt = new Map<string, number>();\nlet restoring: { top: number; until: number } | null = null;\n\nconst address = () => herePath() + hereSearch();\nconst placeOf = (entry: Place | undefined): string =>\n entry ? JSON.stringify([entry.kind, entry.table, entry.pageId, entry.view, entry.key ?? null]) : '';\n/* Whether the entry names another thing altogether, not another look at this one. */\nconst sameThing = (a: Place | undefined, b: Place | undefined) =>\n (a?.kind ?? '') === (b?.kind ?? '') && (a?.table ?? '') === (b?.table ?? '') && (a?.pageId ?? '') === (b?.pageId ?? '');\n\n/**\n * Start listening. Once, from the shell: Back and Forward are told apart from\n * a click by the `popstate` that precedes their paint, and the hold ends on\n * the reader's first input.\n */\nexport function installNavigationHold(host: HTMLElement, reads?: HoldProbe): void {\n const first = content === null;\n content = host;\n if (!first) return;\n if (reads) probe = reads;\n /* A read that answers enables the next in the render after it, with\n nothing out between the two: any change to a read starts the quiet\n count again. */\n probe.watch(() => {\n if (hold) stirred = true;\n });\n /* And a room still drawing itself is still arriving: a commit into the pane\n (not the picture, whose own drawing is in its shadow root) stirs too. */\n if (typeof MutationObserver === 'function') {\n new MutationObserver((records) => {\n if (hold && records.some((record) => record.target !== hold!.copy)) stirred = true;\n }).observe(host, { childList: true, subtree: true, characterData: true, attributes: true });\n }\n /* Registered before the shell's own listener, which paints: the mark is set when the paint comes. */\n onNavigate(() => {\n traversedAt = performance.now();\n }, true);\n /* The page's stylesheets, read for the picture before the first navigation\n needs them — when the page is idle, so starting up never waits on it. */\n const warm = () => {\n mirrorSheets();\n };\n if (typeof requestIdleCallback === 'function') requestIdleCallback(warm, { timeout: 3000 });\n else setTimeout(warm, 1000);\n /* And each one a part brings when it loads, as it arrives. The published\n client links a part's stylesheet when the part is first drawn (a record's\n sections, the related lists); read only at the next navigation, it was\n still on its way then, and that navigation went unheld — the related\n record painted into an empty pane. Under Vite every sheet is a style\n element, whose text is there at once, so only the bundle showed it. */\n if (typeof MutationObserver === 'function') {\n new MutationObserver((records) => {\n for (const record of records)\n for (const node of Array.from(record.addedNodes)) {\n if (!(node instanceof HTMLLinkElement) || !/\\bstylesheet\\b/i.test(node.rel) || !node.href) continue;\n if (node.sheet) readLinked(node.href);\n else node.addEventListener('load', () => readLinked(node.href), { once: true });\n }\n }).observe(document.head, { childList: true });\n }\n const input = (pointer: boolean) => (event: Event) => {\n lastInput = { pointer, at: performance.now(), target: event.target };\n if (hold) release();\n restoring = null;\n };\n addHostListener(window, 'pointerdown', input(true), true);\n addHostListener(window, 'keydown', input(false), true);\n const moved = () => {\n if (hold) release();\n restoring = null;\n };\n addHostListener(window, 'wheel', moved, { capture: true, passive: true });\n addHostListener(window, 'touchmove', moved, { capture: true, passive: true });\n}\n\n/**\n * Before a paint: hold the screen on show when the paint starts the room over.\n * `room` is whether the room is new; `entry` and `depth` are the walk's top\n * entry and length as the paint will draw them.\n */\nexport function beforePaint(room: boolean, entry: Place | undefined, depth: number): void {\n const pane = content;\n const traversal = performance.now() - traversedAt < TRAVERSAL_WINDOW;\n traversedAt = -Infinity;\n if (!pane || !pane.isConnected || !shown) return;\n if (!hold) scrollAt.set(shown.address, pane.scrollTop);\n if (scrollAt.size > REMEMBERED) scrollAt.delete(scrollAt.keys().next().value!);\n if (!room) return;\n const again = entry === shown.entry;\n const scroll: Hold['scroll'] = traversal ? 'restore' : again || placeOf(entry) === shown.place ? 'keep' : 'top';\n if (hold) {\n /* A room that redirects as it opens (a bare list to its first tab, a row\n to its page) is still the same navigation: the copy stays, the budget\n runs on, and a step it began is not undone by a replace it made. */\n if (hold.scroll === 'keep') hold.scroll = scroll;\n return;\n }\n if (!pane.firstElementChild) return;\n const recent = performance.now() - lastInput.at < 1000;\n const enter =\n !traversal &&\n !again &&\n lastInput.pointer &&\n recent &&\n !motionStill() &&\n (!sameThing(entry, shown.entry as Place | undefined) || depth !== shown.depth);\n /* The focus leaves the room it stands in now, while nothing on the page waits to be restyled. Taken away with the\n room, it went in the middle of the paint, and Chrome brought the whole pane's style up to date to let it go: the\n picture and the room being left, restyled only to be removed, 60 ms of a tab's click on the vitals' slowed CPU.\n The blur is the one removal sends (Chrome sends it), sent first; the room puts the focus back where it belongs.\n Only where the focus is what was just clicked: a search narrowing the list as it is typed into a rail's box,\n arriving while the pointer goes down on one of the box's suggestions, leaves the focus in the box, which the\n suggestion still needs. */\n const focused = document.activeElement;\n if (\n lastInput.pointer &&\n recent &&\n focused &&\n pane.contains(focused) &&\n lastInput.target instanceof Node &&\n focused.contains(lastInput.target)\n )\n (focused as HTMLElement).blur();\n const made = picture(pane);\n /* Nothing to draw the picture with (no constructable stylesheets): the paint is only a paint, as it was. */\n if (!made) return;\n const { copy } = made;\n pane.append(copy);\n /* Written only where there is a scroll to copy: writing it lays the whole\n picture out inside the click, before the room's own render, and a\n screen left at its top — most of them — has nothing to copy. */\n if (made.scrolled) made.picture.scrollTop = made.scrolled;\n /* A room reached from the keyboard, or a refinement of the room on screen,\n puts the focus back where the reader's hands are (a tab, a filter, the\n first row) the moment it is drawn: under the picture it is transparent,\n so it can take it. A step to a new place taken with the pointer, and Back,\n move no focus into the room, and there it is hidden outright, so nothing\n it does while arriving is a layout shift. */\n const focusable = !traversal && (scroll === 'keep' || (recent && !lastInput.pointer));\n pane.classList.add('nav-holding');\n pane.classList.toggle('nav-holding-focusable', focusable);\n pane.classList.remove(ENTER_CLASS);\n hold = {\n copy,\n picture: made.picture,\n mark: workMark(),\n quiet: 0,\n frame: 0,\n scroll,\n enter,\n timers: [\n setTimeout(() => {\n copy.classList.add('nav-held-waiting');\n pane.setAttribute('aria-busy', 'true');\n }, BUDGET),\n setTimeout(release, CAP),\n ],\n };\n}\n\n/** After the paint: the address is the new one; start watching for the room to be complete. */\nexport function afterPaint(entry: Place | undefined, depth: number): void {\n shown = { entry, place: placeOf(entry), depth, address: address() };\n if (!hold) return;\n hold.quiet = 0;\n /* The frame this paint lands in is not counted: the room's effects, which\n ask for what it needs, run after it. */\n if (!hold.frame)\n hold.frame = requestAnimationFrame(() => {\n if (hold) hold.frame = requestAnimationFrame(watch);\n });\n}\n\nfunction watch(): void {\n if (!hold) return;\n const busy = stirred || workSince(hold.mark) || probe.busy();\n stirred = false;\n hold.quiet = busy ? 0 : hold.quiet + 1;\n if (hold.quiet >= QUIET_FRAMES) {\n release();\n return;\n }\n hold.frame = requestAnimationFrame(watch);\n}\n\n/** The room underneath is shown, and the copy of the one it replaced goes. */\nfunction release(): void {\n const ending = hold;\n if (!ending) return;\n hold = null;\n ending.timers.forEach(clearTimeout);\n if (ending.frame) cancelAnimationFrame(ending.frame);\n const pane = content;\n ending.copy.remove();\n if (!pane) return;\n pane.classList.remove('nav-holding', 'nav-holding-focusable');\n pane.removeAttribute('aria-busy');\n if (ending.scroll === 'top') pane.scrollTop = 0;\n else if (ending.scroll === 'restore') restoreScroll(pane, scrollAt.get(address()) ?? 0);\n if (ending.enter) {\n pane.classList.add(ENTER_CLASS);\n /* Off again once it has run, so nothing is left transformed under a popup. */\n setTimeout(() => pane.classList.remove(ENTER_CLASS), 400);\n }\n}\n\n/**\n * Back to where the reader was. A room past its budget may still be growing\n * toward that point, so the position is asked again each frame for a moment,\n * until it can be reached or the reader moves.\n */\nfunction restoreScroll(pane: HTMLElement, top: number): void {\n pane.scrollTop = top;\n if (pane.scrollTop >= top - 1) {\n restoring = null;\n return;\n }\n restoring = { top, until: performance.now() + 1500 };\n const again = () => {\n if (!restoring || performance.now() > restoring.until) {\n restoring = null;\n return;\n }\n pane.scrollTop = restoring.top;\n if (pane.scrollTop >= restoring.top - 1) {\n restoring = null;\n return;\n }\n requestAnimationFrame(again);\n };\n requestAnimationFrame(again);\n}\n\n/* ---------- the picture ---------- */\n\n/* The page's stylesheets, one constructed twin of each, for the picture's\n shadow root to adopt. Read from each sheet's source — a style element's\n text, a linked file's — because the CSS object model does not give it\n back whole: Chrome serializes `font: 500 12px/1.5 var(--sans)` followed by\n a `font-variant-numeric` as nothing at all, and the picture's list count\n came out in the wrong weight and size. `:root` is read as the root's twin,\n by a class of the same weight (as `html` it weighed less than a\n pseudo-class and lost rules it had won on the page). A sheet switched off\n is left out and a sheet under media keeps it. Another origin's sheet is\n left out: it can only hold font faces, and those are the document's. The\n twins of the pane's ancestors draw no box — they are there for the\n selectors (`body.app-mode .content`, a look's `[data-visual-theme]`) and\n for what inherits — and the root's zoom is not applied twice. */\nconst TWIN = 'nav-held-twin';\nconst ROOT_TWIN = 'nav-held-root';\nconst built = new WeakMap<CSSStyleSheet, { text: string; media: string; sheet: CSSStyleSheet }>();\n/* A linked sheet's text: undefined while it is read, null for one that cannot be (another origin's). */\nconst linked = new Map<string, string | null | undefined>();\nlet twins: CSSStyleSheet | null = null;\n\nfunction readLinked(href: string): void {\n if (linked.has(href)) return;\n let url: URL;\n try {\n url = new URL(href, document.baseURI);\n } catch {\n linked.set(href, null);\n return;\n }\n if (url.origin !== window.location.origin) {\n linked.set(href, null);\n return;\n }\n linked.set(href, undefined);\n /* The file the page already loaded, asked for as the page asked for it (a\n server that answers a script to a plain fetch of a stylesheet — Vite's,\n under development — answers the stylesheet): the cache answers. */\n void fetch(url, { credentials: 'same-origin', headers: { accept: 'text/css,*/*;q=0.1' } })\n .then(\n (reply) => (reply.ok ? reply.text() : null),\n () => null,\n )\n .then((text) => {\n linked.set(href, text);\n /* And its twin built now, while nothing waits: left to the next navigation, the App's own sheet (390 KB),\n still on its way when the page was first idle, was built in the click that opened a record or a tab, 35 ms\n of it on the vitals' slowed CPU (test/built-client-vitals.mjs). */\n mirrorSheets();\n });\n}\n\n/** A sheet's own text, null to leave it out, or undefined while it is still being read. */\nfunction sourceOf(sheet: CSSStyleSheet): string | null | undefined {\n const owner = sheet.ownerNode;\n if (owner instanceof HTMLStyleElement) return owner.textContent ?? '';\n if (!sheet.href) return null;\n if (!linked.has(sheet.href)) readLinked(sheet.href);\n return linked.get(sheet.href);\n}\n\nfunction mirrorSheets(): CSSStyleSheet[] | null {\n try {\n const sheets: CSSStyleSheet[] = [];\n let unread = false;\n for (const sheet of Array.from(document.styleSheets)) {\n if (sheet.disabled) continue;\n const text = sourceOf(sheet);\n if (text === undefined) {\n unread = true;\n continue;\n }\n if (text === null) continue;\n const media = sheet.media?.mediaText ?? '';\n let twin = built.get(sheet);\n if (!twin || twin.text !== text || twin.media !== media) {\n const made = new CSSStyleSheet({ baseURL: sheet.href ?? document.baseURI, ...(media ? { media } : {}) });\n made.replaceSync(text.replace(/:root\\b/g, `.${ROOT_TWIN}`));\n twin = { text, media, sheet: made };\n built.set(sheet, twin);\n }\n sheets.push(twin.sheet);\n }\n /* A sheet not read yet would draw a picture that differs from the screen: this navigation goes unheld. */\n if (unread) return null;\n if (!twins) {\n twins = new CSSStyleSheet();\n twins.replaceSync(`.${TWIN}{display:contents!important;zoom:1!important}`);\n }\n return [...sheets, ...(document.adoptedStyleSheets ?? []), twins];\n } catch {\n return null;\n }\n}\n\n/**\n * The picture of the pane as it stands: a host in the pane's scroll content,\n * over exactly the part the reader sees, holding in a closed shadow root a\n * twin of every ancestor, the pane's own twin scrolled to where the pane is,\n * and a still copy of what the pane holds.\n */\nfunction picture(pane: HTMLElement): { copy: HTMLElement; picture: HTMLElement; scrolled: number } | null {\n const sheets = mirrorSheets();\n if (!sheets || typeof pane.attachShadow !== 'function') return null;\n const copy = document.createElement('div');\n copy.className = 'nav-held';\n copy.setAttribute('aria-hidden', 'true');\n copy.inert = true;\n /* Scroll offsets and a pane's client height are layout pixels, the ruler `top` speaks. */\n copy.style.top = `${pane.scrollTop}px`;\n copy.style.height = `${pane.clientHeight}px`;\n const root = copy.attachShadow({ mode: 'closed' });\n try {\n root.adoptedStyleSheets = sheets;\n } catch {\n return null;\n }\n let inner: ParentNode = root;\n const chain: Element[] = [];\n for (let at = pane.parentElement; at; at = at.parentElement) chain.unshift(at);\n for (const ancestor of chain) {\n const twin = document.createElement(ancestor.tagName.toLowerCase());\n for (const { name, value } of Array.from(ancestor.attributes)) twin.setAttribute(name, value);\n twin.classList.add(TWIN);\n if (ancestor === shellRoot()) twin.classList.add(ROOT_TWIN);\n inner.append(twin);\n inner = twin;\n }\n const twin = pane.cloneNode(false) as HTMLElement;\n twin.classList.remove('nav-holding', ENTER_CLASS);\n twin.removeAttribute('aria-busy');\n twin.style.height = '100%';\n twin.style.overflow = 'hidden';\n for (const child of Array.from(pane.children)) {\n if (child instanceof HTMLElement && !child.classList.contains('nav-held')) twin.append(still(child));\n }\n inner.append(twin);\n return { copy, picture: twin, scrolled: pane.scrollTop };\n}\n\n/**\n * A still copy of a part of the screen: what it looks like, and nothing it\n * does. The names of form controls go (a radio copied into the picture must\n * not join a group), and so does autofocus; a canvas is copied as its\n * picture, and a field as the value typed into it.\n */\nfunction still(node: HTMLElement): HTMLElement {\n const copy = node.cloneNode(true) as HTMLElement;\n for (const element of [copy, ...Array.from(copy.querySelectorAll<HTMLElement>('[name], [autofocus]'))]) {\n element.removeAttribute('name');\n element.removeAttribute('autofocus');\n }\n const from = node.querySelectorAll('canvas');\n if (from.length) {\n const to = copy.querySelectorAll('canvas');\n from.forEach((canvas, i) => {\n try {\n to[i]?.getContext('2d')?.drawImage(canvas, 0, 0);\n } catch {\n /* A tainted or empty canvas is left blank. */\n }\n });\n }\n /* Values typed into fields are state, not attributes: carried over so the picture matches. */\n const fields = node.querySelectorAll('input, textarea, select');\n if (fields.length) {\n const copies = copy.querySelectorAll('input, textarea, select');\n fields.forEach((field, i) => {\n const twin = copies[i] as HTMLInputElement | undefined;\n if (!twin) return;\n if (field instanceof HTMLInputElement && (field.type === 'checkbox' || field.type === 'radio')) twin.checked = field.checked;\n else twin.value = (field as HTMLInputElement).value;\n });\n }\n return copy;\n}\n\n/** Whether a navigation is holding the screen it left; for tests and the shell. */\nexport const holding = (): boolean => hold !== null;\n/** The picture being held, which only its shadow root reaches; for tests. */\nexport const heldPicture = (): HTMLElement | null => hold?.picture ?? null;\n","/** What connectionList says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n runtimeMetadataIsInvalid: 'Runtime metadata is invalid.',\n invalidRuntimeApplicationList: 'Invalid runtime application list.',\n chooseAnApplicationUrl: 'Choose an application URL to continue.',\n invalidRuntimeApplicationOrConnection: 'Invalid runtime application or connection list.',\n});\n","/**\n * Which connection or App this tab is on, from the server's runtime: the\n * first question boot asks, and the list the shell keeps current.\n *\n * Both shells start here. An App server answers with its Apps and the tab\n * takes the one its address names; the database browser answers with its\n * connections, which the Workbench's picker draws (connections.js registers\n * it with `whenConnectionControls`). An App is not a connection manager, so\n * where nothing draws the picker it and the database label stay hidden.\n */\nimport { $, api, state } from './core.js';\nimport { syncWriteMode } from './write.js';\nimport { connectionGeneration } from './connectionTransition.js';\nimport { canManageConnections, setAppConfigured } from './connectionScope.js';\nimport { RuntimeMetadataError, UnknownAppError } from './requestIdentity.js';\nimport { say } from './copy/shell/connectionList.js';\n\n/** @type {import('@mistriwork/engine/shared/connection.js').RuntimeMetadata | null} */\nlet initialRuntime = null;\n\n/** Choose the logical App before the first schema or manifest request. */\nexport async function bootstrapRequestIdentity(requested) {\n try {\n /** @type {import('@mistriwork/engine/shared/connection.js').RuntimeMetadata} */\n const runtime = await api('/api/runtime');\n if (typeof runtime?.appConfigured !== 'boolean') throw new RuntimeMetadataError(say('runtimeMetadataIsInvalid'));\n setAppConfigured(runtime.appConfigured);\n if (runtime.appConfigured) {\n if (\n !Array.isArray(runtime.apps) ||\n runtime.apps.some(\n (app) => !app || typeof app.id !== 'string' || !app.id || typeof app.name !== 'string' || typeof app.writable !== 'boolean',\n )\n ) {\n throw new RuntimeMetadataError(say('invalidRuntimeApplicationList'));\n }\n const selected = requested || runtime.active;\n if (!selected) throw new Error(say('chooseAnApplicationUrl'));\n if (!runtime.apps.some((app) => app.id === selected)) throw new UnknownAppError(selected, runtime.apps);\n state.activeConnection = selected;\n state.connections = runtime.apps;\n }\n initialRuntime = runtime;\n } catch (error) {\n initialRuntime = null;\n setAppConfigured(null);\n throw error;\n }\n}\n\nexport async function initConnections(onSwitched) {\n state.onSwitched = onSwitched;\n await refreshConnections();\n if (!state.activeConnection) throw new Error(say('common.applicationRuntimeIsUnavailable'));\n}\n\n/**\n * Redraw the picker from the server's list.\n *\n * Exported because a deep link switches connection without going through\n * `selectConnection` — it opens the connection the link names and rebuilds\n * the trail — and the picker was left showing whatever the server called\n * active. Landing on a link into one database with the sidebar naming another\n * is the interface disagreeing with itself about where you are.\n */\nlet listGeneration = 0;\nexport async function refreshConnections() {\n const request = ++listGeneration;\n const generation = connectionGeneration();\n const connection = state.activeConnection;\n const isCurrent = () => request === listGeneration && generation === connectionGeneration() && connection === state.activeConnection;\n let data;\n try {\n /** @type {import('@mistriwork/engine/shared/connection.js').RuntimeMetadata} */\n const runtime = initialRuntime ?? (await api('/api/runtime'));\n initialRuntime = null;\n if (!isCurrent()) return;\n if (runtime?.appConfigured === true) {\n data = { connections: runtime.apps, active: runtime.active, appConfigured: true };\n } else if (runtime?.appConfigured === false) {\n data = { ...(await api('/api/connections')), appConfigured: false };\n } else {\n throw new Error(say('common.runtimeMetadataIsUnavailable'));\n }\n } catch {\n if (!isCurrent()) return;\n setAppConfigured(null);\n /* One connection, no config file: the picker has nothing to offer, so it\n gets out of the way rather than showing a control with one option.\n \n `conn-select` was the `<select>` this used to be, and there has been no\n such element since it became a custom dropdown — so this line, on the\n one path that runs when the connection list cannot be read, threw a\n TypeError out of the handler meant to recover from the failure. It\n escaped `initConnections`, which boot awaits, and the page never\n finished starting: a server hiccup on one request took the whole app\n down rather than hiding a picker. */\n $('conn-picker').hidden = true;\n $('db-label').hidden = !canManageConnections();\n controls?.retire($('conn-picker'));\n return;\n }\n if (!isCurrent()) return;\n if (!Array.isArray(data.connections)) throw new Error(say('invalidRuntimeApplicationOrConnection'));\n // Internal ownership/cache keys keep their historical connection names.\n // App runtime metadata contains authored App IDs, not database connections.\n state.connections = data.connections;\n setAppConfigured(typeof data.appConfigured === 'boolean' ? data.appConfigured : null);\n // The server default is only for boot. An established tab owns its connection.\n if (!state.activeConnection) state.activeConnection = data.active;\n\n /* Write mode is remembered per connection, and until now it was only\n re-read when someone *switched* connection — never on the way in. So a\n page reload landed on the active connection with write mode off, and the\n setting quietly came back the moment you switched away and back. `initWriteMode`\n runs before this, when `state.activeConnection` is still undefined, so\n there is nothing it could have read. */\n syncWriteMode();\n\n syncConnectionControls();\n}\n\n/**\n * The Workbench's picker, which draws the connection controls once its shell\n * is loaded (connections.js). A registration rather than an import: an App\n * never loads the picker, and the list is the kit's.\n * @type {{ draw(picker: HTMLElement): void, retire(picker: HTMLElement): void } | null}\n */\nlet controls = null;\n/** @param {{ draw(picker: HTMLElement): void, retire(picker: HTMLElement): void }} next */\nexport function whenConnectionControls(next) {\n controls = next;\n}\n\n/** App ownership: an App is not a connection manager. */\nexport function syncConnectionControls() {\n const picker = $('conn-picker');\n if (!canManageConnections() || !controls) {\n picker.hidden = true;\n $('db-label').hidden = true;\n controls?.retire(picker);\n return;\n }\n controls.draw(picker);\n}\n","/** What tour says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theDatabase: 'The database you are on',\n clickItToSwitch: 'Click it to switch, add another, or edit one. Everything else on the ',\n screenComesFromWhichever: 'screen comes from whichever one is named here.',\n everyTableWithItsSize: 'Every table, with its size',\n theNumberIsHow: 'The number is how many rows are in it. Views are marked. Click one to browse it.',\n askInWordsNotSql: 'Ask in words, not SQL',\n tableFirstThenConditions: 'Table first, then conditions, then sort and limit. Press ? for the full ',\n grammarOrSqlToSee: 'grammar, or SQL to see what it compiled to.',\n aRowIsAPlace: 'A row is a place, not a record',\n clickAnyRowAndYouGet: 'Click any row and you get every row elsewhere that points at it. The ',\n ordersOnACustomer: 'orders on a customer, the customer on an order. No joins to write, and ',\n aTrailBehindYouThatGoes: 'a trail behind you that goes back the way you came.',\n readOnlyUntilYouSay: 'Read only until you say otherwise',\n theWorkbenchStartsRead: 'The workbench starts read-only. Open this menu and choose Editing enabled ',\n toEditThisConnection: 'to edit this connection. Review and apply your changes; ⌘Z undoes an edit.',\n andTheRest: 'And the rest',\n kJumpsToAny: '⌘K jumps to any table, view or database. ··· has the diagram, the ',\n exportsSavedViewsAndThisTour: 'exports, saved views, and this tour again.',\n takeTheTour: 'Take the tour',\n sixThingsWorthKnowing: 'six things worth knowing',\n});\n","/**\n * A short walk around the interface, once.\n *\n * The case for it is narrow and real. Almost everything here is discoverable\n * by clicking, and four things are not: that the bar takes a language rather\n * than SQL, that clicking a row is the whole point rather than a way to see\n * its columns, that editing exists at all behind a switch that says \"Read\n * only\", and that the thing in the corner is a database picker. Each is one\n * sentence. A tour is worth six sentences and nothing more.\n *\n * What that rules out is most of what tours do. There is no progress bar, no\n * confetti, nothing that has to be dismissed twice, and no stop that says\n * \"click here to continue\" — the reader is never made to perform the\n * interface to get out of the tour, because a tour that drives is a tour\n * people learn to escape rather than read. Escape ends it, so does Skip, and\n * ending it is remembered.\n *\n * Two things it does that a simpler version would not:\n *\n * - **A stop whose anchor is not on screen is dropped**, not shown pointing\n * at nothing. The sidebar collapses, the toolbar sheds buttons at narrow\n * widths, and a card captioning an empty rectangle is worse than one\n * fewer stop.\n *\n * - **One stop has no anchor at all.** The idea that a row is a place you\n * walk from is the reason this tool exists and it is not a control, so it\n * is not attached to one. Pinning it to whichever element happened to be\n * nearby would be inventing a location for an idea.\n *\n * It is remembered in `localStorage`, so it is per browser rather than per\n * connection: it teaches the interface, and the interface does not change\n * when the database does.\n */\nimport { createElement } from 'react';\nimport { addMenuItem, menuMode } from './menu.js';\nimport { mount, unmount } from './components/mount.js';\nimport { sayUnavailable } from './components/onDemand.js';\nimport { say } from './copy/workbench/tour.js';\nimport { portalRoot } from './shellHost.js';\n\nconst SEEN = 'mistri.tour.v1';\n\n/**\n * The stops, in the order the eye takes them: where you are, what is here,\n * how to ask, what happens when you click, what it will not do, and where the\n * rest is.\n */\nconst STOPS = [\n {\n /* Two spellings of one thing, and which is on screen depends on how many\n connections there are: the picker when there is a choice to make, the\n plain label when there is not. A stop that named only one of them was\n silently dropped for everybody with a config file — which is to say for\n everybody the tour is most useful to. */\n anchor: ['#conn-picker', '#db-label'],\n title: say('theDatabase'),\n body: say('clickItToSwitch') + say('screenComesFromWhichever'),\n },\n {\n anchor: '.sidebar',\n title: say('everyTableWithItsSize'),\n body: say('theNumberIsHow'),\n },\n {\n anchor: '#querybar',\n title: say('askInWordsNotSql'),\n /* Set as code rather than run into the sentence. A query in prose is a\n string of ordinary words that happens to be a literal, and the reader\n has to be told which part to type. */\n code: 'customer active = true sort name limit 20',\n body: say('tableFirstThenConditions') + say('grammarOrSqlToSee'),\n },\n {\n /* No anchor: an idea, not a control. */\n anchor: null,\n title: say('aRowIsAPlace'),\n body: say('clickAnyRowAndYouGet') + say('ordersOnACustomer') + say('aTrailBehindYouThatGoes'),\n },\n {\n anchor: '#more-button',\n title: say('readOnlyUntilYouSay'),\n body: say('theWorkbenchStartsRead') + say('toEditThisConnection'),\n },\n {\n anchor: '#search-button',\n title: say('andTheRest'),\n body: say('kJumpsToAny') + say('exportsSavedViewsAndThisTour'),\n },\n];\n\nfunction tourSeen() {\n try {\n return window.localStorage.getItem(SEEN) === 'done';\n } catch {\n /* Private browsing, or storage turned off. Treating that as \"already\n seen\" is the right way to be wrong: a tour that cannot remember being\n dismissed would open on every single load. */\n return true;\n }\n}\n\nfunction remember() {\n try {\n window.localStorage.setItem(SEEN, 'done');\n } catch {\n /* Nothing to do, and nothing worth saying about it. */\n }\n}\n\nlet host = null;\n\nfunction endTour({ remembering = true } = {}) {\n if (remembering) remember();\n if (!host) return;\n unmount(host);\n host.remove();\n host = null;\n}\n\n/* The card is fetched the first time the tour starts: most visits are not a first one. */\nlet starting = false;\n\n/** Start it, or do nothing if there is nothing to show. The card is `components/Tour.tsx`. */\nasync function startTour({ asked = false } = {}) {\n if (host || starting || menuMode() !== 'workbench') return;\n starting = true;\n let card;\n try {\n card = await import('./components/Tour.js');\n } catch (error) {\n console.error('The tour chunk did not load.', error);\n /* Offered only to someone who asked: an unasked tour that cannot come is no one's loss. */\n if (asked) sayUnavailable();\n return;\n } finally {\n starting = false;\n }\n const { Tour, anchorFor } = card;\n if (host || menuMode() !== 'workbench') return;\n const stops = STOPS.filter((s) => s.anchor === null || anchorFor(s.anchor) !== undefined);\n /* Only the anchorless stop left means the interface it describes is not on\n screen, and one card about walking rows is not a tour. */\n if (stops.filter((s) => s.anchor).length < 2) return;\n host = document.createElement('div');\n host.className = 'tour-host';\n portalRoot().append(host);\n mount(host, createElement(Tour, { stops, onEnd: () => endTour() }));\n}\n\n/**\n * Offer it, and show it the first time.\n *\n * The menu item is registered whether or not the tour has been seen: the one\n * thing worse than a tour nobody asked for is one that cannot be found again\n * by somebody who now wants it.\n */\nexport function initTour() {\n addMenuItem({\n label: say('takeTheTour'),\n scope: 'workbench',\n detail: say('sixThingsWorthKnowing'),\n onSelect: () => {\n void startTour({ asked: true });\n },\n });\n if (tourSeen()) return;\n /* After the first paint, so the stops have something to measure. Two frames\n rather than a timeout: the second one runs after the first has been\n drawn, which is exactly the condition, rather than a guess in\n milliseconds that is wrong on a slow machine. */\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n void startTour();\n }),\n );\n}\n","/**\n * A press on a row or a link that opens a record begins reading the record's\n * page (recordCompose.ts) while the button is still down, so the page's one\n * request overlaps the click and the screen held for it (navigationHold.ts)\n * is let go sooner. Only a press, Enter, or a focus that stays: a pointer\n * passing over a list asks nothing.\n */\nimport { prefetchRecord, state } from './core.js';\nimport { shell } from './shellMode.js';\nimport { appListFor } from './components/appListModel.js';\nimport { beginRecordPage } from './recordCompose.js';\nimport { addHostListener } from './shellHost.js';\n\n/* Whether a press on a record of this table opens its page: the record\n opener's own rule (appnav.js), asked without opening anything — a split\n shows its pick beside the list and a peek draws a drawer, and neither\n asks for a page. */\nfunction opensAsPage(tableId: string): boolean {\n if (!shell().inApp()) return true;\n const here = (state as { stack?: Array<{ query?: string; view?: string }> }).stack?.at(-1);\n const entry = appListFor(tableId, here?.query, here?.view) as { presentation?: { kind?: string }; open?: string } | undefined;\n return entry?.presentation?.kind !== 'split' && entry?.open !== 'drawer';\n}\n\n/* A focus that stays this long is a reader choosing a row, not passing\n through a list on the arrow keys. */\nconst SETTLED_FOCUS = 150;\n\nfunction intent(target: EventTarget | null): [string, Record<string, unknown>] | undefined {\n const element = target instanceof Element ? target.closest('[data-opens]') : null;\n const said = element?.getAttribute('data-opens');\n if (!said) return undefined;\n try {\n const [table, key] = JSON.parse(said) as [unknown, unknown];\n return typeof table === 'string' && key && typeof key === 'object' ? [table, key as Record<string, unknown>] : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Begin reading a record's page for a press that opens it as one: the walk\n * asks this (core.js `prefetchRecord`) through the shell, which names it at\n * boot (app.js).\n */\nexport function prefetchRecordPage(pageId: string, tableId: string, key: Record<string, unknown>): void {\n if (opensAsPage(tableId)) beginRecordPage((state as { activeConnection?: string }).activeConnection ?? '', pageId, key);\n}\n\nlet listening = false;\n/**\n * From the shell's start (app.js): every row and link that opens a record\n * says which (`opensRecord`, recordIntent.ts), and a press, Enter, or a\n * focus that stays begins reading its page.\n */\nexport function listenForRecordPresses(): void {\n if (listening || typeof document === 'undefined') return;\n listening = true;\n let pressedAt = -Infinity;\n let focusTimer: ReturnType<typeof setTimeout> | undefined;\n const press = (event: Event) => {\n const asked = intent(event.target);\n if (asked) prefetchRecord(...asked);\n };\n addHostListener(\n document,\n 'pointerdown',\n (event) => {\n pressedAt = performance.now();\n press(event);\n },\n true,\n );\n addHostListener(\n document,\n 'keydown',\n (event) => {\n if ((event as KeyboardEvent).key === 'Enter') press(event);\n },\n true,\n );\n addHostListener(\n document,\n 'focusin',\n (event) => {\n clearTimeout(focusTimer);\n const asked = intent(event.target);\n /* A press focuses what it pressed, and has begun its page already. */\n if (asked && performance.now() - pressedAt > 500) focusTimer = setTimeout(() => prefetchRecord(...asked), SETTLED_FOCUS);\n },\n true,\n );\n addHostListener(\n document,\n 'focusout',\n () => {\n clearTimeout(focusTimer);\n },\n true,\n );\n}\n","/** What Peek says, in the record page room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n clickToOpen: 'click to open',\n});\n","/**\n * What is on the other end of a reference, without going there.\n *\n * `sold_by 4` is a promise that an answer exists in another table. So a\n * reference answers itself on hover: a card with the referenced row's\n * identifying fields, near the chip, gone when the pointer leaves. Three\n * things make it bearable: it waits until the pointer has settled, it\n * remembers (the cache is Query's), and it gives up quietly.\n *\n * One layer for the whole page, listening on the document: a table redraws\n * its rows on every page and a virtualised one replaces them as you scroll,\n * so a listener per chip would be thousands of registrations with no one\n * place to take them off again.\n */\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { api, columnLabel, emptyWord, findTable, labelPath, state, viewportBox, viewportSize } from '../core.js';\nimport type { TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport { presentationColumns } from './columnPresentation.js';\nimport { Value } from './Value.js';\nimport { say } from '../copy/record/components/Peek.js';\nimport { addHostListener, removeHostListener } from '../shellHost.js';\n\n/** How long the pointer must rest on a chip before anything is fetched. */\nconst SETTLE_MS = 320;\n/** Fields shown before the card stops listing. */\nconst FIELDS = 6;\n\ninterface Target {\n chip: HTMLElement;\n table: TableMeta;\n column: string;\n value: string;\n}\n\n/** The key first, then the label column, then whatever else fits. */\nfunction fieldsFor(table: TableMeta): string[] {\n const key = table.columns.filter((c) => c.primaryKey).map((c) => c.name);\n const label = labelPath(table) as string | undefined;\n return [\n ...key,\n ...(label && !key.includes(label) ? [label] : []),\n ...table.columns.map((c) => c.name).filter((n) => !key.includes(n) && n !== label),\n ].slice(0, FIELDS);\n}\n\nexport function PeekLayer() {\n const [target, setTarget] = useState<Target | null>(null);\n useEffect(() => {\n let timer = 0;\n const onEnter = (e: Event) => {\n const chip = (e.target as Element).closest?.('[data-ref-table]') as HTMLElement | null;\n if (!chip) return;\n const table = findTable(chip.dataset.refTable ?? '') as TableMeta | undefined;\n const column = chip.dataset.refColumn;\n const value = chip.dataset.refValue;\n if (!table || !column || !value) return;\n clearTimeout(timer);\n timer = window.setTimeout(() => setTarget({ chip, table, column, value }), SETTLE_MS);\n };\n const onLeave = (e: Event) => {\n if ((e.target as Element).closest?.('[data-ref-table]')) {\n clearTimeout(timer);\n setTarget(null);\n }\n };\n const hide = () => {\n clearTimeout(timer);\n setTarget(null);\n };\n addHostListener(document, 'mouseover', onEnter);\n addHostListener(document, 'mouseout', onLeave);\n /* Focus opens it too, so the card is reachable without a pointer. */\n addHostListener(document, 'focusin', onEnter);\n addHostListener(document, 'focusout', onLeave);\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') hide();\n };\n addHostListener(document, 'keydown', onKey);\n // Anything that moves the page out from under the card invalidates it.\n addHostListener(window, 'scroll', hide, true);\n addHostListener(window, 'resize', hide);\n return () => {\n clearTimeout(timer);\n removeHostListener(document, 'mouseover', onEnter);\n removeHostListener(document, 'mouseout', onLeave);\n removeHostListener(document, 'focusin', onEnter);\n removeHostListener(document, 'focusout', onLeave);\n removeHostListener(document, 'keydown', onKey);\n removeHostListener(window, 'scroll', hide, true);\n removeHostListener(window, 'resize', hide);\n };\n }, []);\n return target ? <PeekCard target={target} /> : null;\n}\n\nfunction PeekCard({ target }: { target: Target }) {\n const { chip, table, column, value } = target;\n const fields = fieldsFor(table);\n const columns = presentationColumns(state.schema, table, fields);\n /* The connection is part of the key: staging's employee must not show for\n production's reference. */\n const row = useQuery<Record<string, unknown> | null>({\n queryKey: ['peek', (state as { activeConnection?: string }).activeConnection ?? '', table.id, column, value, fields],\n queryFn: async () => {\n const data = await api('/api/view/run', {\n view: {\n id: `peek:${table.id}`,\n name: table.name,\n base: table.id,\n columns: fields.map((path) => ({ path })),\n filter: { groups: [[{ path: column, op: '=', value }]] },\n limit: 1,\n },\n });\n return data.rows?.[0] ?? null;\n },\n staleTime: Infinity,\n retry: false,\n });\n const card = useRef<HTMLDivElement>(null);\n\n /* The native tooltip has to go while the card is up: taken off the anchor\n and anything inside it, and only what was there is put back. */\n useEffect(() => {\n if (!row.data) return;\n const suppressed: Array<[Element, string]> = [];\n for (const node of [chip, ...chip.querySelectorAll('[title]')]) {\n const title = node.getAttribute('title');\n if (title === null) continue;\n suppressed.push([node, title]);\n node.removeAttribute('title');\n }\n return () => {\n for (const [node, title] of suppressed) node.setAttribute('title', title);\n };\n }, [row.data, chip]);\n\n /* Against the *value*, not the cell: the cell's text alignment says which\n edge the reader is looking at. Below by default; up only when there is\n no room; nudged sideways rather than allowed off the edge. */\n useLayoutEffect(() => {\n const node = card.current;\n if (!node || !chip.isConnected) return;\n const at = viewportBox(chip);\n const box = viewportBox(node);\n const view = viewportSize();\n const margin = 8;\n let top = at.bottom + 4;\n if (top + box.height > view.height - margin) {\n const above = at.top - box.height - 4;\n top = above > margin ? above : Math.max(margin, view.height - box.height - margin);\n }\n const align = getComputedStyle(chip).textAlign;\n const wanted =\n align === 'right' || align === 'end' ? at.right - box.width : align === 'center' ? at.left + at.width / 2 - box.width / 2 : at.left;\n const left = Math.min(Math.max(margin, wanted), Math.max(margin, view.width - box.width - margin));\n node.style.top = `${Math.round(top)}px`;\n node.style.left = `${Math.round(left)}px`;\n });\n\n if (!row.data || !chip.isConnected) return null;\n const data = row.data;\n return (\n <div className=\"peek\" role=\"tooltip\" ref={card}>\n <div className=\"peek-head\">\n <span className=\"peek-table\">{table.name}</span>\n <span className=\"peek-key\">{value}</span>\n </div>\n <div className=\"peek-body\">\n {fields.map((name) => (\n <div key={name} className=\"peek-line\">\n <span className=\"peek-name\" title={name}>\n {(columnLabel(table.id, name) as string | null) ?? name}\n </span>\n {data[name] === null || data[name] === undefined ? (\n <span className=\"peek-value null\" title=\"null\">\n {emptyWord()}\n </span>\n ) : (\n <div className=\"peek-value\">\n <Value col={columns.get(name)} value={data[name]} tableId={table.id} compact />\n </div>\n )}\n </div>\n ))}\n </div>\n {/* The card is a glance; clicking the chip is the walk. */}\n <div className=\"peek-foot\">{say('clickToOpen')}</div>\n </div>\n );\n}\n","/**\n * What is on the other end of a reference, without going there.\n *\n * `sold_by 4` is not an answer. It is a promise that an answer exists in\n * another table, and collecting it costs a navigation, a look, and a click\n * back — by which time you have lost the row you were reading. That round\n * trip is the tax this tool charges on the thing it is best at, and most of\n * the time the question is small: *who is 4?*\n *\n * So a reference answers itself on hover — the card is `components/Peek.tsx`.\n * This module is the seam the vanilla client still uses: the marker that\n * makes an element peekable, the layer's one mount, and the cache reset.\n */\nimport { createElement } from 'react';\nimport { mount, queryClient } from './components/mount.js';\nimport { PeekLayer } from './components/Peek.js';\nimport { sessionIdentity, subscribeSessionIdentity } from './sessionIdentity.js';\nimport { portalRoot } from './shellHost.js';\n\nlet host = null;\n\n/**\n * Emptied when the schema changes underneath the cached rows.\n *\n * The connection key separates databases, not accounts or tenant generations.\n * Identity changes also retire the mounted layer's hover timer and target.\n */\nexport function clearPeekCache() {\n queryClient.removeQueries({ queryKey: ['peek'] });\n}\n\n/** One layer for the whole page, listening on the document. */\nexport function initPeek() {\n if (host?.isConnected) return;\n host = document.createElement('div');\n host.className = 'peek-host';\n portalRoot().append(host);\n mount(host, createElement(PeekLayer, { key: sessionIdentity().epoch }));\n}\n\nsubscribeSessionIdentity(() => {\n clearPeekCache();\n if (host?.isConnected) mount(host, createElement(PeekLayer, { key: sessionIdentity().epoch }));\n});\n\n/** Mark an element as a reference worth peeking at. */\nexport function peekable(node, references, value) {\n if (!references || value === null || value === undefined || value === '') return node;\n node.dataset.refTable = references.table;\n node.dataset.refColumn = references.column;\n node.dataset.refValue = String(value);\n return node;\n}\n","/**\n * Where a composer session lives in the URL: a tab on a table (composer.js\n * says why). Read by the entry point on every navigation and by the composer.\n */\n\n/** The view id encoded in a stack entry's tab, or null if it is not a view. */\nexport function viewTabOf(entry) {\n if (!entry || entry.kind !== 'table') return null;\n const tab = entry.tab ?? 'rows';\n if (tab === 'view') return '';\n /* Two forms, and the leading character says which. `view:<id>` names\n something saved; `view+<text>` carries the view itself, so a composer\n session that was never saved is still a link you can send someone. */\n if (tab.startsWith('view:')) return tab.slice(5);\n if (tab.startsWith('view+')) return `+${tab.slice(5)}`;\n return null;\n}\n","/** What composerEntry says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n viewsMore: 'Views…',\n composeAcrossTables: 'compose across tables',\n});\n","/**\n * The view composer's entry point: its menu item, and the navigation it\n * follows. composer.js — the draft, the paths, the panel — loads the first\n * time a view is opened, from the menu or from a link whose tab is a view;\n * until then a walk update costs one look at the current entry.\n */\nimport { currentEntry, state, subscribeWalk } from './core.js';\nimport { addMenuItem } from './menu.js';\nimport { sayUnavailable } from './components/onDemand.js';\nimport { viewTabOf } from './composerTab.js';\nimport { say } from './copy/workbench/composerEntry.js';\nimport { addHostListener } from './shellHost.js';\n\n/** @type {Promise<typeof import('./composer.js')> | undefined} */\nlet loading;\n/** @type {typeof import('./composer.js') | undefined} */\nlet composer;\nconst load = () =>\n (loading ??= import('./composer.js').then(\n (module) => (composer = module),\n (error) => {\n loading = undefined;\n console.error('The composer chunk did not load.', error);\n sayUnavailable();\n throw error;\n },\n ));\n\n/* Reconcile with wherever the app now is. Nothing to load while no view is\n open: composer.js closes an overlay it has, and there is none before it. */\nfunction sync() {\n if (composer) composer.sync();\n else if (state.schema && viewTabOf(currentEntry()) !== null)\n void load().then(\n (module) => module.sync(),\n () => {},\n );\n}\n\nfunction attach() {\n /* Registered rather than inserted. The composer does not need to know what\n else is in the header, and the header does not need to know the composer\n exists — which is what let six top-level buttons become one menu without\n touching this file's reason for existing. */\n addMenuItem({\n label: say('viewsMore'),\n scope: 'workbench',\n detail: say('composeAcrossTables'),\n onSelect: () =>\n void load().then(\n (module) => module.openFromTopbar(),\n () => {},\n ),\n });\n\n addHostListener(window, 'resize', () => composer?.positionRoot());\n addHostListener(document, 'keydown', (e) => {\n if (e.key === 'Escape') composer?.escapeComposer();\n });\n\n /* Schema readiness precedes restoration of a cold link's walk. Reconcile\n after the walk changes, outside core's synchronous React paint, rather\n than guessing how long restoration will take. */\n subscribeWalk(() => setTimeout(sync, 0));\n sync();\n}\n\nif (document.readyState === 'loading') {\n addHostListener(document, 'DOMContentLoaded', attach);\n} else {\n attach();\n}\n","/** What app says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages(\n {\n /* The skip link and the wordmark's title, said over the page's HTML (index.html). */\n skipToContent: 'Skip to content',\n backToTheSchema: 'Back to the schema (h)',\n brandHome: '{app} home',\n openingWorkspace: 'Opening workspace…',\n filterMenu: 'Filter menu',\n filterTables: 'Filter tables',\n appMenu: 'App menu',\n authoring: 'Authoring',\n themeLab: 'Theme lab',\n appSettings: 'App settings',\n viewMenu: 'View',\n preferences: 'Preferences…',\n appearanceAndListSettings: 'appearance and list settings',\n pages: 'Pages',\n showingInstead: '{message} Showing {label} instead.',\n sessionExpired: 'Session expired',\n signedOut: 'Signed out',\n accountChanged: 'Account changed',\n sessionUnavailable: 'Session unavailable',\n reloadToVerifyYourSession:\n 'Reload to verify your session and continue. Unsaved edits have not been submitted. If a save was in progress, check the record before trying again.',\n couldNotReadTheSchema: 'Could not read the schema: {message}',\n thisTenantLinkIsInvalid: 'This tenant link is invalid. Your current tenant has not changed.',\n darkMode: 'Dark mode',\n theCurrentDatabase: 'the current database',\n one: 'one {base}',\n },\n {\n /* The words a visitor sees in the shell; the rest are said in English. */\n es: {\n appMenu: 'Menú de la aplicación',\n viewMenu: 'Ver',\n preferences: 'Preferencias…',\n appearanceAndListSettings: 'apariencia y ajustes de las listas',\n darkMode: 'Modo oscuro',\n skipToContent: 'Saltar al contenido',\n brandHome: 'Inicio de {app}',\n appSettings: 'Ajustes de la aplicación',\n pages: 'Páginas',\n },\n },\n);\n","/**\n * The kit's shell: the walk, the content pane, the address, the menu, the\n * palette and the keys every page shares, and dispatch to a view. It names\n * neither product: a product's main (appShell.js, workbenchShell.js) calls\n * `boot` with its chrome and, for the Workbench, its tools — the kit's shell\n * API, shells.ts.\n *\n * Loaded by a main once who-am-I has said this page is an App or a database\n * to browse, rather than a public page (publicSurface.js) — so a sign-in\n * screen or a public form never downloads it. Its first paint is this chunk\n * and the entry, fetched together (the server names both in the page): the\n * App framework's chrome (appnav.js) rides in the same chunk, and the\n * Workbench's page names the Workbench's chunk beside them.\n *\n * Everything here is wiring. The views live in their own files and reach the\n * shared state through core.js.\n */\nimport { createElement } from 'react';\nimport { mount, queryClient, unmount, unmountAll } from './components/mount.js';\nimport { requireTenantSelection, sessionIdentity, tenantLeaseActive } from './sessionIdentity.js';\nimport { configureSessionLifecycle, invalidateSession, startSessionMonitoring } from './sessionLifecycle.js';\nimport { Content, holdHome, homeIsHeld, noticeOnContent, setKnownPages } from './components/Content.js';\nimport { setListNavigation } from './components/listNavigation.js';\nimport { viewLink } from './components/viewLink.js';\nimport { Sidebar, moveSidebar, openSidebarChoice } from './components/Sidebar.js';\nimport { setSidebarFilter } from './components/sidebarModel.js';\nimport {\n $,\n allowMutationExit,\n api,\n backTo,\n connectionChanged,\n currentEntry,\n el,\n findTable,\n go,\n invalidateNavigation,\n pageView,\n render,\n setPaintHold,\n state,\n toast,\n} from './core.js';\nimport { afterPaint, beforePaint, installNavigationHold } from './navigationHold.js';\nimport { setStartupProbe } from './startupHold.js';\nimport { initWriteMode, prepareEditingExit } from './write.js';\nimport { bootstrapRequestIdentity, initConnections, refreshConnections, syncConnectionControls } from './connectionList.js';\nimport { RuntimeMetadataError, UnknownAppError } from './requestIdentity.js';\nimport { beginConnectionTransition } from './connectionTransition.js';\nimport { initTour } from './tour.js';\nimport { canManageConnections, canUseDatabaseTools } from './connectionScope.js';\nimport { effectiveTheme, themeLabel, toggleTheme } from './theme.js';\nimport { finishStartup } from './startup.js';\nimport { allowSync, applyHash, connectionFromHash, readAddress, resolveLabels, syncHash, toHash, whileApplying } from './url.js';\nimport { initMenu, addMenuItem, setMenuGroup, setMenuMode } from './menu.js';\nimport { ask } from './prompt.js';\nimport { onDemand } from './components/onDemand.js';\nimport { forgetPages, pagesFor, prefetchPages, recordPageId, whenPagesChange } from './page.js';\nimport { listenForRecordPresses, prefetchRecordPage } from './recordPress.js';\nimport { installShell, shell } from './shellMode.js';\nimport { onLanguagePicked, subscribeMessages } from './messages.js';\nimport { applyDensity } from './density.js';\nimport { applyTypography } from './typography.js';\nimport { openPrefs } from './prefs.js';\nimport { loadTemplates } from './template.js';\nimport { initPeek } from './peek.js';\nimport { initPalette, initSidebarToggle, openPalette } from './palette.js';\nimport { registerSurface } from './surfaces.js';\nimport { OverflowMenu } from './components/OverflowMenu.js';\n/* Imported for its side effect: composerEntry.js attaches the composer's\n entry point, the way history.js does, and loads the composer when a view\n opens. Loading it from a stylesheet's onload worked, but a script that\n runs because a CSS file finished downloading is a dependency nobody would\n guess from reading either file. */\nimport './composerEntry.js';\nimport { say } from './copy/shell/app.js';\nimport { arrivedPlacement, herePath, hereSearch, shown, shownUnplaced } from './addressMount.js';\nimport {\n addHostListener,\n navReplace,\n navState,\n onNavigate,\n sayBrandName,\n setTabTitle,\n shellBody,\n shellQuery,\n shellQueryAll,\n} from './shellHost.js';\n/* The product this page runs, installed by its main (`boot`): its chrome,\n and the Workbench's tools where it is the Workbench. */\n/** @type {import('./shells.js').ShellChrome} */\nlet chrome = /** @type {any} */ (null);\n/** @type {import('./shells.js').ShellTools | undefined} */\nlet offeredTools;\n\n/* The tools once started, for the brand pass and the menu's places; null\n before the Workbench's first paint, and always in an App. */\n/** @type {import('./shells.js').ShellTools | null} */\nlet tools = null;\nfunction startTools() {\n if (offeredTools && !tools) {\n tools = offeredTools;\n offeredTools.start(kit);\n }\n}\n\n/**\n * What the page says when no connection opened: the Workbench's welcome, with\n * what is listed, where it manages connections; anywhere else the product's\n * own screen — no App by the name asked for, or why it is not served\n * (appUnavailable.js).\n * @param {any[]} listed\n * @param {UnknownAppError} [unknown]\n * @param {string} [unavailable]\n */\nfunction showUnopened(listed, unknown = undefined, unavailable = undefined) {\n if (unknown || !canManageConnections() || !offeredTools) chrome.unavailable(unknown, unavailable);\n else offeredTools.showWelcome(listed);\n}\n\n/* React list surfaces may be mounted outside Content (for example in a record\n dialog), so the shell supplies their one navigation capability at boot. */\nsetListNavigation(viewLink);\n\nregisterSurface('overflowMenu', OverflowMenu);\n/* The palette is drawn the first time ⌘K or Search asks for it; it arrives whole (palette.js awaits it). */\nregisterSurface(\n 'palette',\n onDemand(() => import('./components/Palette.js'), 'Palette', { quiet: true }),\n);\nregisterSurface(\n 'composer',\n onDemand(() => import('./components/Composer.js'), 'Composer'),\n);\n/* Authoring dialogs, loaded the first time one opens: most readers never do. */\nconst ThemeLab = onDemand(() => import('./components/ThemeLab.js'), 'ThemeLab', { quiet: true });\n/* ---------- dispatch ---------- */\n\n/**\n * Back to the schema, from anywhere.\n *\n * At module scope because the trail needs it as well as the wordmark — see\n * the root crumb in `breadcrumb`.\n */\nfunction goHome() {\n if (!allowMutationExit()) return;\n invalidateNavigation();\n state.stack = [];\n state.page = 0;\n $('query').value = '';\n render();\n}\n\nfunction showWorkspaceOpening() {\n const status = el('p', { class: 'workspace-opening', role: 'status' });\n $('content').replaceChildren(status);\n // Mount the live region before its words; never retain the previous tenant's content.\n requestAnimationFrame(() => {\n if (status.isConnected) status.textContent = say('openingWorkspace');\n });\n}\n\nasync function clearSurface(me) {\n chrome.retire?.(me);\n chrome.navigationReady?.(false);\n shellBody().classList.add('tenant-pending');\n $('content').hidden = true;\n beginConnectionTransition();\n invalidateNavigation();\n state.schema = null;\n state.stack = [];\n state.canWrite = false;\n state.page = 0;\n $('query').value = '';\n $('table-filter').value = '';\n unmountAll(shellQuery('.account-host'));\n forgetPages();\n setKnownPages([]);\n // mount.tsx defers root disposal so React can remove its portals itself.\n await Promise.resolve();\n shellQueryAll('.tenant-control-host').forEach((host) => host.remove());\n $('errors').replaceChildren();\n $('errors').hidden = true;\n $('explain').textContent = '';\n $('explain-pane').hidden = true;\n $('toast').replaceChildren();\n $('toast').hidden = true;\n showWorkspaceOpening();\n $('content').hidden = false;\n navReplace(shown(`/${encodeURIComponent(state.activeConnection)}`));\n await chrome.showAccount?.(me, kit);\n}\n\nasync function rebuildSurface(me) {\n const owner = sessionIdentity(),\n transition = beginConnectionTransition();\n try {\n // The new context's schema, runtime, App and pages together, as at start.\n const appLoaded = chrome.loadNav();\n prefetchPages();\n const [schema] = await Promise.all([api('/api/schema'), refreshConnections()]);\n if (sessionIdentity() !== owner) return;\n state.schema = schema;\n await Promise.all([loadTemplates(), tools?.loadStores(), appLoaded]);\n if (sessionIdentity() !== owner) return;\n unmount($('content'));\n await Promise.resolve();\n if (sessionIdentity() !== owner) return;\n $('content').replaceChildren();\n // A tenant switch goes home on purpose (goHome below), so nothing is held.\n holdHome(false);\n mount($('content'), createElement(Content, { onHome: goHome }));\n shellBody().classList.remove('tenant-pending');\n initMenu();\n applyBrand();\n renderTableList();\n initWriteMode();\n void chrome.loadFilters?.();\n void registerPages();\n connectionChanged();\n goHome();\n chrome.navigationReady?.(true);\n await chrome.showAccount?.(me, kit);\n } finally {\n transition.finish();\n }\n}\n\n/* What the shells call back into (shells.ts `KitShell`). */\nlet businessRetired = false;\n/** @type {import('./shells.js').KitShell} */\nconst kit = {\n goHome,\n showWorkspaceOpening,\n clearSurface,\n rebuildSurface,\n retired: () => businessRetired,\n retire: () => {\n businessRetired = true;\n },\n};\n\n/* Which row paint is current, for the one branch that answers asynchronously. */\nlet rowPaint = 0;\n\n/* ---------- sidebar ---------- */\n\n/**\n * Move focus into the panel beside the list.\n *\n * The first thing worth landing on rather than the first focusable thing:\n * a column header or a row, not the breadcrumb you just came through. If the\n * panel has nothing to focus, the container itself takes it, so the keyboard\n * is at least on the right side of the page.\n */\nfunction focusContent() {\n const content = $('content');\n const target = content.querySelector('tbody tr, .th-sort, .related-item, .field-group-head') ?? content;\n if (target === content) content.tabIndex = -1;\n if (target instanceof HTMLElement) target.focus({ preventScroll: true });\n target.scrollIntoView?.({ block: 'nearest' });\n}\n\nfunction renderTableList(filterText = '') {\n const list = $('table-list');\n const appMode = shell().inApp();\n const filterInput = $('table-filter');\n const filterLabel = appMode ? say('filterMenu') : say('filterTables');\n filterInput.placeholder = `${filterLabel}\\u2026`;\n filterInput.setAttribute('aria-label', filterLabel);\n list.closest('nav')?.setAttribute('aria-label', appMode ? say('appMenu') : say('common.tables2'));\n $('topnav').setAttribute('aria-label', say('appMenu'));\n /* The product decides where its menu stands (an App's appChrome.js): the\n side list, a strip under the header, or a phone's drawer. */\n const sideList = chrome.menu();\n /* The list is a component (components/Sidebar.tsx) drawn into the `ul`; the\n filter text and the keyboard's cursor are its store. Drawn again on\n every call rather than left to redraw itself, because the app, the\n mode and the schema are read at draw time and the callers here are\n the places that know they changed. */\n setSidebarFilter(filterText);\n if (!sideList) {\n unmount(list);\n return;\n }\n mount(list, createElement(Sidebar, { host: list }));\n}\n\n/**\n * The shell's own words that the page's HTML or a one-time pass wrote: the\n * skip link, the wordmark's title, a visitor's Sign in. Said again whenever\n * the language changes, since a visitor's language arrives with the App's\n * payload — after the shell has drawn — and a reader may pick another.\n */\nfunction sayShellWords() {\n const skip = shellQuery('.skip-link');\n if (skip) skip.textContent = say('skipToContent');\n const app = shell().inApp() ? shell().app() : undefined;\n $('home-button')?.setAttribute('title', app ? say('brandHome', { app: app.name }) : say('backToTheSchema'));\n const signIn = shellQuery('.account-sign-in');\n if (signIn) signIn.textContent = say('common.signIn');\n}\nsubscribeMessages(sayShellWords);\n\n/**\n * The shell answers to the app when one is running: the brand in the top bar\n * and the tab's title carry its name, and hand back to tablewalk when the\n * connection has no app.\n */\nfunction applyBrand() {\n const app = shell().app();\n const inApp = shell().inApp();\n sayBrandName(shellQuery('.brand-name'), app ? app.name : 'tablewalk', app?.shortName);\n sayShellWords();\n setTabTitle(say('common.documentTitle', { title: app ? app.name : state.schema.label }));\n chrome.brand();\n /* The class is the seam the stylesheet hides explorer chrome behind, the\n way `first-run` already does. The app's colours ride the same switch. */\n shellBody().classList.toggle('app-mode', inApp);\n shellBody().classList.toggle('app-bound', !canManageConnections());\n $('sql-toggle').hidden = !canUseDatabaseTools();\n $('search-button').classList.toggle('tn-search', inApp);\n syncConnectionControls();\n setMenuMode(inApp ? 'app' : 'workbench');\n tools?.brand();\n chrome.dress();\n setMenuGroup(\n say('authoring'),\n app ? [] : [{ label: say('themeLab'), category: say('authoring'), onSelect: () => void ask(ThemeLab, {}) }],\n );\n setMenuGroup(say('appSettings'), chrome.settings?.() ?? []);\n /* The reader's own settings — density, list sizes — live in one dialog,\n reachable from here and from ⌘K, and apply the moment they change.\n Density itself is applied on every brand pass so a fresh boot honours\n the stored choice before anyone opens anything. */\n applyDensity();\n applyTypography();\n setMenuGroup(say('viewMenu'), [\n {\n label: () => say('preferences'),\n category: () => say('preferences.title'),\n detail: () => say('appearanceAndListSettings'),\n onSelect: openPrefs,\n },\n ]);\n}\n\n/**\n * Every page this connection has, as one command each.\n *\n * Registered rather than given a nav item: a database with one page does not\n * deserve a permanent tab, and one with nine cannot fit them. `addMenuItem`\n * puts each in the overflow menu and in ⌘K from a single registration, which\n * is where someone looks for \"the customer page\" anyway.\n */\nlet pagesRegistration = 0;\nasync function registerPages() {\n const registration = ++pagesRegistration;\n const connection = state.activeConnection;\n const schema = state.schema;\n const isCurrent = () => registration === pagesRegistration && connection === state.activeConnection && schema === state.schema;\n setKnownPages([]);\n setMenuGroup(say('pages'), []);\n try {\n /* `onSelect` and `detail`, which is what the registry reads. It had been\n `run` and `hint` — names nothing on the other side of this call knows —\n so every page in ⌘K and in the overflow menu threw on click and did\n nothing visible. The one command group built from data was the one\n group nobody could use. */\n const pages = await pagesFor();\n if (!isCurrent()) return;\n setKnownPages(pages.filter((p) => !p.error));\n /* The home screen is drawn before this arrives — it is the first paint —\n so it is drawn again once the pages are known. Only there: anywhere\n else the reader is looking at something, and redrawing it under them\n to add a list they cannot see is worse than the wait. */\n if (!currentEntry()) render();\n setMenuGroup(\n say('pages'),\n pages.map((page) => ({\n scope: 'workbench',\n category: say('pages'),\n label: page.name,\n detail: page.error ? page.error : say('one', { base: page.base }),\n onSelect: () => {\n if (!isCurrent()) return;\n if (page.error) {\n toast(page.error, 'error');\n return;\n }\n go(pageView(page.id, page.base), 'reset');\n },\n })),\n 'page',\n );\n } catch {\n /* A connection whose pages cannot be read is a connection with no pages\n in the menu. It is not a reason to stop starting up. */\n }\n}\n\n/* ---------- a save, followed ---------- */\n\n/**\n * The App again after a save (appLive.ts), drawn where the reader stands.\n * The walk is kept, so the address, the open record and the trail are, and\n * the pane keeps its scroll (a paint of the same entry, navigationHold.ts).\n * The room itself is drawn again rather than kept: a record's surface is\n * fenced to the App it opened under (recordSurface.ts), because its grants\n * and actions were that App's, so its unsent edits go with it. A save that\n * changed which App this is, or left none, is a different page: that one is\n * loaded whole.\n */\nasync function reloadAppInPlace() {\n const before = shell().app();\n if (!(await chrome.reloadNav?.())) return;\n const after = shell().app();\n if (!before || !after || before.id !== after.id) {\n window.location.reload();\n return;\n }\n // The App's pages are its own; the menu is rebuilt from them (whenPagesChange).\n forgetPages();\n void queryClient.invalidateQueries();\n applyBrand();\n renderTableList($('table-filter').value);\n state.navMode = 'replace';\n render();\n}\n\n/* Only where the server says it watches the App's source (appChrome.js). */\nconst followSaves = () => chrome.followSaves?.(reloadAppInPlace);\n\n/* ---------- boot ---------- */\n\n/**\n * Switch connection, then rebuild the trail from the link.\n *\n * The order is the point: the hash is parsed only after the new schema has\n * arrived, because a trail into another database names tables this one does\n * not have and would parse to nothing.\n */\nasync function switchAndRestore(id, hash) {\n const transition = beginConnectionTransition();\n try {\n const schema = canManageConnections()\n ? (await api('/api/connections/select', { id })).schema\n : await api(`/api/schema?app=${encodeURIComponent(id)}`);\n if (!transition.isCurrent()) return;\n state.schema = schema;\n state.activeConnection = id;\n /* The picker names this tab's connection, not the server's idea of an\n active one. A link into one database with the sidebar naming another is\n the interface disagreeing with itself about where you are — and now\n that every request carries its own connection, the server's active is\n not this tab's answer to anything. */\n void refreshConnections();\n /* Layouts, saved pages, SQL and the app manifest are stored per\n connection, so the new connection's are pulled before anything is\n drawn with them — and before the menu is rebuilt, which reads the\n saved-pages mirror. In parallel: four independent round trips in a\n row was a whole extra beat of sidebar-blank per deep link. */\n await Promise.all([loadTemplates(), tools?.loadStores(), chrome.loadNav()]);\n if (!transition.isCurrent()) return;\n // Un-awaited on purpose: a warm cache, not a gate on first paint.\n void chrome.loadFilters?.();\n // A different database has different pages.\n void registerPages();\n /* Same signal the picker sends, so a deep link into another database\n rebuilds the long-lived surfaces the way a switch does. */\n connectionChanged();\n renderTableList();\n /* A list said in words (`/thread/board?tab=…`) is read against the\n App just loaded, as applyHash reads one on the connection already open. */\n const parsed = readAddress(hash, (t) => findTable(t) ?? state.schema.tables.find((x) => x.name === t));\n holdHome(false);\n whileApplying(() => {\n state.stack = parsed?.stack ?? [];\n state.page = 0;\n state.navMode = 'replace';\n render();\n });\n /* Written explicitly, after the suppressed render. Boot renders once\n before the link is applied and stamps the *previous* connection into\n the address bar; without this the URL keeps claiming a database the\n page is no longer showing, and copying it hands someone the wrong\n link. */\n /* Open the address gate here, not in boot: on a cold deep link into\n another database the boot deliberately left it shut so that no render\n between then and now could stamp the outgoing connection into the bar.\n Now the target is loaded and current, so its address is the right one\n to write. Idempotent for the picker/popstate callers, where it is\n already open. */\n allowSync();\n state.navMode = 'replace';\n syncHash();\n $('db-label').textContent = `${schema.label} · ${schema.dialect}`;\n applyBrand();\n followSaves();\n if (parsed?.stack.length) void resolveLabels(parsed.stack, (t) => findTable(t));\n } catch (err) {\n if (!transition.isCurrent()) return;\n // Finish loading whichever schema remains after a failed overlapping switch.\n await state.onSwitched?.(transition.isCurrent);\n if (!transition.isCurrent()) return;\n connectionChanged();\n /* A dead end otherwise.\n \n A bookmarked link naming a connection that has since been removed used\n to render this message and stop, on a page whose only way forward was\n editing the URL by hand — while the database the session *is* connected\n to sat there, loaded and unreachable. The fallback is made out loud\n instead: say which link failed, then show the connection we do have.\n Silently substituting it would be the other error, and the worse one. */\n const said = el('p', {\n class: 'note',\n text: say('showingInstead', { message: err.message, label: state.schema?.label ?? say('theCurrentDatabase') }),\n });\n if (!state.schema) {\n $('content').replaceChildren(said);\n return;\n }\n state.stack = [];\n state.page = 0;\n holdHome(false);\n allowSync();\n state.navMode = 'replace';\n render();\n syncHash();\n // Above the landing page rather than instead of it: the reason and the\n // way forward want to be on screen together.\n noticeOnContent(said.textContent);\n } finally {\n transition.finish();\n }\n}\n\n/**\n * The rest of boot, from who-am-I's answer, for the product whose main\n * asked it (shells.ts `ShellProduct`): that main drew whatever its product\n * shows before the shell (an App's public pages, its sign-in).\n * @param {Record<string, any>} me\n * @param {unknown} landingAt where the address landed (publicRoutes.js `landingRoute`), which the App's chrome reads\n * @param {import('./shells.js').ShellProduct} installed\n */\nexport async function boot(me, landingAt, installed) {\n chrome = installed.chrome;\n offeredTools = installed.tools;\n /* The shell's answers to the kit (shellMode.ts), named before anything\n asks: the product's (an App's words, openers and tenant, appnav.js; the\n Workbench's glance), and the walk's page resolver and read-ahead. The\n Workbench's tools name their own Undo when they start (workbench.js). */\n installShell({\n ...chrome.answers,\n resolvePage: recordPageId,\n prefetchRecord: prefetchRecordPage,\n });\n chrome.start?.(me);\n await chrome.loadTenancy?.(me);\n configureSessionLifecycle({\n onReload: () => window.location.reload(),\n ...chrome.lifecycle?.(me, kit),\n onLock: (reason) => {\n chrome.retire?.(me);\n beginConnectionTransition();\n invalidateNavigation();\n state.schema = null;\n state.stack = [];\n state.canWrite = false;\n state.activeConnection = null;\n state.connections = [];\n unmountAll();\n shellBody().classList.add('session-locked', 'signed-out');\n const titles = {\n expired: say('sessionExpired'),\n 'signed-out': say('signedOut'),\n 'account-changed': say('accountChanged'),\n 'other-tab': say('accountChanged'),\n unavailable: say('sessionUnavailable'),\n };\n const reload = el('button', { type: 'button', text: say('common.reload'), onclick: () => window.location.reload() });\n const lock = el(\n 'section',\n { id: 'session-lock', role: 'alertdialog', 'aria-modal': 'true', 'aria-labelledby': 'session-lock-title' },\n [el('h1', { id: 'session-lock-title', text: titles[reason] }), el('p', { text: say('reloadToVerifyYourSession') }), reload],\n );\n for (const child of shellBody().children) child.setAttribute('inert', '');\n shellBody().append(lock);\n // React must remove its portals before their DOM parents disappear.\n queueMicrotask(() => {\n for (const child of [...shellBody().children]) if (child !== lock) child.remove();\n });\n finishStartup();\n reload.focus();\n },\n });\n addHostListener(\n document,\n 'keydown',\n (event) => {\n if (sessionIdentity().mode === 'locked') event.stopImmediatePropagation();\n else if (sessionIdentity().tenant && !tenantLeaseActive()) event.stopImmediatePropagation();\n else if (\n sessionIdentity().tenantRequired &&\n !sessionIdentity().tenant &&\n !(event.target instanceof Element && event.target.closest('.tenant-chooser, .account-host, [role=\"dialog\"], [role=\"menu\"]'))\n )\n event.stopImmediatePropagation();\n },\n true,\n );\n /* Captured before anything can render. The first paint calls syncHash and\n would otherwise overwrite the incoming link with the empty state — the\n deep link would be destroyed a few milliseconds before being read. */\n /* The path: the app routes by path, and a fragment is not an address. */\n /* Read in the inside form (addressMount.js): the App's id first, whatever\n the bar says of its mount and the base path. */\n let incoming = herePath();\n let incomingLocation = herePath() + hereSearch() + window.location.hash;\n let tenantIncoming;\n\n const requestedApp = connectionFromHash(incoming);\n if (me.signedIn) startSessionMonitoring();\n const signedInStart = chrome.signedInStart?.(me, landingAt) ?? null;\n if (signedInStart) {\n incoming = signedInStart;\n incomingLocation = incoming;\n navReplace(shown(incoming));\n }\n if (me.tenant === true) {\n /* The tenant chooser comes first, in the App's look (appChrome.js). */\n const chosen = (await chrome.chooseTenant?.(me, requestedApp, incomingLocation, kit)) ?? null;\n if (!chosen) return;\n ({ incoming, tenantIncoming } = chosen);\n }\n try {\n await bootstrapRequestIdentity(connectionFromHash(incoming));\n if (businessRetired) return;\n if (me.signedIn && state.activeConnection !== me.appId) {\n invalidateSession('account-changed');\n return;\n }\n } catch (err) {\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n if (err.status === 401 && err.signIn) return;\n if (err instanceof RuntimeMetadataError) throw err;\n /* A tenant's public address that names no tenant: one 404, which says\n nothing of any tenant, and a sentence that blames no database. */\n if (err.status === 404 && !me.signedIn && arrivedPlacement()) {\n // In the App's own look and under its name, as the tenant chooser is: never the database browser's.\n chrome.wearLook?.(me, me.look ?? me.signIn?.look);\n chrome.noWorkspace?.(\n typeof me.appName === 'string' ? me.appName : me.appId,\n shownUnplaced(`/${encodeURIComponent(me.appId)}/sign-in`),\n );\n return;\n }\n // Offline metadata cannot authorize the database browser's setup wizard.\n /* A server that is up and says why it is not serving the App — reloading\n it, or waiting for a restart — is not a database it could not reach. */\n showUnopened(\n [],\n err instanceof UnknownAppError ? err : undefined,\n err.status === 503 && typeof err.message === 'string' && err.message ? err.message : undefined,\n );\n return;\n }\n /* The schema, the App and its pages depend on the connection the runtime\n just named, not on each other: asked together, rather than each after the\n last answer. The App's load never throws; the pages are adopted by the\n page cache when it is first asked (page.js). */\n const appLoaded = chrome.loadNav();\n prefetchPages();\n try {\n state.schema = await api('/api/schema');\n if (businessRetired) {\n state.schema = null;\n return;\n }\n } catch (err) {\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n /* A 409 here means there is no connection to read a schema *from*, which\n is a screen rather than an error — and its message, \"No connection is\n open.\", is true, unhelpful, and the last thing a first-time reader\n should meet.\n \n Asked this way round rather than by checking the connection list first,\n which is what this did: that put a second request in front of every\n ordinary load to answer a question only the empty case ever asks. The\n failure already carries the answer. */\n if (err.status === 401 && err.signIn) return;\n if (err.status === 409) {\n /* Unconditionally, and with whatever is listed. A 409 here means no\n connection is *open* — which covers both an empty server and one\n whose only connection failed to open. The second used to fall\n through to \"Could not read the schema: No connection is open.\",\n a true sentence with nothing to click. */\n showUnopened((await offeredTools?.listConnections()) ?? []);\n return;\n }\n $('content').replaceChildren(el('p', { class: 'note', text: say('couldNotReadTheSchema', { message: err.message }) }));\n return;\n }\n const content = $('content');\n /* The ··· menu's button, before anything looks for it — the app-issues\n badge sits beside it. Its commands register below and are read when it\n opens. */\n initMenu();\n $('db-label').textContent = `${state.schema.label} · ${state.schema.dialect}`;\n await appLoaded;\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n /* The Workbench's tools are started before it paints. */\n startTools();\n /* The content pane is one component tree from here on, driven by the\n walk (components/Content.tsx): every render() is a paint of it. Mounted only\n once the schema is known, because the landing reads it — and once the App\n is, as rebuildTenantSurface mounts it. A first paint that had not yet heard\n of the App drew the Workbench's landing behind the startup veil, and so\n fetched the schema diagram's chunk for a reader who would never see it. */\n content.replaceChildren();\n /* Held before the tree mounts: from here to applying the address, every\n await is a chance for React to commit an empty walk as home (Content.tsx\n holdHome). A bare `/{app}` is held too, and drawn by the same paint. */\n holdHome(Boolean(connectionFromHash(incoming)));\n /* A paint that starts the room over keeps the screen it leaves until the\n new room is complete (navigationHold.ts). The walk's top entry says\n whether it is a step to a new place, which starts at the top. */\n const reads = {\n busy: () => queryClient.isFetching() > 0,\n watch: (changed) => queryClient.getQueryCache().subscribe(changed),\n };\n installNavigationHold(content, reads);\n /* And the first page is revealed complete the same way (startupHold.ts). */\n setStartupProbe(reads);\n /* An App's list keeps its room through a refinement now, as the Workbench's\n table does (Content.tsx), so only a room started over is held. */\n setPaintHold({\n before: (roomChanged) => beforePaint(roomChanged, currentEntry(), state.stack.length),\n after: () => afterPaint(currentEntry(), state.stack.length),\n });\n /* A press on a record begins reading its page, so the hold is short (recordCompose.ts). */\n listenForRecordPresses();\n mount(content, createElement(Content, { onHome: goHome }));\n shellBody().classList.remove('tenant-pending');\n applyBrand();\n void chrome.showAccount?.(me, kit);\n renderTableList();\n initWriteMode();\n tools?.menu('editing');\n initPalette();\n initPeek();\n /* Registered here rather than on a connection switch, which is where it\n used to be — so on an ordinary boot nothing was listening, and a page\n built in the builder did not appear in the menu or in ⌘K until the tab\n was reloaded. The one place that runs on every start is this one. */\n whenPagesChange(() => void registerPages());\n initSidebarToggle();\n // Only remount navigation on a breakpoint crossing; record editors keep their owner.\n chrome.compactNavigation?.addEventListener('change', () => {\n if (!businessRetired && sessionIdentity().mode !== 'locked') renderTableList($('table-filter').value);\n });\n // The theme bench moved the menu (themeBench.ts): the shell is drawn again around the same room.\n chrome.whenMenuMoves?.(() => {\n if (!businessRetired && sessionIdentity().mode !== 'locked') renderTableList($('table-filter').value);\n });\n /* The SQL pane and the Workbench's Undo, whose menu names the last edit at once; an App has neither. */\n tools?.menu('sql');\n /* Connections first, then the per-connection stores, then the first\n render. The stores are keyed by connection id, and loading them before\n `initConnections` has named one filed everything under a connection\n called nothing — templates got away with it because every browser that\n saved one also mirrored it locally under the right key; the pages file\n restore was the first reader with no local copy to fall back on. */\n await initConnections(async (isCurrent = () => true) => {\n /* The picker's switch is a full arrival in another database: its\n per-connection stores, its app (or none), its dress. Without this\n the previous connection's app-mode chrome and theme survived the\n switch — a database with no app wearing another app's clothes. */\n await Promise.all([loadTemplates(), tools?.loadStores(), chrome.loadNav()]);\n if (!isCurrent() || businessRetired || sessionIdentity().mode === 'locked') return;\n void chrome.loadFilters?.();\n void registerPages();\n applyBrand();\n renderTableList($('table-filter').value);\n followSaves();\n });\n if (businessRetired) return;\n await Promise.all([loadTemplates(), tools?.loadStores()]);\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n // Un-awaited on purpose: a warm cache, not a gate on first paint.\n void chrome.loadFilters?.();\n /* After the saved-pages mirror is filled, or the menu and ⌘K are built\n from an empty list and a page restored from the file is invisible until\n something else rebuilds them. */\n void registerPages();\n\n /* A link present on load wins over the default view: someone arriving from\n a pasted link should land where the link points, not on the schema.\n\n The empty state is painted only when there is no link to honour. It used\n to be painted unconditionally, first, which meant a deep link spent a\n moment showing the *active* connection's landing page — and that paint\n wrote its own address into the bar over the link that had not been read\n yet. `allowSync` keeps the bar shut until this is done either way. */\n const linked = Boolean(connectionFromHash(incoming));\n if (!linked) render();\n\n let restoring;\n /* With its search: a public list's address says its question there. */\n const restored = applyHash(tenantIncoming ?? incoming + hereSearch(), {\n findTableById: (id) => findTable(id) ?? state.schema.tables.find((t) => t.name === id),\n selectConnection: (connection, path) => {\n restoring = switchAndRestore(connection, path);\n return restoring;\n },\n });\n /* `'switching'` means applyHash handed off to an async connection switch.\n That switch owns *both* the render and opening the address gate\n (`switchAndRestore` calls `allowSync`), so the boot does neither here.\n Opening the gate now would let any render that lands mid-switch — a\n pages-change rebuild is the one that bit — write the OUTGOING connection\n into the bar for a frame, which is the cold-tab `/demo` leak. */\n if (restored !== 'switching') {\n holdHome(false);\n allowSync();\n if (restored || linked) render();\n }\n if (restoring) await restoring;\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n /* A switch another one overtook never applied this address; whatever it\n led to is where the reader is, so the hold ends with boot regardless. */\n if (restoring && homeIsHeld()) {\n holdHome(false);\n render();\n }\n\n /* Last, and after the first render: every stop measures an element that has\n to exist, and the menu item it registers should sit below the ones the\n features added rather than above them. */\n initTour();\n followSaves();\n /* A reader's language pick, where the server says the App's words: asked again in their words, where they stand. */\n onLanguagePicked(() => void reloadAppInPlace());\n\n /* The skip link lands on the pane itself, not a row in it: Tab goes on\n from the top of the room. Its fragment is not followed, because a\n fragment navigation fires `popstate` below. */\n shellQuery('.skip-link')?.addEventListener('click', (event) => {\n event.preventDefault();\n const content = $('content');\n content.tabIndex = -1;\n content.focus({ preventScroll: true });\n content.scrollIntoView?.({ block: 'start' });\n });\n\n /* `popstate`, because the address is written with pushState and a path:\n Back and Forward fire this, and a hash listener would never hear them\n again. */\n onNavigate(() => {\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n if (!allowMutationExit()) {\n navReplace(shown(toHash()));\n return;\n }\n if (sessionIdentity().tenantRequired) {\n chrome.followHistory?.(herePath() + hereSearch() + window.location.hash, {\n currentHref: toHash,\n replace: (href) => navReplace(shown(href)),\n /* The walk rides in history state (url.js); the address is the one thing on screen. */\n apply: (href) => {\n const trail = navState()?.trail;\n applyHash(typeof trail === 'string' ? trail : href, {\n findTableById: (id) => findTable(id),\n selectConnection: switchAndRestore,\n walk: typeof trail === 'string',\n });\n },\n canLeave: async () => {\n if (!allowMutationExit()) return false;\n return prepareEditingExit();\n },\n reload: () => window.location.reload(),\n invalid: () => {\n toast(say('thisTenantLinkIsInvalid'), 'error');\n },\n });\n return;\n }\n /* An App's address is the one thing on screen; the walk that reached it\n rides in history state (url.js), so Back returns to the list and its\n crumbs, not to a page that forgot where it came from. */\n const trail = navState()?.trail;\n applyHash(typeof trail === 'string' ? trail : herePath() + hereSearch(), {\n findTableById: (id) => findTable(id) ?? state.schema.tables.find((t) => t.name === id),\n selectConnection: switchAndRestore,\n walk: typeof trail === 'string',\n });\n });\n chrome.navigationReady?.(true);\n void chrome.showAccount?.(me, kit);\n\n const filterInput = $('table-filter');\n filterInput.addEventListener('input', () => renderTableList(filterInput.value));\n\n /* Filtering to one table and then having to reach for the mouse is the\n kind of small friction that makes a tool feel unfinished. Typing narrows,\n arrows choose, Enter opens — and with a single match, Enter alone is\n enough. */\n /* Bound on the whole sidebar rather than on the filter field.\n\n Arrows only worked while the field had focus, so clicking a table and\n then pressing Down scrolled the page instead of moving to the next\n table — the list looked keyboard-navigable and was not, which is worse\n than not offering it. */\n shellQuery('.sidebar').addEventListener('keydown', (e) => {\n if (!(e instanceof KeyboardEvent) || e.defaultPrevented) return;\n const list = $('table-list');\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n moveSidebar(1, list, filterInput);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n moveSidebar(-1, list, filterInput);\n } else if (e.key === 'ArrowRight' && e.target !== filterInput) {\n /* Rightwards is where the table you highlighted is. The list chooses\n what to show; the panel is where you then work, and reaching it\n should not mean going back to the mouse. */\n e.preventDefault();\n focusContent();\n } else if (e.key === 'Enter' && e.target === filterInput) {\n e.preventDefault();\n // No explicit highlight means \"the obvious one\": the only match, or\n // the first of several. Enter commits: a push, so the table you chose\n // is a place you can come back to, unlike the ones you skimmed past.\n if (openSidebarChoice()) {\n if (!shell().inApp() && window.matchMedia('(max-width: 600px)').matches) {\n const collapse = shellQuery('.sidebar-collapse');\n if (collapse instanceof HTMLButtonElement) collapse.click();\n }\n filterInput.blur();\n }\n } else if (e.key === 'Escape' && e.target === filterInput) {\n if (filterInput.value) {\n // First Escape clears the filter, a second leaves the field. Clearing\n // and blurring together loses the list you were about to pick from.\n e.preventDefault();\n e.stopPropagation();\n filterInput.value = '';\n renderTableList('');\n } else {\n filterInput.blur();\n }\n }\n });\n\n /* The schema diagram is reachable at any time, not only from the empty\n state — it is how you re-orient after walking somewhere unfamiliar. */\n\n $('search-button').addEventListener('click', () => openPalette());\n // The wordmark is the one thing every web app makes a home link, and not\n // doing it is a small surprise on every page.\n $('home-button').addEventListener('click', goHome);\n\n tools?.menu('schema');\n /* App mode is a commitment: once launched, the app is the product and\n the explorer waits behind one deliberate gesture — this menu item and\n the w key, not a standing rung of chrome. The label reads by mode. */\n /* Registers its own menu item, so it lands between Schema and Connections —\n next to the other \"what is this database\" answer rather than at the end. */\n chrome.initHelp();\n tools?.menu('undo');\n addMenuItem({\n /* System is an explicit preference; this shortcut always flips the visible mode. */\n label: () => say('darkMode'),\n category: () => say('preferences.title'),\n checked: () => effectiveTheme() === 'dark',\n detail: () => themeLabel(),\n onSelect: () => {\n toggleTheme();\n render();\n },\n });\n tools?.menu('tools');\n\n addHostListener(document, 'keydown', (e) => {\n /* The query bar's own keys (Escape, `/`, `t`) are the Workbench's (workbench.js). */\n const active = document.activeElement;\n const typing = /input|textarea/i.test(active?.tagName ?? '') || active?.getAttribute?.('contenteditable') === 'true';\n /* And not while something is open over the page.\n \n These are single-key shortcuts on the document, so they fired through\n any surface that did not stop them: Backspace with the focus on a\n dialog's button walked the trail *behind* the modal, which then closed\n onto a different record than the one it was opened from. A dialog is\n modal by definition; the page under it is not taking keys. */\n const covered = Boolean(active?.closest?.('[role=\"dialog\"], dialog[open], .pb, .help-panel, .palette, .conn-manager'));\n if (covered) return;\n\n // Backspace-as-back is a habit from file browsers, but only when the\n // caret is not in a text field.\n if (!typing && (e.key === 'Backspace' || (e.key === '[' && e.metaKey)) && state.stack.length > 1) {\n e.preventDefault();\n backTo(state.stack.length - 2);\n }\n if (e.key === 'h' && !typing && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n goHome();\n }\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-0UZ1Re1k.js","names":["say","say","_Fragment","say","_Fragment","say","QUIET_FRAMES","say","_Fragment","say","_Fragment","say","say","say","say","host","say","say","say","say","shown","__exportAll","prefetchRecord","rowLabel","navState","subscribeSessionIdentity","el","paintVersion","defineMessages","pageView","tenantLeaseActive","subscribeMessages","setPaintHold","sayBrandName","adoptCss","addHostListener","state","setTabTitle","render","primaryKey","installShell","toast","invalidateSession","renderCrumbs","sessionIdentity","portalRoot","onNavigate","removeHostListener","shellQueryAll","RuntimeMetadataError","subscribeWalk","shellQuery","tableView","configureSessionLifecycle","shellRoot","UnknownAppError","invalidateNavigation","api","workMark","connectionGeneration","arrivedPlacement","connectionChanged","shownUnplaced","viewportBox","currentEntry","go","allowMutationExit","beginConnectionTransition","onLanguagePicked","shell","humanName","findTable","$","viewportSize","backTo","workSince","herePath","emptyWord","shellBody","hereSearch","startSessionMonitoring","columnLabel","shown$1","labelPath","roomVersion","navReplace","useQueryClient","ErrorBoundary","useMessageLanguage","Icon","useQuery","queryClient","setListNavigation","mount","unmount","unmountAll","Delayed","safeHref","onDemand","sayUnavailable","prefetchPages","pagesFor","recordPageId","whenPagesChange","forgetPages","formAt","formViewKey","dashPageId","dashViewKey","dashboardAt","homeRoom","activeClauses","ask","withoutCondition","deriveFilterNames","withoutClause","resolveLabels","whileApplying","readdress","applyHash","syncHash","readAddress","toHash","allowSync","splitOf","appListFor","appListQuery","appCrumbLabel","crumbToolsRef","crumbNoteRef","useWalk","viewLink","WorkbenchLanding","canUseDatabaseTools","canManageConnections","rememberVisit","RECORD_REFRESH_FAILED","savedViewsFor","PageView","beginRecordPage","RecordGone","setAppConfigured","loadTemplates","captureRecordSurfaceOwner","forgetPage","usePageSurface","openPrefs","motionStill","TableRoom","openSidebarChoice","setSidebarFilter","RowRoom","DashboardRoom","openPalette","documentAt","AppListRoom","initPalette","Sidebar","initSidebarToggle","moveSidebar","FilterSection","NothingGranted","registerSurface","menuMode","setMenuGroup","setMenuMode","initMenu","addMenuItem","syncWriteMode","initWriteMode","prepareEditingExit","Value","presentationColumns","OverflowMenu","toggleTheme","themeLabel","effectiveTheme","finishStartup","applyDensity","applyTypography","connectionFromHash","Fragment$1","say$7","nameOf","entry","app","dashboard","form","splitSelection","top","stack","list","sameRoom","next","homeWords","name","said","trailSetting","trailOf","walked","crumbBarShown","setting","Crumbs","home","previous","trail","shown","index","onHome","i","last","first","n","previousTable","showsTable","tableWord","ownStep","content","Fragment","say$6","PageSkeleton","spoken","connection","PageRoom","resolved","useState","owner","schema","surfaceOwner","useMemo","surface","def","needsResolution","base","column","rest","pair","version","rootRow","early","planned","useEffect","page","Known","others","onLayout","saved","WithRoot","Rootless","Arriving","spec","Chooser","what","query","setQuery","draw","listEntry","key","probe","gone","plan","Revealed","label","tab","ARRIVING_SHAPE_MS","QUIET_FRAMES$1","REVEAL_CAP","box","useRef","client","useLayoutEffect","own","pane","root","covered","mark","hidden","done","quiet","stirred","frame","hide","finish","cap","drawn","cover","stop","watch","busy","say$5","SavedViewsBar","isPlain","alreadySaved","views","v","active","view","onRename","onRemove","onSave","clause","SavedViewsSection","bar","AppFooter","links","footer","href","link","BreakdownRoom","knownPages","setKnownPages","pages","notice","noticeOnContent","homeHeld","holdHome","held","homeIsHeld","Content","body","ContentBody","framed","withFooter","paint","homeDash","homeEntry","Home","loadError","room","LoadErrorNote","Room","table","appList","document","rooms","CAP","QUIET_FRAMES","REMEMBERED","ENTER_CLASS","hold","traversedAt","TRAVERSAL_WINDOW","lastInput","scrollAt","restoring","address","placeOf","sameThing","a","b","installNavigationHold","host","reads","records","record","warm","node","readLinked","input","event","release","moved","beforePaint","traversal","again","scroll","recent","enter","depth","focused","made","picture","copy","focusable","afterPaint","ending","restoreScroll","TWIN","ROOT_TWIN","built","linked","twins","url","reply","text","mirrorSheets","sourceOf","sheet","sheets","unread","media","twin","inner","chain","at","ancestor","value","child","still","element","from","to","canvas","fields","copies","field","say$4","initialRuntime","bootstrapRequestIdentity","runtime","selected","requested","error","initConnections","onSwitched","refreshConnections","listGeneration","request","generation","isCurrent","data","controls","syncConnectionControls","picker","say$3","SEEN","STOPS","tourSeen","remember","host$1","endTour","remembering","starting","startTour","card","asked","stops","s","anchorFor","createElement","Tour","initTour","opensAsPage","here","tableId","SETTLED_FOCUS","intent","target","prefetchRecordPage","pageId","listening","listenForRecordPresses","pressedAt","focusTimer","press","say$2","SETTLE_MS","FIELDS","fieldsFor","c","PeekLayer","setTarget","timer","onEnter","chip","e","onLeave","onKey","PeekCard","columns","row","suppressed","title","above","align","wanted","left","clearPeekCache","initPeek","viewTabOf","say$1","loading","composer","load","module","sync","attach","say","app_exports","boot","chrome","offeredTools","tools","startTools","kit","showUnopened","unknown","unavailable","listed","ThemeLab","goHome","showWorkspaceOpening","status","clearSurface","me","rebuildSurface","transition","appLoaded","applyBrand","renderTableList","registerPages","businessRetired","focusContent","appMode","filterInput","filterLabel","sideList","filterText","sayShellWords","skip","signIn","inApp","pagesRegistration","registration","p","reloadAppInPlace","before","after","followSaves","switchAndRestore","id","parsed","hash","t","x","err","installed","titles","reload","lock","reason","incoming","incomingLocation","tenantIncoming","requestedApp","signedInStart","landingAt","chosen","changed","setStartupProbe","roomChanged","restored","path","collapse","typing"],"sources":["../../../../../kit/src/client/copy/shell/components/Crumbs.ts","../../../../../kit/src/client/components/Crumbs.tsx","../../../../../kit/src/client/copy/record/components/PageRoom.ts","../../../../../kit/src/client/components/PageRoom.tsx","../../../../../kit/src/client/copy/lists/components/SavedViews.ts","../../../../../kit/src/client/components/SavedViews.tsx","../../../../../kit/src/client/components/AppFooter.css?inline","../../../../../kit/src/client/components/AppFooter.tsx","../../../../../kit/src/client/components/Content.tsx","../../../../../kit/src/client/navigationHold.ts","../../../../../kit/src/client/copy/shell/connectionList.ts","../../../../../kit/src/client/connectionList.js","../../../../../kit/src/client/copy/workbench/tour.ts","../../../../../kit/src/client/tour.js","../../../../../kit/src/client/recordPress.ts","../../../../../kit/src/client/copy/record/components/Peek.ts","../../../../../kit/src/client/components/Peek.tsx","../../../../../kit/src/client/peek.js","../../../../../kit/src/client/composerTab.js","../../../../../kit/src/client/copy/workbench/composerEntry.ts","../../../../../kit/src/client/composerEntry.js","../../../../../kit/src/client/copy/shell/app.ts","../../../../../kit/src/client/app.js"],"sourcesContent":["/** What Crumbs says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages(\n {\n trail: 'Trail',\n theSchemaYourWork: 'The schema, your work, the diagram (h)',\n appHome: '{app} home',\n home: 'Home',\n back: 'Back to {previous}',\n },\n {\n /* The words a visitor sees in the shell; the rest are said in English. */\n es: {\n trail: 'Ruta',\n appHome: 'Inicio de {app}',\n home: 'Inicio',\n back: 'Volver a {previous}',\n },\n },\n);\n","/**\n * The trail.\n *\n * It starts at the schema, and says so: a link opened deep — which is how\n * most links are opened — must offer a way back to the landing, and the\n * wordmark is not where anybody looks for one. A house rather than the\n * word, because the one thing in the trail that is not a step should not\n * look like one. Then one crumb per entry of the walk, the last of them\n * the current room; and at the end, the walk's own Back — up the trail,\n * not to whatever was looked at last, because a trail arrived at by\n * pasted link has crumbs and no browser history behind it.\n */\nimport { crumbNoteRef, crumbToolsRef } from './crumbSlot.js';\nimport { Fragment } from 'react';\nimport { backTo, findTable } from '../core.js';\nimport { shell } from '../shellMode.js';\nimport { humanName } from '@mistriwork/engine/shared/model.js';\nimport { appCrumbLabel, appListFor, splitOf } from './appListModel.js';\nimport { dashboardAt, formAt } from './appRooms.js';\nimport { useWalk, type WalkEntry } from './walk.js';\nimport { say } from '../copy/shell/components/Crumbs.js';\nimport { Icon } from './Icon.js';\nimport { useMessageLanguage } from './useMessageLanguage.js';\n\n/** What a crumb is called: the app's word for a list, a record's name, a page's. */\nfunction nameOf(entry: WalkEntry): string {\n if (entry.kind === 'page' && !entry.table && entry.pageId) {\n const app = shell().app();\n const dashboard = app && dashboardAt(app, entry.pageId);\n if (dashboard) return dashboard.label;\n const form = app && formAt(app, entry.pageId);\n if (form) return form.label;\n }\n if (entry.kind === 'table' || entry.kind === 'breakdown') {\n const app =\n shell().inApp() && entry.kind === 'table'\n ? appCrumbLabel({ table: entry.table ?? '', query: entry.query ?? '', view: entry.view })\n : null;\n return app ?? entry.query ?? '';\n }\n return entry.label ?? (entry.table && shell().inApp() ? humanName(entry.table) : entry.table) ?? entry.pageId ?? '…';\n}\n\n/* A split's selected record is its list's selection: the list and the row\n beside it are one room, and one crumb. Drawn as two, the trail read \"Inbox\n › Inbox\" and offered a Back to the very list on screen. */\nfunction splitSelection(stack: WalkEntry[]): boolean {\n const top = stack.at(-1);\n const list = stack.at(-2);\n if (!shell().inApp() || top?.kind !== 'row' || list?.kind !== 'table' || !list.table || list.table !== top.table) return false;\n return splitOf(appListFor(list.table, list.query, top.view ?? list.view)) !== undefined;\n}\n\n/* A room keeps its place in the address, and a place it pushes (a list\n chosen in the Pick walk) is a step Back returns from — but it is still the\n one room, so it is one crumb: the trail read \"Pick walk › Pick walk\". Of a\n run of steps in the same room, only the newest is drawn. */\nconst sameRoom = (entry: WalkEntry, next: WalkEntry | undefined): boolean =>\n Boolean(\n next && entry.kind === 'page' && next.kind === 'page' && !entry.table && !next.table && entry.pageId && entry.pageId === next.pageId,\n );\n\n/* The home crumb is the schema in the browser and the App's home in an App,\n where a reader was told \"Schema\" for the App's own front room. */\nfunction homeWords(): { title: string; 'aria-label': string } {\n const name = shell().inApp() ? (shell().app() as { name?: string } | null)?.name : undefined;\n if (shell().inApp()) {\n const said = name ? say('appHome', { app: name }) : say('home');\n return { title: said, 'aria-label': said };\n }\n return { title: say('theSchemaYourWork'), 'aria-label': say('common.schema') };\n}\n\n/* What the App asks of its trail (`ui.shell.breadcrumbs`). By default a room reached straight from the menu names\n itself in its own heading row, with no bar over it, and the trail, once there is one, starts at the first room:\n a bar that only said \"home › Leads\" over a list called Leads was chrome, and the house a second way home beside\n the menu. The Workbench keeps the whole trail; its first crumb is the schema, which nothing else offers. */\nfunction trailSetting(): { top: boolean; home: boolean } | false {\n if (!shell().inApp()) return { top: true, home: true };\n const said = shell().app()?.ui?.shell?.breadcrumbs;\n if (said === false) return false;\n if (said === true) return { top: true, home: true };\n return { top: said?.top ?? false, home: said?.home ?? false };\n}\n\n// Indices stay the walk's own: only the selected row is left off the end.\nconst trailOf = (walked: WalkEntry[]): WalkEntry[] => (splitSelection(walked) ? walked.slice(0, -1) : walked);\n\n/**\n * Whether the bar is drawn over this walk. Read from the walk itself, in the same render that draws the room, so a\n * list knows on its first paint whether its title goes in the bar or in its own heading row (crumbSlot.ts): decided\n * any later, the heading moved after the paint and every row under it jumped. A room is deeper than the menu once\n * the walk has a second step, or when it is a record however it was reached (a link straight to one).\n */\nexport function crumbBarShown(walked: WalkEntry[]): boolean {\n const setting = trailSetting();\n if (!setting) return false;\n if (setting.top) return true;\n const stack = trailOf(walked);\n const top = stack.at(-1);\n return stack.length > 1 || top?.kind === 'row' || (top?.kind === 'page' && top.key != null);\n}\n\nexport function Crumbs({ onHome }: { onHome: () => void }) {\n const walked = useWalk();\n /* Said again when a visitor's language arrives with the App. */\n useMessageLanguage();\n const stack = trailOf(walked);\n const setting = trailSetting();\n const home = Boolean(setting && setting.home);\n const previous = stack.length > 1 ? stack[stack.length - 2] : null;\n /* A public reader's record page names itself in its heading straight\n below: the trail ends at the list it came from, which stays a link. */\n const top = stack[stack.length - 1];\n const trail =\n shell().publicVisitor() && stack.length > 1 && top && (top.kind === 'row' || top.kind === 'page') && top.table\n ? stack.slice(0, -1)\n : stack;\n // Each crumb keeps its index in the walk, which is where it goes back to.\n const shown = trail.map((entry, index) => ({ entry, index })).filter(({ entry, index }) => !sameRoom(entry, trail[index + 1]));\n return (\n <nav className=\"crumbs\" aria-label={say('trail')}>\n {home && (\n <button type=\"button\" className=\"crumb-home\" {...homeWords()} onClick={onHome}>\n <svg\n viewBox=\"0 0 16 16\"\n width=\"17\"\n height=\"17\"\n aria-hidden=\"true\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M2 7.2 8 2.4l6 4.8\" />\n <path d=\"M3.4 6.6V13a.6.6 0 0 0 .6.6h8a.6.6 0 0 0 .6-.6V6.6\" />\n </svg>\n </button>\n )}\n {shown.map(({ entry, index: i }, n) => {\n const last = i === stack.length - 1;\n /* Without the house the first step stands at the start of the bar, with nothing before it to separate. */\n const first = n === 0 && !home;\n /* A row crumb names its table when the walk has changed table —\n which is exactly what following a foreign key does. A page crumb\n is a record crumb drawn as a page, on the same rule. */\n const previousTable = i > 0 ? stack[i - 1].table : null;\n const named = entry.kind === 'row' || entry.kind === 'page';\n /* A dashboard's or a form's page crumb has no table, and `undefined` is not the first crumb's `null`: without\n the table itself the trail drew an empty step before the title. */\n const showsTable = named && entry.label != null && !!entry.table && entry.table !== previousTable;\n /* In an App the table is its own step of the trail, said in the resource's label (\"Properties\"), with the\n separator every step has; the Workbench keeps the table's own name as a qualifier of the record. */\n const tableWord = entry.table\n ? shell().inApp()\n ? appCrumbLabel({ table: entry.table, query: '', view: entry.view }) ||\n humanName((findTable(entry.table) as { name?: string } | undefined)?.name ?? entry.table) ||\n entry.table\n : entry.table\n : '';\n const ownStep = showsTable && shell().inApp();\n const content = (\n <>\n {showsTable && !ownStep && (\n <span className=\"crumb-table\" title={entry.table}>\n {tableWord}\n </span>\n )}\n {nameOf(entry)}\n </>\n );\n return (\n <Fragment key={i}>\n {ownStep && (\n <>\n {!first && <span className=\"sep\">›</span>}\n <span className=\"crumb-table-step\">{tableWord}</span>\n </>\n )}\n {(!first || ownStep) && <span className=\"sep\">›</span>}\n {last ? (\n <span className=\"current\">{content}</span>\n ) : (\n <button type=\"button\" onClick={() => backTo(i)}>\n {content}\n </button>\n )}\n </Fragment>\n );\n })}\n {/* A list's title, count and star land here; its verbs, at the end. */}\n <span className=\"crumb-note\" ref={crumbNoteRef} />\n {/* The walk's Back repeats the trail's own last step; a public reader has\n the trail and the browser's Back, and one more button is chrome. */}\n {previous && !shell().publicVisitor() && (\n <button\n type=\"button\"\n className=\"crumb-back\"\n title={say('back', { previous: nameOf(previous) })}\n onClick={() => backTo(stack.length - 2)}\n >\n <Icon name=\"caret-left\" size={16} />\n <span>{say('common.back')}</span>\n </button>\n )}\n <div className=\"crumb-tools\" ref={crumbToolsRef} />\n </nav>\n );\n}\n","/** What PageRoom says, in the record page room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n pickABelow: 'Pick a {thing} below to open this page.',\n pickAnBelow: 'Pick an {thing} below to open this page.',\n});\n","/**\n * A page as a room. The page is a component (components/Page.tsx) and its pure\n * parts are components/pageModel.ts; page.js keeps the registry every module\n * asks — the config's pages, the suggested one every table has, the ones\n * this browser built. This is the walk's business in between: which\n * definition a link names, the root read off the address, the probe that\n * settles whether the record still exists, the plan the server writes for\n * the page, the crumb and the visit remembered for home.\n *\n * Four asks in a row, each a Query enabled by the one before, each keyed by\n * what it depends on and kept only while the room is up. Nothing paints\n * for an entry that is no longer the one on the walk: the key changed with\n * it, and the callbacks check the entry before touching it.\n */\nimport { useEffect, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { currentEntry, go, humanName, pageView, primaryKey, renderCrumbs, rowLabel, state, tableView } from '../core.js';\nimport { shell } from '../shellMode.js';\nimport { deriveFilterNames } from '../filterbar.js';\nimport { forgetPage, rememberVisit } from '../pagemarks.js';\nimport { readdress, syncHash } from '../url.js';\nimport type { TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport { appListFor, appListQuery, type ListSpec } from './appListModel.js';\nimport { PageView } from './Page.js';\nimport { type PageEntry } from './pageModel.js';\nimport {\n captureRecordSurfaceOwner,\n RECORD_REFRESH_FAILED,\n usePageSurface,\n type RecordSurfacePage as Def,\n type RecordSurfaceAlternative as Others,\n} from './recordSurface.js';\nimport { AppListRoom } from './Rooms.js';\nimport { FilterSection, TableRoom } from './TableRoom.js';\nimport { say } from '../copy/record/components/PageRoom.js';\nimport { RecordGone } from './RecordGone.js';\nimport { Delayed } from './Skeleton.js';\nimport { onDemand } from './onDemand.js';\nimport { workMark, workSince } from '../pendingWork.js';\nimport { shellRoot } from '../shellHost.js';\n\n/* App mode reads pages in the app's words; the workbench reads them raw. */\n/* Drawn only past the hold's cap, so it is a part of its own: no record's first page carries it. */\nconst PageSkeleton = onDemand(() => import('./PageSkeleton.js'), 'PageSkeleton', { quiet: true });\n\nconst spoken = (name: string): string => (shell().inApp() ? (humanName(name) as string) : name);\nconst connection = () => (state as { activeConnection?: string }).activeConnection ?? '';\n\nexport function PageRoom({ entry }: { entry: PageEntry }) {\n const [, resolved] = useState(0);\n const owner = connection();\n const schema = state.schema;\n // A routed lifetime still requires this exact walk entry. Explicit surfaces\n // supply their own lifetime predicate without changing the routed fence.\n const surfaceOwner = useMemo(() => captureRecordSurfaceOwner(() => currentEntry() === entry), [entry]);\n const surface = usePageSurface(surfaceOwner, entry);\n const { definition: def, page, base, needsResolution } = surface;\n useLayoutEffect(() => {\n if (!needsResolution || !base || currentEntry() !== entry || connection() !== owner || state.schema !== schema || !surface.isCurrent())\n return;\n /* A deep link names the page but not its table — the definition is the\n one source of that. Backfilled after commit, before mounting readers: the\n sidebar highlight, the crumb, and `openRecord`'s root-in-place guard. */\n entry.table = base.id;\n /* A link carries the root as text, because a single-column key is written\n as a bare value and only the base table says which column that is. */\n if (!entry.key && entry.rootBody !== undefined) {\n entry.key = entry.rootBody.includes('=')\n ? Object.fromEntries(\n entry.rootBody.split(',').map((pair) => {\n const [column, ...rest] = pair.split('=');\n return [column, rest.join('=')];\n }),\n )\n : { [(primaryKey(base) as string[])[0]]: entry.rootBody };\n }\n resolved((version) => version + 1);\n renderCrumbs();\n }, [entry, base, needsResolution, owner, schema, surface.isCurrent]);\n const rootRow = surface.rootRow;\n useEffect(() => {\n if (!rootRow || !base || currentEntry() !== entry || !surface.isCurrent()) return;\n const early = rowLabel(base, rootRow) as string | null;\n if (early && entry.label !== early) {\n entry.label = early;\n renderCrumbs();\n }\n }, [rootRow]); // eslint-disable-line react-hooks/exhaustive-deps\n const planned = surface.plan.data;\n /* `page` too: a suggested page asks its plan and root beside its definition, so both can land first, and a visit\n that waited only on them was never recorded once the definition came. */\n useEffect(() => {\n if (planned && rootRow && page && currentEntry() === entry && surface.isCurrent()) {\n rememberVisit({ pageId: page.id, name: page.name, base: page.base, key: entry.key, label: entry.label });\n }\n }, [planned, rootRow, page]); // eslint-disable-line react-hooks/exhaustive-deps\n if (!surface.isCurrent()) return null;\n return (\n <div className=\"panel-pad\">\n {surface.content && surface.refreshFailed && (\n <p role=\"alert\" className=\"note\">\n {RECORD_REFRESH_FAILED}\n </p>\n )}\n {def.isError && !page ? (\n <p className=\"note\">{(def.error as Error).message}</p>\n ) : !page ? null : page.error ? (\n <>\n <div className=\"page-head\">\n <h1 className=\"page-title\">{page.name}</h1>\n </div>\n <div className=\"page-body\">\n <p className=\"note\">{page.error}</p>\n </div>\n </>\n ) : !base ? (\n <p className=\"note\">{say('common.isNotATable', { base: page.base })}</p>\n ) : needsResolution ? null : (\n <Known entry={entry} page={page} base={base} surface={surface} />\n )}\n </div>\n );\n}\n\nfunction Known({\n entry,\n page,\n base,\n surface,\n}: {\n entry: PageEntry;\n page: Def;\n base: TableMeta;\n surface: ReturnType<typeof usePageSurface>;\n}) {\n const others = surface.others;\n /* The builder is the Workbench's (pagebuilder.js), reached through the shell: only the Workbench authors pages (PageHead's `authoring`). */\n const onLayout = () =>\n shell().editPage?.(page, {\n recordKey: entry.key,\n onSaved: (saved: { id: string; base: string }) => go(pageView(saved.id, saved.base, entry.key, entry.label), 'replace'),\n /* Deleting the page you are standing on has to go somewhere: the table it\n was about. Pinned or recently opened, it is neither now. */\n onDeleted: () => {\n forgetPage(page.id);\n go(tableView(page.base), 'replace');\n },\n });\n if (!others.data) return entry.key ? <Arriving page={page} /> : null;\n return entry.key ? (\n <WithRoot entry={entry} page={page} base={base} surface={surface} onLayout={onLayout} />\n ) : (\n <Rootless entry={entry} page={page} base={base} others={others.data} onLayout={onLayout} />\n );\n}\n\n/**\n * No record chosen: the list *is* the chooser. The app's list page in app\n * mode — tabs, named filters, chips, the lot — and the plain grid in the\n * workbench; a row click opens this record as a page, because the walk is\n * already in page view and `openRecord` keeps it there.\n */\nfunction Rootless({\n entry,\n page,\n base,\n others,\n onLayout,\n}: {\n entry: PageEntry;\n page: Def;\n base: TableMeta;\n others: Others[];\n onLayout: () => void;\n}) {\n useEffect(() => {\n if (currentEntry() === entry && entry.label !== page.name) {\n entry.label = page.name;\n renderCrumbs();\n }\n }, [entry, page.name]);\n const spec = shell().inApp() ? (appListFor(base.id) as ListSpec) : null;\n return (\n <PageView\n entry={entry}\n page={page}\n base={base}\n plans={[]}\n others={others}\n onLabel={() => {}}\n onTab={() => {}}\n onLayout={onLayout}\n chooser={<Chooser entry={entry} base={base} spec={spec} />}\n />\n );\n}\n\nfunction Chooser({ entry, base, spec }: { entry: PageEntry & { chooserQuery?: string }; base: TableMeta; spec: ListSpec | null }) {\n const what = spoken(base.name);\n /* Redrawn in place on every tab click and filter: the chooser lives\n inside the page entry, and its questions must not move the walk. The\n query rides on the entry so the pager's re-render comes back to it —\n not in the URL: the link names the page, and the chooser is a moment. */\n const [query, setQuery] = useState<string>(entry.chooserQuery ?? (spec ? appListQuery(spec) : base.id));\n const draw = (next: string) => {\n entry.chooserQuery = next;\n setQuery(next);\n };\n const listEntry = { kind: 'table' as const, table: base.id, query };\n return (\n <>\n <p className=\"note page-empty\">{say(/^[aeiou]/i.test(what) ? 'pickAnBelow' : 'pickABelow', { thing: what.toLowerCase() })}</p>\n <div className=\"page-root-list\">\n {spec ? (\n <AppListRoom entry={listEntry} spec={spec} navigate={draw} />\n ) : (\n <>\n {/* The workbench chooser gets the named boxes too, the key columns\n leading: the one lookup the old root bar guaranteed was \"by id\". */}\n <FilterSection\n entry={listEntry}\n navigate={draw}\n names={[...new Set([...(primaryKey(base) as string[]), ...(deriveFilterNames(base) as string[])])]}\n />\n <TableRoom entry={listEntry} chrome={false} interactive={false} />\n </>\n )}\n </div>\n </>\n );\n}\n\n/**\n * A record chosen. The root first, before any section: a page for a record\n * that is gone used to say so in one box while the metrics around it\n * rendered zeros. One pk-sized fetch settles existence, and brings the\n * label, so the crumb and the pill say the name before the sections\n * resolve. Then one planning call for the whole page, and a run per section.\n */\nfunction WithRoot({\n entry,\n page,\n base,\n surface,\n onLayout,\n}: {\n entry: PageEntry;\n page: Def;\n base: TableMeta;\n surface: ReturnType<typeof usePageSurface>;\n onLayout: () => void;\n}) {\n const key = entry.key as Record<string, unknown>;\n const { probe, gone, plan, content } = surface;\n if (!probe.data) return <Arriving page={page} />;\n if (gone) {\n return (\n <div className=\"page-body\">\n <RecordGone base={base} spoken={spoken(base.name)} />\n </div>\n );\n }\n if (plan.isError && !content) return <p className=\"note\">{(plan.error as Error).message}</p>;\n if (!content) return <Arriving page={page} />;\n return (\n <Revealed>\n <PageView\n {...content}\n onLayout={onLayout}\n onLabel={(label) => {\n /* Written onto the entry as well as shown, so going away and coming\n back through the trail keeps the name rather than dropping to the\n key. Guarded on the entry still being the current one. */\n if (!label || currentEntry() !== entry || !surface.isCurrent()) return;\n /* A public record's slug is its name (publicAddress.ts): written once the\n name is known, however it came to be known — a crumb may have named\n the entry before the page did. */\n if (entry.label === label) {\n readdress();\n return;\n }\n entry.label = label;\n renderCrumbs();\n readdress();\n /* Recorded again now that the record has a name. */\n rememberVisit({ pageId: page.id, name: page.name, base: page.base, key, label });\n }}\n onTab={(tab) => {\n if (currentEntry() !== entry || !surface.isCurrent()) return;\n entry.tab = tab;\n syncHash();\n }}\n />\n </Revealed>\n );\n}\n\n/**\n * The record while its page is on its way: nothing drawn, and the page's\n * height held. Under a held screen (navigationHold.ts) it is never seen;\n * past the hold's cap it keeps what stands below (the footer) where the page\n * will push it, so the page that arrives moves nothing already on screen. A\n * name or a status drawn here from the row that opened it would move as the\n * real head arrives, taller, with its verbs: that is the layout shift this\n * holds off, so it says no words. Past the cap it draws the page's anatomy in\n * placeholders (PageSkeleton) inside the held height, replaced whole: an\n * empty pane under the crumbs read as a page that had failed, not one coming.\n */\nfunction Arriving({ page }: { page: Def }) {\n return (\n <div className=\"page-arriving\" aria-busy=\"true\" style={{ minHeight: '100vh' }}>\n <Delayed ms={ARRIVING_SHAPE_MS}>\n <PageSkeleton sections={page.sections} />\n </Delayed>\n </div>\n );\n}\n\n/* Past the navigation hold's cap (navigationHold.ts, 1.5s) the pane is uncovered: only then is the page's shape worth\n drawing, and under the hold it is never seen, so it never shows on a page that arrives in time. */\nconst ARRIVING_SHAPE_MS = 1500;\n\n/* Frames with nothing asked and nothing drawn before a page is complete: the navigation hold's count. */\nconst QUIET_FRAMES = 3;\n/* The longest a page arriving uncovered is kept out of sight, as the hold's cap. */\nconst REVEAL_CAP = 1500;\n\n/**\n * The record's page as it arrives, shown once it is complete. A section\n * draws when its own read answers, and the header's verbs when their\n * availability does: under the navigation hold (navigationHold.ts) or the\n * startup veil (startupHold.ts) none of that is seen. But each lets go at\n * its cap, and a page still arriving then drew in steps — a head a line\n * taller once its verbs came, sections growing under it — moving what was\n * already on screen (0.43 on the lender's loan when its read outlasted the\n * hold). So a page that is uncovered before it is complete is kept out of\n * sight, at Arriving's height, until nothing asked since it mounted is out,\n * no read is running and nothing is drawn into it for three frames, and is\n * then shown whole. Covered and complete, it changes nothing: no style is\n * written, so the hold sees nothing stir.\n */\nexport function Revealed({ children }: { children: ReactNode }) {\n const box = useRef<HTMLDivElement>(null);\n const client = useQueryClient();\n useLayoutEffect(() => {\n const own = box.current;\n const pane = own?.closest('.content');\n if (!own) return;\n const root = shellRoot();\n const covered = () => Boolean(pane?.classList.contains('nav-holding')) || root.hasAttribute('data-starting');\n const mark = workMark();\n let hidden = false,\n done = false,\n quiet = 0,\n stirred = false,\n frame = 0;\n const hide = () => {\n if (hidden || done || covered()) return;\n hidden = true;\n own.style.visibility = 'hidden';\n own.style.minHeight = '100vh';\n };\n const finish = () => {\n if (done) return;\n done = true;\n cancelAnimationFrame(frame);\n clearTimeout(cap);\n drawn.disconnect();\n cover.disconnect();\n stop();\n if (hidden) {\n own.style.removeProperty('visibility');\n own.style.removeProperty('min-height');\n }\n };\n /* Told as a microtask, so a cover that lifts hides the page before the frame paints it. */\n const cover = new MutationObserver(hide);\n if (pane) cover.observe(pane, { attributes: true, attributeFilter: ['class'] });\n cover.observe(root, { attributes: true, attributeFilter: ['data-starting'] });\n const drawn = new MutationObserver(() => {\n stirred = true;\n });\n drawn.observe(own, { childList: true, subtree: true, characterData: true });\n const stop = client.getQueryCache().subscribe(() => {\n stirred = true;\n });\n const cap = setTimeout(finish, REVEAL_CAP);\n const watch = () => {\n const busy = stirred || workSince(mark) || client.isFetching() > 0;\n stirred = false;\n quiet = busy ? 0 : quiet + 1;\n if (quiet >= QUIET_FRAMES) {\n finish();\n return;\n }\n frame = requestAnimationFrame(watch);\n };\n hide();\n frame = requestAnimationFrame(watch);\n return finish;\n }, [client]);\n return (\n <div ref={box} className=\"page-revealed\">\n {children}\n </div>\n );\n}\n\nexport type { ReactNode };\n","/** What SavedViews says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n removeNameLabel: 'Remove {name}',\n saveThisFilter: '+ Save this filter',\n removeLabelText: 'Remove {label} {text}',\n});\n","/**\n * Saved filters, as named tabs on a table, beside what is narrowing the\n * result right now — each with a way off. The query bar can write clauses\n * but could not un-write them: having sorted by clicking a header, going\n * back to unsorted meant finding `sort contract_id` in a line of text and\n * deleting exactly it. The store and the naming live in `views.js`.\n */\nimport { savedViewsFor } from '../views.js';\nimport { go, tableView } from '../core.js';\nimport { activeClauses, withoutClause, withoutCondition } from '../clauses.js';\nimport { say } from '../copy/lists/components/SavedViews.js';\n\nexport interface SavedView {\n id: string;\n name: string;\n query: string;\n}\ninterface Entry {\n table: string;\n query: string;\n}\ninterface Clause {\n key: 'sort' | 'filter' | 'show' | 'limit';\n label: string;\n text: string;\n index?: number;\n}\n\n/** Drawn into the `div.views` tablist the crossing owns, so the bar's direct-child rules keep holding. */\nexport function SavedViewsBar({\n entry,\n views,\n onSave,\n onRename,\n onRemove,\n}: {\n entry: Entry;\n views: SavedView[];\n onSave: () => void;\n onRename: (view: SavedView) => void;\n onRemove: (view: SavedView) => void;\n}) {\n /* \"All\" is the unfiltered table, and is only meaningful once something else exists to contrast it with. */\n const isPlain = entry.query.trim() === entry.table;\n const alreadySaved = views.some((v) => v.query.trim() === entry.query.trim());\n return (\n <>\n {views.length ? (\n <button type=\"button\" className=\"view-tab\" aria-pressed={isPlain} onClick={() => go(tableView(entry.table), 'replace')}>\n {say('common.all')}\n </button>\n ) : null}\n {views.map((view) => {\n const active = view.query.trim() === entry.query.trim();\n return (\n <span key={view.id} className={`view-tab-wrap${active ? ' active' : ''}`}>\n <button\n type=\"button\"\n className=\"view-tab\"\n aria-pressed={active}\n title={view.query}\n onClick={() => go(tableView(entry.table, view.query), 'replace')}\n onDoubleClick={() => onRename(view)}\n >\n {view.name}\n </button>\n <button\n type=\"button\"\n className=\"view-remove\"\n title={say('common.removeName', { name: view.name })}\n aria-label={say('removeNameLabel', { name: view.name })}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(view);\n }}\n >\n ×\n </button>\n </span>\n );\n })}\n {/* Saving is offered only when there is a filter worth saving. */}\n {!isPlain && !alreadySaved ? (\n <button type=\"button\" className=\"view-save\" onClick={onSave}>\n {say('saveThisFilter')}\n </button>\n ) : null}\n {(activeClauses(entry.query) as Clause[]).map((clause, i) => (\n <span key={`${clause.key}${clause.index ?? ''}${i}`} className={`clause clause-${clause.key}`}>\n <span className=\"clause-label\">{clause.label}</span>\n <span className=\"clause-text\" title={clause.text}>\n {clause.text}\n </span>\n {/* A filter chip removes its own condition; everything else removes the whole clause. */}\n <button\n type=\"button\"\n className=\"clause-remove\"\n title={say('removeLabelText', { label: clause.label, text: clause.text })}\n aria-label={say('removeLabelText', { label: clause.label, text: clause.text })}\n onClick={() =>\n go(\n tableView(\n entry.table,\n clause.index === undefined ? withoutClause(entry.query, clause.key) : withoutCondition(entry.query, clause.index),\n ),\n 'replace',\n )\n }\n >\n ×\n </button>\n </span>\n ))}\n </>\n );\n}\n\n/**\n * The strip over the explorer's table view: the tablist the stylesheet\n * addresses, or nothing at all. The store and the naming are views.js's.\n */\nexport function SavedViewsSection({ entry }: { entry: Entry }) {\n const bar = savedViewsFor(entry) as {\n views: SavedView[];\n onSave: () => void;\n onRename: (v: SavedView) => void;\n onRemove: (v: SavedView) => void;\n } | null;\n if (!bar) return null;\n return (\n /* A group of switches, not a tablist: beside the saved filters it holds\n their removals, \"Save this filter\" and the query's own chips, none of\n which is a tab, and a tablist may hold only tabs. */\n <div className=\"views\" role=\"group\" aria-label={say('common.savedFilters')}>\n <SavedViewsBar entry={entry} views={bar.views} onSave={bar.onSave} onRename={bar.onRename} onRemove={bar.onRemove} />\n </div>\n );\n}\n","/* A component's own rules, brought with it: after the base, before any look (style.css names the order). */\n@layer components {\n/* Under the room, not beside it: the footer takes the content's width and is\n separated by a rule rather than a band of its own colour, so it reads as\n the end of the page instead of a second surface. Quiet by construction —\n dimmed text at 13px, the same step the landing's footer uses. */\n.app-footer {\n display: grid; gap: var(--space-3h);\n margin-top: var(--space-7); padding: 20px var(--space-4h) 28px;\n border-top: 1px solid var(--line);\n color: var(--ink-muted); font-size: var(--text-base);\n}\n.app-footer-text { margin: 0; max-width: 70ch; line-height: 1.6; }\n.app-footer-links { display: flex; flex-wrap: wrap; gap: var(--space-3) 20px; margin: 0; padding: 0; list-style: none; }\n.app-footer-links a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }\n.app-footer-links a:hover { color: var(--ink); }\n}\n","/**\n * The App's footer: a line of small print and a row of links, drawn under\n * every room of an App that declares `ui.footer`.\n *\n * A landing already had a footer of its own, which is where this shape comes\n * from (`appLanding.parseFooter`). What was missing is the one people read: a\n * public-facing App's listing and record pages ended in nothing, while the\n * sites they are modelled on carry their terms, privacy and contact links on\n * every page. The database browser has no footer and gets none — this belongs\n * to an App, the way a look does.\n *\n * Every string the author wrote is drawn as React text, so markup in it is\n * shown and never run, and a link's href was held to https:, mailto: and tel:\n * when the App loaded.\n */\nimport type { LandingLink } from '@mistriwork/engine/shared/servedApp.js';\nimport { safeHref } from './LandingSurface.js';\nimport './AppFooter.css';\n\nexport function AppFooter({ footer }: { footer: { text?: string; links?: LandingLink[] } }) {\n const links = footer.links ?? [];\n if (!footer.text && !links.length) return null;\n return (\n <footer className=\"app-footer\">\n {footer.text && <p className=\"app-footer-text\">{footer.text}</p>}\n {links.length ? (\n <ul className=\"app-footer-links\">\n {links.map((link, index) => {\n const href = safeHref(link.href);\n return (\n <li key={index}>\n {href ? (\n <a href={href} rel=\"noreferrer noopener\">\n {link.label}\n </a>\n ) : (\n <span>{link.label}</span>\n )}\n </li>\n );\n })}\n </ul>\n ) : null}\n </footer>\n );\n}\n","/**\n * The content pane: what is on screen, decided by the walk.\n *\n * Mounted once on `#content` and subscribed to the walk. Nothing on the\n * stack is a landing — the app's screen or its home card, the workbench's\n * shape of the database; otherwise the trail, then the room the top entry\n * names. Each kind is named explicitly: a dispatch whose last branch is\n * \"or else a row\" turns every kind it has not heard of into a record view\n * asking for a key nobody supplied.\n *\n * Three ticks drive it. Every `render()` is a paint: the address bar is\n * written. The room is keyed by the room tick (core.js `roomVersion`), which\n * moves on nearly every paint, so the room's state and its fetches start\n * over the way a repaint always did — except for a refinement of the table\n * room on screen (a page, a page size, a header's sort or filter), which\n * keeps the room and lets its Query re-ask in place — in an App's list as in\n * the Workbench's table. A crumb correction\n * (`renderCrumbs`) ticks the walk alone: the trail re-reads its labels and\n * the room is left be, because re-fetching the row that just resolved its\n * own label would loop.\n */\nimport { Fragment, useLayoutEffect } from 'react';\nimport { currentEntry, paintVersion, renderCrumbs, roomVersion } from '../core.js';\nimport { shell } from '../shellMode.js';\nimport { syncHash } from '../url.js';\nimport { appListFor, type ListSpec } from './appListModel.js';\nimport { ASSISTANT_PAGE, INBOX_PAGE, dashPageId, dashViewKey, formViewKey, homeRoom } from './appRooms.js';\nimport { onDemand } from './onDemand.js';\nimport type { BreakdownEntry } from './Breakdown.js';\nimport { crumbBarShown, Crumbs } from './Crumbs.js';\nimport type { DashboardDef } from './dashboardModel.js';\nimport { LoadErrorNote, NothingGranted, WorkbenchLanding } from './Landing.js';\nimport type { PageEntry } from './pageModel.js';\nimport { PageRoom } from './PageRoom.js';\nimport type { RowEntry } from './Record.js';\nimport { AppListRoom, DashboardRoom, RowRoom } from './Rooms.js';\nimport { SavedViewsSection } from './SavedViews.js';\nimport { TableRoom } from './TableRoom.js';\nimport type { TableEntry } from './TableView.js';\nimport { useWalk } from './walk.js';\nimport type { KnownPage } from './WorkPanel.js';\nimport { AppFooter } from './AppFooter.js';\nimport { documentAt } from '../documents.js';\nimport { ErrorBoundary } from './ErrorBoundary.js';\n\n/* A breakdown is the query language at work, loaded when one is first asked. */\nconst BreakdownRoom = onDemand(() => import('./BreakdownRoom.js'), 'BreakdownRoom');\n/* An App's own rooms — its home, a form, the inbox, the assistant, a record's document — are the App\n framework's, drawn through the shell's rooms slot (shellMode.ts `rooms`); this pane names none of them. */\n\n/* The pages this connection has, as the last read left them. Synchronous,\n because the landing is drawn before anything is fetched — the shell fills\n this once the pages are known, and a first visit has none to show. */\nlet knownPages: KnownPage[] = [];\nexport function setKnownPages(pages: KnownPage[]): void {\n knownPages = pages;\n}\n\n/* A sentence above the landing — the link that could not be followed, and\n the way forward — shown until the next paint takes it away. */\nlet notice: { text: string; paint: number } | null = null;\nexport function noticeOnContent(text: string): void {\n notice = { text, paint: paintVersion() };\n renderCrumbs();\n}\n\n/* Set by boot while an address it has not applied yet names somewhere: the\n walk is still empty then, and an empty walk is home. Drawn in that gap,\n the home dashboard mounted and fired every tile's query — fourteen\n requests on a warm-tab deep link to a list — for a room nobody asked\n for, replaced a moment later. Released the moment the address is\n applied (app.js boot, switchAndRestore), and the paint that follows\n draws the room the address names. */\nlet homeHeld = false;\nexport function holdHome(held: boolean): void {\n homeHeld = held;\n}\nexport function homeIsHeld(): boolean {\n return homeHeld;\n}\n\nexport function Content({ onHome }: { onHome: () => void }) {\n useWalk();\n const frame = shell().inApp() ? shell().app()?.ui.shell : undefined;\n const body = <ContentBody onHome={onHome} />;\n /* The frame draws the content's width, gutter and title. Placement, the\n menu, search and breadcrumbs are drawn elsewhere and need no frame. */\n const framed = frame !== undefined && (frame.width !== undefined || frame.gutter !== undefined || frame.heading === false);\n /* The App's footer belongs to every room, so it is drawn here rather than\n by each room — and inside the frame, so it takes the content's width\n rather than the window's. A landing standing alone draws its own (LandingSurface); one drawn as this\n pane's home is told not to (PublicHome), so there is one footer either way. */\n const footer = shell().inApp() ? shell().app()?.ui.footer : undefined;\n const withFooter = footer ? (\n <>\n {body}\n <AppFooter footer={footer} />\n </>\n ) : (\n body\n );\n return framed ? (\n <div\n className={`app-content-frame${frame?.heading === false ? ' app-content-no-title' : ''}`}\n data-width={frame?.width}\n data-gutter={frame?.gutter}\n >\n {withFooter}\n </div>\n ) : (\n withFooter\n );\n}\n\nfunction ContentBody({ onHome }: { onHome: () => void }) {\n const walked = useWalk();\n const paint = paintVersion();\n const entry = currentEntry() as ((TableEntry | BreakdownEntry | PageEntry | RowEntry) & { kind: string }) | undefined;\n /* Every paint is a state change worth linking to, so the address bar is\n written here rather than at each of the dozen places that call go(). */\n useLayoutEffect(() => {\n syncHash();\n }, [paint]);\n const said = notice && notice.paint === paint ? <p className=\"note\">{notice.text}</p> : null;\n\n const app = shell().inApp() ? shell().app() : null;\n /* Where this visitor starts is the server's answer (the payload's `home`),\n followed and never worked out here: one of the App's rooms, or — when\n it names none — a public view (AppHome.tsx). */\n const home = app ? homeRoom(app) : undefined;\n const homeDash = home && 'sections' in home ? (home as DashboardDef) : undefined;\n const homeEntry =\n entry?.kind === 'page' && (entry as PageEntry).tab === 'home' && homeDash && (entry as PageEntry).pageId === dashPageId(homeDash.id)\n ? (entry as PageEntry)\n : undefined;\n if (!entry && homeHeld) return null;\n if (!entry || homeEntry) {\n /* In an app, home is the app: where its work starts and what is waiting,\n not the anatomy of the database it happens to run on. The schema\n summary and diagram still exist — they are the workbench's landing,\n one \"All tables\" flip away. */\n if (shell().inApp()) {\n const Home = shell().rooms.Home;\n return Home ? <Home paint={paint} said={said} entry={homeEntry} pages={knownPages} /> : null;\n }\n // An App is served, and this account's roles read none of it.\n if (shell().app())\n return (\n <>\n {said}\n <NothingGranted />\n </>\n );\n return (\n <>\n {said}\n <WorkbenchLanding pages={knownPages} />\n </>\n );\n }\n\n const loadError = shell().inApp() ? shell().loadError() : '';\n /* Spelled apart, so a room in one mode is never taken for the same room\n in the other when the mode changes under the same key. An App's list\n keeps its room through a refinement too (a header's sort, a page): it\n was keyed by the paint, so a sort threw the whole grid away and built\n it again inside the click, the slowest interaction measured on a list\n (test/built-client-vitals.mjs). */\n const room = shell().inApp() ? `app:${roomVersion()}` : `room:${roomVersion()}`;\n return (\n <>\n {/* Decided here, from the walk, in the render that draws the room: a list painted without the bar has its\n heading row from the first frame (crumbSlot.ts), and one painted with it never draws that row at all. */}\n {crumbBarShown(walked) && (\n <div className=\"crumbs-host\">\n <Crumbs onHome={onHome} />\n </div>\n )}\n <LoadErrorNote error={loadError} />\n {said}\n {/* A room that throws says so under the trail, which still leads out of it. */}\n <Fragment key={room}>\n <ErrorBoundary scope=\"room\">\n <Room entry={entry} />\n </ErrorBoundary>\n </Fragment>\n </>\n );\n}\n\nfunction Room({ entry }: { entry: (TableEntry | BreakdownEntry | PageEntry | RowEntry) & { kind: string } }) {\n if (entry.kind === 'table') {\n const table = entry as TableEntry;\n /* In app mode every table renders as an app list page — one of the\n App's views when it has one, a synthesized one (humanized name,\n derived filters) when a drill from a page lands outside them. Same\n entry, same URL; which room you are in decides the dress. */\n const appList = shell().inApp() ? (appListFor(table.table, table.query) as ListSpec | null) : null;\n if (appList) return <AppListRoom entry={table} spec={appList} />;\n /* Saved filters sit above the view tabs and below the trail: they are a\n property of the table you are on, not of the walk that got you here. */\n return (\n <>\n <SavedViewsSection entry={table} />\n <TableRoom entry={table} />\n </>\n );\n }\n if (entry.kind === 'breakdown') return <BreakdownRoom entry={entry as BreakdownEntry} />;\n /* A record's document is said where its tab would be (`/orders/12/invoice`): the record's room yields to the sheet. */\n const document = entry.kind === 'page' || entry.kind === 'row' ? documentAt(entry as PageEntry | RowEntry) : undefined;\n const rooms = shell().rooms;\n if (document) return rooms.Document ? <rooms.Document entry={entry as PageEntry | RowEntry} document={document} /> : null;\n if (entry.kind === 'page') {\n const page = entry as PageEntry;\n /* A dashboard rides the page token with a reserved id space: saved pages\n say `saved:`, config pages `config-`, suggestions `suggested:` —\n `dash-` and `form-` are the app's own screens, and branching here\n costs the URL machinery nothing. */\n if (shell().inApp() && dashViewKey(page.pageId) !== undefined) return <DashboardRoom entry={page} />;\n if (shell().inApp() && formViewKey(page.pageId) !== undefined) return rooms.Form ? <rooms.Form entry={page} /> : null;\n if (shell().inApp() && page.pageId === INBOX_PAGE) return rooms.Inbox ? <rooms.Inbox /> : null;\n if (shell().inApp() && page.pageId === ASSISTANT_PAGE) return rooms.Assistant ? <rooms.Assistant conversation={page.tab} /> : null;\n return <PageRoom entry={page} />;\n }\n return <RowRoom entry={entry as RowEntry} />;\n}\n","/**\n * A navigation swaps finished screens (docs/design.md, motion rule 9).\n *\n * Every paint that starts a room over used to take the room it left off the\n * screen at once and draw the new one as its answers came in: an empty pane\n * for a frame, then a skeleton, then the header, the sections, the aside and\n * the related lists one by one, each pushing the next down. Measured on\n * Compass and on the Keystone lender App, list → record painted in four to\n * eight steps over 100–450 ms, with a layout shift at each.\n *\n * So the screen being left is held — a still copy of it, standing where it\n * stood — while the room that replaces it is drawn underneath, laid out but\n * not shown, and asks for what it needs. When nothing asked since the\n * navigation began is still out (pendingWork.ts, and the room's reads), the\n * copy goes and the new room is there, complete. Most rooms are complete\n * well inside BUDGET ms, and the reader sees one screen replace another.\n * Past it the copy is dimmed, still, so the wait is said without anything\n * moving; and a room still not complete at CAP ms is shown as it stands, its\n * own placeholders saying the rest is coming — a server that slow should not\n * keep the reader looking at a screen they left.\n *\n * The copy is a picture and nothing else: drawn in a closed shadow root,\n * under the page's own stylesheets and a twin of every element the pane\n * stands in, so it looks exactly as the screen did — and no lookup by id,\n * no selector, no test's locator and no assistive technology finds a second\n * record title, a second radio group or a second field in it. The room\n * beneath is the only one there is: laid out and focusable, only not yet\n * painted. Any input — a press, a key, a wheel — ends the hold at once, so\n * nothing waits on it (motion rule 7).\n *\n * A step to a new place starts at the top; Back and Forward return to where\n * the reader was on that screen; a refinement of the place on screen (a\n * sort, a tab, a write that repaints) keeps the scroll it had. A step to a\n * new place taken with the pointer may enter with 160 ms of opacity and a\n * few pixels of settle, once the screen is complete; a key, a refinement or\n * Back animates nothing, and reduced motion silences the enter in the\n * stylesheet.\n */\nimport { motionStill } from './motionStill.js';\nimport { workMark, workSince } from './pendingWork.js';\nimport { addHostListener, onNavigate, shellRoot } from './shellHost.js';\nimport { herePath, hereSearch } from './addressMount.js';\n\n/** How long a navigation holds the screen it left without saying so, in ms. */\nexport const BUDGET = 300;\n/** The longest it holds it at all, in ms. */\nexport const CAP = 1500;\n/* Quiet frames, counted from the frame after the paint: a Query that answers\n enables the next one in the render after it, and React draws that render\n in slices between frames, so a frame or two with nothing out can sit\n between two asks. Anything drawn into the room counts as not quiet. */\nconst QUIET_FRAMES = 3;\n/* Scroll positions to return to, by address; bounded, as a walk is. */\nconst REMEMBERED = 100;\nconst ENTER_CLASS = 'nav-enter';\n\ninterface Place {\n kind?: string;\n table?: string;\n pageId?: string;\n key?: unknown;\n view?: string;\n}\n\ninterface Hold {\n copy: HTMLElement;\n picture: HTMLElement;\n mark: number;\n timers: Array<ReturnType<typeof setTimeout>>;\n frame: number;\n quiet: number;\n scroll: 'top' | 'keep' | 'restore';\n enter: boolean;\n}\n\n/** What else says a room is still arriving: its reads (TanStack Query), which may wait on more than a request. */\ninterface HoldProbe {\n /** Whether a read is running now. */\n busy(): boolean;\n /** Told of every change to any read; returns the way to stop listening. */\n watch(changed: () => void): () => void;\n}\n\nlet content: HTMLElement | null = null;\nlet probe: HoldProbe = { busy: () => false, watch: () => () => {} };\nlet stirred = false;\nlet hold: Hold | null = null;\nlet shown: { entry: unknown; place: string; depth: number; address: string } | null = null;\n/* When the last Back or Forward came. A traversal the shell refuses (a\n change still pending) paints nothing, so the mark is read only by a paint\n that follows it closely, and only once. */\nlet traversedAt = -Infinity;\nconst TRAVERSAL_WINDOW = 1000;\nlet lastInput: { pointer: boolean; at: number; target?: EventTarget | null } = { pointer: false, at: 0 };\nconst scrollAt = new Map<string, number>();\nlet restoring: { top: number; until: number } | null = null;\n\nconst address = () => herePath() + hereSearch();\nconst placeOf = (entry: Place | undefined): string =>\n entry ? JSON.stringify([entry.kind, entry.table, entry.pageId, entry.view, entry.key ?? null]) : '';\n/* Whether the entry names another thing altogether, not another look at this one. */\nconst sameThing = (a: Place | undefined, b: Place | undefined) =>\n (a?.kind ?? '') === (b?.kind ?? '') && (a?.table ?? '') === (b?.table ?? '') && (a?.pageId ?? '') === (b?.pageId ?? '');\n\n/**\n * Start listening. Once, from the shell: Back and Forward are told apart from\n * a click by the `popstate` that precedes their paint, and the hold ends on\n * the reader's first input.\n */\nexport function installNavigationHold(host: HTMLElement, reads?: HoldProbe): void {\n const first = content === null;\n content = host;\n if (!first) return;\n if (reads) probe = reads;\n /* A read that answers enables the next in the render after it, with\n nothing out between the two: any change to a read starts the quiet\n count again. */\n probe.watch(() => {\n if (hold) stirred = true;\n });\n /* And a room still drawing itself is still arriving: a commit into the pane\n (not the picture, whose own drawing is in its shadow root) stirs too. */\n if (typeof MutationObserver === 'function') {\n new MutationObserver((records) => {\n if (hold && records.some((record) => record.target !== hold!.copy)) stirred = true;\n }).observe(host, { childList: true, subtree: true, characterData: true, attributes: true });\n }\n /* Registered before the shell's own listener, which paints: the mark is set when the paint comes. */\n onNavigate(() => {\n traversedAt = performance.now();\n }, true);\n /* The page's stylesheets, read for the picture before the first navigation\n needs them — when the page is idle, so starting up never waits on it. */\n const warm = () => {\n mirrorSheets();\n };\n if (typeof requestIdleCallback === 'function') requestIdleCallback(warm, { timeout: 3000 });\n else setTimeout(warm, 1000);\n /* And each one a part brings when it loads, as it arrives. The published\n client links a part's stylesheet when the part is first drawn (a record's\n sections, the related lists); read only at the next navigation, it was\n still on its way then, and that navigation went unheld — the related\n record painted into an empty pane. Under Vite every sheet is a style\n element, whose text is there at once, so only the bundle showed it. */\n if (typeof MutationObserver === 'function') {\n new MutationObserver((records) => {\n for (const record of records)\n for (const node of Array.from(record.addedNodes)) {\n if (!(node instanceof HTMLLinkElement) || !/\\bstylesheet\\b/i.test(node.rel) || !node.href) continue;\n if (node.sheet) readLinked(node.href);\n else node.addEventListener('load', () => readLinked(node.href), { once: true });\n }\n }).observe(document.head, { childList: true });\n }\n const input = (pointer: boolean) => (event: Event) => {\n lastInput = { pointer, at: performance.now(), target: event.target };\n if (hold) release();\n restoring = null;\n };\n addHostListener(window, 'pointerdown', input(true), true);\n addHostListener(window, 'keydown', input(false), true);\n const moved = () => {\n if (hold) release();\n restoring = null;\n };\n addHostListener(window, 'wheel', moved, { capture: true, passive: true });\n addHostListener(window, 'touchmove', moved, { capture: true, passive: true });\n}\n\n/**\n * Before a paint: hold the screen on show when the paint starts the room over.\n * `room` is whether the room is new; `entry` and `depth` are the walk's top\n * entry and length as the paint will draw them.\n */\nexport function beforePaint(room: boolean, entry: Place | undefined, depth: number): void {\n const pane = content;\n const traversal = performance.now() - traversedAt < TRAVERSAL_WINDOW;\n traversedAt = -Infinity;\n if (!pane || !pane.isConnected || !shown) return;\n if (!hold) scrollAt.set(shown.address, pane.scrollTop);\n if (scrollAt.size > REMEMBERED) scrollAt.delete(scrollAt.keys().next().value!);\n if (!room) return;\n const again = entry === shown.entry;\n const scroll: Hold['scroll'] = traversal ? 'restore' : again || placeOf(entry) === shown.place ? 'keep' : 'top';\n if (hold) {\n /* A room that redirects as it opens (a bare list to its first tab, a row\n to its page) is still the same navigation: the copy stays, the budget\n runs on, and a step it began is not undone by a replace it made. */\n if (hold.scroll === 'keep') hold.scroll = scroll;\n return;\n }\n if (!pane.firstElementChild) return;\n const recent = performance.now() - lastInput.at < 1000;\n const enter =\n !traversal &&\n !again &&\n lastInput.pointer &&\n recent &&\n !motionStill() &&\n (!sameThing(entry, shown.entry as Place | undefined) || depth !== shown.depth);\n /* The focus leaves the room it stands in now, while nothing on the page waits to be restyled. Taken away with the\n room, it went in the middle of the paint, and Chrome brought the whole pane's style up to date to let it go: the\n picture and the room being left, restyled only to be removed, 60 ms of a tab's click on the vitals' slowed CPU.\n The blur is the one removal sends (Chrome sends it), sent first; the room puts the focus back where it belongs.\n Only where the focus is what was just clicked: a search narrowing the list as it is typed into a rail's box,\n arriving while the pointer goes down on one of the box's suggestions, leaves the focus in the box, which the\n suggestion still needs. */\n const focused = document.activeElement;\n if (\n lastInput.pointer &&\n recent &&\n focused &&\n pane.contains(focused) &&\n lastInput.target instanceof Node &&\n focused.contains(lastInput.target)\n )\n (focused as HTMLElement).blur();\n const made = picture(pane);\n /* Nothing to draw the picture with (no constructable stylesheets): the paint is only a paint, as it was. */\n if (!made) return;\n const { copy } = made;\n pane.append(copy);\n /* Written only where there is a scroll to copy: writing it lays the whole\n picture out inside the click, before the room's own render, and a\n screen left at its top — most of them — has nothing to copy. */\n if (made.scrolled) made.picture.scrollTop = made.scrolled;\n /* A room reached from the keyboard, or a refinement of the room on screen,\n puts the focus back where the reader's hands are (a tab, a filter, the\n first row) the moment it is drawn: under the picture it is transparent,\n so it can take it. A step to a new place taken with the pointer, and Back,\n move no focus into the room, and there it is hidden outright, so nothing\n it does while arriving is a layout shift. */\n const focusable = !traversal && (scroll === 'keep' || (recent && !lastInput.pointer));\n pane.classList.add('nav-holding');\n pane.classList.toggle('nav-holding-focusable', focusable);\n pane.classList.remove(ENTER_CLASS);\n hold = {\n copy,\n picture: made.picture,\n mark: workMark(),\n quiet: 0,\n frame: 0,\n scroll,\n enter,\n timers: [\n setTimeout(() => {\n copy.classList.add('nav-held-waiting');\n pane.setAttribute('aria-busy', 'true');\n }, BUDGET),\n setTimeout(release, CAP),\n ],\n };\n}\n\n/** After the paint: the address is the new one; start watching for the room to be complete. */\nexport function afterPaint(entry: Place | undefined, depth: number): void {\n shown = { entry, place: placeOf(entry), depth, address: address() };\n if (!hold) return;\n hold.quiet = 0;\n /* The frame this paint lands in is not counted: the room's effects, which\n ask for what it needs, run after it. */\n if (!hold.frame)\n hold.frame = requestAnimationFrame(() => {\n if (hold) hold.frame = requestAnimationFrame(watch);\n });\n}\n\nfunction watch(): void {\n if (!hold) return;\n const busy = stirred || workSince(hold.mark) || probe.busy();\n stirred = false;\n hold.quiet = busy ? 0 : hold.quiet + 1;\n if (hold.quiet >= QUIET_FRAMES) {\n release();\n return;\n }\n hold.frame = requestAnimationFrame(watch);\n}\n\n/** The room underneath is shown, and the copy of the one it replaced goes. */\nfunction release(): void {\n const ending = hold;\n if (!ending) return;\n hold = null;\n ending.timers.forEach(clearTimeout);\n if (ending.frame) cancelAnimationFrame(ending.frame);\n const pane = content;\n ending.copy.remove();\n if (!pane) return;\n pane.classList.remove('nav-holding', 'nav-holding-focusable');\n pane.removeAttribute('aria-busy');\n if (ending.scroll === 'top') pane.scrollTop = 0;\n else if (ending.scroll === 'restore') restoreScroll(pane, scrollAt.get(address()) ?? 0);\n if (ending.enter) {\n pane.classList.add(ENTER_CLASS);\n /* Off again once it has run, so nothing is left transformed under a popup. */\n setTimeout(() => pane.classList.remove(ENTER_CLASS), 400);\n }\n}\n\n/**\n * Back to where the reader was. A room past its budget may still be growing\n * toward that point, so the position is asked again each frame for a moment,\n * until it can be reached or the reader moves.\n */\nfunction restoreScroll(pane: HTMLElement, top: number): void {\n pane.scrollTop = top;\n if (pane.scrollTop >= top - 1) {\n restoring = null;\n return;\n }\n restoring = { top, until: performance.now() + 1500 };\n const again = () => {\n if (!restoring || performance.now() > restoring.until) {\n restoring = null;\n return;\n }\n pane.scrollTop = restoring.top;\n if (pane.scrollTop >= restoring.top - 1) {\n restoring = null;\n return;\n }\n requestAnimationFrame(again);\n };\n requestAnimationFrame(again);\n}\n\n/* ---------- the picture ---------- */\n\n/* The page's stylesheets, one constructed twin of each, for the picture's\n shadow root to adopt. Read from each sheet's source — a style element's\n text, a linked file's — because the CSS object model does not give it\n back whole: Chrome serializes `font: 500 12px/1.5 var(--sans)` followed by\n a `font-variant-numeric` as nothing at all, and the picture's list count\n came out in the wrong weight and size. `:root` is read as the root's twin,\n by a class of the same weight (as `html` it weighed less than a\n pseudo-class and lost rules it had won on the page). A sheet switched off\n is left out and a sheet under media keeps it. Another origin's sheet is\n left out: it can only hold font faces, and those are the document's. The\n twins of the pane's ancestors draw no box — they are there for the\n selectors (`body.app-mode .content`, a look's `[data-visual-theme]`) and\n for what inherits — and the root's zoom is not applied twice. */\nconst TWIN = 'nav-held-twin';\nconst ROOT_TWIN = 'nav-held-root';\nconst built = new WeakMap<CSSStyleSheet, { text: string; media: string; sheet: CSSStyleSheet }>();\n/* A linked sheet's text: undefined while it is read, null for one that cannot be (another origin's). */\nconst linked = new Map<string, string | null | undefined>();\nlet twins: CSSStyleSheet | null = null;\n\nfunction readLinked(href: string): void {\n if (linked.has(href)) return;\n let url: URL;\n try {\n url = new URL(href, document.baseURI);\n } catch {\n linked.set(href, null);\n return;\n }\n if (url.origin !== window.location.origin) {\n linked.set(href, null);\n return;\n }\n linked.set(href, undefined);\n /* The file the page already loaded, asked for as the page asked for it (a\n server that answers a script to a plain fetch of a stylesheet — Vite's,\n under development — answers the stylesheet): the cache answers. */\n void fetch(url, { credentials: 'same-origin', headers: { accept: 'text/css,*/*;q=0.1' } })\n .then(\n (reply) => (reply.ok ? reply.text() : null),\n () => null,\n )\n .then((text) => {\n linked.set(href, text);\n /* And its twin built now, while nothing waits: left to the next navigation, the App's own sheet (390 KB),\n still on its way when the page was first idle, was built in the click that opened a record or a tab, 35 ms\n of it on the vitals' slowed CPU (test/built-client-vitals.mjs). */\n mirrorSheets();\n });\n}\n\n/** A sheet's own text, null to leave it out, or undefined while it is still being read. */\nfunction sourceOf(sheet: CSSStyleSheet): string | null | undefined {\n const owner = sheet.ownerNode;\n if (owner instanceof HTMLStyleElement) return owner.textContent ?? '';\n if (!sheet.href) return null;\n if (!linked.has(sheet.href)) readLinked(sheet.href);\n return linked.get(sheet.href);\n}\n\nfunction mirrorSheets(): CSSStyleSheet[] | null {\n try {\n const sheets: CSSStyleSheet[] = [];\n let unread = false;\n for (const sheet of Array.from(document.styleSheets)) {\n if (sheet.disabled) continue;\n const text = sourceOf(sheet);\n if (text === undefined) {\n unread = true;\n continue;\n }\n if (text === null) continue;\n const media = sheet.media?.mediaText ?? '';\n let twin = built.get(sheet);\n if (!twin || twin.text !== text || twin.media !== media) {\n const made = new CSSStyleSheet({ baseURL: sheet.href ?? document.baseURI, ...(media ? { media } : {}) });\n made.replaceSync(text.replace(/:root\\b/g, `.${ROOT_TWIN}`));\n twin = { text, media, sheet: made };\n built.set(sheet, twin);\n }\n sheets.push(twin.sheet);\n }\n /* A sheet not read yet would draw a picture that differs from the screen: this navigation goes unheld. */\n if (unread) return null;\n if (!twins) {\n twins = new CSSStyleSheet();\n twins.replaceSync(`.${TWIN}{display:contents!important;zoom:1!important}`);\n }\n return [...sheets, ...(document.adoptedStyleSheets ?? []), twins];\n } catch {\n return null;\n }\n}\n\n/**\n * The picture of the pane as it stands: a host in the pane's scroll content,\n * over exactly the part the reader sees, holding in a closed shadow root a\n * twin of every ancestor, the pane's own twin scrolled to where the pane is,\n * and a still copy of what the pane holds.\n */\nfunction picture(pane: HTMLElement): { copy: HTMLElement; picture: HTMLElement; scrolled: number } | null {\n const sheets = mirrorSheets();\n if (!sheets || typeof pane.attachShadow !== 'function') return null;\n const copy = document.createElement('div');\n copy.className = 'nav-held';\n copy.setAttribute('aria-hidden', 'true');\n copy.inert = true;\n /* Scroll offsets and a pane's client height are layout pixels, the ruler `top` speaks. */\n copy.style.top = `${pane.scrollTop}px`;\n copy.style.height = `${pane.clientHeight}px`;\n const root = copy.attachShadow({ mode: 'closed' });\n try {\n root.adoptedStyleSheets = sheets;\n } catch {\n return null;\n }\n let inner: ParentNode = root;\n const chain: Element[] = [];\n for (let at = pane.parentElement; at; at = at.parentElement) chain.unshift(at);\n for (const ancestor of chain) {\n const twin = document.createElement(ancestor.tagName.toLowerCase());\n for (const { name, value } of Array.from(ancestor.attributes)) twin.setAttribute(name, value);\n twin.classList.add(TWIN);\n if (ancestor === shellRoot()) twin.classList.add(ROOT_TWIN);\n inner.append(twin);\n inner = twin;\n }\n const twin = pane.cloneNode(false) as HTMLElement;\n twin.classList.remove('nav-holding', ENTER_CLASS);\n twin.removeAttribute('aria-busy');\n twin.style.height = '100%';\n twin.style.overflow = 'hidden';\n for (const child of Array.from(pane.children)) {\n if (child instanceof HTMLElement && !child.classList.contains('nav-held')) twin.append(still(child));\n }\n inner.append(twin);\n return { copy, picture: twin, scrolled: pane.scrollTop };\n}\n\n/**\n * A still copy of a part of the screen: what it looks like, and nothing it\n * does. The names of form controls go (a radio copied into the picture must\n * not join a group), and so does autofocus; a canvas is copied as its\n * picture, and a field as the value typed into it.\n */\nfunction still(node: HTMLElement): HTMLElement {\n const copy = node.cloneNode(true) as HTMLElement;\n for (const element of [copy, ...Array.from(copy.querySelectorAll<HTMLElement>('[name], [autofocus]'))]) {\n element.removeAttribute('name');\n element.removeAttribute('autofocus');\n }\n const from = node.querySelectorAll('canvas');\n if (from.length) {\n const to = copy.querySelectorAll('canvas');\n from.forEach((canvas, i) => {\n try {\n to[i]?.getContext('2d')?.drawImage(canvas, 0, 0);\n } catch {\n /* A tainted or empty canvas is left blank. */\n }\n });\n }\n /* Values typed into fields are state, not attributes: carried over so the picture matches. */\n const fields = node.querySelectorAll('input, textarea, select');\n if (fields.length) {\n const copies = copy.querySelectorAll('input, textarea, select');\n fields.forEach((field, i) => {\n const twin = copies[i] as HTMLInputElement | undefined;\n if (!twin) return;\n if (field instanceof HTMLInputElement && (field.type === 'checkbox' || field.type === 'radio')) twin.checked = field.checked;\n else twin.value = (field as HTMLInputElement).value;\n });\n }\n return copy;\n}\n\n/** Whether a navigation is holding the screen it left; for tests and the shell. */\nexport const holding = (): boolean => hold !== null;\n/** The picture being held, which only its shadow root reaches; for tests. */\nexport const heldPicture = (): HTMLElement | null => hold?.picture ?? null;\n","/** What connectionList says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n runtimeMetadataIsInvalid: 'Runtime metadata is invalid.',\n invalidRuntimeApplicationList: 'Invalid runtime application list.',\n chooseAnApplicationUrl: 'Choose an application URL to continue.',\n invalidRuntimeApplicationOrConnection: 'Invalid runtime application or connection list.',\n});\n","/**\n * Which connection or App this tab is on, from the server's runtime: the\n * first question boot asks, and the list the shell keeps current.\n *\n * Both shells start here. An App server answers with its Apps and the tab\n * takes the one its address names; the database browser answers with its\n * connections, which the Workbench's picker draws (connections.js registers\n * it with `whenConnectionControls`). An App is not a connection manager, so\n * where nothing draws the picker it and the database label stay hidden.\n */\nimport { $, api, state } from './core.js';\nimport { syncWriteMode } from './write.js';\nimport { connectionGeneration } from './connectionTransition.js';\nimport { canManageConnections, setAppConfigured } from './connectionScope.js';\nimport { RuntimeMetadataError, UnknownAppError } from './requestIdentity.js';\nimport { say } from './copy/shell/connectionList.js';\n\n/** @type {import('@mistriwork/engine/shared/connection.js').RuntimeMetadata | null} */\nlet initialRuntime = null;\n\n/** Choose the logical App before the first schema or manifest request. */\nexport async function bootstrapRequestIdentity(requested) {\n try {\n /** @type {import('@mistriwork/engine/shared/connection.js').RuntimeMetadata} */\n const runtime = await api('/api/runtime');\n if (typeof runtime?.appConfigured !== 'boolean') throw new RuntimeMetadataError(say('runtimeMetadataIsInvalid'));\n setAppConfigured(runtime.appConfigured);\n if (runtime.appConfigured) {\n if (\n !Array.isArray(runtime.apps) ||\n runtime.apps.some(\n (app) => !app || typeof app.id !== 'string' || !app.id || typeof app.name !== 'string' || typeof app.writable !== 'boolean',\n )\n ) {\n throw new RuntimeMetadataError(say('invalidRuntimeApplicationList'));\n }\n const selected = requested || runtime.active;\n if (!selected) throw new Error(say('chooseAnApplicationUrl'));\n if (!runtime.apps.some((app) => app.id === selected)) throw new UnknownAppError(selected, runtime.apps);\n state.activeConnection = selected;\n state.connections = runtime.apps;\n }\n initialRuntime = runtime;\n } catch (error) {\n initialRuntime = null;\n setAppConfigured(null);\n throw error;\n }\n}\n\nexport async function initConnections(onSwitched) {\n state.onSwitched = onSwitched;\n await refreshConnections();\n if (!state.activeConnection) throw new Error(say('common.applicationRuntimeIsUnavailable'));\n}\n\n/**\n * Redraw the picker from the server's list.\n *\n * Exported because a deep link switches connection without going through\n * `selectConnection` — it opens the connection the link names and rebuilds\n * the trail — and the picker was left showing whatever the server called\n * active. Landing on a link into one database with the sidebar naming another\n * is the interface disagreeing with itself about where you are.\n */\nlet listGeneration = 0;\nexport async function refreshConnections() {\n const request = ++listGeneration;\n const generation = connectionGeneration();\n const connection = state.activeConnection;\n const isCurrent = () => request === listGeneration && generation === connectionGeneration() && connection === state.activeConnection;\n let data;\n try {\n /** @type {import('@mistriwork/engine/shared/connection.js').RuntimeMetadata} */\n const runtime = initialRuntime ?? (await api('/api/runtime'));\n initialRuntime = null;\n if (!isCurrent()) return;\n if (runtime?.appConfigured === true) {\n data = { connections: runtime.apps, active: runtime.active, appConfigured: true };\n } else if (runtime?.appConfigured === false) {\n data = { ...(await api('/api/connections')), appConfigured: false };\n } else {\n throw new Error(say('common.runtimeMetadataIsUnavailable'));\n }\n } catch {\n if (!isCurrent()) return;\n setAppConfigured(null);\n /* One connection, no config file: the picker has nothing to offer, so it\n gets out of the way rather than showing a control with one option.\n \n `conn-select` was the `<select>` this used to be, and there has been no\n such element since it became a custom dropdown — so this line, on the\n one path that runs when the connection list cannot be read, threw a\n TypeError out of the handler meant to recover from the failure. It\n escaped `initConnections`, which boot awaits, and the page never\n finished starting: a server hiccup on one request took the whole app\n down rather than hiding a picker. */\n $('conn-picker').hidden = true;\n $('db-label').hidden = !canManageConnections();\n controls?.retire($('conn-picker'));\n return;\n }\n if (!isCurrent()) return;\n if (!Array.isArray(data.connections)) throw new Error(say('invalidRuntimeApplicationOrConnection'));\n // Internal ownership/cache keys keep their historical connection names.\n // App runtime metadata contains authored App IDs, not database connections.\n state.connections = data.connections;\n setAppConfigured(typeof data.appConfigured === 'boolean' ? data.appConfigured : null);\n // The server default is only for boot. An established tab owns its connection.\n if (!state.activeConnection) state.activeConnection = data.active;\n\n /* Write mode is remembered per connection, and until now it was only\n re-read when someone *switched* connection — never on the way in. So a\n page reload landed on the active connection with write mode off, and the\n setting quietly came back the moment you switched away and back. `initWriteMode`\n runs before this, when `state.activeConnection` is still undefined, so\n there is nothing it could have read. */\n syncWriteMode();\n\n syncConnectionControls();\n}\n\n/**\n * The Workbench's picker, which draws the connection controls once its shell\n * is loaded (connections.js). A registration rather than an import: an App\n * never loads the picker, and the list is the kit's.\n * @type {{ draw(picker: HTMLElement): void, retire(picker: HTMLElement): void } | null}\n */\nlet controls = null;\n/**\n * @param {{ draw(picker: HTMLElement): void, retire(picker: HTMLElement): void }} next\n * @public the database browser's (scripts/boundary/entries.json, \"host\")\n */\nexport function whenConnectionControls(next) {\n controls = next;\n}\n\n/** App ownership: an App is not a connection manager. */\nexport function syncConnectionControls() {\n const picker = $('conn-picker');\n if (!canManageConnections() || !controls) {\n picker.hidden = true;\n $('db-label').hidden = true;\n controls?.retire(picker);\n return;\n }\n controls.draw(picker);\n}\n","/** What tour says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n theDatabase: 'The database you are on',\n clickItToSwitch: 'Click it to switch, add another, or edit one. Everything else on the ',\n screenComesFromWhichever: 'screen comes from whichever one is named here.',\n everyTableWithItsSize: 'Every table, with its size',\n theNumberIsHow: 'The number is how many rows are in it. Views are marked. Click one to browse it.',\n askInWordsNotSql: 'Ask in words, not SQL',\n tableFirstThenConditions: 'Table first, then conditions, then sort and limit. Press ? for the full ',\n grammarOrSqlToSee: 'grammar, or SQL to see what it compiled to.',\n aRowIsAPlace: 'A row is a place, not a record',\n clickAnyRowAndYouGet: 'Click any row and you get every row elsewhere that points at it. The ',\n ordersOnACustomer: 'orders on a customer, the customer on an order. No joins to write, and ',\n aTrailBehindYouThatGoes: 'a trail behind you that goes back the way you came.',\n readOnlyUntilYouSay: 'Read only until you say otherwise',\n theWorkbenchStartsRead: 'The workbench starts read-only. Open this menu and choose Editing enabled ',\n toEditThisConnection: 'to edit this connection. Review and apply your changes; ⌘Z undoes an edit.',\n andTheRest: 'And the rest',\n kJumpsToAny: '⌘K jumps to any table, view or database. ··· has the diagram, the ',\n exportsSavedViewsAndThisTour: 'exports, saved views, and this tour again.',\n takeTheTour: 'Take the tour',\n sixThingsWorthKnowing: 'six things worth knowing',\n});\n","/**\n * A short walk around the interface, once.\n *\n * The case for it is narrow and real. Almost everything here is discoverable\n * by clicking, and four things are not: that the bar takes a language rather\n * than SQL, that clicking a row is the whole point rather than a way to see\n * its columns, that editing exists at all behind a switch that says \"Read\n * only\", and that the thing in the corner is a database picker. Each is one\n * sentence. A tour is worth six sentences and nothing more.\n *\n * What that rules out is most of what tours do. There is no progress bar, no\n * confetti, nothing that has to be dismissed twice, and no stop that says\n * \"click here to continue\" — the reader is never made to perform the\n * interface to get out of the tour, because a tour that drives is a tour\n * people learn to escape rather than read. Escape ends it, so does Skip, and\n * ending it is remembered.\n *\n * Two things it does that a simpler version would not:\n *\n * - **A stop whose anchor is not on screen is dropped**, not shown pointing\n * at nothing. The sidebar collapses, the toolbar sheds buttons at narrow\n * widths, and a card captioning an empty rectangle is worse than one\n * fewer stop.\n *\n * - **One stop has no anchor at all.** The idea that a row is a place you\n * walk from is the reason this tool exists and it is not a control, so it\n * is not attached to one. Pinning it to whichever element happened to be\n * nearby would be inventing a location for an idea.\n *\n * It is remembered in `localStorage`, so it is per browser rather than per\n * connection: it teaches the interface, and the interface does not change\n * when the database does.\n */\nimport { createElement } from 'react';\nimport { addMenuItem, menuMode } from './menu.js';\nimport { mount, unmount } from './components/mount.js';\nimport { sayUnavailable } from './components/onDemand.js';\nimport { say } from './copy/workbench/tour.js';\nimport { portalRoot } from './shellHost.js';\n\nconst SEEN = 'mistri.tour.v1';\n\n/**\n * The stops, in the order the eye takes them: where you are, what is here,\n * how to ask, what happens when you click, what it will not do, and where the\n * rest is.\n */\nconst STOPS = [\n {\n /* Two spellings of one thing, and which is on screen depends on how many\n connections there are: the picker when there is a choice to make, the\n plain label when there is not. A stop that named only one of them was\n silently dropped for everybody with a config file — which is to say for\n everybody the tour is most useful to. */\n anchor: ['#conn-picker', '#db-label'],\n title: say('theDatabase'),\n body: say('clickItToSwitch') + say('screenComesFromWhichever'),\n },\n {\n anchor: '.sidebar',\n title: say('everyTableWithItsSize'),\n body: say('theNumberIsHow'),\n },\n {\n anchor: '#querybar',\n title: say('askInWordsNotSql'),\n /* Set as code rather than run into the sentence. A query in prose is a\n string of ordinary words that happens to be a literal, and the reader\n has to be told which part to type. */\n code: 'customer active = true sort name limit 20',\n body: say('tableFirstThenConditions') + say('grammarOrSqlToSee'),\n },\n {\n /* No anchor: an idea, not a control. */\n anchor: null,\n title: say('aRowIsAPlace'),\n body: say('clickAnyRowAndYouGet') + say('ordersOnACustomer') + say('aTrailBehindYouThatGoes'),\n },\n {\n anchor: '#more-button',\n title: say('readOnlyUntilYouSay'),\n body: say('theWorkbenchStartsRead') + say('toEditThisConnection'),\n },\n {\n anchor: '#search-button',\n title: say('andTheRest'),\n body: say('kJumpsToAny') + say('exportsSavedViewsAndThisTour'),\n },\n];\n\nfunction tourSeen() {\n try {\n return window.localStorage.getItem(SEEN) === 'done';\n } catch {\n /* Private browsing, or storage turned off. Treating that as \"already\n seen\" is the right way to be wrong: a tour that cannot remember being\n dismissed would open on every single load. */\n return true;\n }\n}\n\nfunction remember() {\n try {\n window.localStorage.setItem(SEEN, 'done');\n } catch {\n /* Nothing to do, and nothing worth saying about it. */\n }\n}\n\nlet host = null;\n\nfunction endTour({ remembering = true } = {}) {\n if (remembering) remember();\n if (!host) return;\n unmount(host);\n host.remove();\n host = null;\n}\n\n/* The card is fetched the first time the tour starts: most visits are not a first one. */\nlet starting = false;\n\n/** Start it, or do nothing if there is nothing to show. The card is `components/Tour.tsx`. */\nasync function startTour({ asked = false } = {}) {\n if (host || starting || menuMode() !== 'workbench') return;\n starting = true;\n let card;\n try {\n card = await import('./components/Tour.js');\n } catch (error) {\n console.error('The tour chunk did not load.', error);\n /* Offered only to someone who asked: an unasked tour that cannot come is no one's loss. */\n if (asked) sayUnavailable();\n return;\n } finally {\n starting = false;\n }\n const { Tour, anchorFor } = card;\n if (host || menuMode() !== 'workbench') return;\n const stops = STOPS.filter((s) => s.anchor === null || anchorFor(s.anchor) !== undefined);\n /* Only the anchorless stop left means the interface it describes is not on\n screen, and one card about walking rows is not a tour. */\n if (stops.filter((s) => s.anchor).length < 2) return;\n host = document.createElement('div');\n host.className = 'tour-host';\n portalRoot().append(host);\n mount(host, createElement(Tour, { stops, onEnd: () => endTour() }));\n}\n\n/**\n * Offer it, and show it the first time.\n *\n * The menu item is registered whether or not the tour has been seen: the one\n * thing worse than a tour nobody asked for is one that cannot be found again\n * by somebody who now wants it.\n */\nexport function initTour() {\n addMenuItem({\n label: say('takeTheTour'),\n scope: 'workbench',\n detail: say('sixThingsWorthKnowing'),\n onSelect: () => {\n void startTour({ asked: true });\n },\n });\n if (tourSeen()) return;\n /* After the first paint, so the stops have something to measure. Two frames\n rather than a timeout: the second one runs after the first has been\n drawn, which is exactly the condition, rather than a guess in\n milliseconds that is wrong on a slow machine. */\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n void startTour();\n }),\n );\n}\n","/**\n * A press on a row or a link that opens a record begins reading the record's\n * page (recordCompose.ts) while the button is still down, so the page's one\n * request overlaps the click and the screen held for it (navigationHold.ts)\n * is let go sooner. Only a press, Enter, or a focus that stays: a pointer\n * passing over a list asks nothing.\n */\nimport { prefetchRecord, state } from './core.js';\nimport { shell } from './shellMode.js';\nimport { appListFor } from './components/appListModel.js';\nimport { beginRecordPage } from './recordCompose.js';\nimport { addHostListener } from './shellHost.js';\n\n/* Whether a press on a record of this table opens its page: the record\n opener's own rule (appnav.js), asked without opening anything — a split\n shows its pick beside the list and a peek draws a drawer, and neither\n asks for a page. */\nfunction opensAsPage(tableId: string): boolean {\n if (!shell().inApp()) return true;\n const here = (state as { stack?: Array<{ query?: string; view?: string }> }).stack?.at(-1);\n const entry = appListFor(tableId, here?.query, here?.view) as { presentation?: { kind?: string }; open?: string } | undefined;\n return entry?.presentation?.kind !== 'split' && entry?.open !== 'drawer';\n}\n\n/* A focus that stays this long is a reader choosing a row, not passing\n through a list on the arrow keys. */\nconst SETTLED_FOCUS = 150;\n\nfunction intent(target: EventTarget | null): [string, Record<string, unknown>] | undefined {\n const element = target instanceof Element ? target.closest('[data-opens]') : null;\n const said = element?.getAttribute('data-opens');\n if (!said) return undefined;\n try {\n const [table, key] = JSON.parse(said) as [unknown, unknown];\n return typeof table === 'string' && key && typeof key === 'object' ? [table, key as Record<string, unknown>] : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Begin reading a record's page for a press that opens it as one: the walk\n * asks this (core.js `prefetchRecord`) through the shell, which names it at\n * boot (app.js).\n */\nexport function prefetchRecordPage(pageId: string, tableId: string, key: Record<string, unknown>): void {\n if (opensAsPage(tableId)) beginRecordPage((state as { activeConnection?: string }).activeConnection ?? '', pageId, key);\n}\n\nlet listening = false;\n/**\n * From the shell's start (app.js): every row and link that opens a record\n * says which (`opensRecord`, recordIntent.ts), and a press, Enter, or a\n * focus that stays begins reading its page.\n */\nexport function listenForRecordPresses(): void {\n if (listening || typeof document === 'undefined') return;\n listening = true;\n let pressedAt = -Infinity;\n let focusTimer: ReturnType<typeof setTimeout> | undefined;\n const press = (event: Event) => {\n const asked = intent(event.target);\n if (asked) prefetchRecord(...asked);\n };\n addHostListener(\n document,\n 'pointerdown',\n (event) => {\n pressedAt = performance.now();\n press(event);\n },\n true,\n );\n addHostListener(\n document,\n 'keydown',\n (event) => {\n if ((event as KeyboardEvent).key === 'Enter') press(event);\n },\n true,\n );\n addHostListener(\n document,\n 'focusin',\n (event) => {\n clearTimeout(focusTimer);\n const asked = intent(event.target);\n /* A press focuses what it pressed, and has begun its page already. */\n if (asked && performance.now() - pressedAt > 500) focusTimer = setTimeout(() => prefetchRecord(...asked), SETTLED_FOCUS);\n },\n true,\n );\n addHostListener(\n document,\n 'focusout',\n () => {\n clearTimeout(focusTimer);\n },\n true,\n );\n}\n","/** What Peek says, in the record page room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n clickToOpen: 'click to open',\n});\n","/**\n * What is on the other end of a reference, without going there.\n *\n * `sold_by 4` is a promise that an answer exists in another table. So a\n * reference answers itself on hover: a card with the referenced row's\n * identifying fields, near the chip, gone when the pointer leaves. Three\n * things make it bearable: it waits until the pointer has settled, it\n * remembers (the cache is Query's), and it gives up quietly.\n *\n * One layer for the whole page, listening on the document: a table redraws\n * its rows on every page and a virtualised one replaces them as you scroll,\n * so a listener per chip would be thousands of registrations with no one\n * place to take them off again.\n */\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { api, columnLabel, emptyWord, findTable, labelPath, state, viewportBox, viewportSize } from '../core.js';\nimport type { TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport { presentationColumns } from './columnPresentation.js';\nimport { Value } from './Value.js';\nimport { say } from '../copy/record/components/Peek.js';\nimport { addHostListener, removeHostListener } from '../shellHost.js';\n\n/** How long the pointer must rest on a chip before anything is fetched. */\nconst SETTLE_MS = 320;\n/** Fields shown before the card stops listing. */\nconst FIELDS = 6;\n\ninterface Target {\n chip: HTMLElement;\n table: TableMeta;\n column: string;\n value: string;\n}\n\n/** The key first, then the label column, then whatever else fits. */\nfunction fieldsFor(table: TableMeta): string[] {\n const key = table.columns.filter((c) => c.primaryKey).map((c) => c.name);\n const label = labelPath(table) as string | undefined;\n return [\n ...key,\n ...(label && !key.includes(label) ? [label] : []),\n ...table.columns.map((c) => c.name).filter((n) => !key.includes(n) && n !== label),\n ].slice(0, FIELDS);\n}\n\nexport function PeekLayer() {\n const [target, setTarget] = useState<Target | null>(null);\n useEffect(() => {\n let timer = 0;\n const onEnter = (e: Event) => {\n const chip = (e.target as Element).closest?.('[data-ref-table]') as HTMLElement | null;\n if (!chip) return;\n const table = findTable(chip.dataset.refTable ?? '') as TableMeta | undefined;\n const column = chip.dataset.refColumn;\n const value = chip.dataset.refValue;\n if (!table || !column || !value) return;\n clearTimeout(timer);\n timer = window.setTimeout(() => setTarget({ chip, table, column, value }), SETTLE_MS);\n };\n const onLeave = (e: Event) => {\n if ((e.target as Element).closest?.('[data-ref-table]')) {\n clearTimeout(timer);\n setTarget(null);\n }\n };\n const hide = () => {\n clearTimeout(timer);\n setTarget(null);\n };\n addHostListener(document, 'mouseover', onEnter);\n addHostListener(document, 'mouseout', onLeave);\n /* Focus opens it too, so the card is reachable without a pointer. */\n addHostListener(document, 'focusin', onEnter);\n addHostListener(document, 'focusout', onLeave);\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') hide();\n };\n addHostListener(document, 'keydown', onKey);\n // Anything that moves the page out from under the card invalidates it.\n addHostListener(window, 'scroll', hide, true);\n addHostListener(window, 'resize', hide);\n return () => {\n clearTimeout(timer);\n removeHostListener(document, 'mouseover', onEnter);\n removeHostListener(document, 'mouseout', onLeave);\n removeHostListener(document, 'focusin', onEnter);\n removeHostListener(document, 'focusout', onLeave);\n removeHostListener(document, 'keydown', onKey);\n removeHostListener(window, 'scroll', hide, true);\n removeHostListener(window, 'resize', hide);\n };\n }, []);\n return target ? <PeekCard target={target} /> : null;\n}\n\nfunction PeekCard({ target }: { target: Target }) {\n const { chip, table, column, value } = target;\n const fields = fieldsFor(table);\n const columns = presentationColumns(state.schema, table, fields);\n /* The connection is part of the key: staging's employee must not show for\n production's reference. */\n const row = useQuery<Record<string, unknown> | null>({\n queryKey: ['peek', (state as { activeConnection?: string }).activeConnection ?? '', table.id, column, value, fields],\n queryFn: async () => {\n const data = await api('/api/view/run', {\n view: {\n id: `peek:${table.id}`,\n name: table.name,\n base: table.id,\n columns: fields.map((path) => ({ path })),\n filter: { groups: [[{ path: column, op: '=', value }]] },\n limit: 1,\n },\n });\n return data.rows?.[0] ?? null;\n },\n staleTime: Infinity,\n retry: false,\n });\n const card = useRef<HTMLDivElement>(null);\n\n /* The native tooltip has to go while the card is up: taken off the anchor\n and anything inside it, and only what was there is put back. */\n useEffect(() => {\n if (!row.data) return;\n const suppressed: Array<[Element, string]> = [];\n for (const node of [chip, ...chip.querySelectorAll('[title]')]) {\n const title = node.getAttribute('title');\n if (title === null) continue;\n suppressed.push([node, title]);\n node.removeAttribute('title');\n }\n return () => {\n for (const [node, title] of suppressed) node.setAttribute('title', title);\n };\n }, [row.data, chip]);\n\n /* Against the *value*, not the cell: the cell's text alignment says which\n edge the reader is looking at. Below by default; up only when there is\n no room; nudged sideways rather than allowed off the edge. */\n useLayoutEffect(() => {\n const node = card.current;\n if (!node || !chip.isConnected) return;\n const at = viewportBox(chip);\n const box = viewportBox(node);\n const view = viewportSize();\n const margin = 8;\n let top = at.bottom + 4;\n if (top + box.height > view.height - margin) {\n const above = at.top - box.height - 4;\n top = above > margin ? above : Math.max(margin, view.height - box.height - margin);\n }\n const align = getComputedStyle(chip).textAlign;\n const wanted =\n align === 'right' || align === 'end' ? at.right - box.width : align === 'center' ? at.left + at.width / 2 - box.width / 2 : at.left;\n const left = Math.min(Math.max(margin, wanted), Math.max(margin, view.width - box.width - margin));\n node.style.top = `${Math.round(top)}px`;\n node.style.left = `${Math.round(left)}px`;\n });\n\n if (!row.data || !chip.isConnected) return null;\n const data = row.data;\n return (\n <div className=\"peek\" role=\"tooltip\" ref={card}>\n <div className=\"peek-head\">\n <span className=\"peek-table\">{table.name}</span>\n <span className=\"peek-key\">{value}</span>\n </div>\n <div className=\"peek-body\">\n {fields.map((name) => (\n <div key={name} className=\"peek-line\">\n <span className=\"peek-name\" title={name}>\n {(columnLabel(table.id, name) as string | null) ?? name}\n </span>\n {data[name] === null || data[name] === undefined ? (\n <span className=\"peek-value null\" title=\"null\">\n {emptyWord()}\n </span>\n ) : (\n <div className=\"peek-value\">\n <Value col={columns.get(name)} value={data[name]} tableId={table.id} compact />\n </div>\n )}\n </div>\n ))}\n </div>\n {/* The card is a glance; clicking the chip is the walk. */}\n <div className=\"peek-foot\">{say('clickToOpen')}</div>\n </div>\n );\n}\n","/**\n * What is on the other end of a reference, without going there.\n *\n * `sold_by 4` is not an answer. It is a promise that an answer exists in\n * another table, and collecting it costs a navigation, a look, and a click\n * back — by which time you have lost the row you were reading. That round\n * trip is the tax this tool charges on the thing it is best at, and most of\n * the time the question is small: *who is 4?*\n *\n * So a reference answers itself on hover — the card is `components/Peek.tsx`.\n * This module is the seam the vanilla client still uses: the marker that\n * makes an element peekable, the layer's one mount, and the cache reset.\n */\nimport { createElement } from 'react';\nimport { mount, queryClient } from './components/mount.js';\nimport { PeekLayer } from './components/Peek.js';\nimport { sessionIdentity, subscribeSessionIdentity } from './sessionIdentity.js';\nimport { portalRoot } from './shellHost.js';\n\nlet host = null;\n\n/**\n * Emptied when the schema changes underneath the cached rows.\n *\n * The connection key separates databases, not accounts or tenant generations.\n * Identity changes also retire the mounted layer's hover timer and target.\n */\nexport function clearPeekCache() {\n queryClient.removeQueries({ queryKey: ['peek'] });\n}\n\n/** One layer for the whole page, listening on the document. */\nexport function initPeek() {\n if (host?.isConnected) return;\n host = document.createElement('div');\n host.className = 'peek-host';\n portalRoot().append(host);\n mount(host, createElement(PeekLayer, { key: sessionIdentity().epoch }));\n}\n\nsubscribeSessionIdentity(() => {\n clearPeekCache();\n if (host?.isConnected) mount(host, createElement(PeekLayer, { key: sessionIdentity().epoch }));\n});\n\n/** Mark an element as a reference worth peeking at. */\nexport function peekable(node, references, value) {\n if (!references || value === null || value === undefined || value === '') return node;\n node.dataset.refTable = references.table;\n node.dataset.refColumn = references.column;\n node.dataset.refValue = String(value);\n return node;\n}\n","/**\n * Where a composer session lives in the URL: a tab on a table (composer.js\n * says why). Read by the entry point on every navigation and by the composer.\n */\n\n/** The view id encoded in a stack entry's tab, or null if it is not a view. */\nexport function viewTabOf(entry) {\n if (!entry || entry.kind !== 'table') return null;\n const tab = entry.tab ?? 'rows';\n if (tab === 'view') return '';\n /* Two forms, and the leading character says which. `view:<id>` names\n something saved; `view+<text>` carries the view itself, so a composer\n session that was never saved is still a link you can send someone. */\n if (tab.startsWith('view:')) return tab.slice(5);\n if (tab.startsWith('view+')) return `+${tab.slice(5)}`;\n return null;\n}\n","/** What composerEntry says, in the Workbench room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages({\n viewsMore: 'Views…',\n composeAcrossTables: 'compose across tables',\n});\n","/**\n * The view composer's entry point: its menu item, and the navigation it\n * follows. composer.js — the draft, the paths, the panel — loads the first\n * time a view is opened, from the menu or from a link whose tab is a view;\n * until then a walk update costs one look at the current entry.\n */\nimport { currentEntry, state, subscribeWalk } from './core.js';\nimport { addMenuItem } from './menu.js';\nimport { sayUnavailable } from './components/onDemand.js';\nimport { viewTabOf } from './composerTab.js';\nimport { say } from './copy/workbench/composerEntry.js';\nimport { addHostListener } from './shellHost.js';\n\n/** @type {Promise<typeof import('./composer.js')> | undefined} */\nlet loading;\n/** @type {typeof import('./composer.js') | undefined} */\nlet composer;\nconst load = () =>\n (loading ??= import('./composer.js').then(\n (module) => (composer = module),\n (error) => {\n loading = undefined;\n console.error('The composer chunk did not load.', error);\n sayUnavailable();\n throw error;\n },\n ));\n\n/* Reconcile with wherever the app now is. Nothing to load while no view is\n open: composer.js closes an overlay it has, and there is none before it. */\nfunction sync() {\n if (composer) composer.sync();\n else if (state.schema && viewTabOf(currentEntry()) !== null)\n void load().then(\n (module) => module.sync(),\n () => {},\n );\n}\n\nfunction attach() {\n /* Registered rather than inserted. The composer does not need to know what\n else is in the header, and the header does not need to know the composer\n exists — which is what let six top-level buttons become one menu without\n touching this file's reason for existing. */\n addMenuItem({\n label: say('viewsMore'),\n scope: 'workbench',\n detail: say('composeAcrossTables'),\n onSelect: () =>\n void load().then(\n (module) => module.openFromTopbar(),\n () => {},\n ),\n });\n\n addHostListener(window, 'resize', () => composer?.positionRoot());\n addHostListener(document, 'keydown', (e) => {\n if (e.key === 'Escape') composer?.escapeComposer();\n });\n\n /* Schema readiness precedes restoration of a cold link's walk. Reconcile\n after the walk changes, outside core's synchronous React paint, rather\n than guessing how long restoration will take. */\n subscribeWalk(() => setTimeout(sync, 0));\n sync();\n}\n\nif (document.readyState === 'loading') {\n addHostListener(document, 'DOMContentLoaded', attach);\n} else {\n attach();\n}\n","/** What app says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../messages.js';\n\nexport const say = defineMessages(\n {\n /* The skip link and the wordmark's title, said over the page's HTML (index.html). */\n skipToContent: 'Skip to content',\n backToTheSchema: 'Back to the schema (h)',\n brandHome: '{app} home',\n openingWorkspace: 'Opening workspace…',\n filterMenu: 'Filter menu',\n filterTables: 'Filter tables',\n appMenu: 'App menu',\n authoring: 'Authoring',\n themeLab: 'Theme lab',\n appSettings: 'App settings',\n viewMenu: 'View',\n preferences: 'Preferences…',\n appearanceAndListSettings: 'appearance and list settings',\n pages: 'Pages',\n showingInstead: '{message} Showing {label} instead.',\n sessionExpired: 'Session expired',\n signedOut: 'Signed out',\n accountChanged: 'Account changed',\n sessionUnavailable: 'Session unavailable',\n reloadToVerifyYourSession:\n 'Reload to verify your session and continue. Unsaved edits have not been submitted. If a save was in progress, check the record before trying again.',\n couldNotReadTheSchema: 'Could not read the schema: {message}',\n thisTenantLinkIsInvalid: 'This tenant link is invalid. Your current tenant has not changed.',\n darkMode: 'Dark mode',\n theCurrentDatabase: 'the current database',\n one: 'one {base}',\n },\n {\n /* The words a visitor sees in the shell; the rest are said in English. */\n es: {\n appMenu: 'Menú de la aplicación',\n viewMenu: 'Ver',\n preferences: 'Preferencias…',\n appearanceAndListSettings: 'apariencia y ajustes de las listas',\n darkMode: 'Modo oscuro',\n skipToContent: 'Saltar al contenido',\n brandHome: 'Inicio de {app}',\n appSettings: 'Ajustes de la aplicación',\n pages: 'Páginas',\n },\n },\n);\n","/**\n * The kit's shell: the walk, the content pane, the address, the menu, the\n * palette and the keys every page shares, and dispatch to a view. It names\n * neither product: a product's main (appShell.js, workbenchShell.js) calls\n * `boot` with its chrome and, for the Workbench, its tools — the kit's shell\n * API, shells.ts.\n *\n * Loaded by a main once who-am-I has said this page is an App or a database\n * to browse, rather than a public page (publicSurface.js) — so a sign-in\n * screen or a public form never downloads it. Its first paint is this chunk\n * and the entry, fetched together (the server names both in the page): the\n * App framework's chrome (appnav.js) rides in the same chunk, and the\n * Workbench's page names the Workbench's chunk beside them.\n *\n * Everything here is wiring. The views live in their own files and reach the\n * shared state through core.js.\n */\nimport { createElement } from 'react';\nimport { mount, queryClient, unmount, unmountAll } from './components/mount.js';\nimport { requireTenantSelection, sessionIdentity, tenantLeaseActive } from './sessionIdentity.js';\nimport { configureSessionLifecycle, invalidateSession, startSessionMonitoring } from './sessionLifecycle.js';\nimport { Content, holdHome, homeIsHeld, noticeOnContent, setKnownPages } from './components/Content.js';\nimport { setListNavigation } from './components/listNavigation.js';\nimport { viewLink } from './components/viewLink.js';\nimport { Sidebar, moveSidebar, openSidebarChoice } from './components/Sidebar.js';\nimport { setSidebarFilter } from './components/sidebarModel.js';\nimport {\n $,\n allowMutationExit,\n api,\n backTo,\n connectionChanged,\n currentEntry,\n el,\n findTable,\n go,\n invalidateNavigation,\n pageView,\n render,\n setPaintHold,\n state,\n toast,\n} from './core.js';\nimport { afterPaint, beforePaint, installNavigationHold } from './navigationHold.js';\nimport { setStartupProbe } from './startupHold.js';\nimport { initWriteMode, prepareEditingExit } from './write.js';\nimport { bootstrapRequestIdentity, initConnections, refreshConnections, syncConnectionControls } from './connectionList.js';\nimport { RuntimeMetadataError, UnknownAppError } from './requestIdentity.js';\nimport { beginConnectionTransition } from './connectionTransition.js';\nimport { initTour } from './tour.js';\nimport { canManageConnections, canUseDatabaseTools } from './connectionScope.js';\nimport { effectiveTheme, themeLabel, toggleTheme } from './theme.js';\nimport { finishStartup } from './startup.js';\nimport { allowSync, applyHash, connectionFromHash, readAddress, resolveLabels, syncHash, toHash, whileApplying } from './url.js';\nimport { initMenu, addMenuItem, setMenuGroup, setMenuMode } from './menu.js';\nimport { ask } from './prompt.js';\nimport { onDemand } from './components/onDemand.js';\nimport { forgetPages, pagesFor, prefetchPages, recordPageId, whenPagesChange } from './page.js';\nimport { listenForRecordPresses, prefetchRecordPage } from './recordPress.js';\nimport { installShell, shell } from './shellMode.js';\nimport { onLanguagePicked, subscribeMessages } from './messages.js';\nimport { applyDensity } from './density.js';\nimport { applyTypography } from './typography.js';\nimport { openPrefs } from './prefs.js';\nimport { loadTemplates } from './template.js';\nimport { initPeek } from './peek.js';\nimport { initPalette, initSidebarToggle, openPalette } from './palette.js';\nimport { registerSurface } from './surfaces.js';\nimport { OverflowMenu } from './components/OverflowMenu.js';\n/* Imported for its side effect: composerEntry.js attaches the composer's\n entry point, the way history.js does, and loads the composer when a view\n opens. Loading it from a stylesheet's onload worked, but a script that\n runs because a CSS file finished downloading is a dependency nobody would\n guess from reading either file. */\nimport './composerEntry.js';\nimport { say } from './copy/shell/app.js';\nimport { arrivedPlacement, herePath, hereSearch, shown, shownUnplaced } from './addressMount.js';\nimport {\n addHostListener,\n navReplace,\n navState,\n onNavigate,\n sayBrandName,\n setTabTitle,\n shellBody,\n shellQuery,\n shellQueryAll,\n} from './shellHost.js';\n/* The product this page runs, installed by its main (`boot`): its chrome,\n and the Workbench's tools where it is the Workbench. */\n/** @type {import('./shells.js').ShellChrome} */\nlet chrome = /** @type {any} */ (null);\n/** @type {import('./shells.js').ShellTools | undefined} */\nlet offeredTools;\n\n/* The tools once started, for the brand pass and the menu's places; null\n before the Workbench's first paint, and always in an App. */\n/** @type {import('./shells.js').ShellTools | null} */\nlet tools = null;\nfunction startTools() {\n if (offeredTools && !tools) {\n tools = offeredTools;\n offeredTools.start(kit);\n }\n}\n\n/**\n * What the page says when no connection opened: the Workbench's welcome, with\n * what is listed, where it manages connections; anywhere else the product's\n * own screen — no App by the name asked for, or why it is not served\n * (appUnavailable.js).\n * @param {any[]} listed\n * @param {UnknownAppError} [unknown]\n * @param {string} [unavailable]\n */\nfunction showUnopened(listed, unknown = undefined, unavailable = undefined) {\n if (unknown || !canManageConnections() || !offeredTools) chrome.unavailable(unknown, unavailable);\n else offeredTools.showWelcome(listed);\n}\n\n/* React list surfaces may be mounted outside Content (for example in a record\n dialog), so the shell supplies their one navigation capability at boot. */\nsetListNavigation(viewLink);\n\nregisterSurface('overflowMenu', OverflowMenu);\n/* The palette is drawn the first time ⌘K or Search asks for it; it arrives whole (palette.js awaits it). */\nregisterSurface(\n 'palette',\n onDemand(() => import('./components/Palette.js'), 'Palette', { quiet: true }),\n);\nregisterSurface(\n 'composer',\n onDemand(() => import('./components/Composer.js'), 'Composer'),\n);\n/* Authoring dialogs, loaded the first time one opens: most readers never do. */\nconst ThemeLab = onDemand(() => import('./components/ThemeLab.js'), 'ThemeLab', { quiet: true });\n/* ---------- dispatch ---------- */\n\n/**\n * Back to the schema, from anywhere.\n *\n * At module scope because the trail needs it as well as the wordmark — see\n * the root crumb in `breadcrumb`.\n */\nfunction goHome() {\n if (!allowMutationExit()) return;\n invalidateNavigation();\n state.stack = [];\n state.page = 0;\n $('query').value = '';\n render();\n}\n\nfunction showWorkspaceOpening() {\n const status = el('p', { class: 'workspace-opening', role: 'status' });\n $('content').replaceChildren(status);\n // Mount the live region before its words; never retain the previous tenant's content.\n requestAnimationFrame(() => {\n if (status.isConnected) status.textContent = say('openingWorkspace');\n });\n}\n\nasync function clearSurface(me) {\n chrome.retire?.(me);\n chrome.navigationReady?.(false);\n shellBody().classList.add('tenant-pending');\n $('content').hidden = true;\n beginConnectionTransition();\n invalidateNavigation();\n state.schema = null;\n state.stack = [];\n state.canWrite = false;\n state.page = 0;\n $('query').value = '';\n $('table-filter').value = '';\n unmountAll(shellQuery('.account-host'));\n forgetPages();\n setKnownPages([]);\n // mount.tsx defers root disposal so React can remove its portals itself.\n await Promise.resolve();\n shellQueryAll('.tenant-control-host').forEach((host) => host.remove());\n $('errors').replaceChildren();\n $('errors').hidden = true;\n $('explain').textContent = '';\n $('explain-pane').hidden = true;\n $('toast').replaceChildren();\n $('toast').hidden = true;\n showWorkspaceOpening();\n $('content').hidden = false;\n navReplace(shown(`/${encodeURIComponent(state.activeConnection)}`));\n await chrome.showAccount?.(me, kit);\n}\n\nasync function rebuildSurface(me) {\n const owner = sessionIdentity(),\n transition = beginConnectionTransition();\n try {\n // The new context's schema, runtime, App and pages together, as at start.\n const appLoaded = chrome.loadNav();\n prefetchPages();\n const [schema] = await Promise.all([api('/api/schema'), refreshConnections()]);\n if (sessionIdentity() !== owner) return;\n state.schema = schema;\n await Promise.all([loadTemplates(), tools?.loadStores(), appLoaded]);\n if (sessionIdentity() !== owner) return;\n unmount($('content'));\n await Promise.resolve();\n if (sessionIdentity() !== owner) return;\n $('content').replaceChildren();\n // A tenant switch goes home on purpose (goHome below), so nothing is held.\n holdHome(false);\n mount($('content'), createElement(Content, { onHome: goHome }));\n shellBody().classList.remove('tenant-pending');\n initMenu();\n applyBrand();\n renderTableList();\n initWriteMode();\n void chrome.loadFilters?.();\n void registerPages();\n connectionChanged();\n goHome();\n chrome.navigationReady?.(true);\n await chrome.showAccount?.(me, kit);\n } finally {\n transition.finish();\n }\n}\n\n/* What the shells call back into (shells.ts `KitShell`). */\nlet businessRetired = false;\n/** @type {import('./shells.js').KitShell} */\nconst kit = {\n goHome,\n showWorkspaceOpening,\n clearSurface,\n rebuildSurface,\n retired: () => businessRetired,\n retire: () => {\n businessRetired = true;\n },\n};\n\n/* Which row paint is current, for the one branch that answers asynchronously. */\nlet rowPaint = 0;\n\n/* ---------- sidebar ---------- */\n\n/**\n * Move focus into the panel beside the list.\n *\n * The first thing worth landing on rather than the first focusable thing:\n * a column header or a row, not the breadcrumb you just came through. If the\n * panel has nothing to focus, the container itself takes it, so the keyboard\n * is at least on the right side of the page.\n */\nfunction focusContent() {\n const content = $('content');\n const target = content.querySelector('tbody tr, .th-sort, .related-item, .field-group-head') ?? content;\n if (target === content) content.tabIndex = -1;\n if (target instanceof HTMLElement) target.focus({ preventScroll: true });\n target.scrollIntoView?.({ block: 'nearest' });\n}\n\nfunction renderTableList(filterText = '') {\n const list = $('table-list');\n const appMode = shell().inApp();\n const filterInput = $('table-filter');\n const filterLabel = appMode ? say('filterMenu') : say('filterTables');\n filterInput.placeholder = `${filterLabel}\\u2026`;\n filterInput.setAttribute('aria-label', filterLabel);\n list.closest('nav')?.setAttribute('aria-label', appMode ? say('appMenu') : say('common.tables2'));\n $('topnav').setAttribute('aria-label', say('appMenu'));\n /* The product decides where its menu stands (an App's appChrome.js): the\n side list, a strip under the header, or a phone's drawer. */\n const sideList = chrome.menu();\n /* The list is a component (components/Sidebar.tsx) drawn into the `ul`; the\n filter text and the keyboard's cursor are its store. Drawn again on\n every call rather than left to redraw itself, because the app, the\n mode and the schema are read at draw time and the callers here are\n the places that know they changed. */\n setSidebarFilter(filterText);\n if (!sideList) {\n unmount(list);\n return;\n }\n mount(list, createElement(Sidebar, { host: list }));\n}\n\n/**\n * The shell's own words that the page's HTML or a one-time pass wrote: the\n * skip link, the wordmark's title, a visitor's Sign in. Said again whenever\n * the language changes, since a visitor's language arrives with the App's\n * payload — after the shell has drawn — and a reader may pick another.\n */\nfunction sayShellWords() {\n const skip = shellQuery('.skip-link');\n if (skip) skip.textContent = say('skipToContent');\n const app = shell().inApp() ? shell().app() : undefined;\n $('home-button')?.setAttribute('title', app ? say('brandHome', { app: app.name }) : say('backToTheSchema'));\n const signIn = shellQuery('.account-sign-in');\n if (signIn) signIn.textContent = say('common.signIn');\n}\nsubscribeMessages(sayShellWords);\n\n/**\n * The shell answers to the app when one is running: the brand in the top bar\n * and the tab's title carry its name, and hand back to tablewalk when the\n * connection has no app.\n */\nfunction applyBrand() {\n const app = shell().app();\n const inApp = shell().inApp();\n sayBrandName(shellQuery('.brand-name'), app ? app.name : 'tablewalk', app?.shortName);\n sayShellWords();\n setTabTitle(say('common.documentTitle', { title: app ? app.name : state.schema.label }));\n chrome.brand();\n /* The class is the seam the stylesheet hides explorer chrome behind, the\n way `first-run` already does. The app's colours ride the same switch. */\n shellBody().classList.toggle('app-mode', inApp);\n shellBody().classList.toggle('app-bound', !canManageConnections());\n $('sql-toggle').hidden = !canUseDatabaseTools();\n $('search-button').classList.toggle('tn-search', inApp);\n syncConnectionControls();\n setMenuMode(inApp ? 'app' : 'workbench');\n tools?.brand();\n chrome.dress();\n setMenuGroup(\n say('authoring'),\n app ? [] : [{ label: say('themeLab'), category: say('authoring'), onSelect: () => void ask(ThemeLab, {}) }],\n );\n setMenuGroup(say('appSettings'), chrome.settings?.() ?? []);\n /* The reader's own settings — density, list sizes — live in one dialog,\n reachable from here and from ⌘K, and apply the moment they change.\n Density itself is applied on every brand pass so a fresh boot honours\n the stored choice before anyone opens anything. */\n applyDensity();\n applyTypography();\n setMenuGroup(say('viewMenu'), [\n {\n label: () => say('preferences'),\n category: () => say('preferences.title'),\n detail: () => say('appearanceAndListSettings'),\n onSelect: openPrefs,\n },\n ]);\n}\n\n/**\n * Every page this connection has, as one command each.\n *\n * Registered rather than given a nav item: a database with one page does not\n * deserve a permanent tab, and one with nine cannot fit them. `addMenuItem`\n * puts each in the overflow menu and in ⌘K from a single registration, which\n * is where someone looks for \"the customer page\" anyway.\n */\nlet pagesRegistration = 0;\nasync function registerPages() {\n const registration = ++pagesRegistration;\n const connection = state.activeConnection;\n const schema = state.schema;\n const isCurrent = () => registration === pagesRegistration && connection === state.activeConnection && schema === state.schema;\n setKnownPages([]);\n setMenuGroup(say('pages'), []);\n try {\n /* `onSelect` and `detail`, which is what the registry reads. It had been\n `run` and `hint` — names nothing on the other side of this call knows —\n so every page in ⌘K and in the overflow menu threw on click and did\n nothing visible. The one command group built from data was the one\n group nobody could use. */\n const pages = await pagesFor();\n if (!isCurrent()) return;\n setKnownPages(pages.filter((p) => !p.error));\n /* The home screen is drawn before this arrives — it is the first paint —\n so it is drawn again once the pages are known. Only there: anywhere\n else the reader is looking at something, and redrawing it under them\n to add a list they cannot see is worse than the wait. */\n if (!currentEntry()) render();\n setMenuGroup(\n say('pages'),\n pages.map((page) => ({\n scope: 'workbench',\n category: say('pages'),\n label: page.name,\n detail: page.error ? page.error : say('one', { base: page.base }),\n onSelect: () => {\n if (!isCurrent()) return;\n if (page.error) {\n toast(page.error, 'error');\n return;\n }\n go(pageView(page.id, page.base), 'reset');\n },\n })),\n 'page',\n );\n } catch {\n /* A connection whose pages cannot be read is a connection with no pages\n in the menu. It is not a reason to stop starting up. */\n }\n}\n\n/* ---------- a save, followed ---------- */\n\n/**\n * The App again after a save (appLive.ts), drawn where the reader stands.\n * The walk is kept, so the address, the open record and the trail are, and\n * the pane keeps its scroll (a paint of the same entry, navigationHold.ts).\n * The room itself is drawn again rather than kept: a record's surface is\n * fenced to the App it opened under (recordSurface.ts), because its grants\n * and actions were that App's, so its unsent edits go with it. A save that\n * changed which App this is, or left none, is a different page: that one is\n * loaded whole.\n */\nasync function reloadAppInPlace() {\n const before = shell().app();\n if (!(await chrome.reloadNav?.())) return;\n const after = shell().app();\n if (!before || !after || before.id !== after.id) {\n window.location.reload();\n return;\n }\n // The App's pages are its own; the menu is rebuilt from them (whenPagesChange).\n forgetPages();\n void queryClient.invalidateQueries();\n applyBrand();\n renderTableList($('table-filter').value);\n state.navMode = 'replace';\n render();\n}\n\n/* Only where the server says it watches the App's source (appChrome.js). */\nconst followSaves = () => chrome.followSaves?.(reloadAppInPlace);\n\n/* ---------- boot ---------- */\n\n/**\n * Switch connection, then rebuild the trail from the link.\n *\n * The order is the point: the hash is parsed only after the new schema has\n * arrived, because a trail into another database names tables this one does\n * not have and would parse to nothing.\n */\nasync function switchAndRestore(id, hash) {\n const transition = beginConnectionTransition();\n try {\n const schema = canManageConnections()\n ? (await api('/api/connections/select', { id })).schema\n : await api(`/api/schema?app=${encodeURIComponent(id)}`);\n if (!transition.isCurrent()) return;\n state.schema = schema;\n state.activeConnection = id;\n /* The picker names this tab's connection, not the server's idea of an\n active one. A link into one database with the sidebar naming another is\n the interface disagreeing with itself about where you are — and now\n that every request carries its own connection, the server's active is\n not this tab's answer to anything. */\n void refreshConnections();\n /* Layouts, saved pages, SQL and the app manifest are stored per\n connection, so the new connection's are pulled before anything is\n drawn with them — and before the menu is rebuilt, which reads the\n saved-pages mirror. In parallel: four independent round trips in a\n row was a whole extra beat of sidebar-blank per deep link. */\n await Promise.all([loadTemplates(), tools?.loadStores(), chrome.loadNav()]);\n if (!transition.isCurrent()) return;\n // Un-awaited on purpose: a warm cache, not a gate on first paint.\n void chrome.loadFilters?.();\n // A different database has different pages.\n void registerPages();\n /* Same signal the picker sends, so a deep link into another database\n rebuilds the long-lived surfaces the way a switch does. */\n connectionChanged();\n renderTableList();\n /* A list said in words (`/thread/board?tab=…`) is read against the\n App just loaded, as applyHash reads one on the connection already open. */\n const parsed = readAddress(hash, (t) => findTable(t) ?? state.schema.tables.find((x) => x.name === t));\n holdHome(false);\n whileApplying(() => {\n state.stack = parsed?.stack ?? [];\n state.page = 0;\n state.navMode = 'replace';\n render();\n });\n /* Written explicitly, after the suppressed render. Boot renders once\n before the link is applied and stamps the *previous* connection into\n the address bar; without this the URL keeps claiming a database the\n page is no longer showing, and copying it hands someone the wrong\n link. */\n /* Open the address gate here, not in boot: on a cold deep link into\n another database the boot deliberately left it shut so that no render\n between then and now could stamp the outgoing connection into the bar.\n Now the target is loaded and current, so its address is the right one\n to write. Idempotent for the picker/popstate callers, where it is\n already open. */\n allowSync();\n state.navMode = 'replace';\n syncHash();\n $('db-label').textContent = `${schema.label} · ${schema.dialect}`;\n applyBrand();\n followSaves();\n if (parsed?.stack.length) void resolveLabels(parsed.stack, (t) => findTable(t));\n } catch (err) {\n if (!transition.isCurrent()) return;\n // Finish loading whichever schema remains after a failed overlapping switch.\n await state.onSwitched?.(transition.isCurrent);\n if (!transition.isCurrent()) return;\n connectionChanged();\n /* A dead end otherwise.\n \n A bookmarked link naming a connection that has since been removed used\n to render this message and stop, on a page whose only way forward was\n editing the URL by hand — while the database the session *is* connected\n to sat there, loaded and unreachable. The fallback is made out loud\n instead: say which link failed, then show the connection we do have.\n Silently substituting it would be the other error, and the worse one. */\n const said = el('p', {\n class: 'note',\n text: say('showingInstead', { message: err.message, label: state.schema?.label ?? say('theCurrentDatabase') }),\n });\n if (!state.schema) {\n $('content').replaceChildren(said);\n return;\n }\n state.stack = [];\n state.page = 0;\n holdHome(false);\n allowSync();\n state.navMode = 'replace';\n render();\n syncHash();\n // Above the landing page rather than instead of it: the reason and the\n // way forward want to be on screen together.\n noticeOnContent(said.textContent);\n } finally {\n transition.finish();\n }\n}\n\n/**\n * The rest of boot, from who-am-I's answer, for the product whose main\n * asked it (shells.ts `ShellProduct`): that main drew whatever its product\n * shows before the shell (an App's public pages, its sign-in).\n * @param {Record<string, any>} me\n * @param {unknown} landingAt where the address landed (publicRoutes.js `landingRoute`), which the App's chrome reads\n * @param {import('./shells.js').ShellProduct} installed\n */\nexport async function boot(me, landingAt, installed) {\n chrome = installed.chrome;\n offeredTools = installed.tools;\n /* The shell's answers to the kit (shellMode.ts), named before anything\n asks: the product's (an App's words, openers and tenant, appnav.js; the\n Workbench's glance), and the walk's page resolver and read-ahead. The\n Workbench's tools name their own Undo when they start (workbench.js). */\n installShell({\n ...chrome.answers,\n resolvePage: recordPageId,\n prefetchRecord: prefetchRecordPage,\n });\n chrome.start?.(me);\n await chrome.loadTenancy?.(me);\n configureSessionLifecycle({\n onReload: () => window.location.reload(),\n ...chrome.lifecycle?.(me, kit),\n onLock: (reason) => {\n chrome.retire?.(me);\n beginConnectionTransition();\n invalidateNavigation();\n state.schema = null;\n state.stack = [];\n state.canWrite = false;\n state.activeConnection = null;\n state.connections = [];\n unmountAll();\n shellBody().classList.add('session-locked', 'signed-out');\n const titles = {\n expired: say('sessionExpired'),\n 'signed-out': say('signedOut'),\n 'account-changed': say('accountChanged'),\n 'other-tab': say('accountChanged'),\n unavailable: say('sessionUnavailable'),\n };\n const reload = el('button', { type: 'button', text: say('common.reload'), onclick: () => window.location.reload() });\n const lock = el(\n 'section',\n { id: 'session-lock', role: 'alertdialog', 'aria-modal': 'true', 'aria-labelledby': 'session-lock-title' },\n [el('h1', { id: 'session-lock-title', text: titles[reason] }), el('p', { text: say('reloadToVerifyYourSession') }), reload],\n );\n for (const child of shellBody().children) child.setAttribute('inert', '');\n shellBody().append(lock);\n // React must remove its portals before their DOM parents disappear.\n queueMicrotask(() => {\n for (const child of [...shellBody().children]) if (child !== lock) child.remove();\n });\n finishStartup();\n reload.focus();\n },\n });\n addHostListener(\n document,\n 'keydown',\n (event) => {\n if (sessionIdentity().mode === 'locked') event.stopImmediatePropagation();\n else if (sessionIdentity().tenant && !tenantLeaseActive()) event.stopImmediatePropagation();\n else if (\n sessionIdentity().tenantRequired &&\n !sessionIdentity().tenant &&\n !(event.target instanceof Element && event.target.closest('.tenant-chooser, .account-host, [role=\"dialog\"], [role=\"menu\"]'))\n )\n event.stopImmediatePropagation();\n },\n true,\n );\n /* Captured before anything can render. The first paint calls syncHash and\n would otherwise overwrite the incoming link with the empty state — the\n deep link would be destroyed a few milliseconds before being read. */\n /* The path: the app routes by path, and a fragment is not an address. */\n /* Read in the inside form (addressMount.js): the App's id first, whatever\n the bar says of its mount and the base path. */\n let incoming = herePath();\n let incomingLocation = herePath() + hereSearch() + window.location.hash;\n let tenantIncoming;\n\n const requestedApp = connectionFromHash(incoming);\n if (me.signedIn) startSessionMonitoring();\n const signedInStart = chrome.signedInStart?.(me, landingAt) ?? null;\n if (signedInStart) {\n incoming = signedInStart;\n incomingLocation = incoming;\n navReplace(shown(incoming));\n }\n if (me.tenant === true) {\n /* The tenant chooser comes first, in the App's look (appChrome.js). */\n const chosen = (await chrome.chooseTenant?.(me, requestedApp, incomingLocation, kit)) ?? null;\n if (!chosen) return;\n ({ incoming, tenantIncoming } = chosen);\n }\n try {\n await bootstrapRequestIdentity(connectionFromHash(incoming));\n if (businessRetired) return;\n if (me.signedIn && state.activeConnection !== me.appId) {\n invalidateSession('account-changed');\n return;\n }\n } catch (err) {\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n if (err.status === 401 && err.signIn) return;\n if (err instanceof RuntimeMetadataError) throw err;\n /* A tenant's public address that names no tenant: one 404, which says\n nothing of any tenant, and a sentence that blames no database. */\n if (err.status === 404 && !me.signedIn && arrivedPlacement()) {\n // In the App's own look and under its name, as the tenant chooser is: never the database browser's.\n chrome.wearLook?.(me, me.look ?? me.signIn?.look);\n chrome.noWorkspace?.(\n typeof me.appName === 'string' ? me.appName : me.appId,\n shownUnplaced(`/${encodeURIComponent(me.appId)}/sign-in`),\n );\n return;\n }\n // Offline metadata cannot authorize the database browser's setup wizard.\n /* A server that is up and says why it is not serving the App — reloading\n it, or waiting for a restart — is not a database it could not reach. */\n showUnopened(\n [],\n err instanceof UnknownAppError ? err : undefined,\n err.status === 503 && typeof err.message === 'string' && err.message ? err.message : undefined,\n );\n return;\n }\n /* The schema, the App and its pages depend on the connection the runtime\n just named, not on each other: asked together, rather than each after the\n last answer. The App's load never throws; the pages are adopted by the\n page cache when it is first asked (page.js). */\n const appLoaded = chrome.loadNav();\n prefetchPages();\n try {\n state.schema = await api('/api/schema');\n if (businessRetired) {\n state.schema = null;\n return;\n }\n } catch (err) {\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n /* A 409 here means there is no connection to read a schema *from*, which\n is a screen rather than an error — and its message, \"No connection is\n open.\", is true, unhelpful, and the last thing a first-time reader\n should meet.\n \n Asked this way round rather than by checking the connection list first,\n which is what this did: that put a second request in front of every\n ordinary load to answer a question only the empty case ever asks. The\n failure already carries the answer. */\n if (err.status === 401 && err.signIn) return;\n if (err.status === 409) {\n /* Unconditionally, and with whatever is listed. A 409 here means no\n connection is *open* — which covers both an empty server and one\n whose only connection failed to open. The second used to fall\n through to \"Could not read the schema: No connection is open.\",\n a true sentence with nothing to click. */\n showUnopened((await offeredTools?.listConnections()) ?? []);\n return;\n }\n $('content').replaceChildren(el('p', { class: 'note', text: say('couldNotReadTheSchema', { message: err.message }) }));\n return;\n }\n const content = $('content');\n /* The ··· menu's button, before anything looks for it — the app-issues\n badge sits beside it. Its commands register below and are read when it\n opens. */\n initMenu();\n $('db-label').textContent = `${state.schema.label} · ${state.schema.dialect}`;\n await appLoaded;\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n /* The Workbench's tools are started before it paints. */\n startTools();\n /* The content pane is one component tree from here on, driven by the\n walk (components/Content.tsx): every render() is a paint of it. Mounted only\n once the schema is known, because the landing reads it — and once the App\n is, as rebuildTenantSurface mounts it. A first paint that had not yet heard\n of the App drew the Workbench's landing behind the startup veil, and so\n fetched the schema diagram's chunk for a reader who would never see it. */\n content.replaceChildren();\n /* Held before the tree mounts: from here to applying the address, every\n await is a chance for React to commit an empty walk as home (Content.tsx\n holdHome). A bare `/{app}` is held too, and drawn by the same paint. */\n holdHome(Boolean(connectionFromHash(incoming)));\n /* A paint that starts the room over keeps the screen it leaves until the\n new room is complete (navigationHold.ts). The walk's top entry says\n whether it is a step to a new place, which starts at the top. */\n const reads = {\n busy: () => queryClient.isFetching() > 0,\n watch: (changed) => queryClient.getQueryCache().subscribe(changed),\n };\n installNavigationHold(content, reads);\n /* And the first page is revealed complete the same way (startupHold.ts). */\n setStartupProbe(reads);\n /* An App's list keeps its room through a refinement now, as the Workbench's\n table does (Content.tsx), so only a room started over is held. */\n setPaintHold({\n before: (roomChanged) => beforePaint(roomChanged, currentEntry(), state.stack.length),\n after: () => afterPaint(currentEntry(), state.stack.length),\n });\n /* A press on a record begins reading its page, so the hold is short (recordCompose.ts). */\n listenForRecordPresses();\n mount(content, createElement(Content, { onHome: goHome }));\n shellBody().classList.remove('tenant-pending');\n applyBrand();\n void chrome.showAccount?.(me, kit);\n renderTableList();\n initWriteMode();\n tools?.menu('editing');\n initPalette();\n initPeek();\n /* Registered here rather than on a connection switch, which is where it\n used to be — so on an ordinary boot nothing was listening, and a page\n built in the builder did not appear in the menu or in ⌘K until the tab\n was reloaded. The one place that runs on every start is this one. */\n whenPagesChange(() => void registerPages());\n initSidebarToggle();\n // Only remount navigation on a breakpoint crossing; record editors keep their owner.\n chrome.compactNavigation?.addEventListener('change', () => {\n if (!businessRetired && sessionIdentity().mode !== 'locked') renderTableList($('table-filter').value);\n });\n // The theme bench moved the menu (themeBench.ts): the shell is drawn again around the same room.\n chrome.whenMenuMoves?.(() => {\n if (!businessRetired && sessionIdentity().mode !== 'locked') renderTableList($('table-filter').value);\n });\n /* The SQL pane and the Workbench's Undo, whose menu names the last edit at once; an App has neither. */\n tools?.menu('sql');\n /* Connections first, then the per-connection stores, then the first\n render. The stores are keyed by connection id, and loading them before\n `initConnections` has named one filed everything under a connection\n called nothing — templates got away with it because every browser that\n saved one also mirrored it locally under the right key; the pages file\n restore was the first reader with no local copy to fall back on. */\n await initConnections(async (isCurrent = () => true) => {\n /* The picker's switch is a full arrival in another database: its\n per-connection stores, its app (or none), its dress. Without this\n the previous connection's app-mode chrome and theme survived the\n switch — a database with no app wearing another app's clothes. */\n await Promise.all([loadTemplates(), tools?.loadStores(), chrome.loadNav()]);\n if (!isCurrent() || businessRetired || sessionIdentity().mode === 'locked') return;\n void chrome.loadFilters?.();\n void registerPages();\n applyBrand();\n renderTableList($('table-filter').value);\n followSaves();\n });\n if (businessRetired) return;\n await Promise.all([loadTemplates(), tools?.loadStores()]);\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n // Un-awaited on purpose: a warm cache, not a gate on first paint.\n void chrome.loadFilters?.();\n /* After the saved-pages mirror is filled, or the menu and ⌘K are built\n from an empty list and a page restored from the file is invisible until\n something else rebuilds them. */\n void registerPages();\n\n /* A link present on load wins over the default view: someone arriving from\n a pasted link should land where the link points, not on the schema.\n\n The empty state is painted only when there is no link to honour. It used\n to be painted unconditionally, first, which meant a deep link spent a\n moment showing the *active* connection's landing page — and that paint\n wrote its own address into the bar over the link that had not been read\n yet. `allowSync` keeps the bar shut until this is done either way. */\n const linked = Boolean(connectionFromHash(incoming));\n if (!linked) render();\n\n let restoring;\n /* With its search: a public list's address says its question there. */\n const restored = applyHash(tenantIncoming ?? incoming + hereSearch(), {\n findTableById: (id) => findTable(id) ?? state.schema.tables.find((t) => t.name === id),\n selectConnection: (connection, path) => {\n restoring = switchAndRestore(connection, path);\n return restoring;\n },\n });\n /* `'switching'` means applyHash handed off to an async connection switch.\n That switch owns *both* the render and opening the address gate\n (`switchAndRestore` calls `allowSync`), so the boot does neither here.\n Opening the gate now would let any render that lands mid-switch — a\n pages-change rebuild is the one that bit — write the OUTGOING connection\n into the bar for a frame, which is the cold-tab `/demo` leak. */\n if (restored !== 'switching') {\n holdHome(false);\n allowSync();\n if (restored || linked) render();\n }\n if (restoring) await restoring;\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n /* A switch another one overtook never applied this address; whatever it\n led to is where the reader is, so the hold ends with boot regardless. */\n if (restoring && homeIsHeld()) {\n holdHome(false);\n render();\n }\n\n /* Last, and after the first render: every stop measures an element that has\n to exist, and the menu item it registers should sit below the ones the\n features added rather than above them. */\n initTour();\n followSaves();\n /* A reader's language pick, where the server says the App's words: asked again in their words, where they stand. */\n onLanguagePicked(() => void reloadAppInPlace());\n\n /* The skip link lands on the pane itself, not a row in it: Tab goes on\n from the top of the room. Its fragment is not followed, because a\n fragment navigation fires `popstate` below. */\n shellQuery('.skip-link')?.addEventListener('click', (event) => {\n event.preventDefault();\n const content = $('content');\n content.tabIndex = -1;\n content.focus({ preventScroll: true });\n content.scrollIntoView?.({ block: 'start' });\n });\n\n /* `popstate`, because the address is written with pushState and a path:\n Back and Forward fire this, and a hash listener would never hear them\n again. */\n onNavigate(() => {\n if (businessRetired || sessionIdentity().mode === 'locked') return;\n if (!allowMutationExit()) {\n navReplace(shown(toHash()));\n return;\n }\n if (sessionIdentity().tenantRequired) {\n chrome.followHistory?.(herePath() + hereSearch() + window.location.hash, {\n currentHref: toHash,\n replace: (href) => navReplace(shown(href)),\n /* The walk rides in history state (url.js); the address is the one thing on screen. */\n apply: (href) => {\n const trail = navState()?.trail;\n applyHash(typeof trail === 'string' ? trail : href, {\n findTableById: (id) => findTable(id),\n selectConnection: switchAndRestore,\n walk: typeof trail === 'string',\n });\n },\n canLeave: async () => {\n if (!allowMutationExit()) return false;\n return prepareEditingExit();\n },\n reload: () => window.location.reload(),\n invalid: () => {\n toast(say('thisTenantLinkIsInvalid'), 'error');\n },\n });\n return;\n }\n /* An App's address is the one thing on screen; the walk that reached it\n rides in history state (url.js), so Back returns to the list and its\n crumbs, not to a page that forgot where it came from. */\n const trail = navState()?.trail;\n applyHash(typeof trail === 'string' ? trail : herePath() + hereSearch(), {\n findTableById: (id) => findTable(id) ?? state.schema.tables.find((t) => t.name === id),\n selectConnection: switchAndRestore,\n walk: typeof trail === 'string',\n });\n });\n chrome.navigationReady?.(true);\n void chrome.showAccount?.(me, kit);\n\n const filterInput = $('table-filter');\n filterInput.addEventListener('input', () => renderTableList(filterInput.value));\n\n /* Filtering to one table and then having to reach for the mouse is the\n kind of small friction that makes a tool feel unfinished. Typing narrows,\n arrows choose, Enter opens — and with a single match, Enter alone is\n enough. */\n /* Bound on the whole sidebar rather than on the filter field.\n\n Arrows only worked while the field had focus, so clicking a table and\n then pressing Down scrolled the page instead of moving to the next\n table — the list looked keyboard-navigable and was not, which is worse\n than not offering it. */\n shellQuery('.sidebar').addEventListener('keydown', (e) => {\n if (!(e instanceof KeyboardEvent) || e.defaultPrevented) return;\n const list = $('table-list');\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n moveSidebar(1, list, filterInput);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n moveSidebar(-1, list, filterInput);\n } else if (e.key === 'ArrowRight' && e.target !== filterInput) {\n /* Rightwards is where the table you highlighted is. The list chooses\n what to show; the panel is where you then work, and reaching it\n should not mean going back to the mouse. */\n e.preventDefault();\n focusContent();\n } else if (e.key === 'Enter' && e.target === filterInput) {\n e.preventDefault();\n // No explicit highlight means \"the obvious one\": the only match, or\n // the first of several. Enter commits: a push, so the table you chose\n // is a place you can come back to, unlike the ones you skimmed past.\n if (openSidebarChoice()) {\n if (!shell().inApp() && window.matchMedia('(max-width: 600px)').matches) {\n const collapse = shellQuery('.sidebar-collapse');\n if (collapse instanceof HTMLButtonElement) collapse.click();\n }\n filterInput.blur();\n }\n } else if (e.key === 'Escape' && e.target === filterInput) {\n if (filterInput.value) {\n // First Escape clears the filter, a second leaves the field. Clearing\n // and blurring together loses the list you were about to pick from.\n e.preventDefault();\n e.stopPropagation();\n filterInput.value = '';\n renderTableList('');\n } else {\n filterInput.blur();\n }\n }\n });\n\n /* The schema diagram is reachable at any time, not only from the empty\n state — it is how you re-orient after walking somewhere unfamiliar. */\n\n $('search-button').addEventListener('click', () => openPalette());\n // The wordmark is the one thing every web app makes a home link, and not\n // doing it is a small surprise on every page.\n $('home-button').addEventListener('click', goHome);\n\n tools?.menu('schema');\n /* App mode is a commitment: once launched, the app is the product and\n the explorer waits behind one deliberate gesture — this menu item and\n the w key, not a standing rung of chrome. The label reads by mode. */\n /* Registers its own menu item, so it lands between Schema and Connections —\n next to the other \"what is this database\" answer rather than at the end. */\n chrome.initHelp();\n tools?.menu('undo');\n addMenuItem({\n /* System is an explicit preference; this shortcut always flips the visible mode. */\n label: () => say('darkMode'),\n category: () => say('preferences.title'),\n checked: () => effectiveTheme() === 'dark',\n detail: () => themeLabel(),\n onSelect: () => {\n toggleTheme();\n render();\n },\n });\n tools?.menu('tools');\n\n addHostListener(document, 'keydown', (e) => {\n /* The query bar's own keys (Escape, `/`, `t`) are the Workbench's (workbench.js). */\n const active = document.activeElement;\n const typing = /input|textarea/i.test(active?.tagName ?? '') || active?.getAttribute?.('contenteditable') === 'true';\n /* And not while something is open over the page.\n \n These are single-key shortcuts on the document, so they fired through\n any surface that did not stop them: Backspace with the focus on a\n dialog's button walked the trail *behind* the modal, which then closed\n onto a different record than the one it was opened from. A dialog is\n modal by definition; the page under it is not taking keys. */\n const covered = Boolean(active?.closest?.('[role=\"dialog\"], dialog[open], .pb, .help-panel, .palette, .conn-manager'));\n if (covered) return;\n\n // Backspace-as-back is a habit from file browsers, but only when the\n // caret is not in a text field.\n if (!typing && (e.key === 'Backspace' || (e.key === '[' && e.metaKey)) && state.stack.length > 1) {\n e.preventDefault();\n backTo(state.stack.length - 2);\n }\n if (e.key === 'h' && !typing && !e.metaKey && !e.ctrlKey) {\n e.preventDefault();\n goHome();\n }\n });\n}\n"],"mappings":"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"}
|