@masterteam/task-schedule 0.0.17 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,180 +1,182 @@
1
- # `@masterteam/task-schedule`
2
-
3
- Syncfusion Gantt based task-schedule package with external model switching.
4
-
5
- ## Public API
6
-
7
- - `TaskSchedule` component (`mt-task-schedule`)
8
- - `TaskScheduleHeader` component (`mt-task-schedule-header`)
9
- - `TaskScheduleImportDialog` component (`mt-task-schedule-import-dialog`)
10
- - `TaskScheduleFetchDataAdapter` interface
11
- - `TaskScheduleActionDataAdapter` interface
12
- - `TaskScheduleFetchService`
13
- - `TaskScheduleActionService`
14
- - `TaskScheduleModelType`
15
- - `TaskScheduleContext`
16
- - `TASK_SCHEDULE_DEFAULT_PDF_FONT`
17
-
18
- ## Inputs
19
-
20
- - `context`: object with required `levelId` and `levelDataId` for fetch-based schedule reads
21
-
22
- Main context fields:
23
-
24
- - `modelType`: `'default' | 'edit' | 'baseline' | 'criticalPath' | 'critical-path' | 'resources' | 'unscheduled' | 'phaseGate' | 'custom'`
25
- - `langCode`: `'en' | 'ar' | null`
26
- - `dateFormat`: default `dd/MM/yyyy`
27
- - `height`: default `760px`
28
- - `pdfFonts`: optional `{ regular?: string; arabic?: string; size?: number }`
29
- - `mppRequestTimeoutMs`: optional timeout for MPP import, apply, and export requests. Defaults to `300000` ms.
30
- - `mppPreviewMaxRows`: optional MPP import normalization cap. Defaults to `400` preview rows.
31
- - `mppKeepRawPayload`: optional flag to retain the raw MPP import response on `TaskScheduleImportResult.raw`. Defaults to `false`.
32
-
33
- ## Outputs
34
-
35
- - `toolbarAction`
36
- - `actionBegin`
37
- - `actionCompleted`
38
- - `loaded`
39
- - `loadError`
40
-
41
- `TaskScheduleFetchDataAdapter` methods:
42
-
43
- - `load(modelType, context)`
44
- - `importTasks(context, file)`
45
- - `exportTasks(context)`
46
- - `loadDependencies(context)`
47
- - `loadTimeline(context, mode)`
48
- - `loadBaselineVersions(context)`
49
- - `loadBaselineSnapshot(context, version?)`
50
-
51
- `TaskScheduleActionDataAdapter` methods:
52
-
53
- - `createTask(context, payload)`
54
- - `updateTask(context, taskId, payload)`
55
- - `deleteTask(context, taskId)`
56
- - `updateBulkTasks(context, payload)`
57
- - `updateParent(context, taskId, parentId)`
58
- - `updateOrder(context, payload)`
59
- - `updateProgress(context, taskId, payload)`
60
- - `applyImportedTasks(context, payload)`
61
- - `setBaseline(context, payload?)`
62
- - `createDependency(context, payload)`
63
- - `updateDependency(context, dependencyId, payload)`
64
- - `deleteDependency(context, dependencyId)`
65
-
66
- ## Usage
67
-
68
- ```ts
69
- import { Component, signal } from '@angular/core';
70
- import {
71
- TaskSchedule,
72
- TaskScheduleModelType,
73
- } from '@masterteam/task-schedule';
74
-
75
- @Component({
76
- standalone: true,
77
- imports: [TaskSchedule],
78
- selector: 'app-task-schedule-host',
79
- template: `
80
- <mt-task-schedule
81
- [context]="{
82
- levelId: 12,
83
- modelType: modelType(),
84
- levelDataId: 18,
85
- langCode: 'en'
86
- }"
87
- />
88
- `,
89
- })
90
- export class TaskScheduleHostComponent {
91
- readonly modelType = signal<TaskScheduleModelType>('default');
92
- }
93
- ```
94
-
95
- `mt-task-schedule` uses `TaskScheduleFetchService` for reads and `TaskScheduleActionService` for write actions.
96
- `mt-task-schedule-header` and `TaskScheduleImportDialog` also split fetch/write behavior across the same two services.
97
-
98
- Backend routes used:
99
-
100
- - Mixed schedule reads (default/edit/critical/custom/resources/unscheduled): `POST /api/levels/{levelId}/{levelDataId}/schedule/read`
101
- - Phase-gate runtime tree: `GET /api/levels/{levelId}/{levelDataId}/schedule/tree?renderMode=PhaseGate`
102
- - Runtime baseline snapshot view: `GET /api/levels/{levelId}/{levelDataId}/schedule/baselines/latest`
103
- - Runtime baseline history: `GET /api/levels/{levelId}/{levelDataId}/schedule/baselines`
104
- - Runtime baseline version snapshot: `GET /api/levels/{levelId}/{levelDataId}/schedule/baselines/{version}`
105
- - Runtime dependencies: `GET/POST/PUT/DELETE /api/levels/{levelId}/{levelDataId}/schedule/dependencies`
106
- - Runtime timeline buckets: `POST /api/levels/{levelId}/{levelDataId}/schedule/read` with `mode: 'Timeline'`
107
- - Custom view config: `GET /api/schedulemanager/{levelId}/schedule/{customViewId}`
108
- - Team members (edit/resources mode): `GET /api/levels/{levelId}/TeamMember`
109
-
110
- Runtime mutations (when `levelDataId` exists):
111
-
112
- - `POST /api/process-submit` for create/update/delete/progress
113
- - `PUT /api/levels/{levelId}/{levelDataId}/schedule/bulk-update`
114
- - `PUT /api/levels/{levelId}/{levelDataId}/schedule/reorder`
115
- - `POST /api/levels/{levelId}/{levelDataId}/schedule/baselines` (set baseline)
116
- - `GET /api/levels/{levelId}/{levelDataId}/schedule/mpp` (export)
117
-
118
- Plain schedule reads no longer use legacy `/api/tasks/...` read routes.
119
- Import dialog keeps its current MPP preview/apply flow unless `endpoints.importTasks` / `endpoints.applyImportedTasks` are overridden.
120
-
121
- For `schedule/read` query responses, `TaskScheduleFetchService` maps native fields through `catalog.properties`: it resolves each property's `normalizedKey` to the Gantt field and reads the matching `record.values[property.key]` wrapper. Date fields prefer `raw` values and are converted from valid date/UTC strings to local date-only `Date` objects before binding to Syncfusion Gantt.
122
-
123
- Context options for backend routing:
124
-
125
- - `modelType`: selected schedule mode
126
- - `langCode`: optional language override
127
- - `dateFormat`: optional gantt date format
128
- - `height`: optional gantt height
129
- - `customViewId`: used in `custom` mode to load schedule-manager view columns
130
- - `resources`: optional static resource list override
131
- - `endpoints`: optional endpoint template overrides (`processSubmit`, `scheduleRead`, `scheduleQuery`, `scheduleTree`, `scheduleTreePhaseGate`, `scheduleDependencies`, `scheduleDependencyById`, `scheduleBaselines`, `scheduleBaselineByVersion`, `scheduleViewById`, `teamMembers`, `createTask`, etc.)
132
- - `endpoints.importTasks` / `endpoints.applyImportedTasks`: optional overrides for runtime/legacy MPP import flow
133
- - `endpoints.setBaseline`: optional override for baseline endpoint (runtime default: `/api/levels/{levelId}/{levelDataId}/schedule/baselines`)
134
- - `endpoints.exportTasks`: optional override for export endpoint (runtime default: `/api/levels/{levelId}/{levelDataId}/schedule/mpp`)
135
- - `pdfFonts`: optional `{ regular?: string; arabic?: string; size?: number }` base64 font config for PDF export
136
-
137
- HTTP base URL, auth, language headers, and idempotency are expected to be handled by the host app interceptors.
138
-
139
- When no PDF font is provided, package fallback uses embedded `TASK_SCHEDULE_DEFAULT_PDF_FONT`.
140
-
141
- ## Import Dialog
142
-
143
- Use `TaskScheduleImportDialog` with `ModalService` to import `.mpp`/`.xer` files and apply tasks (replace or append).
144
- The dialog is Tailwind-based and uses `@masterteam/components` (`mt-button`, `mt-entity-preview`).
145
- Imported rows support inline editing before apply (task name, planned/actual dates, assignee, progress) with per-row selection.
146
- The preview is capped by `maxRows`/`context.mppPreviewMaxRows` to keep large MPP files responsive. Select-all and apply operate on the visible preview rows only when the backend returns more rows than the preview cap. The full raw import payload is not retained unless `context.mppKeepRawPayload` is enabled.
147
-
148
- ## Shell Component
149
-
150
- Use `mt-task-schedule-header` as a reusable schedule header that combines:
151
-
152
- - mode switcher
153
- - Set Baseline action (feature service `setBaseline`)
154
- - Import dialog orchestration
155
- - Export tasks action (feature service `exportTasks`)
156
-
157
- It does not render `mt-task-schedule` internally. Use it separately when you want a standard schedule header above your own schedule host.
158
-
159
- Shell parity control fields also live on `context`:
160
-
161
- - `modeOptions`
162
- - `allowEditMode`
163
- - `allowImport`
164
- - `allowSetBaseline`
165
- - `hasTasks`
166
- - `baselinePending`
167
-
168
- Use the fetch service for reads/import preview/export and the action service for mutations. The package does not use NGXS.
169
-
170
- Fetch and action helpers exposed for runtime helpers:
171
-
172
- - `loadDependencies`
173
- - `createDependency`
174
- - `updateDependency`
175
- - `deleteDependency`
176
- - `loadTimeline`
177
- - `loadBaselineVersions`
178
- - `loadBaselineSnapshot`
179
-
180
- See `PARITY_REPORT.md` for legacy-to-package migration coverage.
1
+ # `@masterteam/task-schedule`
2
+
3
+ Syncfusion Gantt based task-schedule package with external model switching.
4
+
5
+ ## Public API
6
+
7
+ - `TaskSchedule` component (`mt-task-schedule`)
8
+ - `TaskScheduleHeader` component (`mt-task-schedule-header`)
9
+ - `TaskScheduleImportDialog` component (`mt-task-schedule-import-dialog`)
10
+ - `TaskScheduleFetchDataAdapter` interface
11
+ - `TaskScheduleActionDataAdapter` interface
12
+ - `TaskScheduleFetchService`
13
+ - `TaskScheduleActionService`
14
+ - `TaskScheduleModelType`
15
+ - `TaskScheduleContext`
16
+ - `TASK_SCHEDULE_DEFAULT_PDF_FONT`
17
+
18
+ ## Inputs
19
+
20
+ - `context`: object with required `levelId` and `levelDataId` for fetch-based schedule reads
21
+
22
+ Main context fields:
23
+
24
+ - `modelType`: `'default' | 'edit' | 'baseline' | 'criticalPath' | 'critical-path' | 'resources' | 'unscheduled' | 'phaseGate' | 'custom'`
25
+ - `langCode`: `'en' | 'ar' | null`
26
+ - `dateFormat`: default `dd/MM/yyyy`
27
+ - `height`: default `760px`
28
+ - `pdfFonts`: optional `{ regular?: string; arabic?: string; size?: number }`
29
+ - `mppRequestTimeoutMs`: optional timeout for MPP import, apply, and export requests. Defaults to `300000` ms.
30
+ - `mppPreviewMaxRows`: optional MPP import normalization cap. Defaults to `400` preview rows.
31
+ - `mppPreviewMaxResponseBytes`: optional maximum import response size to parse for preview rows. Defaults to `5000000` bytes; larger successful responses are treated as direct backend-applied imports.
32
+ - `mppKeepRawPayload`: optional flag to retain the raw MPP import response on `TaskScheduleImportResult.raw`. Defaults to `false`.
33
+
34
+ ## Outputs
35
+
36
+ - `toolbarAction`
37
+ - `actionBegin`
38
+ - `actionCompleted`
39
+ - `loaded`
40
+ - `loadError`
41
+
42
+ `TaskScheduleFetchDataAdapter` methods:
43
+
44
+ - `load(modelType, context)`
45
+ - `importTasks(context, file)`
46
+ - `exportTasks(context)`
47
+ - `loadDependencies(context)`
48
+ - `loadTimeline(context, mode)`
49
+ - `loadBaselineVersions(context)`
50
+ - `loadBaselineSnapshot(context, version?)`
51
+
52
+ `TaskScheduleActionDataAdapter` methods:
53
+
54
+ - `createTask(context, payload)`
55
+ - `updateTask(context, taskId, payload)`
56
+ - `deleteTask(context, taskId)`
57
+ - `updateBulkTasks(context, payload)`
58
+ - `updateParent(context, taskId, parentId)`
59
+ - `updateOrder(context, payload)`
60
+ - `updateProgress(context, taskId, payload)`
61
+ - `applyImportedTasks(context, payload)`
62
+ - `setBaseline(context, payload?)`
63
+ - `createDependency(context, payload)`
64
+ - `updateDependency(context, dependencyId, payload)`
65
+ - `deleteDependency(context, dependencyId)`
66
+
67
+ ## Usage
68
+
69
+ ```ts
70
+ import { Component, signal } from '@angular/core';
71
+ import {
72
+ TaskSchedule,
73
+ TaskScheduleModelType,
74
+ } from '@masterteam/task-schedule';
75
+
76
+ @Component({
77
+ standalone: true,
78
+ imports: [TaskSchedule],
79
+ selector: 'app-task-schedule-host',
80
+ template: `
81
+ <mt-task-schedule
82
+ [context]="{
83
+ levelId: 12,
84
+ modelType: modelType(),
85
+ levelDataId: 18,
86
+ langCode: 'en'
87
+ }"
88
+ />
89
+ `,
90
+ })
91
+ export class TaskScheduleHostComponent {
92
+ readonly modelType = signal<TaskScheduleModelType>('default');
93
+ }
94
+ ```
95
+
96
+ `mt-task-schedule` uses `TaskScheduleFetchService` for reads and `TaskScheduleActionService` for write actions.
97
+ `mt-task-schedule-header` and `TaskScheduleImportDialog` also split fetch/write behavior across the same two services.
98
+
99
+ Backend routes used:
100
+
101
+ - Mixed schedule reads (default/edit/critical/custom/resources/unscheduled): `POST /api/levels/{levelId}/{levelDataId}/schedule/read`
102
+ - Phase-gate runtime tree: `GET /api/levels/{levelId}/{levelDataId}/schedule/tree?renderMode=PhaseGate`
103
+ - Runtime baseline snapshot view: `GET /api/levels/{levelId}/{levelDataId}/schedule/baselines/latest`
104
+ - Runtime baseline history: `GET /api/levels/{levelId}/{levelDataId}/schedule/baselines`
105
+ - Runtime baseline version snapshot: `GET /api/levels/{levelId}/{levelDataId}/schedule/baselines/{version}`
106
+ - Runtime dependencies: `GET/POST/PUT/DELETE /api/levels/{levelId}/{levelDataId}/schedule/dependencies`
107
+ - Runtime timeline buckets: `POST /api/levels/{levelId}/{levelDataId}/schedule/read` with `mode: 'Timeline'`
108
+ - Custom view config: `GET /api/schedulemanager/{levelId}/schedule/{customViewId}`
109
+ - Team members (edit/resources mode): `GET /api/levels/{levelId}/TeamMember`
110
+
111
+ Runtime mutations (when `levelDataId` exists):
112
+
113
+ - `POST /api/process-submit` for create/update/delete/progress
114
+ - `PUT /api/levels/{levelId}/{levelDataId}/schedule/bulk-update`
115
+ - `PUT /api/levels/{levelId}/{levelDataId}/schedule/reorder`
116
+ - `POST /api/levels/{levelId}/{levelDataId}/schedule/baselines` (set baseline)
117
+ - `GET /api/levels/{levelId}/{levelDataId}/schedule/mpp` (export)
118
+
119
+ Plain schedule reads no longer use legacy `/api/tasks/...` read routes.
120
+ Import dialog keeps its current MPP preview/apply flow unless `endpoints.importTasks` / `endpoints.applyImportedTasks` are overridden.
121
+
122
+ For `schedule/read` query responses, `TaskScheduleFetchService` maps native fields through `catalog.properties`: it resolves each property's `normalizedKey` to the Gantt field and reads the matching `record.values[property.key]` wrapper. Date fields prefer `raw` values and are converted from valid date/UTC strings to local date-only `Date` objects before binding to Syncfusion Gantt.
123
+
124
+ Context options for backend routing:
125
+
126
+ - `modelType`: selected schedule mode
127
+ - `langCode`: optional language override
128
+ - `dateFormat`: optional gantt date format
129
+ - `height`: optional gantt height
130
+ - `customViewId`: used in `custom` mode to load schedule-manager view columns
131
+ - `resources`: optional static resource list override
132
+ - `endpoints`: optional endpoint template overrides (`processSubmit`, `scheduleRead`, `scheduleQuery`, `scheduleTree`, `scheduleTreePhaseGate`, `scheduleDependencies`, `scheduleDependencyById`, `scheduleBaselines`, `scheduleBaselineByVersion`, `scheduleViewById`, `teamMembers`, `createTask`, etc.)
133
+ - `endpoints.importTasks` / `endpoints.applyImportedTasks`: optional overrides for runtime/legacy MPP import flow
134
+ - `endpoints.setBaseline`: optional override for baseline endpoint (runtime default: `/api/levels/{levelId}/{levelDataId}/schedule/baselines`)
135
+ - `endpoints.exportTasks`: optional override for export endpoint (runtime default: `/api/levels/{levelId}/{levelDataId}/schedule/mpp`)
136
+ - `pdfFonts`: optional `{ regular?: string; arabic?: string; size?: number }` base64 font config for PDF export
137
+
138
+ HTTP base URL, auth, language headers, and idempotency are expected to be handled by the host app interceptors.
139
+
140
+ When no PDF font is provided, package fallback uses embedded `TASK_SCHEDULE_DEFAULT_PDF_FONT`.
141
+
142
+ ## Import Dialog
143
+
144
+ Use `TaskScheduleImportDialog` with `ModalService` to import `.mpp`/`.xer` files and apply tasks (replace or append).
145
+ The dialog is Tailwind-based and uses `@masterteam/components` (`mt-button`, `mt-entity-preview`).
146
+ Imported rows render as a checkbox tree so nested MPP summary tasks and children stay readable before apply.
147
+ If the MPP import endpoint returns a successful empty body or a response larger than `mppPreviewMaxResponseBytes`, the package treats it as a direct backend-applied import, closes the dialog with a success result, and lets the host schedule reload instead of rendering an empty preview.
148
+ The preview is capped by `maxRows`/`context.mppPreviewMaxRows` to keep large MPP files responsive. Select-all and apply operate on the visible preview rows only when the backend returns more rows than the preview cap. The full raw import payload is not retained unless `context.mppKeepRawPayload` is enabled.
149
+
150
+ ## Shell Component
151
+
152
+ Use `mt-task-schedule-header` as a reusable schedule header that combines:
153
+
154
+ - mode switcher
155
+ - Set Baseline action (feature service `setBaseline`)
156
+ - Import dialog orchestration
157
+ - Export tasks action (feature service `exportTasks`)
158
+
159
+ It does not render `mt-task-schedule` internally. Use it separately when you want a standard schedule header above your own schedule host.
160
+
161
+ Shell parity control fields also live on `context`:
162
+
163
+ - `modeOptions`
164
+ - `allowEditMode`
165
+ - `allowImport`
166
+ - `allowSetBaseline`
167
+ - `hasTasks`
168
+ - `baselinePending`
169
+
170
+ Use the fetch service for reads/import preview/export and the action service for mutations. The package does not use NGXS.
171
+
172
+ Fetch and action helpers exposed for runtime helpers:
173
+
174
+ - `loadDependencies`
175
+ - `createDependency`
176
+ - `updateDependency`
177
+ - `deleteDependency`
178
+ - `loadTimeline`
179
+ - `loadBaselineVersions`
180
+ - `loadBaselineSnapshot`
181
+
182
+ See `PARITY_REPORT.md` for legacy-to-package migration coverage.
@@ -1,2 +1,2 @@
1
- /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-800:oklch(47.3% .137 46.201);--color-slate-400:oklch(70.4% .04 256.788);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--radius-lg:.5rem;--radius-xl:.75rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.static{position:static}.m-0{margin:calc(var(--spacing) * 0)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.\!h-\[min\(84vh\,43rem\)\]{height:min(84vh,43rem)!important}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.\!max-h-\[84vh\]{max-height:84vh!important}.min-h-0{min-height:calc(var(--spacing) * 0)}.\!w-\[min\(86vw\,60rem\)\]{width:min(86vw,60rem)!important}.\!w-full{width:100%!important}.w-56{width:calc(var(--spacing) * 56)}.w-full{width:100%}.\!max-w-full{max-width:100%!important}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.\!overflow-y-hidden{overflow-y:hidden!important}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-amber-200{border-color:var(--color-amber-200)}.border-red-200{border-color:var(--color-red-200)}.border-surface{border-color:var(--p-content-border-color)}.border-surface-200{border-color:var(--p-surface-200)}@supports (color:color-mix(in lab, red, red)){.border-surface-200{border-color:color-mix(in srgb, var(--p-surface-200) calc(100% * 1), transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-surface-0{background-color:var(--p-surface-0)}@supports (color:color-mix(in lab, red, red)){.bg-surface-0{background-color:color-mix(in srgb, var(--p-surface-0) calc(100% * 1), transparent)}}.bg-surface-50{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.bg-surface-100{background-color:var(--p-surface-100)}@supports (color:color-mix(in lab, red, red)){.bg-surface-100{background-color:color-mix(in srgb, var(--p-surface-100) calc(100% * 1), transparent)}}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-amber-800{color:var(--color-amber-800)}.text-muted-color{color:var(--p-text-muted-color)}.text-red-700{color:var(--color-red-700)}.text-slate-400{color:var(--color-slate-400)}.text-surface-500{color:var(--p-surface-500)}@supports (color:color-mix(in lab, red, red)){.text-surface-500{color:color-mix(in srgb, var(--p-surface-500) calc(100% * 1), transparent)}}.text-surface-600{color:var(--p-surface-600)}@supports (color:color-mix(in lab, red, red)){.text-surface-600{color:color-mix(in srgb, var(--p-surface-600) calc(100% * 1), transparent)}}@media (min-width:48rem){.md\:\!w-\[44rem\]{width:44rem!important}}@media (min-width:64rem){.lg\:grid-cols-\[minmax\(0\,1fr\)_auto_auto\]{grid-template-columns:minmax(0,1fr) auto auto}.lg\:items-end{align-items:flex-end}}@media (min-width:80rem){.xl\:\!w-\[48rem\]{width:48rem!important}}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}
1
+ /*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-font-weight:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-800:oklch(47.3% .137 46.201);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--radius-lg:.5rem;--radius-xl:.75rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.static{position:static}.m-0{margin:0}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.\!h-\[min\(84vh\,43rem\)\]{height:min(84vh,43rem)!important}.h-full{height:100%}.\!max-h-\[84vh\]{max-height:84vh!important}.min-h-0{min-height:0}.\!w-\[min\(86vw\,60rem\)\]{width:min(86vw,60rem)!important}.\!w-full{width:100%!important}.w-56{width:calc(var(--spacing) * 56)}.w-full{width:100%}.\!max-w-full{max-width:100%!important}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-end{justify-content:flex-end}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.\!overflow-y-hidden{overflow-y:hidden!important}.overflow-y-auto{overflow-y:auto}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-amber-200{border-color:var(--color-amber-200)}.border-red-200{border-color:var(--color-red-200)}.border-surface{border-color:var(--p-content-border-color)}.border-surface-200{border-color:var(--p-surface-200)}@supports (color:color-mix(in lab, red, red)){.border-surface-200{border-color:color-mix(in srgb, var(--p-surface-200) calc(100% * 1), transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-surface-0{background-color:var(--p-surface-0)}@supports (color:color-mix(in lab, red, red)){.bg-surface-0{background-color:color-mix(in srgb, var(--p-surface-0) calc(100% * 1), transparent)}}.bg-surface-50{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-amber-800{color:var(--color-amber-800)}.text-muted-color{color:var(--p-text-muted-color)}.text-red-700{color:var(--color-red-700)}.text-surface-500{color:var(--p-surface-500)}@supports (color:color-mix(in lab, red, red)){.text-surface-500{color:color-mix(in srgb, var(--p-surface-500) calc(100% * 1), transparent)}}.text-surface-600{color:var(--p-surface-600)}@supports (color:color-mix(in lab, red, red)){.text-surface-600{color:color-mix(in srgb, var(--p-surface-600) calc(100% * 1), transparent)}}@media (min-width:48rem){.md\:\!w-\[44rem\]{width:44rem!important}}@media (min-width:64rem){.lg\:grid-cols-\[minmax\(0\,1fr\)_auto_auto\]{grid-template-columns:minmax(0,1fr) auto auto}.lg\:items-end{align-items:flex-end}}@media (min-width:80rem){.xl\:\!w-\[48rem\]{width:48rem!important}}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}