@svgrid/enterprise 2.5.2 → 2.6.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/dist/SvAlertRuleEditor.svelte.d.ts +13 -0
- package/dist/SvAlertsManager.svelte.d.ts +14 -0
- package/dist/SvAlertsPanel.svelte.d.ts +9 -0
- package/dist/SvAuthGate.svelte.d.ts +22 -0
- package/dist/SvBoard.svelte.d.ts +35 -0
- package/dist/SvExportMenu.svelte.d.ts +61 -0
- package/dist/SvExpressionEditor.svelte.d.ts +12 -0
- package/dist/SvFileInput.svelte.d.ts +20 -0
- package/dist/SvGridAlerts.svelte.d.ts +77 -0
- package/dist/SvGridBoard.svelte.d.ts +30 -0
- package/dist/SvGridEditPanel.svelte.d.ts +73 -0
- package/dist/SvGridMasterDetail.svelte.d.ts +49 -0
- package/dist/SvGridScheduler.svelte.d.ts +30 -0
- package/dist/SvImportDialog.svelte.d.ts +88 -0
- package/dist/SvLookupInput.svelte.d.ts +21 -0
- package/dist/SvPivotDesigner.svelte.d.ts +176 -0
- package/dist/SvRecordDetail.svelte.d.ts +58 -0
- package/dist/SvSchedule.svelte.d.ts +29 -0
- package/dist/SvSchemaChart.svelte.d.ts +61 -0
- package/dist/SvSchemaDashboard.svelte.d.ts +46 -0
- package/dist/alerts/alert-engine-attach.d.ts +79 -0
- package/dist/alerts/alert-engine-attach.js +106 -0
- package/dist/alerts/alert-engine.d.ts +42 -0
- package/dist/alerts/alert-engine.js +196 -0
- package/dist/alerts/alert-formats.d.ts +26 -0
- package/dist/alerts/alert-formats.js +58 -0
- package/dist/alerts/alert-observer.d.ts +54 -0
- package/dist/alerts/alert-observer.js +156 -0
- package/dist/alerts/alert-scheduler.d.ts +30 -0
- package/dist/alerts/alert-scheduler.js +54 -0
- package/dist/alerts/alert-storage.d.ts +31 -0
- package/dist/alerts/alert-storage.js +92 -0
- package/dist/alerts/alert-store.svelte.d.ts +24 -0
- package/dist/alerts/alert-store.svelte.js +69 -0
- package/dist/alerts/alert-types.d.ts +86 -0
- package/dist/alerts/alert-types.js +1 -0
- package/dist/alerts.d.ts +2 -0
- package/{src/alerts.ts → dist/alerts.js} +9 -9
- package/dist/board.d.ts +7 -0
- package/{src/board.ts → dist/board.js} +13 -14
- package/dist/cdn/svgrid-enterprise.svelte-external.js +2987 -2981
- package/dist/designer/assets/{index-CM5xvaOy.js → index-BF0UH638.js} +3 -3
- package/dist/designer/assets/{src-D-ET9Mmo.js → src-BPJruwB9.js} +184 -184
- package/dist/designer/index.html +2 -2
- package/dist/edit-panel.d.ts +105 -0
- package/dist/edit-panel.js +350 -0
- package/dist/export-conditional.d.ts +31 -0
- package/dist/export-conditional.js +65 -0
- package/dist/export-ooxml.d.ts +93 -0
- package/dist/export-ooxml.js +385 -0
- package/dist/export-pdf.d.ts +107 -0
- package/dist/export-pdf.js +144 -0
- package/dist/export-print.d.ts +55 -0
- package/dist/export-print.js +91 -0
- package/{src/export-serialize.ts → dist/export-serialize.d.ts} +11 -24
- package/dist/export-serialize.js +11 -0
- package/dist/export-xls.d.ts +26 -0
- package/dist/export-xls.js +157 -0
- package/dist/export.d.ts +323 -0
- package/dist/export.js +1021 -0
- package/dist/expressions/evaluate.d.ts +17 -0
- package/dist/expressions/evaluate.js +214 -0
- package/dist/expressions/expression-columns.d.ts +61 -0
- package/dist/expressions/expression-columns.js +72 -0
- package/dist/expressions/expression-types.d.ts +125 -0
- package/dist/expressions/expression-types.js +1 -0
- package/dist/expressions/parse.d.ts +25 -0
- package/dist/expressions/parse.js +537 -0
- package/dist/import.d.ts +232 -0
- package/dist/import.js +846 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +91 -0
- package/dist/install.d.ts +70 -0
- package/dist/install.js +61 -0
- package/dist/license-core.d.ts +37 -0
- package/dist/license-core.js +81 -0
- package/dist/license.d.ts +30 -0
- package/dist/license.js +139 -0
- package/dist/master-detail.d.ts +23 -0
- package/dist/master-detail.js +35 -0
- package/dist/node/studio.js +1 -1
- package/dist/pivot-chart.d.ts +28 -0
- package/dist/pivot-chart.js +71 -0
- package/dist/pivot-designer.d.ts +69 -0
- package/dist/pivot-designer.js +38 -0
- package/dist/pivot-enable.d.ts +6 -0
- package/{src/pivot-enable.ts → dist/pivot-enable.js} +13 -18
- package/dist/pivot.d.ts +111 -0
- package/dist/pivot.js +353 -0
- package/dist/print.d.ts +33 -0
- package/dist/print.js +61 -0
- package/dist/revoked.d.ts +1 -0
- package/{src/revoked.ts → dist/revoked.js} +5 -6
- package/dist/scheduler-assignments.d.ts +64 -0
- package/dist/scheduler-assignments.js +92 -0
- package/dist/scheduler-axis.d.ts +81 -0
- package/dist/scheduler-axis.js +180 -0
- package/{src/scheduler-booking.ts → dist/scheduler-booking.d.ts} +10 -43
- package/dist/scheduler-booking.js +50 -0
- package/dist/scheduler-config.d.ts +177 -0
- package/dist/scheduler-config.js +1 -0
- package/dist/scheduler-dependencies.d.ts +89 -0
- package/dist/scheduler-dependencies.js +179 -0
- package/dist/scheduler-freebusy.d.ts +19 -0
- package/{src/scheduler-freebusy.ts → dist/scheduler-freebusy.js} +9 -19
- package/{src/scheduler-heatmap.ts → dist/scheduler-heatmap.d.ts} +12 -35
- package/dist/scheduler-heatmap.js +41 -0
- package/dist/scheduler-resource-tree.d.ts +48 -0
- package/dist/scheduler-resource-tree.js +78 -0
- package/dist/scheduler-slots.d.ts +37 -0
- package/dist/scheduler-slots.js +80 -0
- package/dist/scheduler-summary.d.ts +41 -0
- package/dist/scheduler-summary.js +54 -0
- package/dist/scheduler.d.ts +7 -0
- package/{src/scheduler.ts → dist/scheduler.js} +13 -14
- package/dist/scheduling.d.ts +132 -0
- package/dist/scheduling.js +228 -0
- package/dist/schema-designer.d.ts +42 -0
- package/dist/schema-designer.js +117 -0
- package/dist/schema.d.ts +369 -0
- package/dist/schema.js +216 -0
- package/dist/smart-shim.d.ts +62 -0
- package/dist/smart-shim.js +34 -0
- package/dist/sources/aggregate.d.ts +43 -0
- package/dist/sources/aggregate.js +60 -0
- package/dist/sources/auth-supabase.d.ts +69 -0
- package/dist/sources/auth-supabase.js +39 -0
- package/dist/sources/dashboard.d.ts +65 -0
- package/dist/sources/dashboard.js +95 -0
- package/dist/sources/field-inference.d.ts +23 -0
- package/dist/sources/field-inference.js +52 -0
- package/dist/sources/filters.d.ts +35 -0
- package/dist/sources/filters.js +52 -0
- package/dist/sources/index.d.ts +18 -0
- package/dist/sources/index.js +18 -0
- package/dist/sources/introspect-supabase.d.ts +30 -0
- package/dist/sources/introspect-supabase.js +134 -0
- package/dist/sources/realtime-supabase.d.ts +37 -0
- package/dist/sources/realtime-supabase.js +52 -0
- package/dist/sources/relation-lookup.d.ts +50 -0
- package/dist/sources/relation-lookup.js +77 -0
- package/dist/sources/rest-adapters.d.ts +48 -0
- package/dist/sources/rest-adapters.js +85 -0
- package/dist/sources/rest.d.ts +38 -0
- package/dist/sources/rest.js +86 -0
- package/dist/sources/schema-from-columns.d.ts +37 -0
- package/dist/sources/schema-from-columns.js +48 -0
- package/dist/sources/supabase.d.ts +33 -0
- package/dist/sources/supabase.js +74 -0
- package/dist/sources/with-entity-rules.d.ts +25 -0
- package/dist/sources/with-entity-rules.js +47 -0
- package/dist/sources/with-relation-labels.d.ts +26 -0
- package/dist/sources/with-relation-labels.js +38 -0
- package/dist/staged-editing.d.ts +85 -0
- package/dist/staged-editing.js +0 -0
- package/dist/studio/bug-report.d.ts +61 -0
- package/dist/studio/bug-report.js +126 -0
- package/dist/studio/cli.d.ts +56 -0
- package/dist/studio/cli.js +70 -0
- package/dist/studio/copilot-core.d.ts +22 -0
- package/{src/studio/copilot-core.ts → dist/studio/copilot-core.js} +34 -38
- package/dist/studio/csv.d.ts +36 -0
- package/dist/studio/csv.js +173 -0
- package/dist/studio/db-connect-string.d.ts +45 -0
- package/dist/studio/db-connect-string.js +113 -0
- package/dist/studio/deploy-cli.d.ts +35 -0
- package/dist/studio/deploy-cli.js +81 -0
- package/dist/studio/emit-project.d.ts +77 -0
- package/dist/studio/emit-project.js +5389 -0
- package/dist/studio/emit-schema.d.ts +110 -0
- package/dist/studio/emit-schema.js +1128 -0
- package/dist/studio/index.d.ts +35 -0
- package/dist/studio/index.js +38 -0
- package/dist/studio/init-flow.d.ts +58 -0
- package/dist/studio/init-flow.js +451 -0
- package/dist/studio/introspect-db.d.ts +47 -0
- package/dist/studio/introspect-db.js +255 -0
- package/dist/studio/introspect-openapi.d.ts +19 -0
- package/dist/studio/introspect-openapi.js +244 -0
- package/dist/studio/introspect-prisma.d.ts +25 -0
- package/dist/studio/introspect-prisma.js +164 -0
- package/dist/studio/introspect.d.ts +35 -0
- package/dist/studio/introspect.js +306 -0
- package/dist/studio/project.d.ts +1327 -0
- package/dist/studio/project.js +1798 -0
- package/dist/studio/sample-data.d.ts +19 -0
- package/dist/studio/sample-data.js +207 -0
- package/dist/studio/samples/ats.d.ts +2 -0
- package/dist/studio/samples/ats.js +194 -0
- package/dist/studio/samples/clinic.d.ts +2 -0
- package/dist/studio/samples/clinic.js +171 -0
- package/dist/studio/samples/crm.d.ts +2 -0
- package/dist/studio/samples/crm.js +280 -0
- package/dist/studio/samples/datasets.d.ts +38 -0
- package/dist/studio/samples/datasets.js +296 -0
- package/dist/studio/samples/ecommerce.d.ts +2 -0
- package/dist/studio/samples/ecommerce.js +178 -0
- package/dist/studio/samples/events.d.ts +2 -0
- package/dist/studio/samples/events.js +192 -0
- package/dist/studio/samples/fleet.d.ts +2 -0
- package/dist/studio/samples/fleet.js +203 -0
- package/dist/studio/samples/gym.d.ts +2 -0
- package/dist/studio/samples/gym.js +205 -0
- package/dist/studio/samples/hr.d.ts +2 -0
- package/dist/studio/samples/hr.js +186 -0
- package/dist/studio/samples/index.d.ts +13 -0
- package/dist/studio/samples/index.js +44 -0
- package/dist/studio/samples/insurance.d.ts +2 -0
- package/dist/studio/samples/insurance.js +220 -0
- package/dist/studio/samples/inventory.d.ts +2 -0
- package/dist/studio/samples/inventory.js +204 -0
- package/dist/studio/samples/invoicing.d.ts +2 -0
- package/dist/studio/samples/invoicing.js +154 -0
- package/dist/studio/samples/library.d.ts +2 -0
- package/dist/studio/samples/library.js +171 -0
- package/dist/studio/samples/live-data.d.ts +5 -0
- package/dist/studio/samples/live-data.js +261 -0
- package/dist/studio/samples/projects.d.ts +2 -0
- package/dist/studio/samples/projects.js +203 -0
- package/dist/studio/samples/realestate.d.ts +2 -0
- package/dist/studio/samples/realestate.js +187 -0
- package/dist/studio/samples/restaurant.d.ts +2 -0
- package/dist/studio/samples/restaurant.js +180 -0
- package/dist/studio/samples/school.d.ts +2 -0
- package/dist/studio/samples/school.js +188 -0
- package/dist/studio/samples/shared.d.ts +142 -0
- package/dist/studio/samples/shared.js +164 -0
- package/dist/studio/samples/starter.d.ts +4 -0
- package/dist/studio/samples/starter.js +237 -0
- package/dist/studio/samples/subscriptions.d.ts +2 -0
- package/dist/studio/samples/subscriptions.js +175 -0
- package/dist/studio/samples/support.d.ts +2 -0
- package/dist/studio/samples/support.js +209 -0
- package/dist/studio/scaffold-app.d.ts +22 -0
- package/{src/studio/scaffold-app.ts → dist/studio/scaffold-app.js} +45 -63
- package/dist/studio/scaffold.d.ts +63 -0
- package/dist/studio/scaffold.js +346 -0
- package/dist/studio/screen-suites.d.ts +193 -0
- package/dist/studio/screen-suites.js +297 -0
- package/dist/studio/themes.d.ts +34 -0
- package/dist/studio/themes.js +41 -0
- package/dist/studio/ui-components.d.ts +89 -0
- package/dist/studio/ui-components.generated.d.ts +29 -0
- package/dist/studio/ui-components.generated.js +7139 -0
- package/dist/studio/ui-components.js +673 -0
- package/dist/studio/user-error.d.ts +23 -0
- package/{src/studio/user-error.ts → dist/studio/user-error.js} +10 -13
- package/dist/studio/verify.d.ts +34 -0
- package/dist/studio/verify.js +47 -0
- package/dist/sveltekit/in-memory.d.ts +14 -0
- package/dist/sveltekit/in-memory.js +113 -0
- package/dist/sveltekit/index.d.ts +6 -0
- package/dist/sveltekit/index.js +5 -0
- package/dist/sveltekit/query-plan.d.ts +44 -0
- package/dist/sveltekit/query-plan.js +76 -0
- package/dist/sveltekit/sql-source.d.ts +47 -0
- package/dist/sveltekit/sql-source.js +106 -0
- package/dist/sveltekit/sql.d.ts +48 -0
- package/dist/sveltekit/sql.js +73 -0
- package/dist/sveltekit/transport.d.ts +209 -0
- package/dist/sveltekit/transport.js +219 -0
- package/{src/sveltekit/types.ts → dist/sveltekit/types.d.ts} +8 -11
- package/dist/sveltekit/types.js +1 -0
- package/dist/upgrade-prompt.d.ts +16 -0
- package/dist/upgrade-prompt.js +141 -0
- package/dist/version.d.ts +13 -0
- package/{src/version.ts → dist/version.js} +1 -1
- package/dist/watermark.d.ts +2 -0
- package/dist/watermark.js +146 -0
- package/package.json +26 -24
- package/src/SvBoard.dom.test.ts +0 -67
- package/src/SvGridAlerts.dom.test.ts +0 -113
- package/src/SvGridEditPanel.dom.test.ts +0 -320
- package/src/SvRecordDetail.dom.test.ts +0 -137
- package/src/SvSchedule.dom.test.ts +0 -57
- package/src/ai-export-pdf.dom.test.ts +0 -77
- package/src/ai-export-xlsx.dom.test.ts +0 -90
- package/src/ai-export.dom.test.ts +0 -114
- package/src/alerts/alert-engine-attach.ts +0 -165
- package/src/alerts/alert-engine.test.ts +0 -135
- package/src/alerts/alert-engine.ts +0 -260
- package/src/alerts/alert-formats.test.ts +0 -87
- package/src/alerts/alert-formats.ts +0 -77
- package/src/alerts/alert-observer.test.ts +0 -189
- package/src/alerts/alert-observer.ts +0 -208
- package/src/alerts/alert-scheduler.ts +0 -96
- package/src/alerts/alert-storage.test.ts +0 -54
- package/src/alerts/alert-storage.ts +0 -116
- package/src/alerts/alert-store.svelte.ts +0 -80
- package/src/alerts/alert-types.ts +0 -94
- package/src/board.dom.test.ts +0 -941
- package/src/edit-panel.test.ts +0 -322
- package/src/edit-panel.ts +0 -379
- package/src/export-conditional.test.ts +0 -60
- package/src/export-conditional.ts +0 -94
- package/src/export-ooxml.test.ts +0 -152
- package/src/export-ooxml.ts +0 -489
- package/src/export-pdf.test.ts +0 -138
- package/src/export-pdf.ts +0 -245
- package/src/export-print.test.ts +0 -66
- package/src/export-print.ts +0 -132
- package/src/export-serialize.test.ts +0 -56
- package/src/export-xls.ts +0 -199
- package/src/export-xlsx-roundtrip.test.ts +0 -120
- package/src/export-xlsx.test.ts +0 -150
- package/src/export.test.ts +0 -349
- package/src/export.ts +0 -1464
- package/src/expressions/evaluate.test.ts +0 -111
- package/src/expressions/evaluate.ts +0 -237
- package/src/expressions/expression-columns.ts +0 -133
- package/src/expressions/expression-types.ts +0 -84
- package/src/expressions/parse.test.ts +0 -106
- package/src/expressions/parse.ts +0 -610
- package/src/import-automap.test.ts +0 -131
- package/src/import-hardening.test.ts +0 -158
- package/src/import.test.ts +0 -415
- package/src/import.ts +0 -1044
- package/src/index.ts +0 -569
- package/src/install.ts +0 -154
- package/src/license-core.test.ts +0 -23
- package/src/license-core.ts +0 -107
- package/src/license-expiry.test.ts +0 -127
- package/src/license.ts +0 -137
- package/src/master-detail.test.ts +0 -61
- package/src/master-detail.ts +0 -42
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js +0 -3875
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-ZrPsKxob.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js +0 -21
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-ACqvWGE2.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js +0 -1938
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-D3w5jt92.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js +0 -205
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-CC2V3H0y.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js +0 -18
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-BXP37tAa.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js +0 -264
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-DwubnU5b.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js +0 -697
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-hD7f6PUz.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js +0 -4938
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DBx1SCN6.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js +0 -495
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-gjfpSTFS.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js +0 -190
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-DKoOKg8S.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js +0 -8
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-C0MiR7eR.js.map +0 -1
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js +0 -138
- package/src/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-B6Y7P0Q-.js.map +0 -1
- package/src/pivot-chart.test.ts +0 -86
- package/src/pivot-chart.ts +0 -112
- package/src/pivot-designer.ts +0 -101
- package/src/pivot.test.ts +0 -335
- package/src/pivot.ts +0 -578
- package/src/print.ts +0 -107
- package/src/scheduler-assignments.test.ts +0 -97
- package/src/scheduler-assignments.ts +0 -134
- package/src/scheduler-axis.test.ts +0 -108
- package/src/scheduler-axis.ts +0 -238
- package/src/scheduler-booking.test.ts +0 -57
- package/src/scheduler-config.ts +0 -179
- package/src/scheduler-dependencies.test.ts +0 -155
- package/src/scheduler-dependencies.ts +0 -223
- package/src/scheduler-freebusy.test.ts +0 -41
- package/src/scheduler-heatmap.test.ts +0 -39
- package/src/scheduler-resource-tree.test.ts +0 -84
- package/src/scheduler-resource-tree.ts +0 -107
- package/src/scheduler-slots.test.ts +0 -53
- package/src/scheduler-slots.ts +0 -94
- package/src/scheduler-summary.test.ts +0 -47
- package/src/scheduler-summary.ts +0 -81
- package/src/scheduling.test.ts +0 -194
- package/src/scheduling.ts +0 -293
- package/src/schema-designer.test.ts +0 -121
- package/src/schema-designer.ts +0 -142
- package/src/schema.test.ts +0 -268
- package/src/schema.ts +0 -562
- package/src/smart-shim.ts +0 -107
- package/src/sources/aggregate.test.ts +0 -79
- package/src/sources/aggregate.ts +0 -102
- package/src/sources/auth-supabase.test.ts +0 -80
- package/src/sources/auth-supabase.ts +0 -87
- package/src/sources/dashboard.kpi.test.ts +0 -50
- package/src/sources/dashboard.test.ts +0 -61
- package/src/sources/dashboard.ts +0 -136
- package/src/sources/field-inference.test.ts +0 -60
- package/src/sources/field-inference.ts +0 -63
- package/src/sources/filters.test.ts +0 -58
- package/src/sources/filters.ts +0 -70
- package/src/sources/index.ts +0 -67
- package/src/sources/introspect-supabase.test.ts +0 -112
- package/src/sources/introspect-supabase.ts +0 -139
- package/src/sources/realtime-supabase.test.ts +0 -93
- package/src/sources/realtime-supabase.ts +0 -99
- package/src/sources/relation-lookup.test.ts +0 -99
- package/src/sources/relation-lookup.ts +0 -128
- package/src/sources/rest-adapters.test.ts +0 -95
- package/src/sources/rest-adapters.ts +0 -120
- package/src/sources/rest.test.ts +0 -104
- package/src/sources/rest.ts +0 -129
- package/src/sources/schema-from-columns.test.ts +0 -106
- package/src/sources/schema-from-columns.ts +0 -88
- package/src/sources/supabase.test.ts +0 -110
- package/src/sources/supabase.ts +0 -99
- package/src/sources/with-entity-rules.test.ts +0 -104
- package/src/sources/with-entity-rules.ts +0 -78
- package/src/sources/with-relation-labels.test.ts +0 -75
- package/src/sources/with-relation-labels.ts +0 -73
- package/src/staged-editing.ts +0 -0
- package/src/studio/bug-report.test.ts +0 -101
- package/src/studio/bug-report.ts +0 -165
- package/src/studio/cli.test.ts +0 -187
- package/src/studio/cli.ts +0 -117
- package/src/studio/copilot-core.test.ts +0 -45
- package/src/studio/csv.test.ts +0 -90
- package/src/studio/csv.ts +0 -165
- package/src/studio/db-connect-string.test.ts +0 -94
- package/src/studio/db-connect-string.ts +0 -128
- package/src/studio/deploy-cli.test.ts +0 -56
- package/src/studio/deploy-cli.ts +0 -100
- package/src/studio/emit-project.test.ts +0 -3324
- package/src/studio/emit-project.ts +0 -5377
- package/src/studio/emit-schema.test.ts +0 -111
- package/src/studio/emit-schema.ts +0 -1181
- package/src/studio/index.ts +0 -380
- package/src/studio/init-flow.test.ts +0 -514
- package/src/studio/init-flow.ts +0 -556
- package/src/studio/introspect-db.test.ts +0 -186
- package/src/studio/introspect-db.ts +0 -312
- package/src/studio/introspect-openapi.test.ts +0 -84
- package/src/studio/introspect-openapi.ts +0 -252
- package/src/studio/introspect-prisma.test.ts +0 -99
- package/src/studio/introspect-prisma.ts +0 -175
- package/src/studio/introspect.test.ts +0 -172
- package/src/studio/introspect.ts +0 -310
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
- package/src/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
- package/src/studio/pipeline.test.ts +0 -42
- package/src/studio/project-robust.test.ts +0 -157
- package/src/studio/project.test.ts +0 -929
- package/src/studio/project.ts +0 -2394
- package/src/studio/sample-data.test.ts +0 -58
- package/src/studio/sample-data.ts +0 -203
- package/src/studio/samples/ats.ts +0 -202
- package/src/studio/samples/clinic.ts +0 -179
- package/src/studio/samples/crm.ts +0 -291
- package/src/studio/samples/datasets.test.ts +0 -84
- package/src/studio/samples/datasets.ts +0 -340
- package/src/studio/samples/ecommerce.ts +0 -187
- package/src/studio/samples/events.ts +0 -201
- package/src/studio/samples/fleet.ts +0 -213
- package/src/studio/samples/gym.ts +0 -215
- package/src/studio/samples/hr.ts +0 -195
- package/src/studio/samples/index.ts +0 -55
- package/src/studio/samples/insurance.ts +0 -229
- package/src/studio/samples/inventory.ts +0 -213
- package/src/studio/samples/invoicing.ts +0 -162
- package/src/studio/samples/library.ts +0 -180
- package/src/studio/samples/live-data.test.ts +0 -99
- package/src/studio/samples/live-data.ts +0 -306
- package/src/studio/samples/projects.ts +0 -212
- package/src/studio/samples/realestate.ts +0 -196
- package/src/studio/samples/restaurant.ts +0 -189
- package/src/studio/samples/samples.test.ts +0 -304
- package/src/studio/samples/school.ts +0 -197
- package/src/studio/samples/seed-floor.test.ts +0 -25
- package/src/studio/samples/shared.ts +0 -237
- package/src/studio/samples/starter.ts +0 -251
- package/src/studio/samples/subscriptions.ts +0 -183
- package/src/studio/samples/support.ts +0 -216
- package/src/studio/scaffold-app.test.ts +0 -91
- package/src/studio/scaffold.test.ts +0 -192
- package/src/studio/scaffold.ts +0 -390
- package/src/studio/screen-suites.test.ts +0 -269
- package/src/studio/screen-suites.ts +0 -448
- package/src/studio/themes.ts +0 -62
- package/src/studio/ui-components-surface.test.ts +0 -185
- package/src/studio/ui-components.generated.ts +0 -7154
- package/src/studio/ui-components.ts +0 -742
- package/src/studio/verify.test.ts +0 -47
- package/src/studio/verify.ts +0 -79
- package/src/sveltekit/in-memory.test.ts +0 -104
- package/src/sveltekit/in-memory.ts +0 -129
- package/src/sveltekit/index.ts +0 -24
- package/src/sveltekit/query-plan.test.ts +0 -109
- package/src/sveltekit/query-plan.ts +0 -125
- package/src/sveltekit/sql-source.test.ts +0 -198
- package/src/sveltekit/sql-source.ts +0 -171
- package/src/sveltekit/sql.test.ts +0 -80
- package/src/sveltekit/sql.ts +0 -131
- package/src/sveltekit/transport-scope.test.ts +0 -125
- package/src/sveltekit/transport.test.ts +0 -201
- package/src/sveltekit/transport.ts +0 -373
- package/src/upgrade-prompt.test.ts +0 -71
- package/src/upgrade-prompt.ts +0 -162
- package/src/version.test.ts +0 -17
- package/src/watermark.test.ts +0 -97
- package/src/watermark.ts +0 -156
- /package/{src → dist}/SvAlertRuleEditor.svelte +0 -0
- /package/{src → dist}/SvAlertsManager.svelte +0 -0
- /package/{src → dist}/SvAlertsPanel.svelte +0 -0
- /package/{src → dist}/SvAuthGate.svelte +0 -0
- /package/{src → dist}/SvBoard.svelte +0 -0
- /package/{src → dist}/SvExportMenu.svelte +0 -0
- /package/{src → dist}/SvExpressionEditor.svelte +0 -0
- /package/{src → dist}/SvFileInput.svelte +0 -0
- /package/{src → dist}/SvGridAlerts.svelte +0 -0
- /package/{src → dist}/SvGridBoard.svelte +0 -0
- /package/{src → dist}/SvGridEditPanel.svelte +0 -0
- /package/{src → dist}/SvGridMasterDetail.svelte +0 -0
- /package/{src → dist}/SvGridScheduler.svelte +0 -0
- /package/{src → dist}/SvImportDialog.svelte +0 -0
- /package/{src → dist}/SvLookupInput.svelte +0 -0
- /package/{src → dist}/SvPivotDesigner.svelte +0 -0
- /package/{src → dist}/SvRecordDetail.svelte +0 -0
- /package/{src → dist}/SvSchedule.svelte +0 -0
- /package/{src → dist}/SvSchemaChart.svelte +0 -0
- /package/{src → dist}/SvSchemaDashboard.svelte +0 -0
- /package/{src → dist}/pdfmake-shims.d.ts +0 -0
- /package/{src → dist}/smart.export.d.ts +0 -0
- /package/{src → dist}/smart.export.js +0 -0
- /package/{src → dist}/studio/HANDLERS-DESIGN.md +0 -0
- /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -0
- /package/{src → dist/studio}/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -0
- /package/{src → dist}/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -0
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
assignedMinutes,
|
|
4
|
-
expandAssignments,
|
|
5
|
-
overallocations,
|
|
6
|
-
resourceLoad,
|
|
7
|
-
type SchedulerAssignment,
|
|
8
|
-
} from './scheduler-assignments'
|
|
9
|
-
|
|
10
|
-
type Ev = { key: string; start: Date; end: Date; resource?: string }
|
|
11
|
-
const D = (h: number) => new Date(2026, 0, 5, h, 0, 0, 0)
|
|
12
|
-
const ev = (key: string, s: number, e: number, resource?: string): Ev => ({ key, start: D(s), end: D(e), resource })
|
|
13
|
-
|
|
14
|
-
const opts = {
|
|
15
|
-
keyOf: (e: Ev) => e.key,
|
|
16
|
-
startOf: (e: Ev) => e.start,
|
|
17
|
-
endOf: (e: Ev) => e.end,
|
|
18
|
-
resourceOf: (e: Ev) => e.resource,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe('expandAssignments', () => {
|
|
22
|
-
it('renders one event once per assigned resource', () => {
|
|
23
|
-
const events = [ev('e1', 9, 11)]
|
|
24
|
-
const assigns: SchedulerAssignment[] = [
|
|
25
|
-
{ id: 'a1', eventId: 'e1', resourceId: 'r1' },
|
|
26
|
-
{ id: 'a2', eventId: 'e1', resourceId: 'r2' },
|
|
27
|
-
]
|
|
28
|
-
const out = expandAssignments(events, assigns, opts)
|
|
29
|
-
expect(out.map((a) => a.resourceId).sort()).toEqual(['r1', 'r2'])
|
|
30
|
-
expect(out.every((a) => a.units === 1)).toBe(true)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('dedupes duplicate resource assignments to the max units', () => {
|
|
34
|
-
const out = expandAssignments([ev('e1', 9, 11)], [
|
|
35
|
-
{ id: 'a1', eventId: 'e1', resourceId: 'r1', units: 0.5 },
|
|
36
|
-
{ id: 'a2', eventId: 'e1', resourceId: 'r1', units: 0.8 },
|
|
37
|
-
], opts)
|
|
38
|
-
expect(out).toHaveLength(1)
|
|
39
|
-
expect(out[0]!.units).toBe(0.8)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('falls back to resourceOf when the event has no assignment', () => {
|
|
43
|
-
const out = expandAssignments([ev('e1', 9, 11, 'rX')], [], opts)
|
|
44
|
-
expect(out).toEqual([expect.objectContaining({ resourceId: 'rX', units: 1 })])
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('drops an event with neither assignment nor resource', () => {
|
|
48
|
-
const out = expandAssignments([ev('e1', 9, 11)], [], opts)
|
|
49
|
-
expect(out).toHaveLength(0)
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe('resourceLoad', () => {
|
|
54
|
-
it('sums units of overlapping allocations on the resource', () => {
|
|
55
|
-
const events = [ev('e1', 9, 11), ev('e2', 10, 12)]
|
|
56
|
-
const allocs = expandAssignments(events, [
|
|
57
|
-
{ id: 'a1', eventId: 'e1', resourceId: 'r1', units: 1 },
|
|
58
|
-
{ id: 'a2', eventId: 'e2', resourceId: 'r1', units: 0.5 },
|
|
59
|
-
], opts)
|
|
60
|
-
expect(resourceLoad(allocs, 'r1', D(10), D(11))).toBe(1.5) // both overlap 10-11
|
|
61
|
-
expect(resourceLoad(allocs, 'r1', D(9), D(10))).toBe(1) // only e1
|
|
62
|
-
expect(resourceLoad(allocs, 'r2', D(9), D(12))).toBe(0)
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
describe('overallocations', () => {
|
|
67
|
-
it('flags buckets where load exceeds capacity', () => {
|
|
68
|
-
const events = [ev('e1', 9, 12), ev('e2', 9, 12)]
|
|
69
|
-
const allocs = expandAssignments(events, [
|
|
70
|
-
{ id: 'a1', eventId: 'e1', resourceId: 'r1' },
|
|
71
|
-
{ id: 'a2', eventId: 'e2', resourceId: 'r1' },
|
|
72
|
-
], opts)
|
|
73
|
-
const buckets = [{ start: D(9), end: D(10) }, { start: D(10), end: D(11) }]
|
|
74
|
-
const over = overallocations(allocs, ['r1'], buckets, 1)
|
|
75
|
-
expect(over).toHaveLength(2) // 2 concurrent > capacity 1, in both buckets
|
|
76
|
-
expect(over[0]).toMatchObject({ resourceId: 'r1', load: 2, capacity: 1 })
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('respects a per-resource capacity function', () => {
|
|
80
|
-
const events = [ev('e1', 9, 12), ev('e2', 9, 12)]
|
|
81
|
-
const allocs = expandAssignments(events, [
|
|
82
|
-
{ id: 'a1', eventId: 'e1', resourceId: 'r1' },
|
|
83
|
-
{ id: 'a2', eventId: 'e2', resourceId: 'r1' },
|
|
84
|
-
], opts)
|
|
85
|
-
const over = overallocations(allocs, ['r1'], [{ start: D(9), end: D(10) }], () => 2)
|
|
86
|
-
expect(over).toHaveLength(0) // capacity 2 absorbs 2 concurrent
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
describe('assignedMinutes', () => {
|
|
91
|
-
it('totals weighted minutes across allocations', () => {
|
|
92
|
-
const allocs = expandAssignments([ev('e1', 9, 11)], [
|
|
93
|
-
{ id: 'a1', eventId: 'e1', resourceId: 'r1', units: 0.5 },
|
|
94
|
-
], opts)
|
|
95
|
-
expect(assignedMinutes(allocs, 'r1')).toBe(60) // 120 min * 0.5
|
|
96
|
-
})
|
|
97
|
-
})
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* scheduler-assignments - the pure core behind Scheduler Pro *multi-assignment*
|
|
3
|
-
* (one event assigned to several resources) and the *resource utilization
|
|
4
|
-
* histogram*. No Svelte, no DOM. Generic over the event shape via accessor
|
|
5
|
-
* callbacks so it needs no dependency on the grid's ResolvedEvent.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/** A many-to-many event <-> resource link, with an optional allocation (0..1). */
|
|
9
|
-
export type SchedulerAssignment = {
|
|
10
|
-
id: string
|
|
11
|
-
eventId: string
|
|
12
|
-
resourceId: string
|
|
13
|
-
/** Allocation fraction, default 1 (full). Summed for histogram / overallocation. */
|
|
14
|
-
units?: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** One event placed on one resource (the flattened render unit). */
|
|
18
|
-
export type Allocation<E = unknown> = {
|
|
19
|
-
event: E
|
|
20
|
-
key: string
|
|
21
|
-
resourceId: string
|
|
22
|
-
units: number
|
|
23
|
-
start: Date
|
|
24
|
-
end: Date
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type ExpandOptions<E> = {
|
|
28
|
-
keyOf: (e: E) => string
|
|
29
|
-
startOf: (e: E) => Date
|
|
30
|
-
endOf: (e: E) => Date
|
|
31
|
-
/** Single-resource fallback when an event has no assignment. */
|
|
32
|
-
resourceOf?: (e: E) => string | undefined
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const MS_MIN = 60_000
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Flatten events into per-resource allocations. An event with assignments renders
|
|
39
|
-
* once per assigned resource (deduped by eventId+resourceId, keeping the max
|
|
40
|
-
* units); an event with none falls back to its single `resourceOf` (units 1), or
|
|
41
|
-
* is dropped when it has neither. The result drives the resource-column bucketing.
|
|
42
|
-
*/
|
|
43
|
-
export function expandAssignments<E>(
|
|
44
|
-
events: ReadonlyArray<E>,
|
|
45
|
-
assignments: ReadonlyArray<SchedulerAssignment>,
|
|
46
|
-
opts: ExpandOptions<E>,
|
|
47
|
-
): Allocation<E>[] {
|
|
48
|
-
// Group assignments by eventId, collapsing duplicate resources to the max units.
|
|
49
|
-
const byEvent = new Map<string, Map<string, number>>()
|
|
50
|
-
for (const a of assignments) {
|
|
51
|
-
if (!a || !a.eventId || !a.resourceId) continue
|
|
52
|
-
let m = byEvent.get(a.eventId)
|
|
53
|
-
if (!m) byEvent.set(a.eventId, (m = new Map()))
|
|
54
|
-
const units = a.units == null ? 1 : a.units
|
|
55
|
-
m.set(a.resourceId, Math.max(m.get(a.resourceId) ?? 0, units))
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const out: Allocation<E>[] = []
|
|
59
|
-
for (const e of events) {
|
|
60
|
-
const key = opts.keyOf(e)
|
|
61
|
-
const start = opts.startOf(e)
|
|
62
|
-
const end = opts.endOf(e)
|
|
63
|
-
const m = byEvent.get(key)
|
|
64
|
-
if (m && m.size) {
|
|
65
|
-
for (const [resourceId, units] of m) out.push({ event: e, key, resourceId, units, start, end })
|
|
66
|
-
} else {
|
|
67
|
-
const resourceId = opts.resourceOf?.(e)
|
|
68
|
-
if (resourceId != null) out.push({ event: e, key, resourceId, units: 1, start, end })
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return out
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** True when `[aStart,aEnd)` overlaps `[bStart,bEnd)`. */
|
|
75
|
-
function overlaps(aStart: Date, aEnd: Date, bStart: Date, bEnd: Date): boolean {
|
|
76
|
-
return aStart.getTime() < bEnd.getTime() && aEnd.getTime() > bStart.getTime()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Summed allocation units on `resourceId` overlapping the bucket
|
|
81
|
-
* `[bucketStart, bucketEnd)` - the height of one histogram bar.
|
|
82
|
-
*/
|
|
83
|
-
export function resourceLoad<E>(
|
|
84
|
-
allocs: ReadonlyArray<Allocation<E>>,
|
|
85
|
-
resourceId: string,
|
|
86
|
-
bucketStart: Date,
|
|
87
|
-
bucketEnd: Date,
|
|
88
|
-
): number {
|
|
89
|
-
let load = 0
|
|
90
|
-
for (const a of allocs) {
|
|
91
|
-
if (a.resourceId !== resourceId) continue
|
|
92
|
-
if (overlaps(a.start, a.end, bucketStart, bucketEnd)) load += a.units
|
|
93
|
-
}
|
|
94
|
-
return load
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/** One over-capacity bucket (summed load exceeds the resource capacity). */
|
|
98
|
-
export type Overallocation = { resourceId: string; start: Date; end: Date; load: number; capacity: number }
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Buckets where a resource's summed load exceeds its capacity. `buckets` are the
|
|
102
|
-
* axis intervals to test; `capacity` is a flat number or a per-resource function
|
|
103
|
-
* (default 1). Used to tint histogram bars / flag conflicts.
|
|
104
|
-
*/
|
|
105
|
-
export function overallocations<E>(
|
|
106
|
-
allocs: ReadonlyArray<Allocation<E>>,
|
|
107
|
-
resourceIds: ReadonlyArray<string>,
|
|
108
|
-
buckets: ReadonlyArray<{ start: Date; end: Date }>,
|
|
109
|
-
capacity: number | ((resourceId: string) => number) = 1,
|
|
110
|
-
): Overallocation[] {
|
|
111
|
-
const capOf = typeof capacity === 'function' ? capacity : () => capacity
|
|
112
|
-
const out: Overallocation[] = []
|
|
113
|
-
for (const resourceId of resourceIds) {
|
|
114
|
-
const cap = capOf(resourceId)
|
|
115
|
-
for (const b of buckets) {
|
|
116
|
-
const load = resourceLoad(allocs, resourceId, b.start, b.end)
|
|
117
|
-
if (load > cap + 1e-9) out.push({ resourceId, start: b.start, end: b.end, load, capacity: cap })
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return out
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Total assigned minutes per resource across `allocs` (a simple utilization
|
|
125
|
-
* roll-up for a legend / header, independent of buckets).
|
|
126
|
-
*/
|
|
127
|
-
export function assignedMinutes<E>(allocs: ReadonlyArray<Allocation<E>>, resourceId: string): number {
|
|
128
|
-
let mins = 0
|
|
129
|
-
for (const a of allocs) {
|
|
130
|
-
if (a.resourceId !== resourceId) continue
|
|
131
|
-
mins += ((a.end.getTime() - a.start.getTime()) / MS_MIN) * a.units
|
|
132
|
-
}
|
|
133
|
-
return mins
|
|
134
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { buildAxis, resolveZoom, timeToX, xToTime, zoomPresets } from './scheduler-axis'
|
|
3
|
-
|
|
4
|
-
const day = (d: number, h = 0) => new Date(2026, 0, d, h, 0, 0, 0)
|
|
5
|
-
|
|
6
|
-
describe('buildAxis - linear (no collapse)', () => {
|
|
7
|
-
it('maps a full day linearly at pxPerMinute', () => {
|
|
8
|
-
const axis = buildAxis(day(5), day(6), { pxPerMinute: 1 }) // 1px/min => 1440px
|
|
9
|
-
expect(axis.totalPx).toBe(1440)
|
|
10
|
-
expect(timeToX(day(5, 12), axis)).toBe(720) // noon = halfway
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
it('timeToX / xToTime round-trip within a working span', () => {
|
|
14
|
-
const axis = buildAxis(day(5), day(6), { pxPerMinute: 1 })
|
|
15
|
-
const t = day(5, 9)
|
|
16
|
-
expect(xToTime(timeToX(t, axis), axis).getTime()).toBe(t.getTime())
|
|
17
|
-
})
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
describe('buildAxis - business hours collapse', () => {
|
|
21
|
-
it('collapses nights to a fixed gap so working hours dominate', () => {
|
|
22
|
-
const axis = buildAxis(day(5), day(7), {
|
|
23
|
-
pxPerMinute: 1,
|
|
24
|
-
businessHours: { start: 9, end: 17 }, // 8h = 480px working
|
|
25
|
-
collapseNonWorking: true,
|
|
26
|
-
collapsedGapPx: 10,
|
|
27
|
-
})
|
|
28
|
-
const working = axis.segments.filter((s) => s.kind === 'working')
|
|
29
|
-
const collapsed = axis.segments.filter((s) => s.kind === 'collapsed')
|
|
30
|
-
expect(working).toHaveLength(2) // two work days
|
|
31
|
-
expect(working[0]!.px).toBe(480)
|
|
32
|
-
// Gaps: before day5 9am, night between, after day6 5pm - each a collapsed 10px.
|
|
33
|
-
expect(collapsed.every((s) => s.px === 10)).toBe(true)
|
|
34
|
-
expect(axis.totalPx).toBe(480 * 2 + 10 * collapsed.length)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('omits gaps entirely when collapsedGapPx is 0', () => {
|
|
38
|
-
const axis = buildAxis(day(5), day(6), {
|
|
39
|
-
pxPerMinute: 1,
|
|
40
|
-
businessHours: { start: 9, end: 17 },
|
|
41
|
-
collapseNonWorking: true,
|
|
42
|
-
collapsedGapPx: 0,
|
|
43
|
-
})
|
|
44
|
-
expect(axis.totalPx).toBe(480) // just the working span
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
describe('buildAxis - weekend collapse', () => {
|
|
49
|
-
it('collapses whole non-working days', () => {
|
|
50
|
-
// Jan 2026: 3rd = Sat, 4th = Sun. Range Fri Jan 2 -> Mon Jan 5.
|
|
51
|
-
const axis = buildAxis(day(2), day(5), {
|
|
52
|
-
pxPerMinute: 1,
|
|
53
|
-
nonWorkingDays: [0, 6],
|
|
54
|
-
collapseWeekends: true,
|
|
55
|
-
collapsedGapPx: 8,
|
|
56
|
-
})
|
|
57
|
-
const collapsed = axis.segments.filter((s) => s.kind === 'collapsed')
|
|
58
|
-
// Sat + Sun are contiguous non-working, so they coalesce to ONE 8px gap.
|
|
59
|
-
expect(collapsed).toHaveLength(1)
|
|
60
|
-
expect(collapsed[0]!.px).toBe(8)
|
|
61
|
-
expect(collapsed[0]!.start.getDate()).toBe(3) // Sat
|
|
62
|
-
expect(collapsed[0]!.end.getDate()).toBe(5) // through to Mon 00:00
|
|
63
|
-
// Fri (full day) + Mon-partial working stays full width.
|
|
64
|
-
const working = axis.segments.filter((s) => s.kind === 'working')
|
|
65
|
-
expect(working.reduce((sum, s) => sum + s.px, 0)).toBe(1440) // Fri = 1440px working (24h, no business hours)
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('buildAxis - piecewise mapping across a collapsed gap', () => {
|
|
70
|
-
it('maps times on either side of a gap to the right x', () => {
|
|
71
|
-
const axis = buildAxis(day(5), day(7), {
|
|
72
|
-
pxPerMinute: 1,
|
|
73
|
-
businessHours: { start: 9, end: 17 },
|
|
74
|
-
collapseNonWorking: true,
|
|
75
|
-
collapsedGapPx: 10,
|
|
76
|
-
})
|
|
77
|
-
// End of day 5 work (17:00) sits at leading-gap + 480 working px.
|
|
78
|
-
const lead = axis.segments[0]!.px // leading collapsed gap (00:00-09:00)
|
|
79
|
-
expect(timeToX(day(5, 17), axis)).toBe(lead + 480)
|
|
80
|
-
// Start of day 6 work (09:00) sits one more gap past that.
|
|
81
|
-
expect(timeToX(day(6, 9), axis)).toBe(lead + 480 + 10)
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('round-trips a working-time point through x and back', () => {
|
|
85
|
-
const axis = buildAxis(day(5), day(7), {
|
|
86
|
-
pxPerMinute: 1,
|
|
87
|
-
businessHours: { start: 9, end: 17 },
|
|
88
|
-
collapseNonWorking: true,
|
|
89
|
-
collapsedGapPx: 10,
|
|
90
|
-
})
|
|
91
|
-
const t = day(6, 13)
|
|
92
|
-
expect(xToTime(timeToX(t, axis), axis).getTime()).toBe(t.getTime())
|
|
93
|
-
})
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
describe('resolveZoom', () => {
|
|
97
|
-
it('passes a ZoomLevel through and computes pxPerMinute', () => {
|
|
98
|
-
const level = zoomPresets.find((z) => z.id === 'hour')!
|
|
99
|
-
const r = resolveZoom(level)
|
|
100
|
-
expect(r.level.id).toBe('hour')
|
|
101
|
-
expect(r.pxPerMinute).toBeCloseTo(level.pxPerTick / level.tickMinutes)
|
|
102
|
-
})
|
|
103
|
-
it('treats a number as a clamped ladder index', () => {
|
|
104
|
-
expect(resolveZoom(0).level).toBe(zoomPresets[0])
|
|
105
|
-
expect(resolveZoom(999).level).toBe(zoomPresets[zoomPresets.length - 1])
|
|
106
|
-
expect(resolveZoom(-5).level).toBe(zoomPresets[0])
|
|
107
|
-
})
|
|
108
|
-
})
|
package/src/scheduler-axis.ts
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* scheduler-axis - the pure core behind Scheduler Pro's *non-working-time
|
|
3
|
-
* collapse* and *continuous zoom*. No Svelte, no DOM.
|
|
4
|
-
*
|
|
5
|
-
* Instead of a single linear time<->pixel scale, the timeline axis becomes a
|
|
6
|
-
* PIECEWISE map: working spans keep a full pixel width (`pxPerMinute`), while
|
|
7
|
-
* non-working spans (nights / weekends) collapse to a thin fixed-width gap (or
|
|
8
|
-
* are omitted). {@link buildAxis} produces the ordered segments; {@link timeToX}
|
|
9
|
-
* / {@link xToTime} map across them. The renderer routes all event positioning
|
|
10
|
-
* and drag snapping through these so a collapsed axis stays consistent.
|
|
11
|
-
*
|
|
12
|
-
* Callers supply the range + working definition; this file never reads the clock.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const MS_MIN = 60_000
|
|
16
|
-
const MS_DAY = 86_400_000
|
|
17
|
-
|
|
18
|
-
export type AxisSegmentKind = 'working' | 'break' | 'collapsed'
|
|
19
|
-
|
|
20
|
-
/** One contiguous stretch of the axis with a resolved pixel width + offset. */
|
|
21
|
-
export type AxisSegment = {
|
|
22
|
-
start: Date
|
|
23
|
-
end: Date
|
|
24
|
-
/** Left offset in px from the axis origin. */
|
|
25
|
-
x: number
|
|
26
|
-
/** Rendered width in px (collapsed gaps get a fixed small width). */
|
|
27
|
-
px: number
|
|
28
|
-
kind: AxisSegmentKind
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type Axis = {
|
|
32
|
-
start: Date
|
|
33
|
-
end: Date
|
|
34
|
-
segments: AxisSegment[]
|
|
35
|
-
totalPx: number
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type BuildAxisOptions = {
|
|
39
|
-
/** Pixel width of one working minute. Default 0.5 (30px/hour). */
|
|
40
|
-
pxPerMinute?: number
|
|
41
|
-
/** Business-hours window in hours, e.g. `{ start: 9, end: 17 }`. Omit = 24h working. */
|
|
42
|
-
businessHours?: { start: number; end: number }
|
|
43
|
-
/** Weekday numbers (0 = Sun .. 6 = Sat) treated as non-working days. */
|
|
44
|
-
nonWorkingDays?: ReadonlyArray<number>
|
|
45
|
-
/** Collapse nights / breaks (time outside business hours) to a gap. */
|
|
46
|
-
collapseNonWorking?: boolean
|
|
47
|
-
/** Collapse whole non-working days (weekends) to a gap. */
|
|
48
|
-
collapseWeekends?: boolean
|
|
49
|
-
/** Width (px) of a collapsed gap marker. Default 12; 0 omits it entirely. */
|
|
50
|
-
collapsedGapPx?: number
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** True when `weekday` is a non-working day. */
|
|
54
|
-
function isNonWorkingDay(weekday: number, days: ReadonlyArray<number> | undefined): boolean {
|
|
55
|
-
return !!days && days.includes(weekday)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* The working `[startMs, endMs)` intervals for the local day beginning at
|
|
60
|
-
* `dayStart`, from `businessHours` (or the whole day when omitted). Empty when the
|
|
61
|
-
* day is a non-working day.
|
|
62
|
-
*/
|
|
63
|
-
function workingSpansForDay(
|
|
64
|
-
dayStart: Date,
|
|
65
|
-
bh: { start: number; end: number } | undefined,
|
|
66
|
-
nonWorkingDays: ReadonlyArray<number> | undefined,
|
|
67
|
-
): Array<[number, number]> {
|
|
68
|
-
if (isNonWorkingDay(dayStart.getDay(), nonWorkingDays)) return []
|
|
69
|
-
const base = dayStart.getTime()
|
|
70
|
-
if (!bh) return [[base, base + MS_DAY]]
|
|
71
|
-
const s = base + bh.start * 60 * MS_MIN
|
|
72
|
-
const e = base + bh.end * 60 * MS_MIN
|
|
73
|
-
return e > s ? [[s, e]] : []
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Build the piecewise axis over `[rangeStart, rangeEnd]`. Walks day by day,
|
|
78
|
-
* emitting `working` segments (full width) interleaved with `break` (outside
|
|
79
|
-
* business hours) and whole non-working-day segments. A non-working segment is
|
|
80
|
-
* rendered `collapsed` (fixed gap px) when the matching collapse flag is on, else
|
|
81
|
-
* kept at full width with kind `break`.
|
|
82
|
-
*/
|
|
83
|
-
export function buildAxis(rangeStart: Date, rangeEnd: Date, opts: BuildAxisOptions = {}): Axis {
|
|
84
|
-
const pxPerMinute = opts.pxPerMinute ?? 0.5
|
|
85
|
-
const gapPx = opts.collapsedGapPx ?? 12
|
|
86
|
-
const pxOfMs = (ms: number) => (ms / MS_MIN) * pxPerMinute
|
|
87
|
-
|
|
88
|
-
// Collect all working spans across the range, clipped to it.
|
|
89
|
-
const rangeS = rangeStart.getTime()
|
|
90
|
-
const rangeE = rangeEnd.getTime()
|
|
91
|
-
const working: Array<[number, number]> = []
|
|
92
|
-
let day = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate())
|
|
93
|
-
// Guard: never loop forever; ranges are bounded (days count).
|
|
94
|
-
let guard = 0
|
|
95
|
-
while (day.getTime() < rangeE && guard++ < 4000) {
|
|
96
|
-
for (const [s, e] of workingSpansForDay(day, opts.businessHours, opts.nonWorkingDays)) {
|
|
97
|
-
const cs = Math.max(s, rangeS)
|
|
98
|
-
const ce = Math.min(e, rangeE)
|
|
99
|
-
if (ce > cs) working.push([cs, ce])
|
|
100
|
-
}
|
|
101
|
-
day = new Date(day.getTime() + MS_DAY)
|
|
102
|
-
}
|
|
103
|
-
working.sort((a, b) => a[0] - b[0])
|
|
104
|
-
|
|
105
|
-
// Weave working spans with the non-working gaps between them (and the edges).
|
|
106
|
-
// Build raw segments (x assigned in a finalize pass so we can coalesce first).
|
|
107
|
-
type Raw = { start: number; end: number; px: number; kind: AxisSegmentKind }
|
|
108
|
-
const raw: Raw[] = []
|
|
109
|
-
let cursor = rangeS
|
|
110
|
-
const pushSegment = (s: number, e: number, kind: AxisSegmentKind) => {
|
|
111
|
-
if (e <= s) return
|
|
112
|
-
if (kind === 'working') {
|
|
113
|
-
raw.push({ start: s, end: e, px: pxOfMs(e - s), kind })
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
// non-working: split into per-day pieces so a whole non-working DAY (weekend)
|
|
117
|
-
// collapses per `collapseWeekends` while a night / break collapses per
|
|
118
|
-
// `collapseNonWorking`. Consecutive collapsed pieces are merged below.
|
|
119
|
-
let a = s
|
|
120
|
-
while (a < e) {
|
|
121
|
-
const d = new Date(a)
|
|
122
|
-
const dayStart = new Date(d.getFullYear(), d.getMonth(), d.getDate())
|
|
123
|
-
const b = Math.min(e, dayStart.getTime() + MS_DAY)
|
|
124
|
-
const wholeDayOff = isNonWorkingDay(dayStart.getDay(), opts.nonWorkingDays)
|
|
125
|
-
const collapse = wholeDayOff ? opts.collapseWeekends : opts.collapseNonWorking
|
|
126
|
-
if (collapse) raw.push({ start: a, end: b, px: gapPx > 0 ? gapPx : 0, kind: 'collapsed' })
|
|
127
|
-
else raw.push({ start: a, end: b, px: pxOfMs(b - a), kind: 'break' })
|
|
128
|
-
a = b
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
for (const [ws, we] of working) {
|
|
133
|
-
if (ws > cursor) pushSegment(cursor, ws, 'break') // non-working gap before this span
|
|
134
|
-
pushSegment(ws, we, 'working')
|
|
135
|
-
cursor = we
|
|
136
|
-
}
|
|
137
|
-
if (cursor < rangeE) pushSegment(cursor, rangeE, 'break') // trailing non-working tail
|
|
138
|
-
|
|
139
|
-
// Coalesce consecutive collapsed pieces into one gap marker (a single collapsed
|
|
140
|
-
// stretch renders as one "gap" of `gapPx`, not one per calendar day), then
|
|
141
|
-
// assign cumulative x offsets.
|
|
142
|
-
const segments: AxisSegment[] = []
|
|
143
|
-
let x = 0
|
|
144
|
-
for (const r of raw) {
|
|
145
|
-
const prev = segments[segments.length - 1]
|
|
146
|
-
if (r.kind === 'collapsed' && prev && prev.kind === 'collapsed') {
|
|
147
|
-
prev.end = new Date(r.end) // extend the existing gap; px stays fixed
|
|
148
|
-
continue
|
|
149
|
-
}
|
|
150
|
-
segments.push({ start: new Date(r.start), end: new Date(r.end), x, px: r.px, kind: r.kind })
|
|
151
|
-
x += r.px
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return { start: rangeStart, end: rangeEnd, segments, totalPx: x }
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/** Find the segment containing `t` (by time), or null when outside the axis. */
|
|
158
|
-
function segmentAt(axis: Axis, t: number): AxisSegment | null {
|
|
159
|
-
for (const seg of axis.segments) {
|
|
160
|
-
if (t >= seg.start.getTime() && t < seg.end.getTime()) return seg
|
|
161
|
-
}
|
|
162
|
-
// Exact end-of-axis maps to the last segment's trailing edge.
|
|
163
|
-
const last = axis.segments[axis.segments.length - 1]
|
|
164
|
-
if (last && t === last.end.getTime()) return last
|
|
165
|
-
return null
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** Map a time to an x offset (px) across the piecewise axis. Clamps to [0,totalPx]. */
|
|
169
|
-
export function timeToX(date: Date, axis: Axis): number {
|
|
170
|
-
const t = date.getTime()
|
|
171
|
-
if (t <= axis.start.getTime()) return 0
|
|
172
|
-
if (t >= axis.end.getTime()) return axis.totalPx
|
|
173
|
-
const seg = segmentAt(axis, t)
|
|
174
|
-
if (!seg) return 0
|
|
175
|
-
const span = seg.end.getTime() - seg.start.getTime()
|
|
176
|
-
const frac = span > 0 ? (t - seg.start.getTime()) / span : 0
|
|
177
|
-
return seg.x + frac * seg.px
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/** Map an x offset (px) back to a time across the piecewise axis. */
|
|
181
|
-
export function xToTime(x: number, axis: Axis): Date {
|
|
182
|
-
if (x <= 0) return new Date(axis.start.getTime())
|
|
183
|
-
if (x >= axis.totalPx) return new Date(axis.end.getTime())
|
|
184
|
-
for (const seg of axis.segments) {
|
|
185
|
-
if (x >= seg.x && x < seg.x + seg.px) {
|
|
186
|
-
const span = seg.end.getTime() - seg.start.getTime()
|
|
187
|
-
const frac = seg.px > 0 ? (x - seg.x) / seg.px : 0
|
|
188
|
-
return new Date(seg.start.getTime() + frac * span)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return new Date(axis.end.getTime())
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// --- zoom -------------------------------------------------------------------
|
|
195
|
-
|
|
196
|
-
export type ZoomMajorUnit = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
|
|
197
|
-
|
|
198
|
-
/** One zoom preset: tick size + pixel density + the coarser grouping unit. */
|
|
199
|
-
export type ZoomLevel = {
|
|
200
|
-
id: string
|
|
201
|
-
label: string
|
|
202
|
-
/** Minutes per minor tick. */
|
|
203
|
-
tickMinutes: number
|
|
204
|
-
/** Pixel width of one minor tick. */
|
|
205
|
-
pxPerTick: number
|
|
206
|
-
majorUnit: ZoomMajorUnit
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/** The built-in zoom ladder, most zoomed-in first (minute detail -> months). */
|
|
210
|
-
export const zoomPresets: ZoomLevel[] = [
|
|
211
|
-
{ id: '5min', label: '5 min', tickMinutes: 5, pxPerTick: 24, majorUnit: 'hour' },
|
|
212
|
-
{ id: '15min', label: '15 min', tickMinutes: 15, pxPerTick: 30, majorUnit: 'hour' },
|
|
213
|
-
{ id: '30min', label: '30 min', tickMinutes: 30, pxPerTick: 40, majorUnit: 'day' },
|
|
214
|
-
{ id: 'hour', label: 'Hourly', tickMinutes: 60, pxPerTick: 50, majorUnit: 'day' },
|
|
215
|
-
{ id: '3hour', label: '3 hours', tickMinutes: 180, pxPerTick: 44, majorUnit: 'day' },
|
|
216
|
-
{ id: 'day', label: 'Daily', tickMinutes: 1440, pxPerTick: 64, majorUnit: 'week' },
|
|
217
|
-
{ id: 'week', label: 'Weekly', tickMinutes: 10_080, pxPerTick: 80, majorUnit: 'month' },
|
|
218
|
-
{ id: 'month', label: 'Monthly', tickMinutes: 43_200, pxPerTick: 72, majorUnit: 'quarter' },
|
|
219
|
-
]
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Resolve `zoom` to a {@link ZoomLevel}. A `ZoomLevel` passes through; a number is
|
|
223
|
-
* an index into `ladder` (clamped). Returns the pixel density too via
|
|
224
|
-
* `pxPerMinute = pxPerTick / tickMinutes` (use it as `buildAxis`'s `pxPerMinute`).
|
|
225
|
-
*/
|
|
226
|
-
export function resolveZoom(
|
|
227
|
-
zoom: number | ZoomLevel,
|
|
228
|
-
ladder: ReadonlyArray<ZoomLevel> = zoomPresets,
|
|
229
|
-
): { level: ZoomLevel; pxPerMinute: number } {
|
|
230
|
-
let level: ZoomLevel
|
|
231
|
-
if (typeof zoom === 'number') {
|
|
232
|
-
const i = Math.max(0, Math.min(ladder.length - 1, Math.round(zoom)))
|
|
233
|
-
level = ladder[i]!
|
|
234
|
-
} else {
|
|
235
|
-
level = zoom
|
|
236
|
-
}
|
|
237
|
-
return { level, pxPerMinute: level.pxPerTick / level.tickMinutes }
|
|
238
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { afterLead, respectsBuffer, withinDurationBounds, type BusyEvent } from './scheduler-booking'
|
|
3
|
-
|
|
4
|
-
const D = (h: number, m = 0) => new Date(2026, 0, 5, h, m, 0, 0)
|
|
5
|
-
const ev = (key: string, sh: number, eh: number, data?: unknown): BusyEvent => ({ key, start: D(sh), end: D(eh), data })
|
|
6
|
-
|
|
7
|
-
describe('respectsBuffer', () => {
|
|
8
|
-
const others = [ev('a', 9, 10), ev('b', 13, 14)]
|
|
9
|
-
|
|
10
|
-
it('passes when the gap before and after is large enough', () => {
|
|
11
|
-
// book 11:00-12:00: 60 min after a(ends 10), 60 min before b(starts 13) -> ok for 30/30 buffers
|
|
12
|
-
expect(respectsBuffer(D(11), D(12), others, 30, 30)).toBe(true)
|
|
13
|
-
})
|
|
14
|
-
it('rejects a direct overlap', () => {
|
|
15
|
-
expect(respectsBuffer(D(9, 30), D(10, 30), others, 0, 0)).toBe(false)
|
|
16
|
-
})
|
|
17
|
-
it('rejects when the gap before is too small', () => {
|
|
18
|
-
// book 10:15-11:00: only 15 min after a(ends 10); need 30 -> reject
|
|
19
|
-
expect(respectsBuffer(D(10, 15), D(11), others, 30, 30)).toBe(false)
|
|
20
|
-
})
|
|
21
|
-
it('rejects when the gap after is too small', () => {
|
|
22
|
-
// book 12:00-12:45: only 15 min before b(starts 13); need 30 -> reject
|
|
23
|
-
expect(respectsBuffer(D(12), D(12, 45), others, 30, 30)).toBe(false)
|
|
24
|
-
})
|
|
25
|
-
it('excludes the moving booking by key', () => {
|
|
26
|
-
const set = [ev('self', 11, 12), ev('a', 9, 10)]
|
|
27
|
-
// moving self to 10:00-10:30 would clash with its own old slot unless excluded
|
|
28
|
-
expect(respectsBuffer(D(10), D(10, 30), set, 0, 0, 'self')).toBe(true)
|
|
29
|
-
})
|
|
30
|
-
it('supports a per-neighbour gap (travel time by location)', () => {
|
|
31
|
-
const jobs = [ev('a', 9, 10, 'north'), ev('b', 13, 14, 'south')]
|
|
32
|
-
const travel = (n: BusyEvent) => (n.data === 'south' ? 90 : 20) // 90 min to/from south
|
|
33
|
-
// book 11:00-12:00: 60 min before b(south) but travel needs 90 -> reject
|
|
34
|
-
expect(respectsBuffer(D(11), D(12), jobs, travel, travel)).toBe(false)
|
|
35
|
-
// 11:00-11:30 leaves 90 before b -> ok
|
|
36
|
-
expect(respectsBuffer(D(11), D(11, 30), jobs, travel, travel)).toBe(true)
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
describe('withinDurationBounds', () => {
|
|
41
|
-
it('enforces min and max minutes', () => {
|
|
42
|
-
expect(withinDurationBounds(D(9), D(9, 30), 30, 90)).toBe(true)
|
|
43
|
-
expect(withinDurationBounds(D(9), D(9, 15), 30, 90)).toBe(false) // too short
|
|
44
|
-
expect(withinDurationBounds(D(9), D(11), 30, 90)).toBe(false) // too long
|
|
45
|
-
})
|
|
46
|
-
it('treats undefined bounds as unbounded', () => {
|
|
47
|
-
expect(withinDurationBounds(D(9), D(15), undefined, undefined)).toBe(true)
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
describe('afterLead', () => {
|
|
52
|
-
it('requires the start to be at least leadMin after now', () => {
|
|
53
|
-
const now = D(10)
|
|
54
|
-
expect(afterLead(D(12), now, 120)).toBe(true) // exactly 120 min ahead
|
|
55
|
-
expect(afterLead(D(11), now, 120)).toBe(false) // only 60 min ahead
|
|
56
|
-
})
|
|
57
|
-
})
|