@morscherlab/mint-sdk 1.4.11 → 1.4.12

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.
Files changed (71) hide show
  1. package/dist/{AlertBox-CIhqsWbN.js → AlertBox-CexONPhA.js} +2 -2
  2. package/dist/{AlertBox-CIhqsWbN.js.map → AlertBox-CexONPhA.js.map} +1 -1
  3. package/dist/{AppSidebar-DbftYDAY.js → AppSidebar-C5zxZifu.js} +6 -6
  4. package/dist/{AppSidebar-DbftYDAY.js.map → AppSidebar-C5zxZifu.js.map} +1 -1
  5. package/dist/{ExperimentPopover-BM92LlrQ.js → ExperimentPopover-CzV1--OY.js} +2 -2
  6. package/dist/{ExperimentPopover-BM92LlrQ.js.map → ExperimentPopover-CzV1--OY.js.map} +1 -1
  7. package/dist/{ExperimentSelectorModal-BOLK-Gl4.js → ExperimentSelectorModal-CUkKmgfr.js} +3 -3
  8. package/dist/{ExperimentSelectorModal-BOLK-Gl4.js.map → ExperimentSelectorModal-CUkKmgfr.js.map} +1 -1
  9. package/dist/{SegmentedControl-Dz41vAFM.js → SegmentedControl-C-sckoJZ.js} +2 -2
  10. package/dist/{SegmentedControl-Dz41vAFM.js.map → SegmentedControl-C-sckoJZ.js.map} +1 -1
  11. package/dist/{SettingsModal-CKWC1JNV.js → SettingsModal-BCuw7uli.js} +6 -6
  12. package/dist/{SettingsModal-CKWC1JNV.js.map → SettingsModal-BCuw7uli.js.map} +1 -1
  13. package/dist/{controlSchemaModel-C20f-1_T.js → controlSchemaModel-C_XqpkgE.js} +2 -2
  14. package/dist/{controlSchemaModel-C20f-1_T.js.map → controlSchemaModel-C_XqpkgE.js.map} +1 -1
  15. package/dist/{data-C72M20rh.js → data-8G-U6Pb0.js} +9 -9
  16. package/dist/{data-C72M20rh.js.map → data-8G-U6Pb0.js.map} +1 -1
  17. package/dist/data.js +7 -7
  18. package/dist/index.js +16 -16
  19. package/dist/{install-DbF7ddGl.js → install-DnBvfEEq.js} +14 -38
  20. package/dist/install-DnBvfEEq.js.map +1 -0
  21. package/dist/install.js +1 -1
  22. package/dist/{lab-B5sKmlWF.js → lab-CPJ7n7e5.js} +37 -166
  23. package/dist/lab-CPJ7n7e5.js.map +1 -0
  24. package/dist/lab.js +4 -4
  25. package/dist/{records-CWRztE5M.js → records-BAymyHAn.js} +10 -110
  26. package/dist/records-BAymyHAn.js.map +1 -0
  27. package/dist/{runtime-OBeh3Knt.js → runtime-C8OanR7O.js} +82 -45
  28. package/dist/runtime-C8OanR7O.js.map +1 -0
  29. package/dist/runtime.js +6 -6
  30. package/dist/{shell-DDgF2bug.js → shell-B9jc0pVb.js} +4 -4
  31. package/dist/{shell-DDgF2bug.js.map → shell-B9jc0pVb.js.map} +1 -1
  32. package/dist/shell.js +4 -4
  33. package/dist/styles.css +59 -104
  34. package/dist/{useExperimentSamples-Cz2v3V_q.js → useExperimentSamples-DEDAKa2E.js} +3 -3
  35. package/dist/{useExperimentSamples-Cz2v3V_q.js.map → useExperimentSamples-DEDAKa2E.js.map} +1 -1
  36. package/dist/{useListReorder-C--K06el.js → useListReorder-W1bzK_bo.js} +2 -2
  37. package/dist/{useListReorder-C--K06el.js.map → useListReorder-W1bzK_bo.js.map} +1 -1
  38. package/dist/{useRackEditor-Cba_0OfI.js → useRackEditor-BWOnob3i.js} +154 -25
  39. package/dist/useRackEditor-BWOnob3i.js.map +1 -0
  40. package/dist/{useRealtime-CNQbrS01.js → useRealtime-B0u_FvEH.js} +2 -2
  41. package/dist/{useRealtime-CNQbrS01.js.map → useRealtime-B0u_FvEH.js.map} +1 -1
  42. package/dist/{useRequest-Bfsh7gIm.js → useRequest-D9-3BS-3.js} +2 -2
  43. package/dist/{useRequest-Bfsh7gIm.js.map → useRequest-D9-3BS-3.js.map} +1 -1
  44. package/package.json +1 -1
  45. package/src/components/FileUploader.vue +3 -35
  46. package/src/components/GeneratedPluginView.vue +35 -81
  47. package/src/components/GeneratedResultRenderer.vue +2 -1
  48. package/src/components/PlotlyChart.vue +1 -1
  49. package/src/generated-ui/main.ts +3 -1
  50. package/src/styles/components/alert-box.css +1 -1
  51. package/src/styles/components/app-sidebar.css +5 -5
  52. package/src/styles/components/button.css +3 -3
  53. package/src/styles/components/checkbox.css +1 -1
  54. package/src/styles/components/collapsible-card.css +1 -1
  55. package/src/styles/components/confirm-dialog.css +2 -2
  56. package/src/styles/components/file-uploader.css +3 -3
  57. package/src/styles/components/icon-button.css +3 -3
  58. package/src/styles/components/loading-spinner.css +1 -1
  59. package/src/styles/components/pill.css +1 -1
  60. package/src/styles/components/plugin-icon.css +1 -1
  61. package/src/styles/components/presence-avatars.css +4 -4
  62. package/src/styles/components/progress-bar.css +1 -1
  63. package/src/styles/components/sequence-input.css +1 -1
  64. package/src/styles/components/slider.css +1 -1
  65. package/src/styles/components/toggle.css +1 -1
  66. package/src/styles/variables.css +4 -0
  67. package/dist/install-DbF7ddGl.js.map +0 -1
  68. package/dist/lab-B5sKmlWF.js.map +0 -1
  69. package/dist/records-CWRztE5M.js.map +0 -1
  70. package/dist/runtime-OBeh3Knt.js.map +0 -1
  71. package/dist/useRackEditor-Cba_0OfI.js.map +0 -1
@@ -22,10 +22,12 @@ import {
22
22
  type GeneratedAnalysisTransport,
23
23
  } from '../composables/useJobsEndpoint'
24
24
  import AlertBox from './AlertBox.vue'
25
+ import AppContainer from './AppContainer.vue'
25
26
  import EmptyState from './EmptyState.vue'
26
27
  import GeneratedResultRenderer from './GeneratedResultRenderer.vue'
27
28
  import LoadingSpinner from './LoadingSpinner.vue'
28
29
  import PluginWorkspaceView from './PluginWorkspaceView.vue'
30
+ import SectionCard from './SectionCard.vue'
29
31
  import { GENERATED_JOBS_API_KEY } from './internal/generatedJobsApi'
30
32
  import { definePluginWorkspaceView } from '../composables/componentSpecs'
31
33
  import { providePluginIdentity } from '../composables/pluginIdentity'
