plum-e2e 2.9.17 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +7 -7
- package/backend/app.js +1 -1
- package/backend/constants/socketEvents.js +8 -14
- package/backend/lib/csv.js +21 -0
- package/backend/lib/exportResponse.js +37 -0
- package/backend/lib/serverBootstrap.js +6 -6
- package/backend/lib/serverConfig.js +5 -3
- package/backend/mcp/server.js +47 -3
- package/backend/middleware/runnerOrAdmin.js +1 -1
- package/backend/package.json +1 -1
- package/backend/prisma/migrations/20260829000000_add_run_queue/migration.sql +29 -0
- package/backend/prisma/schema.prisma +30 -0
- package/backend/routes/active-runs.routes.js +10 -6
- package/backend/routes/node.routes.js +7 -0
- package/backend/routes/reports.routes.js +19 -0
- package/backend/routes/runners.routes.js +1 -1
- package/backend/routes/test-cases.routes.js +12 -0
- package/backend/routes/test-runs.routes.js +17 -0
- package/backend/routes/test-suites.routes.js +34 -0
- package/backend/routes/trigger.routes.js +8 -5
- package/backend/scripts/{manage-runners.mjs → manage-nodes.mjs} +67 -52
- package/backend/server.js +5 -1
- package/backend/services/cronService.js +15 -443
- package/backend/services/exportService.js +339 -0
- package/backend/services/nodeExecutionService.js +13 -1
- package/backend/services/runExecutorService.js +423 -0
- package/backend/services/runQueueService.js +276 -0
- package/backend/services/runnerService.js +22 -4
- package/backend/services/testImportService.js +87 -0
- package/backend/services/triggerService.js +13 -231
- package/backend/websockets/socketHandler.js +32 -590
- package/bin/plum.js +174 -68
- package/docker-compose.yml +1 -1
- package/frontend/.svelte-kit/adapter-node/.vite/manifest.json +78 -70
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/BackLink.DRrgBGDC.css +6 -0
- package/frontend/.svelte-kit/{output/server/_app/immutable/assets/Toast.DENwYn3g.css → adapter-node/_app/immutable/assets/Button.C1zsJAUG.css} +1 -1
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/ExportMenu.DsJQ1Qua.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_layout.B4TT3qNx.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.4bPj83tb.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.Be5c3USL.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.BwgtEi_a.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.ClS4XkkN.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.DOC8fPSI.css +6 -0
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.Dm1nSEgE.css +6 -0
- package/frontend/.svelte-kit/adapter-node/chunks/BackLink.js +1 -1
- package/frontend/.svelte-kit/adapter-node/chunks/Badge.js +1 -1
- package/frontend/.svelte-kit/adapter-node/chunks/{Toast.js → Button.js} +2 -17
- package/frontend/.svelte-kit/adapter-node/chunks/ConfirmModal.js +2 -2
- package/frontend/.svelte-kit/adapter-node/chunks/EmptyState.js +2 -2
- package/frontend/.svelte-kit/adapter-node/chunks/Modal.js +1 -1
- package/frontend/.svelte-kit/adapter-node/chunks/common.js +11 -4
- package/frontend/.svelte-kit/adapter-node/chunks/constants.js +6 -4
- package/frontend/.svelte-kit/adapter-node/chunks/format.js +3 -3
- package/frontend/.svelte-kit/adapter-node/chunks/index.js +4 -4
- package/frontend/.svelte-kit/adapter-node/chunks/internal.js +1 -1
- package/frontend/.svelte-kit/adapter-node/chunks/reports.js +1 -1
- package/frontend/.svelte-kit/adapter-node/chunks/reports2.js +38 -40
- package/frontend/.svelte-kit/adapter-node/chunks/repository.js +26 -14
- package/frontend/.svelte-kit/adapter-node/chunks/runner.js +10 -20
- package/frontend/.svelte-kit/adapter-node/entries/pages/_layout.svelte.js +2 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/live/_id_/_page.svelte.js +254 -0
- package/frontend/.svelte-kit/adapter-node/entries/pages/login/_page.svelte.js +1 -1
- package/frontend/.svelte-kit/adapter-node/entries/pages/reports/_id_/_page.svelte.js +39 -25
- package/frontend/.svelte-kit/adapter-node/entries/pages/reports/_page.svelte.js +23 -19
- package/frontend/.svelte-kit/adapter-node/entries/pages/scheduled-tests/_page.svelte.js +5 -8
- package/frontend/.svelte-kit/adapter-node/entries/pages/settings/_page.svelte.js +354 -185
- package/frontend/.svelte-kit/adapter-node/entries/pages/setup/_page.svelte.js +1 -1
- package/frontend/.svelte-kit/adapter-node/entries/pages/test-repository/_page.svelte.js +55 -36
- package/frontend/.svelte-kit/adapter-node/entries/pages/test-repository/runs/_id_/_page.svelte.js +4 -7
- package/frontend/.svelte-kit/adapter-node/entries/pages/test-repository/suites/_id_/_page.svelte.js +66 -16
- package/frontend/.svelte-kit/adapter-node/manifest-full.js +10 -10
- package/frontend/.svelte-kit/adapter-node/manifest.js +10 -10
- package/frontend/.svelte-kit/adapter-node/nodes/0.js +2 -2
- package/frontend/.svelte-kit/adapter-node/nodes/1.js +1 -1
- package/frontend/.svelte-kit/adapter-node/nodes/10.js +2 -2
- package/frontend/.svelte-kit/adapter-node/nodes/11.js +2 -2
- package/frontend/.svelte-kit/adapter-node/nodes/12.js +2 -2
- package/frontend/.svelte-kit/adapter-node/nodes/2.js +1 -1
- package/frontend/.svelte-kit/adapter-node/nodes/3.js +3 -3
- package/frontend/.svelte-kit/adapter-node/nodes/4.js +3 -3
- package/frontend/.svelte-kit/adapter-node/nodes/5.js +3 -3
- package/frontend/.svelte-kit/adapter-node/nodes/6.js +3 -3
- package/frontend/.svelte-kit/adapter-node/nodes/7.js +2 -2
- package/frontend/.svelte-kit/adapter-node/nodes/8.js +2 -2
- package/frontend/.svelte-kit/adapter-node/nodes/9.js +1 -1
- package/frontend/.svelte-kit/ambient.d.ts +28 -28
- package/frontend/.svelte-kit/generated/client/app.js +4 -4
- package/frontend/.svelte-kit/generated/client/nodes/3.js +1 -1
- package/frontend/.svelte-kit/generated/client/nodes/4.js +1 -1
- package/frontend/.svelte-kit/generated/client/nodes/5.js +1 -1
- package/frontend/.svelte-kit/generated/client/nodes/6.js +1 -1
- package/frontend/.svelte-kit/generated/client-optimized/app.js +4 -4
- package/frontend/.svelte-kit/generated/client-optimized/nodes/3.js +1 -1
- package/frontend/.svelte-kit/generated/client-optimized/nodes/4.js +1 -1
- package/frontend/.svelte-kit/generated/client-optimized/nodes/5.js +1 -1
- package/frontend/.svelte-kit/generated/client-optimized/nodes/6.js +1 -1
- package/frontend/.svelte-kit/generated/server/internal.js +1 -1
- package/frontend/.svelte-kit/output/client/.vite/manifest.json +462 -403
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/0.BEqlRAtD.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/10.DC0wD6w_.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/12.Dm1nSEgE.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/3.Be5c3USL.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/5.ClS4XkkN.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/6.DdQVxyZK.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/8.DOC8fPSI.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/BackLink.DRrgBGDC.css +6 -0
- package/frontend/{build/client/_app/immutable/assets/Toast.DENwYn3g.css → .svelte-kit/output/client/_app/immutable/assets/Button.C1zsJAUG.css} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/ExportMenu.DsJQ1Qua.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_layout.B4TT3qNx.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.4bPj83tb.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.Be5c3USL.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.BwgtEi_a.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.ClS4XkkN.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.DOC8fPSI.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.Dm1nSEgE.css +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/3MBVX4Yb.js +175 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/6VDMVB5U.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/B2lVGNml.js +6 -0
- package/frontend/{build/client/_app/immutable/chunks/2zMvi6fR.js → .svelte-kit/output/client/_app/immutable/chunks/BCh31ecr.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BDb8hZHu.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BIf7lHIm.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BIjh3jiU.js +8 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BTV7EXZb.js +11 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/{DMZwI8Cj.js → BWGoOYU0.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BdBJfKUi.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/{t-La0hgu.js → BnXsGCy3.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BtTNggoY.js +8 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/C4Z3p6jE.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CNpD-yNH.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CUPWZLIN.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/{C1Vid6wz.js → CXQhSK1T.js} +1 -1
- package/frontend/{build/client/_app/immutable/chunks/CKDtmZUQ.js → .svelte-kit/output/client/_app/immutable/chunks/CtgCYzu5.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/{C8OURRSs.js → D72giPTu.js} +1 -1
- package/frontend/{build/client/_app/immutable/chunks/BmZ9upwL.js → .svelte-kit/output/client/_app/immutable/chunks/DDx3no2z.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/D_thT6pZ.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DeiVAbyn.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DiexacSB.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/{DDZw0L0T.js → Dlymnwnf.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/gCgJ3Cwu.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/htkwR9b-.js +6 -0
- package/frontend/{build/client/_app/immutable/chunks/DCgHuuvs.js → .svelte-kit/output/client/_app/immutable/chunks/iL4SCrvY.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/kFFd6Oo5.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/pNZogwkM.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/{w0D4Uzlq.js → prk8PJfA.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/qvxlSGpD.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/r_d1Iu0W.js +6 -0
- package/frontend/{build/client/_app/immutable/chunks/CNdcuGR0.js → .svelte-kit/output/client/_app/immutable/chunks/tsOANt55.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/zXSLr47H.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/entry/app.DgdSwPuN.js +7 -0
- package/frontend/{build/client/_app/immutable/entry/start.4qxHHAcl.js → .svelte-kit/output/client/_app/immutable/entry/start.D_lhI48n.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/0.D2F-i1I5.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/{1.Df9sLw8b.js → 1.JIF2GfHq.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/10.A0AHLfOt.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/11.CVSPxlqY.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/12.CnAR0AQb.js +6 -0
- package/frontend/{build/client/_app/immutable/nodes/2.BCPSg7H4.js → .svelte-kit/output/client/_app/immutable/nodes/2.Bno00fr8.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/3.B6KwaCsM.js +6 -0
- package/frontend/{build/client/_app/immutable/nodes/3.8BFAJoHT.js → .svelte-kit/output/client/_app/immutable/nodes/4.BX70m3v6.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/5.UIFh06yr.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/6.DZ1OV24V.js +10 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/7.B_XntBZ1.js +6 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/8.CVHgJw-E.js +9 -0
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/{9.CvfGx3Hu.js → 9.DDDQPmMj.js} +1 -1
- package/frontend/.svelte-kit/output/client/_app/version.json +1 -1
- package/frontend/.svelte-kit/output/server/.vite/manifest.json +78 -70
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/BackLink.DRrgBGDC.css +6 -0
- package/frontend/.svelte-kit/output/{client/_app/immutable/assets/Toast.DENwYn3g.css → server/_app/immutable/assets/Button.C1zsJAUG.css} +1 -1
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/ExportMenu.DsJQ1Qua.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_layout.B4TT3qNx.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.4bPj83tb.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.Be5c3USL.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.BwgtEi_a.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.ClS4XkkN.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.DOC8fPSI.css +6 -0
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.Dm1nSEgE.css +6 -0
- package/frontend/.svelte-kit/output/server/chunks/BackLink.js +1 -1
- package/frontend/.svelte-kit/output/server/chunks/Badge.js +1 -1
- package/frontend/.svelte-kit/output/server/chunks/{Toast.js → Button.js} +2 -17
- package/frontend/.svelte-kit/output/server/chunks/ConfirmModal.js +2 -2
- package/frontend/.svelte-kit/output/server/chunks/EmptyState.js +2 -2
- package/frontend/.svelte-kit/output/server/chunks/Modal.js +1 -1
- package/frontend/.svelte-kit/output/server/chunks/common.js +11 -4
- package/frontend/.svelte-kit/output/server/chunks/constants.js +6 -4
- package/frontend/.svelte-kit/output/server/chunks/format.js +3 -3
- package/frontend/.svelte-kit/output/server/chunks/index.js +4 -4
- package/frontend/.svelte-kit/output/server/chunks/internal.js +1 -1
- package/frontend/.svelte-kit/output/server/chunks/reports.js +1 -1
- package/frontend/.svelte-kit/output/server/chunks/reports2.js +38 -40
- package/frontend/.svelte-kit/output/server/chunks/repository.js +26 -14
- package/frontend/.svelte-kit/output/server/chunks/runner.js +10 -20
- package/frontend/.svelte-kit/output/server/entries/pages/_layout.svelte.js +2 -0
- package/frontend/.svelte-kit/output/server/entries/pages/live/_id_/_page.svelte.js +254 -0
- package/frontend/.svelte-kit/output/server/entries/pages/login/_page.svelte.js +1 -1
- package/frontend/.svelte-kit/output/server/entries/pages/reports/_id_/_page.svelte.js +39 -25
- package/frontend/.svelte-kit/output/server/entries/pages/reports/_page.svelte.js +23 -19
- package/frontend/.svelte-kit/output/server/entries/pages/scheduled-tests/_page.svelte.js +5 -8
- package/frontend/.svelte-kit/output/server/entries/pages/settings/_page.svelte.js +354 -185
- package/frontend/.svelte-kit/output/server/entries/pages/setup/_page.svelte.js +1 -1
- package/frontend/.svelte-kit/output/server/entries/pages/test-repository/_page.svelte.js +55 -36
- package/frontend/.svelte-kit/output/server/entries/pages/test-repository/runs/_id_/_page.svelte.js +4 -7
- package/frontend/.svelte-kit/output/server/entries/pages/test-repository/suites/_id_/_page.svelte.js +66 -16
- package/frontend/.svelte-kit/output/server/manifest-full.js +10 -10
- package/frontend/.svelte-kit/output/server/manifest.js +10 -10
- package/frontend/.svelte-kit/output/server/nodes/0.js +2 -2
- package/frontend/.svelte-kit/output/server/nodes/1.js +1 -1
- package/frontend/.svelte-kit/output/server/nodes/10.js +2 -2
- package/frontend/.svelte-kit/output/server/nodes/11.js +2 -2
- package/frontend/.svelte-kit/output/server/nodes/12.js +2 -2
- package/frontend/.svelte-kit/output/server/nodes/2.js +1 -1
- package/frontend/.svelte-kit/output/server/nodes/3.js +3 -3
- package/frontend/.svelte-kit/output/server/nodes/4.js +3 -3
- package/frontend/.svelte-kit/output/server/nodes/5.js +3 -3
- package/frontend/.svelte-kit/output/server/nodes/6.js +3 -3
- package/frontend/.svelte-kit/output/server/nodes/7.js +2 -2
- package/frontend/.svelte-kit/output/server/nodes/8.js +2 -2
- package/frontend/.svelte-kit/output/server/nodes/9.js +1 -1
- package/frontend/build/client/_app/immutable/assets/0.BEqlRAtD.css +6 -0
- package/frontend/build/client/_app/immutable/assets/0.BEqlRAtD.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/0.BEqlRAtD.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/10.DC0wD6w_.css +6 -0
- package/frontend/build/client/_app/immutable/assets/10.DC0wD6w_.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/10.DC0wD6w_.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/12.Dm1nSEgE.css +6 -0
- package/frontend/build/client/_app/immutable/assets/12.Dm1nSEgE.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/12.Dm1nSEgE.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/3.Be5c3USL.css +6 -0
- package/frontend/build/client/_app/immutable/assets/3.Be5c3USL.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/3.Be5c3USL.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/5.ClS4XkkN.css +6 -0
- package/frontend/build/client/_app/immutable/assets/5.ClS4XkkN.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/5.ClS4XkkN.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/6.DdQVxyZK.css +6 -0
- package/frontend/build/client/_app/immutable/assets/6.DdQVxyZK.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/6.DdQVxyZK.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/8.DOC8fPSI.css +6 -0
- package/frontend/build/client/_app/immutable/assets/8.DOC8fPSI.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/8.DOC8fPSI.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/BackLink.DRrgBGDC.css +6 -0
- package/frontend/build/client/_app/immutable/assets/BackLink.DRrgBGDC.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/BackLink.DRrgBGDC.css.gz +0 -0
- package/frontend/{.svelte-kit/adapter-node/_app/immutable/assets/Toast.DENwYn3g.css → build/client/_app/immutable/assets/Button.C1zsJAUG.css} +1 -1
- package/frontend/build/client/_app/immutable/assets/Button.C1zsJAUG.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/Button.C1zsJAUG.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/ExportMenu.DsJQ1Qua.css +6 -0
- package/frontend/build/client/_app/immutable/assets/ExportMenu.DsJQ1Qua.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/ExportMenu.DsJQ1Qua.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_layout.B4TT3qNx.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_layout.B4TT3qNx.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_layout.B4TT3qNx.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.4bPj83tb.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_page.4bPj83tb.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.4bPj83tb.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.Be5c3USL.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_page.Be5c3USL.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.Be5c3USL.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BwgtEi_a.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_page.BwgtEi_a.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BwgtEi_a.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.ClS4XkkN.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_page.ClS4XkkN.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.ClS4XkkN.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.DOC8fPSI.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_page.DOC8fPSI.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.DOC8fPSI.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.Dm1nSEgE.css +6 -0
- package/frontend/build/client/_app/immutable/assets/_page.Dm1nSEgE.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.Dm1nSEgE.css.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/3MBVX4Yb.js +175 -0
- package/frontend/build/client/_app/immutable/chunks/3MBVX4Yb.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/3MBVX4Yb.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/6VDMVB5U.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/6VDMVB5U.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/6VDMVB5U.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/B2lVGNml.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/B2lVGNml.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/B2lVGNml.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/chunks/2zMvi6fR.js → build/client/_app/immutable/chunks/BCh31ecr.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/BCh31ecr.js.br +6 -0
- package/frontend/build/client/_app/immutable/chunks/BCh31ecr.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BDb8hZHu.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/BDb8hZHu.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BDb8hZHu.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BIf7lHIm.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/BIf7lHIm.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BIf7lHIm.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BIjh3jiU.js +8 -0
- package/frontend/build/client/_app/immutable/chunks/BIjh3jiU.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BIjh3jiU.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BTV7EXZb.js +11 -0
- package/frontend/build/client/_app/immutable/chunks/BTV7EXZb.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BTV7EXZb.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/{DMZwI8Cj.js → BWGoOYU0.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/BWGoOYU0.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BWGoOYU0.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BdBJfKUi.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/BdBJfKUi.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BdBJfKUi.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/{t-La0hgu.js → BnXsGCy3.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/BnXsGCy3.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BnXsGCy3.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BtTNggoY.js +8 -0
- package/frontend/build/client/_app/immutable/chunks/BtTNggoY.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BtTNggoY.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/C4Z3p6jE.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/C4Z3p6jE.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/C4Z3p6jE.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CNpD-yNH.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/CNpD-yNH.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CNpD-yNH.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CUPWZLIN.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/CUPWZLIN.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CUPWZLIN.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/{C1Vid6wz.js → CXQhSK1T.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/CXQhSK1T.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CXQhSK1T.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/chunks/CKDtmZUQ.js → build/client/_app/immutable/chunks/CtgCYzu5.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/CtgCYzu5.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CtgCYzu5.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/{C8OURRSs.js → D72giPTu.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/D72giPTu.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/D72giPTu.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/chunks/BmZ9upwL.js → build/client/_app/immutable/chunks/DDx3no2z.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/DDx3no2z.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DDx3no2z.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/D_thT6pZ.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/D_thT6pZ.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/D_thT6pZ.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DeiVAbyn.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/DeiVAbyn.js.br +6 -0
- package/frontend/build/client/_app/immutable/chunks/DeiVAbyn.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DiexacSB.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/DiexacSB.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DiexacSB.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/{DDZw0L0T.js → Dlymnwnf.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/Dlymnwnf.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/Dlymnwnf.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/gCgJ3Cwu.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/gCgJ3Cwu.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/gCgJ3Cwu.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/htkwR9b-.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/htkwR9b-.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/htkwR9b-.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/chunks/DCgHuuvs.js → build/client/_app/immutable/chunks/iL4SCrvY.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/iL4SCrvY.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/iL4SCrvY.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/kFFd6Oo5.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/kFFd6Oo5.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/kFFd6Oo5.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/pNZogwkM.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/pNZogwkM.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/pNZogwkM.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/{w0D4Uzlq.js → prk8PJfA.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/prk8PJfA.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/prk8PJfA.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/qvxlSGpD.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/qvxlSGpD.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/qvxlSGpD.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/r_d1Iu0W.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/r_d1Iu0W.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/r_d1Iu0W.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/chunks/CNdcuGR0.js → build/client/_app/immutable/chunks/tsOANt55.js} +1 -1
- package/frontend/build/client/_app/immutable/chunks/tsOANt55.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/tsOANt55.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/zXSLr47H.js +6 -0
- package/frontend/build/client/_app/immutable/chunks/zXSLr47H.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/zXSLr47H.js.gz +0 -0
- package/frontend/build/client/_app/immutable/entry/app.DgdSwPuN.js +7 -0
- package/frontend/build/client/_app/immutable/entry/app.DgdSwPuN.js.br +0 -0
- package/frontend/build/client/_app/immutable/entry/app.DgdSwPuN.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/entry/start.4qxHHAcl.js → build/client/_app/immutable/entry/start.D_lhI48n.js} +1 -1
- package/frontend/build/client/_app/immutable/entry/{start.4qxHHAcl.js.br → start.D_lhI48n.js.br} +1 -1
- package/frontend/build/client/_app/immutable/entry/{start.4qxHHAcl.js.gz → start.D_lhI48n.js.gz} +0 -0
- package/frontend/build/client/_app/immutable/nodes/0.D2F-i1I5.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/0.D2F-i1I5.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/0.D2F-i1I5.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/{1.Df9sLw8b.js → 1.JIF2GfHq.js} +1 -1
- package/frontend/build/client/_app/immutable/nodes/1.JIF2GfHq.js.br +5 -0
- package/frontend/build/client/_app/immutable/nodes/1.JIF2GfHq.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/10.A0AHLfOt.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/10.A0AHLfOt.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/10.A0AHLfOt.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/11.CVSPxlqY.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/11.CVSPxlqY.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/11.CVSPxlqY.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/12.CnAR0AQb.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/12.CnAR0AQb.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/12.CnAR0AQb.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/nodes/2.BCPSg7H4.js → build/client/_app/immutable/nodes/2.Bno00fr8.js} +1 -1
- package/frontend/build/client/_app/immutable/nodes/2.Bno00fr8.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/2.Bno00fr8.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/3.B6KwaCsM.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/3.B6KwaCsM.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/3.B6KwaCsM.js.gz +0 -0
- package/frontend/{.svelte-kit/output/client/_app/immutable/nodes/3.8BFAJoHT.js → build/client/_app/immutable/nodes/4.BX70m3v6.js} +1 -1
- package/frontend/build/client/_app/immutable/nodes/4.BX70m3v6.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/4.BX70m3v6.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/5.UIFh06yr.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/5.UIFh06yr.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/5.UIFh06yr.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/6.DZ1OV24V.js +10 -0
- package/frontend/build/client/_app/immutable/nodes/6.DZ1OV24V.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/6.DZ1OV24V.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/7.B_XntBZ1.js +6 -0
- package/frontend/build/client/_app/immutable/nodes/7.B_XntBZ1.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/7.B_XntBZ1.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/8.CVHgJw-E.js +9 -0
- package/frontend/build/client/_app/immutable/nodes/8.CVHgJw-E.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/8.CVHgJw-E.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/{9.CvfGx3Hu.js → 9.DDDQPmMj.js} +1 -1
- package/frontend/build/client/_app/immutable/nodes/9.DDDQPmMj.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/9.DDDQPmMj.js.gz +0 -0
- package/frontend/build/client/_app/version.json +1 -1
- package/frontend/build/client/_app/version.json.br +0 -0
- package/frontend/build/client/_app/version.json.gz +0 -0
- package/frontend/build/server/chunks/0-38cvTs44.js +22 -0
- package/frontend/build/server/chunks/0-38cvTs44.js.map +5 -0
- package/frontend/build/server/chunks/{1-Kxn9d30Z.js → 1-CcYsajvR.js} +3 -3
- package/frontend/build/server/chunks/{1-Kxn9d30Z.js.map → 1-CcYsajvR.js.map} +1 -1
- package/frontend/build/server/chunks/10-CFR2MUJt.js +14 -0
- package/frontend/build/server/chunks/10-CFR2MUJt.js.map +5 -0
- package/frontend/build/server/chunks/11-BmkiRQ9D.js +14 -0
- package/frontend/build/server/chunks/11-BmkiRQ9D.js.map +5 -0
- package/frontend/build/server/chunks/12-BphJAwnL.js +14 -0
- package/frontend/build/server/chunks/12-BphJAwnL.js.map +5 -0
- package/frontend/build/server/chunks/2-Dalgd2D4.js +14 -0
- package/frontend/build/server/chunks/{2-Dc_rKWoK.js.map → 2-Dalgd2D4.js.map} +1 -1
- package/frontend/build/server/chunks/3-BvsmdXCj.js +14 -0
- package/frontend/build/server/chunks/3-BvsmdXCj.js.map +5 -0
- package/frontend/build/server/chunks/4-CN18WCEn.js +14 -0
- package/frontend/build/server/chunks/4-CN18WCEn.js.map +5 -0
- package/frontend/build/server/chunks/5-BwLYF3xL.js +14 -0
- package/frontend/build/server/chunks/5-BwLYF3xL.js.map +5 -0
- package/frontend/build/server/chunks/6-DTM2N_k3.js +14 -0
- package/frontend/build/server/chunks/6-DTM2N_k3.js.map +5 -0
- package/frontend/build/server/chunks/7-DTNbErSe.js +14 -0
- package/frontend/build/server/chunks/7-DTNbErSe.js.map +5 -0
- package/frontend/build/server/chunks/8-BfCbb7pl.js +14 -0
- package/frontend/build/server/chunks/8-BfCbb7pl.js.map +5 -0
- package/frontend/build/server/chunks/9-CQKepnMw.js +14 -0
- package/frontend/build/server/chunks/{9-DirZG_Lu.js.map → 9-CQKepnMw.js.map} +1 -1
- package/frontend/build/server/chunks/{BackLink-BJ8NaemM.js → BackLink-CMpNTYqE.js} +2 -2
- package/frontend/build/server/chunks/BackLink-CMpNTYqE.js.map +5 -0
- package/frontend/build/server/chunks/{Badge-44ZTDx0V.js → Badge-BTWnF9pA.js} +2 -2
- package/frontend/build/server/chunks/Badge-BTWnF9pA.js.map +5 -0
- package/frontend/build/server/chunks/{Toast-v-q4ZnYq.js → Button-B9h9viZX.js} +3 -17
- package/frontend/build/server/chunks/Button-B9h9viZX.js.map +5 -0
- package/frontend/build/server/chunks/{ConfirmModal-C0EAXcq_.js → ConfirmModal-C6Cz898n.js} +4 -4
- package/frontend/build/server/chunks/ConfirmModal-C6Cz898n.js.map +5 -0
- package/frontend/build/server/chunks/{EmptyState-BA_eXaeR.js → EmptyState-CRtsJIv6.js} +3 -3
- package/frontend/build/server/chunks/EmptyState-CRtsJIv6.js.map +5 -0
- package/frontend/build/server/chunks/{Modal-DChG187n.js → Modal-BJJMnfIg.js} +2 -2
- package/frontend/build/server/chunks/Modal-BJJMnfIg.js.map +5 -0
- package/frontend/build/server/chunks/_layout.svelte-B8vZGefg.js +28 -0
- package/frontend/build/server/chunks/_layout.svelte-B8vZGefg.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-Kg69DDaM.js → _page.svelte-BrYksycU.js} +5 -5
- package/frontend/build/server/chunks/_page.svelte-BrYksycU.js.map +5 -0
- package/frontend/build/server/chunks/_page.svelte-BrnXHxJ4.js +69 -0
- package/frontend/build/server/chunks/_page.svelte-BrnXHxJ4.js.map +5 -0
- package/frontend/build/server/chunks/_page.svelte-C2WqvInJ.js +898 -0
- package/frontend/build/server/chunks/_page.svelte-C2WqvInJ.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-04WxjOuH.js → _page.svelte-CP6jA1ex.js} +9 -9
- package/frontend/build/server/chunks/{_page.svelte-04WxjOuH.js.map → _page.svelte-CP6jA1ex.js.map} +1 -1
- package/frontend/build/server/chunks/{_page.svelte-D3E6Eojd.js → _page.svelte-Cf6bI1Y2.js} +5 -5
- package/frontend/build/server/chunks/_page.svelte-Cf6bI1Y2.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-1as75nPc.js → _page.svelte-D6b-klLK.js} +33 -29
- package/frontend/build/server/chunks/_page.svelte-D6b-klLK.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-CWWeZuid.js → _page.svelte-DBjTpquQ.js} +73 -24
- package/frontend/build/server/chunks/_page.svelte-DBjTpquQ.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-CB8-QBNg.js → _page.svelte-DM1_y4Oq.js} +61 -42
- package/frontend/build/server/chunks/_page.svelte-DM1_y4Oq.js.map +5 -0
- package/frontend/build/server/chunks/_page.svelte-Mo-O3HJ5.js +257 -0
- package/frontend/build/server/chunks/_page.svelte-Mo-O3HJ5.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-BuFusRK1.js → _page.svelte-mZF4NrfU.js} +14 -17
- package/frontend/build/server/chunks/_page.svelte-mZF4NrfU.js.map +5 -0
- package/frontend/build/server/chunks/{_page.svelte-1jo8MapI.js → _page.svelte-nrlgIFaU.js} +13 -15
- package/frontend/build/server/chunks/_page.svelte-nrlgIFaU.js.map +5 -0
- package/frontend/build/server/chunks/{auth-Chw-wBpI.js → auth-DDPlushv.js} +2 -2
- package/frontend/build/server/chunks/{auth-Chw-wBpI.js.map → auth-DDPlushv.js.map} +1 -1
- package/frontend/build/server/chunks/{client-DEmxR_a-.js → client-CsTiGNZy.js} +2 -2
- package/frontend/build/server/chunks/{client-DEmxR_a-.js.map → client-CsTiGNZy.js.map} +1 -1
- package/frontend/build/server/chunks/{common-DYYTVHPw.js → common-DS-Z0UFe.js} +7 -2
- package/frontend/build/server/chunks/common-DS-Z0UFe.js.map +5 -0
- package/frontend/build/server/chunks/{constants-CXTaQaB6.js → constants-OmHysD51.js} +3 -2
- package/frontend/build/server/chunks/constants-OmHysD51.js.map +5 -0
- package/frontend/build/server/chunks/{error.svelte-BD3xNemk.js → error.svelte-BXr4lXlB.js} +3 -3
- package/frontend/build/server/chunks/{error.svelte-BD3xNemk.js.map → error.svelte-BXr4lXlB.js.map} +1 -1
- package/frontend/build/server/chunks/{format-CiNRMfHu.js → format-Bqb0as15.js} +2 -2
- package/frontend/build/server/chunks/{format-CiNRMfHu.js.map → format-Bqb0as15.js.map} +1 -1
- package/frontend/build/server/chunks/{index-server-B3M9vyh2.js → index-server-53nOZg5X.js} +2 -2
- package/frontend/build/server/chunks/{index-server-B3M9vyh2.js.map → index-server-53nOZg5X.js.map} +1 -1
- package/frontend/build/server/chunks/{index2-5R1tbrep.js → index2-DGcbugKe.js} +2 -2
- package/frontend/build/server/chunks/{index2-5R1tbrep.js.map → index2-DGcbugKe.js.map} +1 -1
- package/frontend/build/server/chunks/{reports-D_ApeeNh.js → reports-chCHCDzB.js} +2 -2
- package/frontend/build/server/chunks/{reports-D_ApeeNh.js.map → reports-chCHCDzB.js.map} +1 -1
- package/frontend/build/server/chunks/{reports2-BtElN_53.js → reports2-Dr3zu9CD.js} +8 -9
- package/frontend/build/server/chunks/reports2-Dr3zu9CD.js.map +5 -0
- package/frontend/build/server/chunks/{repository-FYYV_vKE.js → repository-DSsWVKEb.js} +9 -3
- package/frontend/build/server/chunks/repository-DSsWVKEb.js.map +5 -0
- package/frontend/build/server/chunks/runner-aaUtOqck.js +27 -0
- package/frontend/build/server/chunks/runner-aaUtOqck.js.map +5 -0
- package/frontend/build/server/chunks/{stores-BLenR3c1.js → stores-C4ZkywTG.js} +3 -3
- package/frontend/build/server/chunks/{stores-BLenR3c1.js.map → stores-C4ZkywTG.js.map} +1 -1
- package/frontend/build/server/chunks/{theme-nAx-GvX_.js → theme-C81wSe5T.js} +2 -2
- package/frontend/build/server/chunks/{theme-nAx-GvX_.js.map → theme-C81wSe5T.js.map} +1 -1
- package/frontend/build/server/index.js +2 -2
- package/frontend/build/server/index.js.map +1 -1
- package/frontend/build/server/manifest.js +23 -23
- package/frontend/build/server/manifest.js.map +1 -1
- package/frontend/package-lock.json +14 -0
- package/frontend/package.json +2 -0
- package/frontend/src/lib/api/reports.js +7 -0
- package/frontend/src/lib/api/repository.js +28 -0
- package/frontend/src/lib/components/layout/RunnerPanel.svelte +187 -266
- package/frontend/src/lib/components/reports/RecordingPlayer.svelte +172 -2
- package/frontend/src/lib/components/ui/ExportMenu.svelte +154 -0
- package/frontend/src/lib/components/ui/NotificationStack.svelte +177 -0
- package/frontend/src/lib/constants.js +1 -1
- package/frontend/src/lib/copy/common.js +9 -0
- package/frontend/src/lib/copy/reports.js +29 -0
- package/frontend/src/lib/copy/repository.js +4 -0
- package/frontend/src/lib/copy/runners.js +9 -6
- package/frontend/src/lib/copy/settings.js +15 -0
- package/frontend/src/lib/socketEvents.js +3 -15
- package/frontend/src/lib/stores/notifications.js +23 -0
- package/frontend/src/lib/stores/replayVideo.js +51 -0
- package/frontend/src/lib/stores/runner.js +62 -46
- package/frontend/src/lib/utils/download.js +28 -0
- package/frontend/src/lib/utils/replayCapture.js +91 -0
- package/frontend/src/lib/utils/replayVideo.js +111 -0
- package/frontend/src/routes/+layout.svelte +2 -0
- package/frontend/src/routes/{reports/live → live/[id]}/+page.svelte +112 -183
- package/frontend/src/routes/reports/[id]/+page.svelte +38 -3
- package/frontend/src/routes/scheduled-tests/+page.svelte +11 -19
- package/frontend/src/routes/settings/+page.svelte +140 -56
- package/frontend/src/routes/test-repository/+page.svelte +44 -16
- package/frontend/src/routes/test-repository/runs/[id]/+page.svelte +14 -23
- package/frontend/src/routes/test-repository/suites/[id]/+page.svelte +38 -22
- package/package.json +1 -1
- package/backend/services/activeRunsService.js +0 -55
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/BackLink.CvWWuO3h.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_layout.BuhMvMUj.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.0Eln51hV.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.5IJAEAjc.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.BZfe6nWe.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.Bj_a_5lv.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.BwgOqeMo.css +0 -6
- package/frontend/.svelte-kit/adapter-node/_app/immutable/assets/_page.CFnbmY-D.css +0 -6
- package/frontend/.svelte-kit/adapter-node/entries/pages/reports/live/_page.svelte.js +0 -247
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/0.BhSG-jZH.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/10.CdaQUS6U.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/12.Bj_a_5lv.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/4.0Eln51hV.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/5.DFV9OgAu.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/6.CFnbmY-D.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/8.BwgOqeMo.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/BackLink.CvWWuO3h.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/Button.FOWXxvc7.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_layout.BuhMvMUj.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.0Eln51hV.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.5IJAEAjc.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.BZfe6nWe.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.Bj_a_5lv.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.BwgOqeMo.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/assets/_page.CFnbmY-D.css +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/3InFPLvE.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BAACMRH5.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BAMUGSh7.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BKuh57WU.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/BUwxRmHf.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CGeZlCaI.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CMBQQ9RZ.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CMEtqUfQ.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CUC98kMZ.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CgnwuKKO.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/Co3xKhEp.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CuqnZUex.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/CzlPaHY9.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DHM6H-es.js +0 -7
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DSLBMEpr.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/DbgD7JLa.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/TOCyHP97.js +0 -11
- package/frontend/.svelte-kit/output/client/_app/immutable/chunks/kkA1mrsH.js +0 -8
- package/frontend/.svelte-kit/output/client/_app/immutable/entry/app.KrtMZ3my.js +0 -7
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/0.C8DodwXs.js +0 -11
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/10.DEbnxfND.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/11.BViaDK2m.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/12.BMSCSd88.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/4.D-YT_JJe.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/5.DVeH2eQP.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/6.DI7-IJhN.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/7.C-pKvVZy.js +0 -6
- package/frontend/.svelte-kit/output/client/_app/immutable/nodes/8.93Mb3ofT.js +0 -9
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/BackLink.CvWWuO3h.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_layout.BuhMvMUj.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.0Eln51hV.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.5IJAEAjc.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.BZfe6nWe.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.Bj_a_5lv.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.BwgOqeMo.css +0 -6
- package/frontend/.svelte-kit/output/server/_app/immutable/assets/_page.CFnbmY-D.css +0 -6
- package/frontend/.svelte-kit/output/server/entries/pages/reports/live/_page.svelte.js +0 -247
- package/frontend/build/client/_app/immutable/assets/0.BhSG-jZH.css +0 -6
- package/frontend/build/client/_app/immutable/assets/0.BhSG-jZH.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/0.BhSG-jZH.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/10.CdaQUS6U.css +0 -6
- package/frontend/build/client/_app/immutable/assets/10.CdaQUS6U.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/10.CdaQUS6U.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/12.Bj_a_5lv.css +0 -6
- package/frontend/build/client/_app/immutable/assets/12.Bj_a_5lv.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/12.Bj_a_5lv.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/4.0Eln51hV.css +0 -6
- package/frontend/build/client/_app/immutable/assets/4.0Eln51hV.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/4.0Eln51hV.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/5.DFV9OgAu.css +0 -6
- package/frontend/build/client/_app/immutable/assets/5.DFV9OgAu.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/5.DFV9OgAu.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/6.CFnbmY-D.css +0 -6
- package/frontend/build/client/_app/immutable/assets/6.CFnbmY-D.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/6.CFnbmY-D.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/8.BwgOqeMo.css +0 -6
- package/frontend/build/client/_app/immutable/assets/8.BwgOqeMo.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/8.BwgOqeMo.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/BackLink.CvWWuO3h.css +0 -6
- package/frontend/build/client/_app/immutable/assets/BackLink.CvWWuO3h.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/BackLink.CvWWuO3h.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/Button.FOWXxvc7.css +0 -6
- package/frontend/build/client/_app/immutable/assets/Button.FOWXxvc7.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/Button.FOWXxvc7.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/Toast.DENwYn3g.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/Toast.DENwYn3g.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_layout.BuhMvMUj.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_layout.BuhMvMUj.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_layout.BuhMvMUj.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.0Eln51hV.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_page.0Eln51hV.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.0Eln51hV.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.5IJAEAjc.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_page.5IJAEAjc.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.5IJAEAjc.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BZfe6nWe.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_page.BZfe6nWe.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BZfe6nWe.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.Bj_a_5lv.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_page.Bj_a_5lv.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.Bj_a_5lv.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BwgOqeMo.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_page.BwgOqeMo.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.BwgOqeMo.css.gz +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.CFnbmY-D.css +0 -6
- package/frontend/build/client/_app/immutable/assets/_page.CFnbmY-D.css.br +0 -0
- package/frontend/build/client/_app/immutable/assets/_page.CFnbmY-D.css.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/2zMvi6fR.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/2zMvi6fR.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/3InFPLvE.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/3InFPLvE.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/3InFPLvE.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BAACMRH5.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/BAACMRH5.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BAACMRH5.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BAMUGSh7.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/BAMUGSh7.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BAMUGSh7.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BKuh57WU.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/BKuh57WU.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BKuh57WU.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BUwxRmHf.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/BUwxRmHf.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BUwxRmHf.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/BmZ9upwL.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/BmZ9upwL.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/C1Vid6wz.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/C1Vid6wz.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/C8OURRSs.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/C8OURRSs.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CGeZlCaI.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CGeZlCaI.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CGeZlCaI.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CKDtmZUQ.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CKDtmZUQ.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CMBQQ9RZ.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CMBQQ9RZ.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CMBQQ9RZ.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CMEtqUfQ.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CMEtqUfQ.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CMEtqUfQ.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CNdcuGR0.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CNdcuGR0.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CUC98kMZ.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CUC98kMZ.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CUC98kMZ.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CgnwuKKO.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CgnwuKKO.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CgnwuKKO.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/Co3xKhEp.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/Co3xKhEp.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/Co3xKhEp.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CuqnZUex.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CuqnZUex.js.br +0 -5
- package/frontend/build/client/_app/immutable/chunks/CuqnZUex.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/CzlPaHY9.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/CzlPaHY9.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/CzlPaHY9.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DCgHuuvs.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DCgHuuvs.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DDZw0L0T.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DDZw0L0T.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DHM6H-es.js +0 -7
- package/frontend/build/client/_app/immutable/chunks/DHM6H-es.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DHM6H-es.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DMZwI8Cj.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DMZwI8Cj.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DSLBMEpr.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/DSLBMEpr.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DSLBMEpr.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/DbgD7JLa.js +0 -6
- package/frontend/build/client/_app/immutable/chunks/DbgD7JLa.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/DbgD7JLa.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/TOCyHP97.js +0 -11
- package/frontend/build/client/_app/immutable/chunks/TOCyHP97.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/TOCyHP97.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/kkA1mrsH.js +0 -8
- package/frontend/build/client/_app/immutable/chunks/kkA1mrsH.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/kkA1mrsH.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/t-La0hgu.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/t-La0hgu.js.gz +0 -0
- package/frontend/build/client/_app/immutable/chunks/w0D4Uzlq.js.br +0 -0
- package/frontend/build/client/_app/immutable/chunks/w0D4Uzlq.js.gz +0 -0
- package/frontend/build/client/_app/immutable/entry/app.KrtMZ3my.js +0 -7
- package/frontend/build/client/_app/immutable/entry/app.KrtMZ3my.js.br +0 -0
- package/frontend/build/client/_app/immutable/entry/app.KrtMZ3my.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/0.C8DodwXs.js +0 -11
- package/frontend/build/client/_app/immutable/nodes/0.C8DodwXs.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/0.C8DodwXs.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/1.Df9sLw8b.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/1.Df9sLw8b.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/10.DEbnxfND.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/10.DEbnxfND.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/10.DEbnxfND.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/11.BViaDK2m.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/11.BViaDK2m.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/11.BViaDK2m.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/12.BMSCSd88.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/12.BMSCSd88.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/12.BMSCSd88.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/2.BCPSg7H4.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/2.BCPSg7H4.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/3.8BFAJoHT.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/3.8BFAJoHT.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/4.D-YT_JJe.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/4.D-YT_JJe.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/4.D-YT_JJe.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/5.DVeH2eQP.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/5.DVeH2eQP.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/5.DVeH2eQP.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/6.DI7-IJhN.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/6.DI7-IJhN.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/6.DI7-IJhN.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/7.C-pKvVZy.js +0 -6
- package/frontend/build/client/_app/immutable/nodes/7.C-pKvVZy.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/7.C-pKvVZy.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/8.93Mb3ofT.js +0 -9
- package/frontend/build/client/_app/immutable/nodes/8.93Mb3ofT.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/8.93Mb3ofT.js.gz +0 -0
- package/frontend/build/client/_app/immutable/nodes/9.CvfGx3Hu.js.br +0 -0
- package/frontend/build/client/_app/immutable/nodes/9.CvfGx3Hu.js.gz +0 -0
- package/frontend/build/server/chunks/0-D5YWFygh.js +0 -22
- package/frontend/build/server/chunks/0-D5YWFygh.js.map +0 -5
- package/frontend/build/server/chunks/10-l6_ikL_D.js +0 -14
- package/frontend/build/server/chunks/10-l6_ikL_D.js.map +0 -5
- package/frontend/build/server/chunks/11-CNLerze_.js +0 -14
- package/frontend/build/server/chunks/11-CNLerze_.js.map +0 -5
- package/frontend/build/server/chunks/12-De6Ol6pu.js +0 -14
- package/frontend/build/server/chunks/12-De6Ol6pu.js.map +0 -5
- package/frontend/build/server/chunks/2-Dc_rKWoK.js +0 -14
- package/frontend/build/server/chunks/3-DrRqVrcX.js +0 -14
- package/frontend/build/server/chunks/3-DrRqVrcX.js.map +0 -5
- package/frontend/build/server/chunks/4-Bo04DC5Z.js +0 -14
- package/frontend/build/server/chunks/4-Bo04DC5Z.js.map +0 -5
- package/frontend/build/server/chunks/5-CFeE5dPZ.js +0 -14
- package/frontend/build/server/chunks/5-CFeE5dPZ.js.map +0 -5
- package/frontend/build/server/chunks/6-DZk37MZH.js +0 -14
- package/frontend/build/server/chunks/6-DZk37MZH.js.map +0 -5
- package/frontend/build/server/chunks/7-DiQJZEF_.js +0 -14
- package/frontend/build/server/chunks/7-DiQJZEF_.js.map +0 -5
- package/frontend/build/server/chunks/8-CKPVFOqJ.js +0 -14
- package/frontend/build/server/chunks/8-CKPVFOqJ.js.map +0 -5
- package/frontend/build/server/chunks/9-DirZG_Lu.js +0 -14
- package/frontend/build/server/chunks/BackLink-BJ8NaemM.js.map +0 -5
- package/frontend/build/server/chunks/Badge-44ZTDx0V.js.map +0 -5
- package/frontend/build/server/chunks/ConfirmModal-C0EAXcq_.js.map +0 -5
- package/frontend/build/server/chunks/EmptyState-BA_eXaeR.js.map +0 -5
- package/frontend/build/server/chunks/Modal-DChG187n.js.map +0 -5
- package/frontend/build/server/chunks/Toast-v-q4ZnYq.js.map +0 -5
- package/frontend/build/server/chunks/_layout.svelte-CHVI3Prt.js +0 -29
- package/frontend/build/server/chunks/_layout.svelte-CHVI3Prt.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-1as75nPc.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-1jo8MapI.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-8gELc_B1.js +0 -729
- package/frontend/build/server/chunks/_page.svelte-8gELc_B1.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-BuFusRK1.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-CAVyp70V.js +0 -250
- package/frontend/build/server/chunks/_page.svelte-CAVyp70V.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-CB8-QBNg.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-CWWeZuid.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-D3E6Eojd.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-Kg69DDaM.js.map +0 -5
- package/frontend/build/server/chunks/_page.svelte-L9fuiN_q.js +0 -57
- package/frontend/build/server/chunks/_page.svelte-L9fuiN_q.js.map +0 -5
- package/frontend/build/server/chunks/common-DYYTVHPw.js.map +0 -5
- package/frontend/build/server/chunks/constants-CXTaQaB6.js.map +0 -5
- package/frontend/build/server/chunks/reports2-BtElN_53.js.map +0 -5
- package/frontend/build/server/chunks/repository-FYYV_vKE.js.map +0 -5
- package/frontend/build/server/chunks/runner-DC7hXbnY.js +0 -37
- package/frontend/build/server/chunks/runner-DC7hXbnY.js.map +0 -5
- package/frontend/src/lib/components/ui/Toast.svelte +0 -24
- /package/frontend/.svelte-kit/output/client/_app/immutable/assets/{3.BR3wgXcZ.css → 4.BR3wgXcZ.css} +0 -0
- /package/frontend/build/client/_app/immutable/assets/{3.BR3wgXcZ.css → 4.BR3wgXcZ.css} +0 -0
- /package/frontend/build/client/_app/immutable/assets/{3.BR3wgXcZ.css.br → 4.BR3wgXcZ.css.br} +0 -0
- /package/frontend/build/client/_app/immutable/assets/{3.BR3wgXcZ.css.gz → 4.BR3wgXcZ.css.gz} +0 -0
|
@@ -8,30 +8,18 @@
|
|
|
8
8
|
// mirrors backend/constants/socketEvents.js by hand — keep both in sync when
|
|
9
9
|
// adding or renaming an event.
|
|
10
10
|
export const SOCKET_EVENTS = Object.freeze({
|
|
11
|
-
//
|
|
11
|
+
// Client → server: request a run / cancel a run by id
|
|
12
12
|
RUN_TEST: 'run-test',
|
|
13
13
|
CANCEL_TEST: 'cancel-test',
|
|
14
|
-
LOG: 'log',
|
|
15
|
-
DONE: 'done',
|
|
16
14
|
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
RUNNER_LANE_LOG: 'runner-lane-log',
|
|
20
|
-
RUNNER_LANE_STATUS: 'runner-lane-status',
|
|
21
|
-
|
|
22
|
-
// Background runs (cron / REST / MCP triggered, no single owning socket)
|
|
15
|
+
// Server → every client: one run's lifecycle, keyed by runId
|
|
16
|
+
BG_RUN_QUEUED: 'bg-run-queued',
|
|
23
17
|
BG_RUN_START: 'bg-run-start',
|
|
24
18
|
BG_RUN_LOG: 'bg-run-log',
|
|
25
19
|
BG_RUN_DONE: 'bg-run-done',
|
|
26
20
|
BG_RUN_LANES_INIT: 'bg-run-lanes-init',
|
|
27
21
|
BG_RUN_LANE_LOG: 'bg-run-lane-log',
|
|
28
22
|
BG_RUN_LANE_STATUS: 'bg-run-lane-status',
|
|
29
|
-
|
|
30
|
-
// Live rrweb streaming — one shape for every run type, always
|
|
31
|
-
// carrying a lane id (BUILT_IN_RUNNER_ID for the plain single-run case) and
|
|
32
|
-
// a workerId, so a single built-in run with --parallel workers is finally
|
|
33
|
-
// attributable per worker instead of one flat interleaved stream.
|
|
34
|
-
RUNNER_LANE_RRWEB_BATCH: 'runner-lane-rrweb-batch',
|
|
35
23
|
BG_RUN_LANE_RRWEB_BATCH: 'bg-run-lane-rrweb-batch',
|
|
36
24
|
|
|
37
25
|
// Global notifications (any client, not tied to a specific run)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Plum.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { writable } from 'svelte/store';
|
|
7
|
+
import { TOAST_TIMEOUT_MS } from '$lib/constants';
|
|
8
|
+
|
|
9
|
+
// { id, type: 'success' | 'error' | 'info', message, sticky }
|
|
10
|
+
export const notifications = writable([]);
|
|
11
|
+
|
|
12
|
+
let seq = 0;
|
|
13
|
+
|
|
14
|
+
export function notify(type, message, { sticky = false, timeout = TOAST_TIMEOUT_MS } = {}) {
|
|
15
|
+
const id = ++seq;
|
|
16
|
+
notifications.update((list) => [...list, { id, type, message, sticky }]);
|
|
17
|
+
if (!sticky) setTimeout(() => dismissNotification(id), timeout);
|
|
18
|
+
return id;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function dismissNotification(id) {
|
|
22
|
+
notifications.update((list) => list.filter((n) => n.id !== id));
|
|
23
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Plum.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { writable, get } from 'svelte/store';
|
|
7
|
+
import { renderReplayToWebM } from '$lib/utils/replayVideo';
|
|
8
|
+
import { downloadBlob } from '$lib/utils/download';
|
|
9
|
+
|
|
10
|
+
// null when idle; otherwise { status, progress, filename, error }.
|
|
11
|
+
// status: 'rendering' | 'done' | 'error'
|
|
12
|
+
export const replayVideoJob = writable(null);
|
|
13
|
+
|
|
14
|
+
let cancelled = false;
|
|
15
|
+
|
|
16
|
+
export function cancelReplayVideo() {
|
|
17
|
+
cancelled = true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function dismissReplayVideo() {
|
|
21
|
+
replayVideoJob.set(null);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** `replayer` is the live rrweb replayer to record; it is not retained. */
|
|
25
|
+
export async function startReplayVideo({ replayer, durationMs, filename }) {
|
|
26
|
+
if (get(replayVideoJob)?.status === 'rendering') return;
|
|
27
|
+
cancelled = false;
|
|
28
|
+
replayVideoJob.set({ status: 'rendering', progress: 0, filename });
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const blob = await renderReplayToWebM({
|
|
32
|
+
replayer,
|
|
33
|
+
durationMs,
|
|
34
|
+
onProgress: (p) => replayVideoJob.update((j) => (j ? { ...j, progress: p } : j)),
|
|
35
|
+
shouldCancel: () => cancelled
|
|
36
|
+
});
|
|
37
|
+
if (cancelled) {
|
|
38
|
+
replayVideoJob.set(null);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
downloadBlob(blob, filename);
|
|
42
|
+
replayVideoJob.set({ status: 'done', progress: 1, filename });
|
|
43
|
+
setTimeout(() => replayVideoJob.update((j) => (j?.status === 'done' ? null : j)), 6000);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
if (cancelled || e.message === 'Cancelled.') {
|
|
46
|
+
replayVideoJob.set(null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
replayVideoJob.set({ status: 'error', progress: 0, filename, error: e.message });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -4,31 +4,45 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { writable, get } from 'svelte/store';
|
|
7
|
-
import { BROWSERS } from '$lib/constants';
|
|
7
|
+
import { BROWSERS, TRIGGER_TYPES } from '$lib/constants';
|
|
8
8
|
import { SOCKET_EVENTS } from '$lib/socketEvents';
|
|
9
|
+
import { MANUAL_RUN_LABEL } from '$lib/copy/runners';
|
|
9
10
|
import { auth } from './auth';
|
|
10
11
|
|
|
11
12
|
export const socket = writable(null);
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
14
|
+
// runId → run entry. One store for every run whatever its origin (manual, cron,
|
|
15
|
+
// REST, MCP): each is a queued job streamed over the bg-run-* events. Seeded
|
|
16
|
+
// optimistically by triggerRun, then kept current by the socket handlers in
|
|
17
|
+
// RunnerPanel.
|
|
18
|
+
export const backgroundRuns = writable({});
|
|
19
|
+
|
|
20
|
+
export function makeRunEntry({ kind, label, meta, status }) {
|
|
21
|
+
return {
|
|
22
|
+
kind,
|
|
23
|
+
label,
|
|
24
|
+
status, // 'queued' | 'running' | 'done'
|
|
25
|
+
testCompleted: false,
|
|
26
|
+
latestReportId: null,
|
|
27
|
+
verdict: 'idle', // 'idle' | 'pass' | 'fail' | 'cancelled'
|
|
28
|
+
output: '',
|
|
29
|
+
lanes: [], // [{ id, name, testCount, status, logs }]
|
|
30
|
+
currentRun: {
|
|
31
|
+
tag: meta?.tag ?? '',
|
|
32
|
+
workers: meta?.workers,
|
|
33
|
+
browser: meta?.browser,
|
|
34
|
+
runTitle: label,
|
|
35
|
+
startedBy: meta?.startedBy ?? null
|
|
36
|
+
},
|
|
37
|
+
// { [laneId]: { [workerId]: { events: [] } } } — always keyed by laneId
|
|
38
|
+
// even for a single-runner run, so the live view's Runner/Worker tabs
|
|
39
|
+
// don't need a separate code path for that case.
|
|
40
|
+
rrwebByLane: {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
27
43
|
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// reference, so this rebuilds the path down to the mutated bucket rather than
|
|
31
|
-
// pushing in place. Shared by runnerState (interactive) and backgroundRuns.
|
|
44
|
+
// Rebuilds the path down to the mutated bucket (Svelte only re-renders on a new
|
|
45
|
+
// reference) rather than pushing in place.
|
|
32
46
|
export function mergeRRwebBatch(rrwebByLane, { id: laneId, workerId, events }) {
|
|
33
47
|
const lane = rrwebByLane[laneId] ?? {};
|
|
34
48
|
const worker = lane[workerId] ?? { events: [] };
|
|
@@ -41,10 +55,6 @@ export function mergeRRwebBatch(rrwebByLane, { id: laneId, workerId, events }) {
|
|
|
41
55
|
};
|
|
42
56
|
}
|
|
43
57
|
|
|
44
|
-
export function appendRRwebBatch(batch) {
|
|
45
|
-
runnerState.update((s) => ({ ...s, rrwebByLane: mergeRRwebBatch(s.rrwebByLane, batch) }));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
58
|
export const runnerConfig = writable({
|
|
49
59
|
workers: 1,
|
|
50
60
|
testID: '',
|
|
@@ -59,34 +69,31 @@ export const builtInEnabled = writable(true);
|
|
|
59
69
|
export const reportsVersion = writable(0);
|
|
60
70
|
export const runsVersion = writable(0);
|
|
61
71
|
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// runs) — these are spawned server-side with no single browser socket to
|
|
65
|
-
// stream to, so they're tracked separately from `runnerState`.
|
|
66
|
-
export const backgroundRuns = writable({});
|
|
67
|
-
|
|
72
|
+
// Enqueues a run and returns its id so the caller can navigate to /live/<id>.
|
|
73
|
+
// The run stays `queued` until every runner it targets is free.
|
|
68
74
|
export function triggerRun(id, testRunId, notify = {}, runTitle = null) {
|
|
69
75
|
const s = get(socket);
|
|
70
|
-
if (!s) return;
|
|
76
|
+
if (!s) return null;
|
|
71
77
|
|
|
72
78
|
const { workers, testID, browser, selectedRunners } = get(runnerConfig);
|
|
73
|
-
const
|
|
79
|
+
const tag = (id !== undefined ? id : testID).trim().replace(/\sOR\s/gi, (m) => m.toLowerCase());
|
|
80
|
+
const runId = crypto.randomUUID();
|
|
81
|
+
const startedBy = get(auth).user?.name ?? null;
|
|
74
82
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
rrwebByLane: {}
|
|
85
|
-
});
|
|
83
|
+
backgroundRuns.update((r) => ({
|
|
84
|
+
...r,
|
|
85
|
+
[runId]: makeRunEntry({
|
|
86
|
+
kind: TRIGGER_TYPES.MANUAL,
|
|
87
|
+
label: runTitle || tag || MANUAL_RUN_LABEL,
|
|
88
|
+
meta: { tag, workers, browser, startedBy },
|
|
89
|
+
status: 'queued'
|
|
90
|
+
})
|
|
91
|
+
}));
|
|
86
92
|
panelExpanded.set(true);
|
|
87
93
|
|
|
88
94
|
s.emit(SOCKET_EVENTS.RUN_TEST, {
|
|
89
|
-
|
|
95
|
+
runId,
|
|
96
|
+
tag,
|
|
90
97
|
workers,
|
|
91
98
|
browser,
|
|
92
99
|
runners: selectedRunners,
|
|
@@ -94,11 +101,20 @@ export function triggerRun(id, testRunId, notify = {}, runTitle = null) {
|
|
|
94
101
|
notifyDiscord: notify.notifyDiscord ?? false,
|
|
95
102
|
notifySlack: notify.notifySlack ?? false,
|
|
96
103
|
runTitle,
|
|
97
|
-
startedBy
|
|
104
|
+
startedBy
|
|
98
105
|
});
|
|
106
|
+
|
|
107
|
+
return runId;
|
|
99
108
|
}
|
|
100
109
|
|
|
101
|
-
export function cancelRun() {
|
|
110
|
+
export function cancelRun(id) {
|
|
102
111
|
const s = get(socket);
|
|
103
|
-
if (s) s.emit(SOCKET_EVENTS.CANCEL_TEST);
|
|
112
|
+
if (s && id) s.emit(SOCKET_EVENTS.CANCEL_TEST, { runId: id });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Cron runs get a generated run id, not the task name — match one by kind + label.
|
|
116
|
+
export function findActiveCronRun(runs, taskName) {
|
|
117
|
+
return Object.values(runs).find(
|
|
118
|
+
(r) => r.kind === TRIGGER_TYPES.CRON && r.label === taskName && r.status !== 'done'
|
|
119
|
+
);
|
|
104
120
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Plum.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function downloadBlob(blob, filename) {
|
|
7
|
+
const url = URL.createObjectURL(blob);
|
|
8
|
+
const a = document.createElement('a');
|
|
9
|
+
a.href = url;
|
|
10
|
+
a.download = filename;
|
|
11
|
+
document.body.appendChild(a);
|
|
12
|
+
a.click();
|
|
13
|
+
a.remove();
|
|
14
|
+
// Revoking synchronously can cancel the download in some browsers.
|
|
15
|
+
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function filenameFromDisposition(header, fallback) {
|
|
19
|
+
const match = /filename="?([^"]+)"?/.exec(header ?? '');
|
|
20
|
+
return match ? match[1] : fallback;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function downloadFromEndpoint(url, { headers = {}, fallbackName = 'export' } = {}) {
|
|
24
|
+
const res = await fetch(url, { headers });
|
|
25
|
+
if (!res.ok) throw new Error('Export failed');
|
|
26
|
+
const blob = await res.blob();
|
|
27
|
+
downloadBlob(blob, filenameFromDisposition(res.headers.get('Content-Disposition'), fallbackName));
|
|
28
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Plum.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as htmlToImage from 'html-to-image';
|
|
7
|
+
|
|
8
|
+
function toBase64(buffer) {
|
|
9
|
+
const bytes = new Uint8Array(buffer);
|
|
10
|
+
let binary = '';
|
|
11
|
+
for (let i = 0; i < bytes.length; i += 0x8000) {
|
|
12
|
+
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + 0x8000));
|
|
13
|
+
}
|
|
14
|
+
return btoa(binary);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const fontMime = (url) =>
|
|
18
|
+
url.includes('woff2') ? 'font/woff2' : url.includes('woff') ? 'font/woff' : 'font/ttf';
|
|
19
|
+
|
|
20
|
+
const FONT_FACE_RE = /@font-face\s*{[^}]*}/g;
|
|
21
|
+
|
|
22
|
+
async function faceTextsFromHref(href) {
|
|
23
|
+
if (!href) return [];
|
|
24
|
+
try {
|
|
25
|
+
const css = await fetch(href).then((r) => r.text());
|
|
26
|
+
return css.match(FONT_FACE_RE) ?? [];
|
|
27
|
+
} catch {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// html-to-image's own font embedding misses @font-face rules from a cross-origin
|
|
33
|
+
// stylesheet (the tested page's Google Fonts <link>) — the capture then falls
|
|
34
|
+
// back to a default face. Re-fetch the CORS-blocked sheets by URL ourselves.
|
|
35
|
+
export async function collectFontEmbedCSS(doc) {
|
|
36
|
+
const rules = [];
|
|
37
|
+
for (const sheet of doc.styleSheets) {
|
|
38
|
+
let cssRules;
|
|
39
|
+
try {
|
|
40
|
+
cssRules = sheet.cssRules;
|
|
41
|
+
} catch {
|
|
42
|
+
rules.push(...(await faceTextsFromHref(sheet.href)));
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
for (const rule of cssRules) {
|
|
46
|
+
if (rule.type === 5 || rule.constructor?.name === 'CSSFontFaceRule') {
|
|
47
|
+
rules.push(rule.cssText);
|
|
48
|
+
} else if (rule.type === 3 && rule.href) {
|
|
49
|
+
let reachable = true;
|
|
50
|
+
try {
|
|
51
|
+
void rule.styleSheet.cssRules;
|
|
52
|
+
} catch {
|
|
53
|
+
reachable = false;
|
|
54
|
+
}
|
|
55
|
+
if (!reachable) rules.push(...(await faceTextsFromHref(rule.href)));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const cache = new Map();
|
|
61
|
+
const out = [];
|
|
62
|
+
for (let text of rules) {
|
|
63
|
+
const urls = [...text.matchAll(/url\((['"]?)(https?:\/\/[^'")]+)\1\)/g)].map((m) => m[2]);
|
|
64
|
+
for (const url of urls) {
|
|
65
|
+
try {
|
|
66
|
+
if (!cache.has(url)) {
|
|
67
|
+
const buf = await fetch(url).then((r) => r.arrayBuffer());
|
|
68
|
+
cache.set(url, `data:${fontMime(url)};base64,${toBase64(buf)}`);
|
|
69
|
+
}
|
|
70
|
+
text = text.split(url).join(cache.get(url));
|
|
71
|
+
} catch {
|
|
72
|
+
// unreachable font — leave the original url, the face just won't embed
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
out.push(text);
|
|
76
|
+
}
|
|
77
|
+
return out.join('\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** PNG blob of whatever the given rrweb replayer is currently showing. */
|
|
81
|
+
export async function captureReplayFrame(replayer) {
|
|
82
|
+
const doc = replayer?.iframe?.contentDocument;
|
|
83
|
+
if (!doc?.documentElement) throw new Error('Nothing to capture yet — let the replay load first.');
|
|
84
|
+
const fontEmbedCSS = await collectFontEmbedCSS(doc).catch(() => '');
|
|
85
|
+
const blob = await htmlToImage.toBlob(doc.documentElement, {
|
|
86
|
+
backgroundColor: '#ffffff',
|
|
87
|
+
fontEmbedCSS
|
|
88
|
+
});
|
|
89
|
+
if (!blob) throw new Error('Could not capture this frame.');
|
|
90
|
+
return blob;
|
|
91
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Plum.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as htmlToImage from 'html-to-image';
|
|
7
|
+
import fixWebmDuration from 'fix-webm-duration';
|
|
8
|
+
import { collectFontEmbedCSS } from './replayCapture';
|
|
9
|
+
|
|
10
|
+
const FPS = 12;
|
|
11
|
+
const TAIL_MS = 400;
|
|
12
|
+
|
|
13
|
+
const supportedMime = () =>
|
|
14
|
+
['video/webm;codecs=vp9', 'video/webm;codecs=vp8', 'video/webm'].find((m) =>
|
|
15
|
+
MediaRecorder.isTypeSupported(m)
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Records the already-loaded replayer to a WebM blob in the browser — nothing is
|
|
20
|
+
* uploaded. Plays it through in real time (so a mid-recording navigation applies
|
|
21
|
+
* the same as normal playback) while html-to-image snapshots each frame onto a
|
|
22
|
+
* canvas the MediaRecorder samples at FPS; a slow snapshot just repeats the
|
|
23
|
+
* previous frame, so the clip stays the right length.
|
|
24
|
+
*
|
|
25
|
+
* A second rrweb player can't be spun up off-screen for this (two instances
|
|
26
|
+
* fight over shared module state and the hidden one renders blank), so it drives
|
|
27
|
+
* the visible replayer and the caller restores its position afterwards.
|
|
28
|
+
*/
|
|
29
|
+
export async function renderReplayToWebM({ replayer, durationMs, onProgress, shouldCancel }) {
|
|
30
|
+
const iframe = replayer?.iframe;
|
|
31
|
+
if (!iframe?.contentDocument?.documentElement) throw new Error('The replay is not ready yet.');
|
|
32
|
+
if (!durationMs || durationMs < 200) throw new Error('This recording is too short to record.');
|
|
33
|
+
if (typeof MediaRecorder === 'undefined') throw new Error("This browser can't record video.");
|
|
34
|
+
const mime = supportedMime();
|
|
35
|
+
if (!mime) throw new Error("This browser can't record WebM video.");
|
|
36
|
+
|
|
37
|
+
const w = Math.max(320, iframe.offsetWidth || 1280);
|
|
38
|
+
const h = Math.max(240, iframe.offsetHeight || 720);
|
|
39
|
+
const canvas = document.createElement('canvas');
|
|
40
|
+
canvas.width = w;
|
|
41
|
+
canvas.height = h;
|
|
42
|
+
const ctx = canvas.getContext('2d');
|
|
43
|
+
const paintWhite = () => {
|
|
44
|
+
ctx.fillStyle = '#ffffff';
|
|
45
|
+
ctx.fillRect(0, 0, w, h);
|
|
46
|
+
};
|
|
47
|
+
paintWhite();
|
|
48
|
+
|
|
49
|
+
const fontEmbedCSS = await collectFontEmbedCSS(iframe.contentDocument).catch(() => '');
|
|
50
|
+
|
|
51
|
+
const recorder = new MediaRecorder(canvas.captureStream(FPS), {
|
|
52
|
+
mimeType: mime,
|
|
53
|
+
videoBitsPerSecond: 3_500_000
|
|
54
|
+
});
|
|
55
|
+
const chunks = [];
|
|
56
|
+
recorder.ondataavailable = (e) => e.data.size && chunks.push(e.data);
|
|
57
|
+
const stopped = new Promise((res) => (recorder.onstop = res));
|
|
58
|
+
recorder.start(250);
|
|
59
|
+
|
|
60
|
+
replayer.play(0);
|
|
61
|
+
const start = performance.now();
|
|
62
|
+
let capturing = false;
|
|
63
|
+
let renderedMs = 0;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
await new Promise((resolve, reject) => {
|
|
67
|
+
function tick() {
|
|
68
|
+
if (shouldCancel?.()) return reject(new Error('Cancelled.'));
|
|
69
|
+
renderedMs = performance.now() - start;
|
|
70
|
+
onProgress?.(Math.min(1, renderedMs / durationMs));
|
|
71
|
+
|
|
72
|
+
if (!capturing) {
|
|
73
|
+
capturing = true;
|
|
74
|
+
htmlToImage
|
|
75
|
+
.toCanvas(iframe.contentDocument.documentElement, {
|
|
76
|
+
width: w,
|
|
77
|
+
height: h,
|
|
78
|
+
backgroundColor: '#ffffff',
|
|
79
|
+
fontEmbedCSS
|
|
80
|
+
})
|
|
81
|
+
.then((frame) => {
|
|
82
|
+
paintWhite();
|
|
83
|
+
ctx.drawImage(frame, 0, 0, w, h);
|
|
84
|
+
})
|
|
85
|
+
.catch(() => {})
|
|
86
|
+
.finally(() => {
|
|
87
|
+
capturing = false;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (renderedMs >= durationMs + TAIL_MS) resolve();
|
|
92
|
+
else requestAnimationFrame(tick);
|
|
93
|
+
}
|
|
94
|
+
requestAnimationFrame(tick);
|
|
95
|
+
});
|
|
96
|
+
} finally {
|
|
97
|
+
recorder.stop();
|
|
98
|
+
await stopped;
|
|
99
|
+
try {
|
|
100
|
+
replayer.pause(0);
|
|
101
|
+
} catch {
|
|
102
|
+
// caller rebuilds the player anyway
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
onProgress?.(1);
|
|
107
|
+
const raw = new Blob(chunks, { type: mime });
|
|
108
|
+
// MediaRecorder WebM carries no duration in its header — players show it as
|
|
109
|
+
// unseekable / 0:00 until playback ends. Patch the EBML so the file behaves.
|
|
110
|
+
return fixWebmDuration(raw, Math.round(renderedMs), { logger: false }).catch(() => raw);
|
|
111
|
+
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import Nav from '$lib/components/layout/Nav.svelte';
|
|
12
12
|
import PageShell from '$lib/components/layout/PageShell.svelte';
|
|
13
13
|
import RunnerPanel from '$lib/components/layout/RunnerPanel.svelte';
|
|
14
|
+
import NotificationStack from '$lib/components/ui/NotificationStack.svelte';
|
|
14
15
|
import { auth } from '$lib/stores/auth';
|
|
15
16
|
import { checkNeedsSetup } from '$lib/api/auth';
|
|
16
17
|
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
<slot />
|
|
52
53
|
</PageShell>
|
|
53
54
|
<RunnerPanel />
|
|
55
|
+
<NotificationStack />
|
|
54
56
|
{/if}
|
|
55
57
|
{:else}
|
|
56
58
|
<div class="boot-loading">Loading…</div>
|