@@ -48,6 +50,7 @@ const generated = useJobsEndpoint({
48
50
  provide(GENERATED_JOBS_API_KEY, { baseUrl: props.baseUrl, transport: props.transport })
49
51
  const activeDefinitionId = ref('')
50
52
  const selectedJobId = ref('')
53
+ const sidebarCollapsed = ref(false)
51
54
  const valuesByDefinition = reactive<Record<string, Record<string, unknown>>>({})
52
55
  const definitions = computed(() => generated.manifest.value?.jobs ?? [])
53
56
  const activeDefinition = computed(() => (
@@ -77,12 +80,22 @@ const workspace = computed(() => definePluginWorkspaceView({
77
80
  subtitle: generated.manifest.value?.ui.subtitle || generated.manifest.value?.ui.description,
78
81
  // The platform shell renders the toasts around this view.
79
82
  toasts: false,
83
+ floating: true,
80
84
  topBar: {
85
+ variant: 'card',
81
86
  pills: pillNav.value,
87
+ themeToggle: true,
82
88
  settings: false,
83
89
  standaloneLabel: props.showStandaloneLabel ? 'Standalone' : false,
84
90
  },
85
- sidebar: { title: 'Parameters', panels: panels.value, forms: forms.value },
91
+ sidebar: {
92
+ title: 'Parameters',
93
+ width: '300px',
94
+ collapsible: true,
95
+ collapsedWidth: '3rem',
96
+ panels: panels.value,
97
+ forms: forms.value,
98
+ },
86
99
  jobs: generated,
87
100
  }))
88
101
 
@@ -160,6 +173,7 @@ onMounted(() => {
160
173
  <template>
161
174
  <PluginWorkspaceView
162
175
  v-model:view="activeDefinitionId"
176
+ v-model:sidebar-collapsed="sidebarCollapsed"
163
177
  :spec="workspace"
164
178
  :values="currentValues"
165
179
  :form-loading="generated.isSubmitting.value"
@@ -168,7 +182,7 @@ onMounted(() => {
168
182
  @form-submit="submitJob"
169
183
  @job-select="selectJob"
170
184
  >
171
- <main class="mint-generated-workspace">
185
+ <AppContainer direction="column" gap="var(--mint-gutter)" class="mint-generated-workspace">
172
186
  <div v-if="generated.isLoading.value" class="mint-generated-workspace__loading">
173
187
  <LoadingSpinner size="lg" />
174
188
  <span>Loading analysis workspace</span>
@@ -177,18 +191,15 @@ onMounted(() => {
177
191
  <template v-else>
178
192
  <AlertBox v-if="generated.error.value" tone="error">{{ generated.error.value }}</AlertBox>
179
193
 
180
- <header v-if="activeDefinition" class="mint-generated-workspace__header">
181
- <div>
182
- <p class="mint-generated-workspace__eyebrow">Analysis result</p>
183
- <h1>{{ activeDefinition.title }}</h1>
184
- <p v-if="activeDefinition.description">{{ activeDefinition.description }}</p>
185
- </div>
186
- <div class="mint-generated-workspace__resources" aria-label="Job resource requirements">
187
- <span>{{ resourceSummary(activeDefinition) }}</span>
188
- </div>
189
- </header>
190
-
191
- <section class="mint-generated-workspace__result">
194
+ <SectionCard :title="activeDefinition?.title ?? 'Result'">
195
+ <template v-if="activeDefinition" #actions>
196
+ <span class="mint-generated-workspace__resources" aria-label="Job resource requirements">
197
+ {{ resourceSummary(activeDefinition) }}
198
+ </span>
199
+ </template>
200
+ <p v-if="activeDefinition?.description" class="mint-generated-workspace__description">
201
+ {{ activeDefinition.description }}
202
+ </p>
192
203
  <GeneratedResultRenderer
193
204
  v-if="currentResult"
194
205
  :result="currentResult"
@@ -199,93 +210,36 @@ onMounted(() => {
199
210
  description="Set the parameters and run the analysis. Jobs continue independently if you switch tabs."
200
211
  size="md"
201
212
  />
202
- </section>
213
+ </SectionCard>
203
214
  </template>
204
- </main>
215
+ </AppContainer>
205
216
  </PluginWorkspaceView>
206
217
  </template>
207
218
 
208
219
  <style scoped>
209
220
  .mint-generated-workspace {
210
- position: relative;
211
221
  min-width: 0;
212
- min-height: calc(100vh - 5rem);
213
- padding: clamp(1rem, 2.5vw, 2.5rem);
214
- background: var(--bg-primary);
222
+ min-height: 0;
223
+ overflow-y: auto;
215
224
  }
216
225
 
217
226
  .mint-generated-workspace__loading {
218
227
  display: flex;
219
- min-height: 24rem;
228
+ flex: 1;
220
229
  align-items: center;
221
230
  justify-content: center;
222
231
  gap: 0.75rem;
223
232
  color: var(--text-secondary);
224
233
  }
225
234
 
226
- .mint-generated-workspace__header {
227
- display: flex;
228
- align-items: flex-start;
229
- justify-content: space-between;
230
- gap: 1.5rem;
231
- max-width: 76rem;
232
- margin: 0 auto 1.25rem;
233
- }
234
-
235
- .mint-generated-workspace__header h1 {
236
- margin: 0;
237
- color: var(--text-primary);
238
- font-size: clamp(1.35rem, 2vw, 1.8rem);
239
- line-height: 1.2;
240
- }
241
-
242
- .mint-generated-workspace__header p:not(.mint-generated-workspace__eyebrow) {
243
- margin: 0.4rem 0 0;
244
- color: var(--text-secondary);
245
- }
246
-
247
- .mint-generated-workspace__eyebrow {
248
- margin: 0 0 0.35rem;
249
- color: var(--text-secondary);
250
- font-size: 0.72rem;
251
- font-weight: 700;
252
- }
253
-
254
235
  .mint-generated-workspace__resources {
255
- display: flex;
256
- flex-wrap: wrap;
257
- justify-content: flex-end;
258
- gap: 0.4rem;
259
- }
260
-
261
- .mint-generated-workspace__resources span {
262
- padding: 0.3rem 0.55rem;
263
- border: 1px solid var(--border-color);
264
- border-radius: 999px;
265
- background: var(--bg-secondary);
266
- color: var(--text-secondary);
236
+ color: var(--text-muted);
237
+ font-family: var(--font-mono);
267
238
  font-size: 0.75rem;
268
- font-weight: 600;
269
239
  }
270
240
 
271
- .mint-generated-workspace__result {
272
- max-width: 76rem;
273
- min-height: 24rem;
274
- margin: 0 auto;
275
- padding: clamp(1rem, 2vw, 1.75rem);
276
- border: 1px solid var(--border-color);
277
- border-radius: 1rem;
278
- background: var(--bg-secondary);
279
- box-shadow: var(--shadow-sm);
280
- }
281
-
282
- @media (max-width: 640px) {
283
- .mint-generated-workspace__header {
284
- flex-direction: column;
285
- }
286
-
287
- .mint-generated-workspace__resources {
288
- justify-content: flex-start;
289
- }
241
+ .mint-generated-workspace__description {
242
+ margin: 0 0 var(--mint-gutter);
243
+ color: var(--text-secondary);
290
244
  }
291
245
  </style>
@@ -133,6 +133,7 @@ function humanize(value: string): string {
133
133
  padding: 0.75rem 1rem;
134
134
  border-radius: var(--radius-md);
135
135
  background: var(--bg-tertiary);
136
+ font-family: var(--font-mono);
136
137
  font-size: 0.8125rem;
137
138
  line-height: 1.55;
138
139
  white-space: pre-wrap;
@@ -152,7 +153,7 @@ function humanize(value: string): string {
152
153
  gap: 1rem;
153
154
  padding: 1rem;
154
155
  border: 1px solid var(--border-color);
155
- border-radius: 0.75rem;
156
+ border-radius: var(--radius-lg);
156
157
  color: var(--color-primary);
157
158
  text-decoration: none;
158
159
  }
@@ -360,7 +360,7 @@ onBeforeUnmount(() => {
360
360
  margin: 0;
361
361
  padding: 1rem;
362
362
  border: 1px solid var(--mint-error-border);
363
- border-radius: 0.75rem;
363
+ border-radius: var(--radius-lg);
364
364
  background: var(--mint-error-bg);
365
365
  color: var(--mint-error-hover);
366
366
  }
@@ -2,6 +2,7 @@ import { createPinia } from 'pinia'
2
2
  import { createApp, h } from 'vue'
3
3
 
4
4
  import GeneratedPluginView from '../components/GeneratedPluginView.vue'
5
+ import { useSettingsStore } from '../stores/settings'
5
6
  import '../styles/index.css'
6
7
 
7
8
  function generatedApiBase(location: Location): string {
@@ -13,9 +14,10 @@ const app = createApp({
13
14
  name: 'MintGeneratedUiApp',
14
15
  render: () => h(GeneratedPluginView, {
15
16
  baseUrl: generatedApiBase(window.location),
16
- showStandaloneLabel: true,
17
17
  }),
18
18
  })
19
19
 
20
20
  app.use(createPinia())
21
+ // Theme, palette and density apply before the first paint, as in the platform.
22
+ useSettingsStore().initialize()
21
23
  app.mount('#app')
@@ -31,7 +31,7 @@
31
31
  .mint-alert__icon--info { background-color: var(--mint-info-bg); color: var(--mint-info); }
32
32
  .mint-alert__icon--neutral { background-color: var(--bg-tertiary); color: var(--text-secondary); }
33
33
  .mint-alert__icon--primary { background-color: var(--color-primary-soft); color: var(--color-primary); }
34
- .mint-alert__icon--cta { background-color: var(--color-primary-soft); color: var(--color-cta-hover); }
34
+ .mint-alert__icon--cta { background-color: var(--color-primary-soft); color: var(--color-primary-hover); }
35
35
 
36
36
  .mint-alert__content {
37
37
  flex: 1;
@@ -97,8 +97,8 @@
97
97
  min-width: 1.375rem;
98
98
  padding: 0.125rem 0.375rem;
99
99
  border-radius: var(--radius);
100
- background: color-mix(in srgb, var(--color-cta) 14%, transparent);
101
- color: var(--color-cta);
100
+ background: color-mix(in srgb, var(--color-primary) 14%, transparent);
101
+ color: var(--color-primary);
102
102
  font-size: 0.6875rem;
103
103
  font-weight: 700;
104
104
  line-height: 1.1;
@@ -369,7 +369,7 @@
369
369
  width: 11px;
370
370
  height: 11px;
371
371
  border-radius: 9999px;
372
- background: white;
372
+ background: var(--control-knob);
373
373
  box-shadow: var(--shadow-sm);
374
374
  transition: left 180ms var(--mint-ease-out-quart);
375
375
  }
@@ -469,7 +469,7 @@
469
469
  padding: 0 0.25rem;
470
470
  border-radius: var(--radius);
471
471
  background: var(--mint-sidebar-tone);
472
- color: white;
472
+ color: var(--text-on-accent);
473
473
  font-size: 0.6875rem;
474
474
  font-weight: 700;
475
475
  line-height: 1rem;
@@ -492,7 +492,7 @@
492
492
  .mint-sidebar__rail-badge--cta,
493
493
  .mint-sidebar__tag--cta,
494
494
  .mint-sidebar__group-action--cta {
495
- --mint-sidebar-tone: var(--color-cta);
495
+ --mint-sidebar-tone: var(--color-primary);
496
496
  }
497
497
 
498
498
  .mint-sidebar__rail-badge--success,
@@ -68,17 +68,17 @@
68
68
  }
69
69
 
70
70
  .mint-button--cta {
71
- background-color: var(--color-cta);
71
+ background-color: var(--color-primary);
72
72
  color: var(--text-on-accent);
73
73
  }
74
74
 
75
75
  .mint-button--cta:hover:not(.mint-button--disabled) {
76
- background-color: var(--color-cta-hover);
76
+ background-color: var(--color-primary-hover);
77
77
  }
78
78
 
79
79
  .mint-button--danger {
80
80
  background-color: var(--mint-error);
81
- color: white;
81
+ color: var(--text-on-danger);
82
82
  }
83
83
 
84
84
  .mint-button--danger:hover:not(.mint-button--disabled) {
@@ -133,7 +133,7 @@
133
133
  .mint-checkbox__native:disabled + .mint-checkbox__box.mint-checkbox__box--indeterminate {
134
134
  background-color: var(--text-muted);
135
135
  border-color: var(--text-muted);
136
- color: #FFFFFF;
136
+ color: var(--control-knob);
137
137
  }
138
138
 
139
139
  .mint-checkbox__box--sm {
@@ -159,7 +159,7 @@
159
159
 
160
160
  .mint-collapsible-card__badge--cta,
161
161
  .mint-collapsible-card__action--cta {
162
- --mint-sidebar-badge-color: var(--color-cta);
162
+ --mint-sidebar-badge-color: var(--color-primary);
163
163
  }
164
164
 
165
165
  .mint-collapsible-card__badge--success,
@@ -48,8 +48,8 @@
48
48
  }
49
49
 
50
50
  .mint-confirm__icon--cta {
51
- background-color: color-mix(in srgb, var(--color-cta) 12%, transparent);
52
- color: var(--color-cta);
51
+ background-color: color-mix(in srgb, var(--color-primary) 12%, transparent);
52
+ color: var(--color-primary);
53
53
  }
54
54
 
55
55
  .mint-confirm__icon--neutral {
@@ -160,9 +160,9 @@
160
160
  font-size: 0.6875rem;
161
161
  font-weight: 700;
162
162
  font-family: var(--font-mono);
163
- color: var(--badge-color);
164
- background-color: color-mix(in srgb, var(--badge-color) 10%, transparent);
165
- border: 1px solid color-mix(in srgb, var(--badge-color) 20%, transparent);
163
+ color: var(--text-secondary);
164
+ background-color: var(--bg-tertiary);
165
+ border: 1px solid var(--border-color);
166
166
  }
167
167
 
168
168
  .mint-file-uploader__file-meta {
@@ -57,17 +57,17 @@
57
57
  }
58
58
 
59
59
  .mint-icon-button--cta {
60
- background-color: var(--color-cta);
60
+ background-color: var(--color-primary);
61
61
  color: var(--text-on-accent);
62
62
  }
63
63
 
64
64
  .mint-icon-button--cta:hover:not(.mint-icon-button--disabled) {
65
- background-color: var(--color-cta-hover);
65
+ background-color: var(--color-primary-hover);
66
66
  }
67
67
 
68
68
  .mint-icon-button--danger {
69
69
  background-color: var(--mint-error);
70
- color: white;
70
+ color: var(--text-on-danger);
71
71
  }
72
72
 
73
73
  .mint-icon-button--danger:hover:not(.mint-icon-button--disabled) {
@@ -33,7 +33,7 @@
33
33
 
34
34
  /* Tones */
35
35
  .mint-spinner--primary { color: var(--color-primary); }
36
- .mint-spinner--cta { color: var(--color-cta); }
36
+ .mint-spinner--cta { color: var(--color-primary); }
37
37
  .mint-spinner--success { color: var(--mint-success); }
38
38
  .mint-spinner--warning { color: var(--mint-warning); }
39
39
  .mint-spinner--error { color: var(--mint-error); }
@@ -33,7 +33,7 @@
33
33
  (soft-tint background, dot, outline border); `--mint-pill-ink` the text. A
34
34
  `color` prop sets `--mint-pill-tone` inline. */
35
35
  .mint-pill--primary { --mint-pill-tone: var(--color-primary); --mint-pill-ink: var(--color-primary-hover); }
36
- .mint-pill--cta { --mint-pill-tone: var(--color-cta); --mint-pill-ink: var(--color-cta-hover); }
36
+ .mint-pill--cta { --mint-pill-tone: var(--color-primary); --mint-pill-ink: var(--color-primary-hover); }
37
37
  .mint-pill--success { --mint-pill-tone: var(--mint-success); --mint-pill-ink: var(--mint-success-hover); }
38
38
  .mint-pill--warning { --mint-pill-tone: var(--mint-warning); --mint-pill-ink: var(--mint-warning-text); }
39
39
  .mint-pill--error { --mint-pill-tone: var(--mint-error); --mint-pill-ink: var(--mint-error-hover); }
@@ -19,7 +19,7 @@
19
19
  /* Tones (deprecated with the tone/color props, removed in 1.5): the v2 tile no longer reads the variable. */
20
20
  .mint-plugin-icon--neutral { --mint-plugin-icon-tone: var(--text-secondary); }
21
21
  .mint-plugin-icon--primary { --mint-plugin-icon-tone: var(--color-primary); }
22
- .mint-plugin-icon--cta { --mint-plugin-icon-tone: var(--color-cta); }
22
+ .mint-plugin-icon--cta { --mint-plugin-icon-tone: var(--color-primary); }
23
23
  .mint-plugin-icon--success { --mint-plugin-icon-tone: var(--mint-success); }
24
24
  .mint-plugin-icon--warning { --mint-plugin-icon-tone: var(--mint-warning); }
25
25
  .mint-plugin-icon--error { --mint-plugin-icon-tone: var(--mint-error); }
@@ -1,18 +1,18 @@
1
1
  /* PresenceAvatars: an avatar stack that opens a list of who is here.
2
2
  * The editing cue is a ring plus a pencil badge, so it does not depend on
3
- * colour only. Light mode uses --color-cta-hover (3:1 on the card), dark
4
- * mode --color-cta. --mint-presence-surface is the colour the avatars are
3
+ * colour only. Light mode uses --color-primary-hover (3:1 on the card), dark
4
+ * mode --color-primary. --mint-presence-surface is the colour the avatars are
5
5
  * cut out of; set it when the stack sits on another surface. */
6
6
 
7
7
  .mint-presence {
8
- --mint-presence-editing: var(--color-cta-hover);
8
+ --mint-presence-editing: var(--color-primary-hover);
9
9
  --mint-presence-surface: var(--bg-secondary);
10
10
  position: relative;
11
11
  display: inline-flex;
12
12
  }
13
13
 
14
14
  :where(html.dark) .mint-presence {
15
- --mint-presence-editing: var(--color-cta);
15
+ --mint-presence-editing: var(--color-primary);
16
16
  }
17
17
 
18
18
  .mint-presence__trigger {
@@ -46,7 +46,7 @@
46
46
  .mint-progress__bar--success { background-color: var(--mint-success); }
47
47
  .mint-progress__bar--warning { background-color: var(--mint-warning); }
48
48
  .mint-progress__bar--error { background-color: var(--mint-error); }
49
- .mint-progress__bar--cta { background-color: var(--color-cta); }
49
+ .mint-progress__bar--cta { background-color: var(--color-primary); }
50
50
  .mint-progress__bar--neutral { background-color: var(--text-muted); }
51
51
  .mint-progress__bar--info { background-color: var(--color-primary); } /* 6b: progress fill is always primary; --mint-info is for the running dot */
52
52
 
@@ -226,7 +226,7 @@
226
226
  .mint-sequence-input__problem--error .mint-sequence-input__problem-shape { fill: var(--mint-error); }
227
227
 
228
228
  .mint-sequence-input__problem-mark {
229
- stroke: white;
229
+ stroke: var(--text-on-danger);
230
230
  stroke-width: 1.6;
231
231
  stroke-linecap: round;
232
232
  }
@@ -56,7 +56,7 @@
56
56
  box-sizing: border-box;
57
57
  transform: translateX(-50%) translateY(-50%);
58
58
  border-radius: 9999px;
59
- background-color: #FFFFFF;
59
+ background-color: var(--control-knob);
60
60
  border: 1px solid color-mix(in srgb, var(--text-secondary) 40%, transparent);
61
61
  box-shadow: var(--shadow-sm);
62
62
  pointer-events: none;
@@ -151,7 +151,7 @@
151
151
  top: 50%;
152
152
  left: 2px;
153
153
  border-radius: 9999px;
154
- background-color: #FFFFFF;
154
+ background-color: var(--control-knob);
155
155
  box-shadow: var(--shadow-sm);
156
156
  transition: transform 180ms cubic-bezier(0.25, 1, 0.5, 1);
157
157
  pointer-events: none;
@@ -59,6 +59,10 @@
59
59
  --mint-primary: var(--color-primary);
60
60
  /* Text and icons on an accent fill (filled buttons, Save). */
61
61
  --text-on-accent: #FFFFFF;
62
+ /* Text on a --mint-error fill (danger buttons); white in both themes, 3.76:1 on #EF4444. */
63
+ --text-on-danger: #FFFFFF;
64
+ /* Knob of a toggle or slider, and the mark of a disabled checkbox; white in both themes. */
65
+ --control-knob: #FFFFFF;
62
66
  /* Retired hues, aliased to the accent until 1.5 (mint doctor warns on use). */
63
67
  --color-cta: var(--color-primary);
64
68
  --color-cta-hover: var(--color-primary-hover);
@@ -1 +0,0 @@
1
- {"version":3,"file":"install-DbF7ddGl.js","names":["$slots"],"sources":["../src/components/Calendar.vue","../src/components/Calendar.vue","../src/components/AppContainer.vue","../src/components/AppContainer.vue","../src/components/Divider.vue","../src/components/Divider.vue","../src/components/Breadcrumb.vue","../src/components/Breadcrumb.vue","../src/components/FormBuilder.vue","../src/components/FormBuilder.vue","../src/components/index.ts","../src/install.ts"],"sourcesContent":["<script setup lang=\"ts\">\n/** Month calendar for single date, multi-date, or range selection with markers and navigation. */\nimport { ref, computed, watch } from 'vue'\nimport type { CalendarSelectionMode, CalendarMarker, CalendarDayContext } from '../types'\n\n/**\n * Calendar - Month calendar with date selection, range selection, and custom markers.\n *\n * @example\n * ```vue\n * <!-- Single date selection -->\n * <Calendar v-model=\"selectedDate\" />\n *\n * <!-- Range selection -->\n * <Calendar v-model=\"dateRange\" selection-mode=\"range\" />\n *\n * <!-- With markers -->\n * <Calendar :markers=\"[{ date: '2024-01-15', color: '#ff0000', label: 'Event' }]\" />\n * ```\n */\ninterface Props {\n /** Selected date(s) - type depends on selectionMode */\n modelValue?: Date | Date[] | { start: Date; end: Date } | null\n /** Selection behavior mode */\n selectionMode?: CalendarSelectionMode\n /** Display month (0-11) */\n month?: number\n /** Display year */\n year?: number\n /** Always show 6 weeks (42 days) */\n fixedWeeks?: boolean\n /** First day of week (0=Sunday, 1=Monday, etc.) */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /** Show days from adjacent months */\n showOutsideDays?: boolean\n /** Show month navigation buttons */\n showNavigation?: boolean\n /** Visual markers on specific dates */\n markers?: CalendarMarker[]\n /** Earliest selectable date */\n minDate?: Date | string\n /** Latest selectable date */\n maxDate?: Date | string\n /** Explicitly disabled dates */\n disabledDates?: Array<Date | string>\n /** Custom disabled date logic */\n isDateDisabled?: (date: Date) => boolean\n /** Locale for date formatting */\n locale?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n selectionMode: 'single',\n fixedWeeks: true,\n weekStartsOn: 1,\n showOutsideDays: true,\n showNavigation: true,\n markers: () => [],\n disabledDates: () => [],\n locale: 'en-US',\n})\n\n/**\n * @event update:modelValue - Emitted when date selection changes (v-model support)\n * @event update:month - Emitted when displayed month changes\n * @event update:year - Emitted when displayed year changes\n * @event day-click - Emitted when a day is clicked, includes day context\n * @event navigate - Emitted when month navigation occurs\n */\nconst emit = defineEmits<{\n 'update:modelValue': [value: Date | Date[] | { start: Date; end: Date } | null]\n 'update:month': [month: number]\n 'update:year': [year: number]\n 'day-click': [context: CalendarDayContext]\n navigate: [direction: 'prev' | 'next', month: number, year: number]\n}>()\n\nconst today = new Date()\ntoday.setHours(0, 0, 0, 0)\n\nconst currentMonth = ref(props.month ?? today.getMonth())\nconst currentYear = ref(props.year ?? today.getFullYear())\n\n// Range hover tracking\nconst hoveredDate = ref<Date | null>(null)\n\nwatch(() => props.month, (val) => { if (val !== undefined) currentMonth.value = val })\nwatch(() => props.year, (val) => { if (val !== undefined) currentYear.value = val })\n\nconst monthLabel = computed(() => {\n const date = new Date(currentYear.value, currentMonth.value, 1)\n return date.toLocaleDateString(props.locale, { month: 'long', year: 'numeric' })\n})\n\nconst weekDayLabels = computed(() => {\n const labels: string[] = []\n // Use Jan 7, 2024 (Sunday) as reference, then offset by weekStartsOn\n const base = new Date(2024, 0, 7 + props.weekStartsOn)\n for (let i = 0; i < 7; i++) {\n const d = new Date(base)\n d.setDate(d.getDate() + i)\n labels.push(d.toLocaleDateString(props.locale, { weekday: 'short' }))\n }\n return labels\n})\n\nfunction toDateKey(d: Date): string {\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n\nfunction parseDate(val: Date | string): Date {\n if (val instanceof Date) return val\n const d = new Date(val + 'T00:00:00')\n return d\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n}\n\nconst disabledDateSet = computed(() => {\n const set = new Set<string>()\n for (const d of props.disabledDates) {\n const parsed = parseDate(d)\n set.add(toDateKey(parsed))\n }\n return set\n})\n\nconst markerMap = computed(() => {\n const map = new Map<string, CalendarMarker[]>()\n for (const marker of props.markers) {\n const date = parseDate(marker.date)\n const key = toDateKey(date)\n const markers = map.get(key)\n if (markers) {\n markers.push(marker)\n } else {\n map.set(key, [marker])\n }\n }\n return map\n})\n\nfunction isDateSelected(date: Date): boolean {\n const val = props.modelValue\n if (!val) return false\n if (val instanceof Date) return isSameDay(date, val)\n if (Array.isArray(val)) return val.some(d => isSameDay(date, d))\n if ('start' in val && 'end' in val) {\n return isSameDay(date, val.start) || isSameDay(date, val.end)\n }\n return false\n}\n\nfunction isInRange(date: Date): boolean {\n if (props.selectionMode !== 'range') return false\n const val = props.modelValue\n if (!val || !('start' in (val as object))) return false\n const range = val as { start: Date; end: Date }\n\n const t = date.getTime()\n const start = range.start?.getTime()\n if (!start) return false\n\n // If hovering during selection (before end is set)\n if (!range.end && hoveredDate.value) {\n const hov = hoveredDate.value.getTime()\n const [lo, hi] = start <= hov ? [start, hov] : [hov, start]\n return t > lo && t < hi\n }\n\n // Complete range\n if (range.end) {\n const end = range.end.getTime()\n return t > start && t < end\n }\n\n return false\n}\n\nfunction isDisabled(date: Date): boolean {\n if (disabledDateSet.value.has(toDateKey(date))) return true\n if (props.isDateDisabled?.(date)) return true\n if (props.minDate) {\n const min = parseDate(props.minDate)\n if (date < min) return true\n }\n if (props.maxDate) {\n const max = parseDate(props.maxDate)\n if (date > max) return true\n }\n return false\n}\n\nconst calendarDays = computed<CalendarDayContext[]>(() => {\n const first = new Date(currentYear.value, currentMonth.value, 1)\n const startDow = first.getDay()\n const offset = (startDow - props.weekStartsOn + 7) % 7\n\n const totalCells = props.fixedWeeks ? 42 : (() => {\n const daysInMonth = new Date(currentYear.value, currentMonth.value + 1, 0).getDate()\n const needed = offset + daysInMonth\n return Math.ceil(needed / 7) * 7\n })()\n\n const days: CalendarDayContext[] = []\n for (let i = 0; i < totalCells; i++) {\n const date = new Date(currentYear.value, currentMonth.value, 1 - offset + i)\n date.setHours(0, 0, 0, 0)\n const key = toDateKey(date)\n days.push({\n date,\n dayOfMonth: date.getDate(),\n isToday: isSameDay(date, today),\n isSelected: isDateSelected(date),\n isInRange: isInRange(date),\n isDisabled: isDisabled(date),\n isOutsideMonth: date.getMonth() !== currentMonth.value,\n markers: markerMap.value.get(key) ?? [],\n })\n }\n return days\n})\n\n// Range selection state\nconst rangeStart = ref<Date | null>(null)\n\nfunction handleDayClick(day: CalendarDayContext) {\n if (day.isDisabled) return\n if (!props.showOutsideDays && day.isOutsideMonth) return\n\n emit('day-click', day)\n\n if (props.selectionMode === 'none') return\n\n if (props.selectionMode === 'single') {\n emit('update:modelValue', day.date)\n } else if (props.selectionMode === 'multiple') {\n const current = (props.modelValue as Date[] | undefined) ?? []\n const idx = current.findIndex(d => isSameDay(d, day.date))\n if (idx >= 0) {\n const next = [...current]\n next.splice(idx, 1)\n emit('update:modelValue', next)\n } else {\n emit('update:modelValue', [...current, day.date])\n }\n } else if (props.selectionMode === 'range') {\n if (!rangeStart.value) {\n rangeStart.value = day.date\n } else {\n const start = rangeStart.value\n const end = day.date\n rangeStart.value = null\n const ordered = start.getTime() <= end.getTime()\n ? { start, end }\n : { start: end, end: start }\n emit('update:modelValue', ordered)\n }\n }\n}\n\nfunction handleDayHover(day: CalendarDayContext) {\n if (props.selectionMode === 'range' && rangeStart.value) {\n hoveredDate.value = day.date\n }\n}\n\nfunction prevMonth() {\n if (currentMonth.value === 0) {\n currentMonth.value = 11\n currentYear.value--\n emit('update:year', currentYear.value)\n } else {\n currentMonth.value--\n }\n emit('update:month', currentMonth.value)\n emit('navigate', 'prev', currentMonth.value, currentYear.value)\n}\n\nfunction nextMonth() {\n if (currentMonth.value === 11) {\n currentMonth.value = 0\n currentYear.value++\n emit('update:year', currentYear.value)\n } else {\n currentMonth.value++\n }\n emit('update:month', currentMonth.value)\n emit('navigate', 'next', currentMonth.value, currentYear.value)\n}\n</script>\n\n<template>\n <div class=\"mint-calendar\">\n <div v-if=\"showNavigation\" class=\"mint-calendar__header\">\n <button type=\"button\" class=\"mint-calendar__nav-btn\" aria-label=\"Previous month\" @click=\"prevMonth\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <slot name=\"header\" :month=\"currentMonth\" :year=\"currentYear\" :prev-month=\"prevMonth\" :next-month=\"nextMonth\">\n <span class=\"mint-calendar__title\">{{ monthLabel }}</span>\n </slot>\n <button type=\"button\" class=\"mint-calendar__nav-btn\" aria-label=\"Next month\" @click=\"nextMonth\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <div class=\"mint-calendar__weekdays\">\n <span\n v-for=\"(label, i) in weekDayLabels\"\n :key=\"i\"\n class=\"mint-calendar__weekday\"\n >\n <slot name=\"week-day\" :day-name=\"label\" :index=\"i\">{{ label }}</slot>\n </span>\n </div>\n\n <div class=\"mint-calendar__grid\">\n <button\n v-for=\"(day, i) in calendarDays\"\n :key=\"i\"\n type=\"button\"\n :disabled=\"day.isDisabled\"\n :class=\"[\n 'mint-calendar__day',\n {\n 'mint-calendar__day--today': day.isToday,\n 'mint-calendar__day--selected': day.isSelected,\n 'mint-calendar__day--in-range': day.isInRange,\n 'mint-calendar__day--disabled': day.isDisabled,\n 'mint-calendar__day--outside': day.isOutsideMonth,\n 'mint-calendar__day--interactive': selectionMode !== 'none' && !day.isDisabled,\n },\n ]\"\n @click=\"handleDayClick(day)\"\n @mouseenter=\"handleDayHover(day)\"\n >\n <slot name=\"day-content\" :day=\"day\">\n <span class=\"mint-calendar__day-number\">{{ day.dayOfMonth }}</span>\n <div v-if=\"day.markers.length > 0\" class=\"mint-calendar__markers\">\n <span\n v-for=\"(marker, mi) in day.markers.slice(0, 3)\"\n :key=\"mi\"\n :class=\"[\n 'mint-calendar__marker',\n `mint-calendar__marker--${marker.type ?? 'dot'}`,\n ]\"\n :style=\"marker.color ? { '--marker-color': marker.color } : {}\"\n :title=\"marker.label\"\n />\n </div>\n </slot>\n </button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Month calendar for single date, multi-date, or range selection with markers and navigation. */\nimport { ref, computed, watch } from 'vue'\nimport type { CalendarSelectionMode, CalendarMarker, CalendarDayContext } from '../types'\n\n/**\n * Calendar - Month calendar with date selection, range selection, and custom markers.\n *\n * @example\n * ```vue\n * <!-- Single date selection -->\n * <Calendar v-model=\"selectedDate\" />\n *\n * <!-- Range selection -->\n * <Calendar v-model=\"dateRange\" selection-mode=\"range\" />\n *\n * <!-- With markers -->\n * <Calendar :markers=\"[{ date: '2024-01-15', color: '#ff0000', label: 'Event' }]\" />\n * ```\n */\ninterface Props {\n /** Selected date(s) - type depends on selectionMode */\n modelValue?: Date | Date[] | { start: Date; end: Date } | null\n /** Selection behavior mode */\n selectionMode?: CalendarSelectionMode\n /** Display month (0-11) */\n month?: number\n /** Display year */\n year?: number\n /** Always show 6 weeks (42 days) */\n fixedWeeks?: boolean\n /** First day of week (0=Sunday, 1=Monday, etc.) */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /** Show days from adjacent months */\n showOutsideDays?: boolean\n /** Show month navigation buttons */\n showNavigation?: boolean\n /** Visual markers on specific dates */\n markers?: CalendarMarker[]\n /** Earliest selectable date */\n minDate?: Date | string\n /** Latest selectable date */\n maxDate?: Date | string\n /** Explicitly disabled dates */\n disabledDates?: Array<Date | string>\n /** Custom disabled date logic */\n isDateDisabled?: (date: Date) => boolean\n /** Locale for date formatting */\n locale?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n selectionMode: 'single',\n fixedWeeks: true,\n weekStartsOn: 1,\n showOutsideDays: true,\n showNavigation: true,\n markers: () => [],\n disabledDates: () => [],\n locale: 'en-US',\n})\n\n/**\n * @event update:modelValue - Emitted when date selection changes (v-model support)\n * @event update:month - Emitted when displayed month changes\n * @event update:year - Emitted when displayed year changes\n * @event day-click - Emitted when a day is clicked, includes day context\n * @event navigate - Emitted when month navigation occurs\n */\nconst emit = defineEmits<{\n 'update:modelValue': [value: Date | Date[] | { start: Date; end: Date } | null]\n 'update:month': [month: number]\n 'update:year': [year: number]\n 'day-click': [context: CalendarDayContext]\n navigate: [direction: 'prev' | 'next', month: number, year: number]\n}>()\n\nconst today = new Date()\ntoday.setHours(0, 0, 0, 0)\n\nconst currentMonth = ref(props.month ?? today.getMonth())\nconst currentYear = ref(props.year ?? today.getFullYear())\n\n// Range hover tracking\nconst hoveredDate = ref<Date | null>(null)\n\nwatch(() => props.month, (val) => { if (val !== undefined) currentMonth.value = val })\nwatch(() => props.year, (val) => { if (val !== undefined) currentYear.value = val })\n\nconst monthLabel = computed(() => {\n const date = new Date(currentYear.value, currentMonth.value, 1)\n return date.toLocaleDateString(props.locale, { month: 'long', year: 'numeric' })\n})\n\nconst weekDayLabels = computed(() => {\n const labels: string[] = []\n // Use Jan 7, 2024 (Sunday) as reference, then offset by weekStartsOn\n const base = new Date(2024, 0, 7 + props.weekStartsOn)\n for (let i = 0; i < 7; i++) {\n const d = new Date(base)\n d.setDate(d.getDate() + i)\n labels.push(d.toLocaleDateString(props.locale, { weekday: 'short' }))\n }\n return labels\n})\n\nfunction toDateKey(d: Date): string {\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n\nfunction parseDate(val: Date | string): Date {\n if (val instanceof Date) return val\n const d = new Date(val + 'T00:00:00')\n return d\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n}\n\nconst disabledDateSet = computed(() => {\n const set = new Set<string>()\n for (const d of props.disabledDates) {\n const parsed = parseDate(d)\n set.add(toDateKey(parsed))\n }\n return set\n})\n\nconst markerMap = computed(() => {\n const map = new Map<string, CalendarMarker[]>()\n for (const marker of props.markers) {\n const date = parseDate(marker.date)\n const key = toDateKey(date)\n const markers = map.get(key)\n if (markers) {\n markers.push(marker)\n } else {\n map.set(key, [marker])\n }\n }\n return map\n})\n\nfunction isDateSelected(date: Date): boolean {\n const val = props.modelValue\n if (!val) return false\n if (val instanceof Date) return isSameDay(date, val)\n if (Array.isArray(val)) return val.some(d => isSameDay(date, d))\n if ('start' in val && 'end' in val) {\n return isSameDay(date, val.start) || isSameDay(date, val.end)\n }\n return false\n}\n\nfunction isInRange(date: Date): boolean {\n if (props.selectionMode !== 'range') return false\n const val = props.modelValue\n if (!val || !('start' in (val as object))) return false\n const range = val as { start: Date; end: Date }\n\n const t = date.getTime()\n const start = range.start?.getTime()\n if (!start) return false\n\n // If hovering during selection (before end is set)\n if (!range.end && hoveredDate.value) {\n const hov = hoveredDate.value.getTime()\n const [lo, hi] = start <= hov ? [start, hov] : [hov, start]\n return t > lo && t < hi\n }\n\n // Complete range\n if (range.end) {\n const end = range.end.getTime()\n return t > start && t < end\n }\n\n return false\n}\n\nfunction isDisabled(date: Date): boolean {\n if (disabledDateSet.value.has(toDateKey(date))) return true\n if (props.isDateDisabled?.(date)) return true\n if (props.minDate) {\n const min = parseDate(props.minDate)\n if (date < min) return true\n }\n if (props.maxDate) {\n const max = parseDate(props.maxDate)\n if (date > max) return true\n }\n return false\n}\n\nconst calendarDays = computed<CalendarDayContext[]>(() => {\n const first = new Date(currentYear.value, currentMonth.value, 1)\n const startDow = first.getDay()\n const offset = (startDow - props.weekStartsOn + 7) % 7\n\n const totalCells = props.fixedWeeks ? 42 : (() => {\n const daysInMonth = new Date(currentYear.value, currentMonth.value + 1, 0).getDate()\n const needed = offset + daysInMonth\n return Math.ceil(needed / 7) * 7\n })()\n\n const days: CalendarDayContext[] = []\n for (let i = 0; i < totalCells; i++) {\n const date = new Date(currentYear.value, currentMonth.value, 1 - offset + i)\n date.setHours(0, 0, 0, 0)\n const key = toDateKey(date)\n days.push({\n date,\n dayOfMonth: date.getDate(),\n isToday: isSameDay(date, today),\n isSelected: isDateSelected(date),\n isInRange: isInRange(date),\n isDisabled: isDisabled(date),\n isOutsideMonth: date.getMonth() !== currentMonth.value,\n markers: markerMap.value.get(key) ?? [],\n })\n }\n return days\n})\n\n// Range selection state\nconst rangeStart = ref<Date | null>(null)\n\nfunction handleDayClick(day: CalendarDayContext) {\n if (day.isDisabled) return\n if (!props.showOutsideDays && day.isOutsideMonth) return\n\n emit('day-click', day)\n\n if (props.selectionMode === 'none') return\n\n if (props.selectionMode === 'single') {\n emit('update:modelValue', day.date)\n } else if (props.selectionMode === 'multiple') {\n const current = (props.modelValue as Date[] | undefined) ?? []\n const idx = current.findIndex(d => isSameDay(d, day.date))\n if (idx >= 0) {\n const next = [...current]\n next.splice(idx, 1)\n emit('update:modelValue', next)\n } else {\n emit('update:modelValue', [...current, day.date])\n }\n } else if (props.selectionMode === 'range') {\n if (!rangeStart.value) {\n rangeStart.value = day.date\n } else {\n const start = rangeStart.value\n const end = day.date\n rangeStart.value = null\n const ordered = start.getTime() <= end.getTime()\n ? { start, end }\n : { start: end, end: start }\n emit('update:modelValue', ordered)\n }\n }\n}\n\nfunction handleDayHover(day: CalendarDayContext) {\n if (props.selectionMode === 'range' && rangeStart.value) {\n hoveredDate.value = day.date\n }\n}\n\nfunction prevMonth() {\n if (currentMonth.value === 0) {\n currentMonth.value = 11\n currentYear.value--\n emit('update:year', currentYear.value)\n } else {\n currentMonth.value--\n }\n emit('update:month', currentMonth.value)\n emit('navigate', 'prev', currentMonth.value, currentYear.value)\n}\n\nfunction nextMonth() {\n if (currentMonth.value === 11) {\n currentMonth.value = 0\n currentYear.value++\n emit('update:year', currentYear.value)\n } else {\n currentMonth.value++\n }\n emit('update:month', currentMonth.value)\n emit('navigate', 'next', currentMonth.value, currentYear.value)\n}\n</script>\n\n<template>\n <div class=\"mint-calendar\">\n <div v-if=\"showNavigation\" class=\"mint-calendar__header\">\n <button type=\"button\" class=\"mint-calendar__nav-btn\" aria-label=\"Previous month\" @click=\"prevMonth\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <slot name=\"header\" :month=\"currentMonth\" :year=\"currentYear\" :prev-month=\"prevMonth\" :next-month=\"nextMonth\">\n <span class=\"mint-calendar__title\">{{ monthLabel }}</span>\n </slot>\n <button type=\"button\" class=\"mint-calendar__nav-btn\" aria-label=\"Next month\" @click=\"nextMonth\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <div class=\"mint-calendar__weekdays\">\n <span\n v-for=\"(label, i) in weekDayLabels\"\n :key=\"i\"\n class=\"mint-calendar__weekday\"\n >\n <slot name=\"week-day\" :day-name=\"label\" :index=\"i\">{{ label }}</slot>\n </span>\n </div>\n\n <div class=\"mint-calendar__grid\">\n <button\n v-for=\"(day, i) in calendarDays\"\n :key=\"i\"\n type=\"button\"\n :disabled=\"day.isDisabled\"\n :class=\"[\n 'mint-calendar__day',\n {\n 'mint-calendar__day--today': day.isToday,\n 'mint-calendar__day--selected': day.isSelected,\n 'mint-calendar__day--in-range': day.isInRange,\n 'mint-calendar__day--disabled': day.isDisabled,\n 'mint-calendar__day--outside': day.isOutsideMonth,\n 'mint-calendar__day--interactive': selectionMode !== 'none' && !day.isDisabled,\n },\n ]\"\n @click=\"handleDayClick(day)\"\n @mouseenter=\"handleDayHover(day)\"\n >\n <slot name=\"day-content\" :day=\"day\">\n <span class=\"mint-calendar__day-number\">{{ day.dayOfMonth }}</span>\n <div v-if=\"day.markers.length > 0\" class=\"mint-calendar__markers\">\n <span\n v-for=\"(marker, mi) in day.markers.slice(0, 3)\"\n :key=\"mi\"\n :class=\"[\n 'mint-calendar__marker',\n `mint-calendar__marker--${marker.type ?? 'dot'}`,\n ]\"\n :style=\"marker.color ? { '--marker-color': marker.color } : {}\"\n :title=\"marker.label\"\n />\n </div>\n </slot>\n </button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Content card with optional scroll lock, or a transparent flex layout shell with configurable direction and gap. */\nimport { computed } from 'vue'\n\ninterface Props {\n /** Makes the container scrollable (overflow-y: auto). Ignored when direction is set. */\n scrollable?: boolean\n /** Renders as a transparent flex container instead of a card. */\n direction?: 'row' | 'column'\n /** Flex gap between children. Only applies when direction is set. */\n gap?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n scrollable: false,\n gap: '1rem',\n})\n\nconst isLayout = computed(() => !!props.direction)\n</script>\n\n<template>\n <div\n class=\"mint-container\"\n :class=\"\n isLayout\n ? ['mint-container--layout', direction === 'row' ? 'mint-container--row' : 'mint-container--column']\n : ['mint-container--card', scrollable ? 'mint-container--scrollable' : '']\n \"\n :style=\"isLayout ? { gap } : undefined\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Content card with optional scroll lock, or a transparent flex layout shell with configurable direction and gap. */\nimport { computed } from 'vue'\n\ninterface Props {\n /** Makes the container scrollable (overflow-y: auto). Ignored when direction is set. */\n scrollable?: boolean\n /** Renders as a transparent flex container instead of a card. */\n direction?: 'row' | 'column'\n /** Flex gap between children. Only applies when direction is set. */\n gap?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n scrollable: false,\n gap: '1rem',\n})\n\nconst isLayout = computed(() => !!props.direction)\n</script>\n\n<template>\n <div\n class=\"mint-container\"\n :class=\"\n isLayout\n ? ['mint-container--layout', direction === 'row' ? 'mint-container--row' : 'mint-container--column']\n : ['mint-container--card', scrollable ? 'mint-container--scrollable' : '']\n \"\n :style=\"isLayout ? { gap } : undefined\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Horizontal or vertical rule with optional inline text label at center or left. */\ninterface Props {\n vertical?: boolean\n label?: string\n align?: 'center' | 'left'\n spacing?: 'sm' | 'md' | 'lg'\n}\n\nwithDefaults(defineProps<Props>(), {\n vertical: false,\n label: undefined,\n align: 'center',\n spacing: 'md',\n})\n</script>\n\n<template>\n <div\n v-if=\"vertical\"\n :class=\"[\n 'mint-divider',\n 'mint-divider--vertical',\n `mint-divider--${spacing}`,\n ]\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n />\n <div\n v-else\n :class=\"[\n 'mint-divider',\n `mint-divider--${spacing}`,\n label ? `mint-divider--labeled mint-divider--${align}` : '',\n ]\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n >\n <template v-if=\"label\">\n <span v-if=\"align === 'center'\" class=\"mint-divider__line\" />\n <span class=\"mint-divider__label\">{{ label }}</span>\n <span class=\"mint-divider__line\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Horizontal or vertical rule with optional inline text label at center or left. */\ninterface Props {\n vertical?: boolean\n label?: string\n align?: 'center' | 'left'\n spacing?: 'sm' | 'md' | 'lg'\n}\n\nwithDefaults(defineProps<Props>(), {\n vertical: false,\n label: undefined,\n align: 'center',\n spacing: 'md',\n})\n</script>\n\n<template>\n <div\n v-if=\"vertical\"\n :class=\"[\n 'mint-divider',\n 'mint-divider--vertical',\n `mint-divider--${spacing}`,\n ]\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n />\n <div\n v-else\n :class=\"[\n 'mint-divider',\n `mint-divider--${spacing}`,\n label ? `mint-divider--labeled mint-divider--${align}` : '',\n ]\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n >\n <template v-if=\"label\">\n <span v-if=\"align === 'center'\" class=\"mint-divider__line\" />\n <span class=\"mint-divider__label\">{{ label }}</span>\n <span class=\"mint-divider__line\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/** Renders a breadcrumb trail where ancestors are links or emit-based buttons and the last item is the current page. */\nimport { computed, ref, watch } from 'vue'\nimport type { BreadcrumbItem, BreadcrumbItemInput } from '../types'\nimport { normalizeLabelItemInput } from '../utils/items'\n\ninterface Props {\n items: BreadcrumbItemInput[]\n separator?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n separator: '/',\n})\n\nconst emit = defineEmits<{\n navigate: [item: BreadcrumbItem]\n}>()\n\nconst normalizedItems = computed<BreadcrumbItem[]>(() =>\n props.items.map(normalizeLabelItemInput)\n)\n\n/** Trails longer than this collapse their middle into \"…\" (4e). */\nconst MAX_VISIBLE = 4\n\nconst expanded = ref(false)\n\n// A new trail (navigation) starts collapsed again; keyed on labels so a parent\n// re-render with an equal inline array does not collapse it.\nwatch(() => normalizedItems.value.map(item => item.label).join('\\u0000'), () => {\n expanded.value = false\n})\n\n/** Visible segments with their index in the full trail; `null` marks the collapsed \"…\". */\nconst segments = computed<({ item: BreadcrumbItem; index: number } | null)[]>(() => {\n const all = normalizedItems.value.map((item, index) => ({ item, index }))\n if (expanded.value || all.length <= MAX_VISIBLE) return all\n return [all[0], null, ...all.slice(-2)]\n})\n\nconst hiddenCount = computed(() => normalizedItems.value.length - 3)\n\n/** ID-like segments (EXP-042) render mono. */\nfunction isIdLabel(label: string): boolean {\n return /^[A-Z]+-\\d+$/.test(label)\n}\n\nfunction handleClick(item: BreadcrumbItem) {\n if (!item.href) {\n emit('navigate', item)\n }\n}\n</script>\n\n<template>\n <nav class=\"mint-breadcrumb\" aria-label=\"Breadcrumb\">\n <ol class=\"mint-breadcrumb__list\">\n <li\n v-for=\"(segment, position) in segments\"\n :key=\"segment ? segment.index : 'ellipsis'\"\n class=\"mint-breadcrumb__item\"\n >\n <button\n v-if=\"!segment\"\n type=\"button\"\n class=\"mint-breadcrumb__link mint-breadcrumb__ellipsis\"\n :aria-label=\"`Show ${hiddenCount} hidden levels`\"\n :aria-expanded=\"false\"\n @click=\"expanded = true\"\n >\n …\n </button>\n <slot v-else name=\"item\" :item=\"segment.item\" :index=\"segment.index\" :is-last=\"segment.index === normalizedItems.length - 1\">\n <a\n v-if=\"segment.item.href && segment.index !== normalizedItems.length - 1\"\n :href=\"segment.item.href\"\n :class=\"['mint-breadcrumb__link', { 'mint-breadcrumb__segment--id': isIdLabel(segment.item.label) }]\"\n >\n {{ segment.item.label }}\n </a>\n <button\n v-else-if=\"segment.index !== normalizedItems.length - 1\"\n :class=\"['mint-breadcrumb__link', { 'mint-breadcrumb__segment--id': isIdLabel(segment.item.label) }]\"\n @click=\"handleClick(segment.item)\"\n >\n {{ segment.item.label }}\n </button>\n <span\n v-else\n :class=\"['mint-breadcrumb__current', { 'mint-breadcrumb__segment--id': isIdLabel(segment.item.label) }]\"\n aria-current=\"page\"\n >\n {{ segment.item.label }}\n </span>\n </slot>\n <span\n v-if=\"position !== segments.length - 1\"\n class=\"mint-breadcrumb__separator\"\n aria-hidden=\"true\"\n >\n <slot name=\"separator\">\n <svg v-if=\"separator === '/'\" class=\"mint-breadcrumb__chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n <template v-else>{{ separator }}</template>\n </slot>\n </span>\n </li>\n </ol>\n </nav>\n</template>\n","<script setup lang=\"ts\">\n/** Renders a breadcrumb trail where ancestors are links or emit-based buttons and the last item is the current page. */\nimport { computed, ref, watch } from 'vue'\nimport type { BreadcrumbItem, BreadcrumbItemInput } from '../types'\nimport { normalizeLabelItemInput } from '../utils/items'\n\ninterface Props {\n items: BreadcrumbItemInput[]\n separator?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n separator: '/',\n})\n\nconst emit = defineEmits<{\n navigate: [item: BreadcrumbItem]\n}>()\n\nconst normalizedItems = computed<BreadcrumbItem[]>(() =>\n props.items.map(normalizeLabelItemInput)\n)\n\n/** Trails longer than this collapse their middle into \"…\" (4e). */\nconst MAX_VISIBLE = 4\n\nconst expanded = ref(false)\n\n// A new trail (navigation) starts collapsed again; keyed on labels so a parent\n// re-render with an equal inline array does not collapse it.\nwatch(() => normalizedItems.value.map(item => item.label).join('\\u0000'), () => {\n expanded.value = false\n})\n\n/** Visible segments with their index in the full trail; `null` marks the collapsed \"…\". */\nconst segments = computed<({ item: BreadcrumbItem; index: number } | null)[]>(() => {\n const all = normalizedItems.value.map((item, index) => ({ item, index }))\n if (expanded.value || all.length <= MAX_VISIBLE) return all\n return [all[0], null, ...all.slice(-2)]\n})\n\nconst hiddenCount = computed(() => normalizedItems.value.length - 3)\n\n/** ID-like segments (EXP-042) render mono. */\nfunction isIdLabel(label: string): boolean {\n return /^[A-Z]+-\\d+$/.test(label)\n}\n\nfunction handleClick(item: BreadcrumbItem) {\n if (!item.href) {\n emit('navigate', item)\n }\n}\n</script>\n\n<template>\n <nav class=\"mint-breadcrumb\" aria-label=\"Breadcrumb\">\n <ol class=\"mint-breadcrumb__list\">\n <li\n v-for=\"(segment, position) in segments\"\n :key=\"segment ? segment.index : 'ellipsis'\"\n class=\"mint-breadcrumb__item\"\n >\n <button\n v-if=\"!segment\"\n type=\"button\"\n class=\"mint-breadcrumb__link mint-breadcrumb__ellipsis\"\n :aria-label=\"`Show ${hiddenCount} hidden levels`\"\n :aria-expanded=\"false\"\n @click=\"expanded = true\"\n >\n …\n </button>\n <slot v-else name=\"item\" :item=\"segment.item\" :index=\"segment.index\" :is-last=\"segment.index === normalizedItems.length - 1\">\n <a\n v-if=\"segment.item.href && segment.index !== normalizedItems.length - 1\"\n :href=\"segment.item.href\"\n :class=\"['mint-breadcrumb__link', { 'mint-breadcrumb__segment--id': isIdLabel(segment.item.label) }]\"\n >\n {{ segment.item.label }}\n </a>\n <button\n v-else-if=\"segment.index !== normalizedItems.length - 1\"\n :class=\"['mint-breadcrumb__link', { 'mint-breadcrumb__segment--id': isIdLabel(segment.item.label) }]\"\n @click=\"handleClick(segment.item)\"\n >\n {{ segment.item.label }}\n </button>\n <span\n v-else\n :class=\"['mint-breadcrumb__current', { 'mint-breadcrumb__segment--id': isIdLabel(segment.item.label) }]\"\n aria-current=\"page\"\n >\n {{ segment.item.label }}\n </span>\n </slot>\n <span\n v-if=\"position !== segments.length - 1\"\n class=\"mint-breadcrumb__separator\"\n aria-hidden=\"true\"\n >\n <slot name=\"separator\">\n <svg v-if=\"separator === '/'\" class=\"mint-breadcrumb__chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n <template v-else>{{ separator }}</template>\n </slot>\n </span>\n </li>\n </ol>\n </nav>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Generated form for a control model built with `defineControlModel()`.\n *\n * The control model holds the controls, sections, columns, the submit / cancel\n * bar (`actions`) and `enhancements` (dynamic options, validators, a submit\n * handler and field callbacks). Bind the values with `v-model`; the `submit`\n * event carries only the values of the visible fields.\n *\n * Exposes `form`, `validate`, `reset`, `updateSchema`, `goNext`, `goBack`,\n * `goToStep`, and `builder` for imperative control via template refs.\n *\n * Slots:\n * - `field:<name>` — override a single field's input component\n * - `section:<id>` — replace an entire section body\n * - `section:<id>:after` — inject content after a section\n * - `actions` — replace the default action bar when the model sets `actions`\n *\n * @example Recommended\n * ```vue\n * <FormBuilder v-model=\"values\" :spec=\"formModel\" />\n * ```\n */\nimport { computed, ref } from 'vue'\nimport type { FormSchema } from '../types/form-builder'\nimport {\n controlsToFormSchema,\n getControlDefaults,\n type ControlModelBinding,\n} from '../composables/useControlSchema'\nimport FormSchemaInternal from './internal/FormSchemaInternal.vue'\n\ninterface Props {\n /** Control model built with defineControlModel(). Optional: without it the form is empty. */\n spec?: ControlModelBinding\n modelValue?: Record<string, unknown>\n loading?: boolean\n disabled?: boolean\n size?: 'sm' | 'md' | 'lg'\n readonly?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n spec: undefined,\n modelValue: undefined,\n loading: false,\n disabled: false,\n size: undefined,\n readonly: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [data: Record<string, unknown>]\n submit: [data: Record<string, unknown>]\n cancel: []\n}>()\n\nconst schema = computed<FormSchema>(() =>\n props.spec ? controlsToFormSchema(props.spec.controls, props.spec.controlOptions) : { sections: [] },\n)\n\nconst defaults = computed<Record<string, unknown>>(() => ({\n ...(props.spec ? getControlDefaults(props.spec.controls) : {}),\n ...(props.spec?.controlOptions.initialValues ?? {}),\n}))\n\nconst inner = ref<InstanceType<typeof FormSchemaInternal> | null>(null)\n\ndefineExpose({\n get form() { return inner.value?.form },\n get builder() { return inner.value?.builder },\n validate: () => inner.value?.validate(),\n reset: (...args: Parameters<InstanceType<typeof FormSchemaInternal>['reset']>) => inner.value?.reset(...args),\n updateSchema: (...args: Parameters<InstanceType<typeof FormSchemaInternal>['updateSchema']>) => inner.value?.updateSchema(...args),\n goNext: () => inner.value?.goNext(),\n goBack: () => inner.value?.goBack(),\n goToStep: (step: number) => inner.value?.goToStep(step),\n})\n</script>\n\n<template>\n <FormSchemaInternal\n ref=\"inner\"\n :schema=\"schema\"\n :defaults=\"defaults\"\n :model-value=\"modelValue\"\n :enhancements=\"spec?.controlOptions.enhancements\"\n :loading=\"loading\"\n :disabled=\"disabled\"\n :size=\"size\"\n :readonly=\"readonly\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @submit=\"emit('submit', $event)\"\n @cancel=\"emit('cancel')\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]=\"slotProps\">\n <slot :name=\"name\" v-bind=\"slotProps ?? {}\" />\n </template>\n </FormSchemaInternal>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Generated form for a control model built with `defineControlModel()`.\n *\n * The control model holds the controls, sections, columns, the submit / cancel\n * bar (`actions`) and `enhancements` (dynamic options, validators, a submit\n * handler and field callbacks). Bind the values with `v-model`; the `submit`\n * event carries only the values of the visible fields.\n *\n * Exposes `form`, `validate`, `reset`, `updateSchema`, `goNext`, `goBack`,\n * `goToStep`, and `builder` for imperative control via template refs.\n *\n * Slots:\n * - `field:<name>` — override a single field's input component\n * - `section:<id>` — replace an entire section body\n * - `section:<id>:after` — inject content after a section\n * - `actions` — replace the default action bar when the model sets `actions`\n *\n * @example Recommended\n * ```vue\n * <FormBuilder v-model=\"values\" :spec=\"formModel\" />\n * ```\n */\nimport { computed, ref } from 'vue'\nimport type { FormSchema } from '../types/form-builder'\nimport {\n controlsToFormSchema,\n getControlDefaults,\n type ControlModelBinding,\n} from '../composables/useControlSchema'\nimport FormSchemaInternal from './internal/FormSchemaInternal.vue'\n\ninterface Props {\n /** Control model built with defineControlModel(). Optional: without it the form is empty. */\n spec?: ControlModelBinding\n modelValue?: Record<string, unknown>\n loading?: boolean\n disabled?: boolean\n size?: 'sm' | 'md' | 'lg'\n readonly?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n spec: undefined,\n modelValue: undefined,\n loading: false,\n disabled: false,\n size: undefined,\n readonly: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [data: Record<string, unknown>]\n submit: [data: Record<string, unknown>]\n cancel: []\n}>()\n\nconst schema = computed<FormSchema>(() =>\n props.spec ? controlsToFormSchema(props.spec.controls, props.spec.controlOptions) : { sections: [] },\n)\n\nconst defaults = computed<Record<string, unknown>>(() => ({\n ...(props.spec ? getControlDefaults(props.spec.controls) : {}),\n ...(props.spec?.controlOptions.initialValues ?? {}),\n}))\n\nconst inner = ref<InstanceType<typeof FormSchemaInternal> | null>(null)\n\ndefineExpose({\n get form() { return inner.value?.form },\n get builder() { return inner.value?.builder },\n validate: () => inner.value?.validate(),\n reset: (...args: Parameters<InstanceType<typeof FormSchemaInternal>['reset']>) => inner.value?.reset(...args),\n updateSchema: (...args: Parameters<InstanceType<typeof FormSchemaInternal>['updateSchema']>) => inner.value?.updateSchema(...args),\n goNext: () => inner.value?.goNext(),\n goBack: () => inner.value?.goBack(),\n goToStep: (step: number) => inner.value?.goToStep(step),\n})\n</script>\n\n<template>\n <FormSchemaInternal\n ref=\"inner\"\n :schema=\"schema\"\n :defaults=\"defaults\"\n :model-value=\"modelValue\"\n :enhancements=\"spec?.controlOptions.enhancements\"\n :loading=\"loading\"\n :disabled=\"disabled\"\n :size=\"size\"\n :readonly=\"readonly\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @submit=\"emit('submit', $event)\"\n @cancel=\"emit('cancel')\"\n >\n <template v-for=\"(_, name) in $slots\" #[name]=\"slotProps\">\n <slot :name=\"name\" v-bind=\"slotProps ?? {}\" />\n </template>\n </FormSchemaInternal>\n</template>\n","// Components exported from the package root. Lab, shell, data and runtime\n// components are exported from their subpath entries (`src/lab.ts`, ...).\n\n// Base components\nexport { default as BaseButton } from './BaseButton.vue'\nexport { default as BaseInput } from './BaseInput.vue'\nexport { default as BaseSelect } from './BaseSelect.vue'\nexport { default as BaseCheckbox } from './BaseCheckbox.vue'\nexport { default as BaseRadioGroup } from './BaseRadioGroup.vue'\nexport { default as BaseSlider } from './BaseSlider.vue'\nexport { default as BaseTabs } from './BaseTabs.vue'\nexport { default as BaseModal } from './BaseModal.vue'\nexport { default as SegmentedControl } from './SegmentedControl.vue'\nexport { default as BasePill } from './BasePill.vue'\nexport { default as Calendar } from './Calendar.vue'\nexport { default as DataFrame } from './DataFrame.vue'\n\n// Form components\nexport { default as FormField } from './FormField.vue'\nexport { default as DatePicker } from './DatePicker.vue'\nexport { default as NumberInput } from './NumberInput.vue'\nexport { default as FileUploader } from './FileUploader.vue'\n\n// Feedback components\nexport { default as AlertBox } from './AlertBox.vue'\nexport { default as AppToastContainer } from './AppToastContainer.vue'\n\n// Action components\nexport { default as ActionMenu } from './ActionMenu.vue'\nexport { default as ThemeToggle } from './ThemeToggle.vue'\n\n// Layout components\nexport { default as CollapsibleCard } from './CollapsibleCard.vue'\nexport { default as PluginWorkspaceView } from './PluginWorkspaceView.vue'\nexport { default as AppContainer } from './AppContainer.vue'\nexport { default as PluginIcon } from './PluginIcon.vue'\n\n// Utility components\nexport { default as Skeleton } from './Skeleton.vue'\nexport { default as LoadingSpinner } from './LoadingSpinner.vue'\nexport { default as Divider } from './Divider.vue'\nexport { default as ProgressBar } from './ProgressBar.vue'\nexport { default as Avatar } from './Avatar.vue'\nexport { default as EmptyState } from './EmptyState.vue'\nexport { default as Breadcrumb } from './Breadcrumb.vue'\nexport { default as Tooltip } from './Tooltip.vue'\nexport { default as ConfirmDialog } from './ConfirmDialog.vue'\nexport { default as SettingsModal } from './SettingsModal.vue'\n\n// Scientific input components\n\n// Form builder components\nexport { default as FormBuilder } from './FormBuilder.vue'\n\n// Scheduling / booking components\nexport { default as SectionCard } from './SectionCard.vue'\n","import * as rootComponents from './components'\nimport * as dataComponents from './data'\nimport * as labComponents from './lab'\nimport * as runtimeComponents from './runtime'\nimport * as shellComponents from './shell'\n\nconst components = {\n ...rootComponents,\n ...labComponents,\n ...shellComponents,\n ...dataComponents,\n ...runtimeComponents,\n}\n\ntype ComponentRegistryApp = {\n component: (name: string, component: any) => unknown\n}\n\nexport interface MINTSdkPlugin {\n install(app: ComponentRegistryApp): void\n}\n\n/**\n * Vue plugin that registers all MINT SDK components globally, including the\n * components of the `lab`, `shell`, `data` and `runtime` subpaths.\n *\n * @example\n * ```typescript\n * import { createApp } from 'vue'\n * import { MINTSdk } from '@morscherlab/mint-sdk'\n * import '@morscherlab/mint-sdk/styles'\n *\n * const app = createApp(App)\n * app.use(MINTSdk)\n * ```\n */\nexport const MINTSdk: MINTSdkPlugin = {\n install(app) {\n for (const [name, component] of Object.entries(components)) {\n // Check if it's a valid Vue component (has setup, render, or template)\n if (\n component &&\n typeof component === 'object' &&\n ('setup' in component || 'render' in component || '__name' in component)\n ) {\n app.component(name, component)\n }\n }\n },\n}\n\nexport default MINTSdk\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDA,MAAM,QAAQ;;;;;;;;EAkBd,MAAM,OAAO;EAQb,MAAM,wBAAQ,IAAI,KAAK;EACvB,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC;EAEzB,MAAM,eAAe,IAAI,MAAM,SAAS,MAAM,SAAS,CAAC;EACxD,MAAM,cAAc,IAAI,MAAM,QAAQ,MAAM,YAAY,CAAC;EAGzD,MAAM,cAAc,IAAiB,IAAI;EAEzC,YAAY,MAAM,QAAQ,QAAQ;GAAE,IAAI,QAAQ,KAAA,GAAW,aAAa,QAAQ;EAAI,CAAC;EACrF,YAAY,MAAM,OAAO,QAAQ;GAAE,IAAI,QAAQ,KAAA,GAAW,YAAY,QAAQ;EAAI,CAAC;EAEnF,MAAM,aAAa,eAAe;GAEhC,OAAO,IADU,KAAK,YAAY,OAAO,aAAa,OAAO,CACtD,CAAA,CAAK,mBAAmB,MAAM,QAAQ;IAAE,OAAO;IAAQ,MAAM;GAAU,CAAC;EACjF,CAAC;EAED,MAAM,gBAAgB,eAAe;GACnC,MAAM,SAAmB,CAAC;GAE1B,MAAM,OAAO,IAAI,KAAK,MAAM,GAAG,IAAI,MAAM,YAAY;GACrD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,IAAI,KAAK,IAAI;IACvB,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC;IACzB,OAAO,KAAK,EAAE,mBAAmB,MAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC,CAAC;GACtE;GACA,OAAO;EACT,CAAC;EAED,SAAS,UAAU,GAAiB;GAClC,OAAO,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EAC/G;EAEA,SAAS,UAAU,KAA0B;GAC3C,IAAI,eAAe,MAAM,OAAO;GAEhC,uBAAO,IADO,KAAK,MAAM,WAClB;EACT;EAEA,SAAS,UAAU,GAAS,GAAkB;GAC5C,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,KACvC,EAAE,SAAS,MAAM,EAAE,SAAS,KAC5B,EAAE,QAAQ,MAAM,EAAE,QAAQ;EAC9B;EAEA,MAAM,kBAAkB,eAAe;GACrC,MAAM,sBAAM,IAAI,IAAY;GAC5B,KAAK,MAAM,KAAK,MAAM,eAAe;IACnC,MAAM,SAAS,UAAU,CAAC;IAC1B,IAAI,IAAI,UAAU,MAAM,CAAC;GAC3B;GACA,OAAO;EACT,CAAC;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,sBAAM,IAAI,IAA8B;GAC9C,KAAK,MAAM,UAAU,MAAM,SAAS;IAElC,MAAM,MAAM,UADC,UAAU,OAAO,IACR,CAAI;IAC1B,MAAM,UAAU,IAAI,IAAI,GAAG;IAC3B,IAAI,SACF,QAAQ,KAAK,MAAM;SAEnB,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;GAEzB;GACA,OAAO;EACT,CAAC;EAED,SAAS,eAAe,MAAqB;GAC3C,MAAM,MAAM,MAAM;GAClB,IAAI,CAAC,KAAK,OAAO;GACjB,IAAI,eAAe,MAAM,OAAO,UAAU,MAAM,GAAG;GACnD,IAAI,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,MAAK,MAAK,UAAU,MAAM,CAAC,CAAC;GAC/D,IAAI,WAAW,OAAO,SAAS,KAC7B,OAAO,UAAU,MAAM,IAAI,KAAK,KAAK,UAAU,MAAM,IAAI,GAAG;GAE9D,OAAO;EACT;EAEA,SAAS,UAAU,MAAqB;GACtC,IAAI,MAAM,kBAAkB,SAAS,OAAO;GAC5C,MAAM,MAAM,MAAM;GAClB,IAAI,CAAC,OAAO,EAAE,WAAY,MAAiB,OAAO;GAClD,MAAM,QAAQ;GAEd,MAAM,IAAI,KAAK,QAAQ;GACvB,MAAM,QAAQ,MAAM,OAAO,QAAQ;GACnC,IAAI,CAAC,OAAO,OAAO;GAGnB,IAAI,CAAC,MAAM,OAAO,YAAY,OAAO;IACnC,MAAM,MAAM,YAAY,MAAM,QAAQ;IACtC,MAAM,CAAC,IAAI,MAAM,SAAS,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK;IAC1D,OAAO,IAAI,MAAM,IAAI;GACvB;GAGA,IAAI,MAAM,KAAK;IACb,MAAM,MAAM,MAAM,IAAI,QAAQ;IAC9B,OAAO,IAAI,SAAS,IAAI;GAC1B;GAEA,OAAO;EACT;EAEA,SAAS,WAAW,MAAqB;GACvC,IAAI,gBAAgB,MAAM,IAAI,UAAU,IAAI,CAAC,GAAG,OAAO;GACvD,IAAI,MAAM,iBAAiB,IAAI,GAAG,OAAO;GACzC,IAAI,MAAM,SAEJ;QAAA,OADQ,UAAU,MAAM,OACjB,GAAK,OAAO;GAAA;GAEzB,IAAI,MAAM,SAEJ;QAAA,OADQ,UAAU,MAAM,OACjB,GAAK,OAAO;GAAA;GAEzB,OAAO;EACT;EAEA,MAAM,eAAe,eAAqC;GAGxD,MAAM,UADW,IADC,KAAK,YAAY,OAAO,aAAa,OAAO,CAC7C,CAAA,CAAM,OACP,IAAW,MAAM,eAAe,KAAK;GAErD,MAAM,aAAa,MAAM,aAAa,YAAY;IAChD,MAAM,cAAc,IAAI,KAAK,YAAY,OAAO,aAAa,QAAQ,GAAG,CAAC,CAAC,CAAC,QAAQ;IACnF,MAAM,SAAS,SAAS;IACxB,OAAO,KAAK,KAAK,SAAS,CAAC,IAAI;GACjC,EAAA,CAAG;GAEH,MAAM,OAA6B,CAAC;GACpC,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,KAAK;IACnC,MAAM,OAAO,IAAI,KAAK,YAAY,OAAO,aAAa,OAAO,IAAI,SAAS,CAAC;IAC3E,KAAK,SAAS,GAAG,GAAG,GAAG,CAAC;IACxB,MAAM,MAAM,UAAU,IAAI;IAC1B,KAAK,KAAK;KACR;KACA,YAAY,KAAK,QAAQ;KACzB,SAAS,UAAU,MAAM,KAAK;KAC9B,YAAY,eAAe,IAAI;KAC/B,WAAW,UAAU,IAAI;KACzB,YAAY,WAAW,IAAI;KAC3B,gBAAgB,KAAK,SAAS,MAAM,aAAa;KACjD,SAAS,UAAU,MAAM,IAAI,GAAG,KAAK,CAAC;IACxC,CAAC;GACH;GACA,OAAO;EACT,CAAC;EAGD,MAAM,aAAa,IAAiB,IAAI;EAExC,SAAS,eAAe,KAAyB;GAC/C,IAAI,IAAI,YAAY;GACpB,IAAI,CAAC,MAAM,mBAAmB,IAAI,gBAAgB;GAElD,KAAK,aAAa,GAAG;GAErB,IAAI,MAAM,kBAAkB,QAAQ;GAEpC,IAAI,MAAM,kBAAkB,UAC1B,KAAK,qBAAqB,IAAI,IAAI;QAC7B,IAAI,MAAM,kBAAkB,YAAY;IAC7C,MAAM,UAAW,MAAM,cAAqC,CAAC;IAC7D,MAAM,MAAM,QAAQ,WAAU,MAAK,UAAU,GAAG,IAAI,IAAI,CAAC;IACzD,IAAI,OAAO,GAAG;KACZ,MAAM,OAAO,CAAC,GAAG,OAAO;KACxB,KAAK,OAAO,KAAK,CAAC;KAClB,KAAK,qBAAqB,IAAI;IAChC,OACE,KAAK,qBAAqB,CAAC,GAAG,SAAS,IAAI,IAAI,CAAC;GAEpD,OAAO,IAAI,MAAM,kBAAkB,SAAS;IAC1C,IAAI,CAAC,WAAW,OACd,WAAW,QAAQ,IAAI;SAClB;KACL,MAAM,QAAQ,WAAW;KACzB,MAAM,MAAM,IAAI;KAChB,WAAW,QAAQ;KACnB,MAAM,UAAU,MAAM,QAAQ,KAAK,IAAI,QAAQ,IAC3C;MAAE;MAAO;KAAI,IACb;MAAE,OAAO;MAAK,KAAK;KAAM;KAC7B,KAAK,qBAAqB,OAAO;IACnC;GACF;EACF;EAEA,SAAS,eAAe,KAAyB;GAC/C,IAAI,MAAM,kBAAkB,WAAW,WAAW,OAChD,YAAY,QAAQ,IAAI;EAE5B;EAEA,SAAS,YAAY;GACnB,IAAI,aAAa,UAAU,GAAG;IAC5B,aAAa,QAAQ;IACrB,YAAY;IACZ,KAAK,eAAe,YAAY,KAAK;GACvC,OACE,aAAa;GAEf,KAAK,gBAAgB,aAAa,KAAK;GACvC,KAAK,YAAY,QAAQ,aAAa,OAAO,YAAY,KAAK;EAChE;EAEA,SAAS,YAAY;GACnB,IAAI,aAAa,UAAU,IAAI;IAC7B,aAAa,QAAQ;IACrB,YAAY;IACZ,KAAK,eAAe,YAAY,KAAK;GACvC,OACE,aAAa;GAEf,KAAK,gBAAgB,aAAa,KAAK;GACvC,KAAK,YAAY,QAAQ,aAAa,OAAO,YAAY,KAAK;EAChE;;GAIE,OAAA,UAAA,GAAA,mBAgEM,OAhEN,cAgEM;IA/DO,QAAA,kBAAX,UAAA,GAAA,mBAcM,OAdN,cAcM;KAbJ,mBAIS,UAAA;MAJD,MAAK;MAAS,OAAM;MAAyB,cAAW;MAAkB,SAAO;KACvF,GAAA,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,mBAEM,OAAA;MAFD,SAAQ;MAAY,MAAK;MAAO,QAAO;MAAe,gBAAa;MAAI,kBAAe;MAAQ,mBAAgB;KACjH,GAAA,CAAA,mBAA2B,QAAA,EAArB,GAAE,iBAAgB,CAAA,CAAA,GAAA,EAAA,CAAA,EAAA,CAAA;KAG5B,WAEO,KAAA,QAAA,UAAA;MAFc,OAAO,aAAA;MAAe,MAAM,YAAA;MAA0B;MAAwB;KAAnG,SAEO,CADL,mBAA0D,QAA1D,cAA0D,gBAApB,WAAA,KAAU,GAAA,CAAA,CAAA,CAAA;KAElD,mBAIS,UAAA;MAJD,MAAK;MAAS,OAAM;MAAyB,cAAW;MAAc,SAAO;KACnF,GAAA,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAAA,mBAEM,OAAA;MAFD,SAAQ;MAAY,MAAK;MAAO,QAAO;MAAe,gBAAa;MAAI,kBAAe;MAAQ,mBAAgB;KACjH,GAAA,CAAA,mBAA0B,QAAA,EAApB,GAAE,gBAAe,CAAA,CAAA,GAAA,EAAA,CAAA,EAAA,CAAA;;IAK7B,mBAQM,OARN,cAQM,EAPJ,UAAA,IAAA,GAAA,mBAMO,UAAA,MAAA,WALgB,cAAA,QAAb,OAAO,MAAC;KADlB,OAAA,UAAA,GAAA,mBAMO,QAAA;MAJJ,KAAK;MACN,OAAM;KAEN,GAAA,CAAA,WAAqE,KAAA,QAAA,YAAA;MAA9C,SAAU;MAAQ,OAAO;KAAhD,SAAqE,CAAf,gBAAA,gBAAA,KAAK,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;IAI/D,mBAoCM,OApCN,cAoCM,EAnCJ,UAAA,IAAA,GAAA,mBAkCS,UAAA,MAAA,WAjCY,aAAA,QAAX,KAAK,MAAC;KADhB,OAAA,UAAA,GAAA,mBAkCS,UAAA;MAhCN,KAAK;MACN,MAAK;MACJ,UAAU,IAAI;MACd,OAAK,eAAA,CAAA,sBAAA;OAAyF,6BAAA,IAAI;OAAqD,gCAAA,IAAI;OAAwD,gCAAA,IAAI;OAAuD,gCAAA,IAAI;OAAuD,+BAAA,IAAI;OAA+D,mCAAA,QAAA,kBAAa,UAAA,CAAgB,IAAI;;MAW7a,UAAK,WAAE,eAAe,GAAG;MACzB,eAAU,WAAE,eAAe,GAAG;KAE/B,GAAA,CAAA,WAcO,KAAA,QAAA,eAAA,EAdwB,IAAG,SAc3B,CAbL,mBAAmE,QAAnE,cAAmE,gBAAxB,IAAI,UAAU,GAAA,CAAA,GAC9C,IAAI,QAAQ,SAAM,KAA7B,UAAA,GAAA,mBAWM,OAXN,YAWM,EAVJ,UAAA,IAAA,GAAA,mBASE,UAAA,MAAA,WARuB,IAAI,QAAQ,MAAK,GAAA,CAAA,IAAhC,QAAQ,OAAE;MADpB,OAAA,UAAA,GAAA,mBASE,QAAA;OAPC,KAAK;OACL,OAAK,eAAA,CAAA,yBAAuF,0BAAA,OAAO,QAAI,OAAA,CAAA;OAIvG,OAAK,eAAE,OAAO,QAAK,EAAA,kBAAuB,OAAO,MAAK,IAAA,CAAA,CAAA;OACtD,OAAO,OAAO;;;;;;;;;;;;;;;;;;;;;;EEtV7B,MAAM,QAAQ;EAKd,MAAM,WAAW,eAAe,CAAC,CAAC,MAAM,SAAS;;GAI/C,OAAA,UAAA,GAAA,mBAUM,OAAA;IATJ,OAAK,eAAA,CAAC,kBACS,SAAA,QAA8C,CAAA,0BAAA,QAAA,cAAS,QAAA,wBAAA,wBAAA,IAAkG,CAAA,wBAAA,QAAA,aAAU,+BAAA,EAAA,CAAA,CAAA;IAKjL,OAAK,eAAE,SAAA,QAAQ,EAAA,KAAK,QAAA,IAAG,IAAK,KAAA,CAAS;GAEtC,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GEZF,OAAA,QAAA,YADR,UAAA,GAAA,mBASE,OAAA;;IAPC,OAAK,eAAA;;;KAAiF,iBAAA,QAAA;;IAKvF,MAAK;IACL,oBAAiB;GAEnB,GAAA,MAAA,CAAA,MAAA,UAAA,GAAA,mBAeM,OAAA;;IAbH,OAAK,eAAA;;KAAiD,iBAAA,QAAA;KAAiB,QAAA,QAAK,uCAA0C,QAAA,UAAK;;IAK5H,MAAK;IACL,oBAAiB;GAED,GAAA,CAAA,QAAA,SAAhB,UAAA,GAAA,mBAIW,UAAA,EAAA,KAAA,EAAA,GAAA;IAHG,QAAA,UAAK,YAAjB,UAAA,GAAA,mBAA6D,QAA7D,YAA6D,KAAA,mBAAA,IAAA,IAAA;IAC7D,mBAAoD,QAApD,cAAoD,gBAAf,QAAA,KAAK,GAAA,CAAA;IAC1C,OAAA,OAAA,OAAA,KAAA,mBAAmC,QAAA,EAA7B,OAAM,qBAAoB,GAAA,MAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEjBtC,IAAM,cAAc;;;;;;;;;;;;EAbpB,MAAM,QAAQ;EAId,MAAM,OAAO;EAIb,MAAM,kBAAkB,eACtB,MAAM,MAAM,IAAI,uBAAuB,CACzC;;EAKA,MAAM,WAAW,IAAI,KAAK;EAI1B,YAAY,gBAAgB,MAAM,KAAI,SAAQ,KAAK,KAAK,CAAC,CAAC,KAAK,IAAQ,SAAS;GAC9E,SAAS,QAAQ;EACnB,CAAC;;EAGD,MAAM,WAAW,eAAmE;GAClF,MAAM,MAAM,gBAAgB,MAAM,KAAK,MAAM,WAAW;IAAE;IAAM;GAAM,EAAE;GACxE,IAAI,SAAS,SAAS,IAAI,UAAU,aAAa,OAAO;GACxD,OAAO;IAAC,IAAI;IAAI;IAAM,GAAG,IAAI,MAAM,EAAE;GAAC;EACxC,CAAC;EAED,MAAM,cAAc,eAAe,gBAAgB,MAAM,SAAS,CAAC;;EAGnE,SAAS,UAAU,OAAwB;GACzC,OAAO,eAAe,KAAK,KAAK;EAClC;EAEA,SAAS,YAAY,MAAsB;GACzC,IAAI,CAAC,KAAK,MACR,KAAK,YAAY,IAAI;EAEzB;;GAIE,OAAA,UAAA,GAAA,mBAsDM,OAtDN,YAsDM,CArDJ,mBAoDK,MApDL,YAoDK,EAnDH,UAAA,IAAA,GAAA,mBAkDK,UAAA,MAAA,WAjD2B,SAAA,QAAtB,SAAS,aAAQ;IAD3B,OAAA,UAAA,GAAA,mBAkDK,MAAA;KAhDF,KAAK,UAAU,QAAQ,QAAK;KAC7B,OAAM;IAGG,GAAA,CAAA,CAAA,WADT,UAAA,GAAA,mBASS,UAAA;;KAPP,MAAK;KACL,OAAM;KACL,cAAU,QAAU,YAAA,MAAW;KAC/B,iBAAe;KACf,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,SAAA,QAAQ;IACjB,GAAA,OAED,GAAA,UAAA,KACA,WAsBO,KAAA,QAAA,QAAA;KAtBmB,MAAM,QAAQ;KAAO,OAAO,QAAQ;KAAQ,QAAS,QAAQ,UAAU,gBAAA,MAAgB,SAAM;IAAvH,SAsBO,CApBG,QAAQ,KAAK,QAAQ,QAAQ,UAAU,gBAAA,MAAgB,SAAM,KADrE,UAAA,GAAA,mBAMI,KAAA;;KAJD,MAAM,QAAQ,KAAK;KACnB,OAAK,eAAA,CAAA,yBAAA,EAAA,gCAA8D,UAAU,QAAQ,KAAK,KAAK,EAAA,CAAA,CAAA;IAE7F,GAAA,gBAAA,QAAQ,KAAK,KAAK,GAAA,IAAA,UAAA,KAGV,QAAQ,UAAU,gBAAA,MAAgB,SAAM,KADrD,UAAA,GAAA,mBAMS,UAAA;;KAJN,OAAK,eAAA,CAAA,yBAAA,EAAA,gCAA8D,UAAU,QAAQ,KAAK,KAAK,EAAA,CAAA,CAAA;KAC/F,UAAK,WAAE,YAAY,QAAQ,IAAI;IAE7B,GAAA,gBAAA,QAAQ,KAAK,KAAK,GAAA,IAAA,UAAA,MAEvB,UAAA,GAAA,mBAMO,QAAA;;KAJJ,OAAK,eAAA,CAAA,4BAAA,EAAA,gCAAiE,UAAU,QAAQ,KAAK,KAAK,EAAA,CAAA,CAAA;KACnG,gBAAa;IAEV,GAAA,gBAAA,QAAQ,KAAK,KAAK,GAAA,CAAA,EAAA,GAAA,KAAA,GAAA,CAAA,GAIjB,aAAa,SAAA,MAAS,SAAM,KADpC,UAAA,GAAA,mBAWO,QAXP,YAWO,CANL,WAKO,KAAA,QAAA,aAAA,CAAA,SAAA,CAJM,QAAA,cAAS,OAApB,UAAA,GAAA,mBAEM,OAFN,YAEM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAA0B,QAAA,EAApB,GAAE,gBAAe,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,MAEzB,UAAA,GAAA,mBAA2C,UAAA,EAAA,KAAA,EAAA,GAAA,CAAvB,gBAAA,gBAAA,QAAA,SAAS,GAAA,CAAA,CAAA,GAAA,EAAA,EAAA,CAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EE/DzC,MAAM,QAAQ;EASd,MAAM,OAAO;EAMb,MAAM,SAAS,eACb,MAAM,OAAO,qBAAqB,MAAM,KAAK,UAAU,MAAM,KAAK,cAAc,IAAI,EAAE,UAAU,CAAC,EAAE,CACrG;EAEA,MAAM,WAAW,gBAAyC;GACxD,GAAI,MAAM,OAAO,mBAAmB,MAAM,KAAK,QAAQ,IAAI,CAAC;GAC5D,GAAI,MAAM,MAAM,eAAe,iBAAiB,CAAC;EACnD,EAAE;EAEF,MAAM,QAAQ,IAAoD,IAAI;EAEtE,SAAa;GACX,IAAI,OAAO;IAAE,OAAO,MAAM,OAAO;GAAK;GACtC,IAAI,UAAU;IAAE,OAAO,MAAM,OAAO;GAAQ;GAC5C,gBAAgB,MAAM,OAAO,SAAS;GACtC,QAAQ,GAAG,SAAuE,MAAM,OAAO,MAAM,GAAG,IAAI;GAC5G,eAAe,GAAG,SAA8E,MAAM,OAAO,aAAa,GAAG,IAAI;GACjI,cAAc,MAAM,OAAO,OAAO;GAClC,cAAc,MAAM,OAAO,OAAO;GAClC,WAAW,SAAiB,MAAM,OAAO,SAAS,IAAI;EACxD,CAAC;;GAIC,OAAA,UAAA,GAAA,YAiBqB,4BAAA;IAhBf,SAAA;IAAJ,KAAI;IACH,QAAQ,OAAA;IACR,UAAU,SAAA;IACV,eAAa,QAAA;IACb,cAAc,QAAA,MAAM,eAAe;IACnC,SAAS,QAAA;IACT,UAAU,QAAA;IACV,MAAM,QAAA;IACN,UAAU,QAAA;IACV,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,qBAAsB,MAAM;IACpD,UAAM,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,UAAW,MAAM;IAC7B,UAAM,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,QAAA;GAEiBA,GAAAA,YAAAA,EAAAA,GAAAA,EAAAA,GAAAA,CAAAA,WAAAA,KAAAA,SAAZ,GAAG,SAAI;;KAAc;KACrC,IAAA,SAD6C,cAAS,CACtD,WAA8C,KAAA,QAAjC,MAAI,eAAA,mBAAU,aAAS,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;AG1F1C,IAAM,aAAa;CACjB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL;;;;;;;;;;;;;;;AAwBA,IAAa,UAAyB,EACpC,QAAQ,KAAK;CACX,KAAK,MAAM,CAAC,MAAM,cAAc,OAAO,QAAQ,UAAU,GAEvD,IACE,aACA,OAAO,cAAc,aACpB,WAAW,aAAa,YAAY,aAAa,YAAY,YAE9D,IAAI,UAAU,MAAM,SAAS;AAGnC,EACF"}