@morscherlab/mint-sdk 1.1.5 → 1.1.7

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 (100) hide show
  1. package/dist/{EmptyState-LMPS3keb.js → EmptyState-p90quq8Z.js} +2 -2
  2. package/dist/{EmptyState-LMPS3keb.js.map → EmptyState-p90quq8Z.js.map} +1 -1
  3. package/dist/{ExperimentPopover-D6_RGzTY.js → ExperimentPopover-tLwJ7XF4.js} +3 -3
  4. package/dist/{ExperimentPopover-D6_RGzTY.js.map → ExperimentPopover-tLwJ7XF4.js.map} +1 -1
  5. package/dist/{ExperimentSelectorModal-DcQ38zua.js → ExperimentSelectorModal-B6P2msT4.js} +12 -5
  6. package/dist/ExperimentSelectorModal-B6P2msT4.js.map +1 -0
  7. package/dist/{SettingsModal-Ccq2z-Ms.js → SettingsModal-D7LFUokT.js} +100 -156
  8. package/dist/SettingsModal-D7LFUokT.js.map +1 -0
  9. package/dist/__tests__/components/ActionMenu.test.d.ts +1 -0
  10. package/dist/__tests__/components/BaseModal.test.d.ts +1 -0
  11. package/dist/components/ActionMenu.vue.d.ts +21 -0
  12. package/dist/components/BaseModal.vue.d.ts +17 -1
  13. package/dist/components/ExperimentTimeline.vue.d.ts +1 -1
  14. package/dist/components/GeneratedPluginView.vue.d.ts +3 -3
  15. package/dist/components/GeneratedResultRenderer.vue.d.ts +3 -3
  16. package/dist/components/RackEditor.vue.d.ts +1 -1
  17. package/dist/components/SampleLegend.vue.d.ts +1 -1
  18. package/dist/components/SmartGroupManual.vue.d.ts +1 -1
  19. package/dist/components/index.d.ts +1 -0
  20. package/dist/components/index.js +8 -8
  21. package/dist/{components-CV5zuWa8.js → components-CDomhGSj.js} +477 -71
  22. package/dist/components-CDomhGSj.js.map +1 -0
  23. package/dist/composables/controlSchemaDoseDesign.d.ts +8 -1
  24. package/dist/composables/controlSchemaModel.d.ts +10 -1
  25. package/dist/composables/index.js +8 -8
  26. package/dist/composables/useAnalysisArtifacts.d.ts +9 -1
  27. package/dist/composables/useAppExperiment.d.ts +7 -0
  28. package/dist/composables/useBioTemplatePackWorkspace.d.ts +9 -1
  29. package/dist/composables/useControlWorkspace.d.ts +9 -1
  30. package/dist/composables/useGeneratedAnalysis.d.ts +9 -0
  31. package/dist/{composables-CW8NRXLB.js → composables-CRR_JxQD.js} +4 -4
  32. package/dist/{composables-CW8NRXLB.js.map → composables-CRR_JxQD.js.map} +1 -1
  33. package/dist/{experiment-utils-7Yw-h0tD.js → experiment-utils-CLnzPPq5.js} +170 -13
  34. package/dist/experiment-utils-CLnzPPq5.js.map +1 -0
  35. package/dist/index.js +13 -13
  36. package/dist/install.js +7 -7
  37. package/dist/styles.css +764 -610
  38. package/dist/templates/index.js +4 -4
  39. package/dist/{templates-CJRFiWUX.js → templates-Cr-48-u2.js} +2 -2
  40. package/dist/{templates-CJRFiWUX.js.map → templates-Cr-48-u2.js.map} +1 -1
  41. package/dist/types/components.d.ts +32 -0
  42. package/dist/types/index.d.ts +1 -1
  43. package/dist/{useControlSchema-BEAgLyyx.js → useControlSchema-BMVb2XIQ.js} +58 -10
  44. package/dist/useControlSchema-BMVb2XIQ.js.map +1 -0
  45. package/dist/{useDropdownState-Be-ug_ci.js → useDropdownState-DSb3BC3N.js} +2 -2
  46. package/dist/{useDropdownState-Be-ug_ci.js.map → useDropdownState-DSb3BC3N.js.map} +1 -1
  47. package/dist/{useExperimentSelector-DFg_iEHI.js → useExperimentSelector-D0pjj9WH.js} +3 -3
  48. package/dist/{useExperimentSelector-DFg_iEHI.js.map → useExperimentSelector-D0pjj9WH.js.map} +1 -1
  49. package/dist/{useFormBuilder-CR9pBApW.js → useFormBuilder-DG3HOFGA.js} +2 -2
  50. package/dist/{useFormBuilder-CR9pBApW.js.map → useFormBuilder-DG3HOFGA.js.map} +1 -1
  51. package/dist/{useProtocolTemplates-DXeIHMwV.js → useProtocolTemplates-BMt0LlXf.js} +21 -6
  52. package/dist/useProtocolTemplates-BMt0LlXf.js.map +1 -0
  53. package/package.json +2 -1
  54. package/src/__tests__/components/ActionMenu.test.ts +120 -0
  55. package/src/__tests__/components/BaseModal.test.ts +133 -0
  56. package/src/__tests__/components/SettingsModal.test.ts +9 -7
  57. package/src/__tests__/docs/extractDocsComponents.test.ts +15 -1
  58. package/src/__tests__/docs/extractDocsParsing.test.ts +22 -0
  59. package/src/__tests__/docs/frontendDocsCatalog.test.ts +80 -0
  60. package/src/components/ActionMenu.story.vue +26 -0
  61. package/src/components/ActionMenu.vue +209 -0
  62. package/src/components/AppSidebar.vue +2 -13
  63. package/src/components/ArtifactSelectorModal.vue +8 -1
  64. package/src/components/BaseModal.story.vue +107 -1
  65. package/src/components/BaseModal.vue +152 -4
  66. package/src/components/BioTemplateExperimentWorkspaceView.vue +8 -1
  67. package/src/components/BioTemplatePackWorkspaceView.vue +8 -1
  68. package/src/components/BioTemplatePresetWorkspaceView.vue +8 -1
  69. package/src/components/BioTemplateRenderer.vue +8 -1
  70. package/src/components/ComponentBindingRenderer.vue +8 -1
  71. package/src/components/ControlWorkspaceView.vue +8 -1
  72. package/src/components/DoseDesignWorkspaceView.vue +8 -1
  73. package/src/components/ExperimentSelectorModal.vue +8 -1
  74. package/src/components/FormBuilder.vue +5 -0
  75. package/src/components/GeneratedPluginView.vue +12 -2
  76. package/src/components/GeneratedResultRenderer.vue +12 -2
  77. package/src/components/JobsStatusTray.vue +8 -1
  78. package/src/components/PluginWorkspaceView.vue +10 -1
  79. package/src/components/SettingsModal.vue +102 -149
  80. package/src/components/index.ts +1 -0
  81. package/src/composables/controlSchemaDoseDesign.ts +8 -1
  82. package/src/composables/controlSchemaModel.ts +10 -1
  83. package/src/composables/useAnalysisArtifacts.ts +9 -1
  84. package/src/composables/useAppExperiment.ts +7 -0
  85. package/src/composables/useBioTemplatePackWorkspace.ts +9 -1
  86. package/src/composables/useControlWorkspace.ts +9 -1
  87. package/src/composables/useGeneratedAnalysis.ts +9 -0
  88. package/src/styles/components/action-menu.css +59 -0
  89. package/src/styles/components/icon-button.css +7 -3
  90. package/src/styles/components/modal.css +293 -0
  91. package/src/styles/components/settings-modal.css +3 -273
  92. package/src/styles/index.css +1 -0
  93. package/src/types/components.ts +38 -0
  94. package/src/types/index.ts +3 -0
  95. package/dist/ExperimentSelectorModal-DcQ38zua.js.map +0 -1
  96. package/dist/SettingsModal-Ccq2z-Ms.js.map +0 -1
  97. package/dist/components-CV5zuWa8.js.map +0 -1
  98. package/dist/experiment-utils-7Yw-h0tD.js.map +0 -1
  99. package/dist/useControlSchema-BEAgLyyx.js.map +0 -1
  100. package/dist/useProtocolTemplates-DXeIHMwV.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Teleport, Transition, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, isRef, nextTick, normalizeClass, onMounted, onUnmounted, openBlock, ref, renderSlot, toDisplayString, watch, withCtx } from "vue";
1
+ import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, isRef, nextTick, normalizeClass, onMounted, onUnmounted, openBlock, ref, renderList, renderSlot, toDisplayString, watch, withCtx, withKeys, withModifiers } from "vue";
2
2
  //#region src/components/BaseButton.vue?vue&type=script&setup=true&lang.ts
3
3
  var _hoisted_1$1 = ["type", "disabled"];
4
4
  var _hoisted_2$1 = {
@@ -144,9 +144,77 @@ var _hoisted_5 = {
144
144
  key: 1,
145
145
  class: "mint-modal__subtitle"
146
146
  };
147
- var _hoisted_6 = { class: "mint-modal__body" };
148
- var _hoisted_7 = {
147
+ var _hoisted_6 = {
149
148
  key: 2,
149
+ class: "mint-modal__tabs",
150
+ role: "tablist"
151
+ };
152
+ var _hoisted_7 = [
153
+ "aria-selected",
154
+ "aria-disabled",
155
+ "tabindex",
156
+ "onClick"
157
+ ];
158
+ var _hoisted_8 = {
159
+ key: 0,
160
+ class: "mint-modal__tab-meta"
161
+ };
162
+ var _hoisted_9 = {
163
+ key: 3,
164
+ class: "mint-modal__split"
165
+ };
166
+ var _hoisted_10 = {
167
+ class: "mint-modal__rail",
168
+ role: "tablist",
169
+ "aria-orientation": "vertical"
170
+ };
171
+ var _hoisted_11 = { class: "mint-modal__rail-items" };
172
+ var _hoisted_12 = [
173
+ "aria-selected",
174
+ "aria-disabled",
175
+ "tabindex",
176
+ "onClick"
177
+ ];
178
+ var _hoisted_13 = {
179
+ key: 0,
180
+ class: "mint-modal__rail-item-icon",
181
+ "aria-hidden": "true"
182
+ };
183
+ var _hoisted_14 = {
184
+ key: 0,
185
+ viewBox: "0 0 24 24",
186
+ fill: "none",
187
+ stroke: "currentColor",
188
+ "stroke-width": "1.8",
189
+ "stroke-linecap": "round",
190
+ "stroke-linejoin": "round"
191
+ };
192
+ var _hoisted_15 = ["d"];
193
+ var _hoisted_16 = ["d"];
194
+ var _hoisted_17 = ["innerHTML"];
195
+ var _hoisted_18 = { class: "mint-modal__rail-item-text" };
196
+ var _hoisted_19 = { class: "mint-modal__rail-item-label" };
197
+ var _hoisted_20 = {
198
+ key: 0,
199
+ class: "mint-modal__rail-item-description"
200
+ };
201
+ var _hoisted_21 = {
202
+ key: 1,
203
+ class: "mint-modal__rail-item-meta"
204
+ };
205
+ var _hoisted_22 = ["aria-label"];
206
+ var _hoisted_23 = {
207
+ key: 0,
208
+ class: "mint-modal__pane-header"
209
+ };
210
+ var _hoisted_24 = { class: "mint-modal__pane-title" };
211
+ var _hoisted_25 = {
212
+ key: 0,
213
+ class: "mint-modal__pane-subtitle"
214
+ };
215
+ var _hoisted_26 = { class: "mint-modal__pane-body" };
216
+ var _hoisted_27 = {
217
+ key: 5,
150
218
  class: "mint-modal__footer"
151
219
  };
152
220
  //#endregion
@@ -170,13 +238,43 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
170
238
  closeOnEscape: {
171
239
  type: Boolean,
172
240
  default: true
173
- }
241
+ },
242
+ layout: { default: "plain" },
243
+ tabs: { default: () => [] },
244
+ activeTab: {}
174
245
  },
175
- emits: ["update:modelValue", "close"],
246
+ emits: [
247
+ "update:modelValue",
248
+ "update:activeTab",
249
+ "close"
250
+ ],
176
251
  setup(__props, { emit: __emit }) {
177
- /** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant. */
252
+ /** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant/layout. */
178
253
  const props = __props;
179
254
  const emit = __emit;
255
+ const activeTabMeta = computed(() => props.tabs.find((tab) => tab.id === props.activeTab));
256
+ const tabButtonRefs = /* @__PURE__ */ new Map();
257
+ function setTabButtonRef(id, el) {
258
+ if (el instanceof HTMLElement) tabButtonRefs.set(id, el);
259
+ else tabButtonRefs.delete(id);
260
+ }
261
+ function selectTab(tab) {
262
+ if (tab.disabled || tab.id === props.activeTab) return;
263
+ emit("update:activeTab", tab.id);
264
+ }
265
+ /** ARIA tablist keyboard contract: arrows move selection to the next non-disabled tab, wrapping. */
266
+ function focusTab(delta) {
267
+ const enabled = props.tabs.filter((tab) => !tab.disabled);
268
+ if (enabled.length === 0) return;
269
+ const next = enabled[(enabled.findIndex((tab) => tab.id === props.activeTab) + delta + enabled.length) % enabled.length];
270
+ if (!next || next.id === props.activeTab) return;
271
+ emit("update:activeTab", next.id);
272
+ tabButtonRefs.get(next.id)?.focus();
273
+ }
274
+ function isPathIcon(icon) {
275
+ if (!icon) return false;
276
+ return Array.isArray(icon) || icon.trim().startsWith("M") || icon.trim().startsWith("m");
277
+ }
180
278
  const containerRef = ref(null);
181
279
  let previouslyFocused = null;
182
280
  const FOCUSABLE_SELECTOR = [
@@ -189,7 +287,7 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
189
287
  ].join(", ");
190
288
  function getFocusableElements() {
191
289
  if (!containerRef.value) return [];
192
- return Array.from(containerRef.value.querySelectorAll(FOCUSABLE_SELECTOR));
290
+ return Array.from(containerRef.value.querySelectorAll(FOCUSABLE_SELECTOR)).filter((el) => el.tabIndex !== -1);
193
291
  }
194
292
  function handleKeydown(event) {
195
293
  if (event.key === "Escape" && props.closeOnEscape && props.modelValue) {
@@ -245,13 +343,14 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
245
343
  key: 0,
246
344
  class: normalizeClass(["mint-modal", `mint-modal--${__props.variant}`]),
247
345
  onClick: handleOverlayClick
248
- }, [_cache[1] || (_cache[1] = createElementVNode("div", { class: "mint-modal__overlay" }, null, -1)), createElementVNode("div", {
346
+ }, [_cache[5] || (_cache[5] = createElementVNode("div", { class: "mint-modal__overlay" }, null, -1)), createElementVNode("div", {
249
347
  ref_key: "containerRef",
250
348
  ref: containerRef,
251
349
  class: normalizeClass([
252
350
  "mint-modal__container",
253
351
  `mint-modal__container--${__props.size}`,
254
- `mint-modal__container--${__props.variant}`
352
+ `mint-modal__container--${__props.variant}`,
353
+ `mint-modal__container--${__props.layout}`
255
354
  ]),
256
355
  role: "dialog",
257
356
  "aria-modal": "true",
@@ -264,7 +363,7 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
264
363
  class: "mint-modal__close",
265
364
  "aria-label": "Close modal",
266
365
  onClick: close
267
- }, [..._cache[0] || (_cache[0] = [createElementVNode("svg", {
366
+ }, [..._cache[4] || (_cache[4] = [createElementVNode("svg", {
268
367
  class: "mint-modal__close-icon",
269
368
  fill: "none",
270
369
  stroke: "currentColor",
@@ -273,8 +372,66 @@ var BaseModal_default = /* @__PURE__ */ defineComponent({
273
372
  "stroke-linejoin": "round",
274
373
  viewBox: "0 0 24 24"
275
374
  }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])])) : createCommentVNode("", true)])) : createCommentVNode("", true),
276
- createElementVNode("div", _hoisted_6, [renderSlot(_ctx.$slots, "default")]),
277
- _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_7, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
375
+ __props.layout === "tabs" && __props.tabs.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_6, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab) => {
376
+ return openBlock(), createElementBlock("button", {
377
+ key: tab.id,
378
+ ref_for: true,
379
+ ref: (el) => setTabButtonRef(tab.id, el),
380
+ type: "button",
381
+ role: "tab",
382
+ "aria-selected": __props.activeTab === tab.id,
383
+ "aria-disabled": tab.disabled || void 0,
384
+ tabindex: __props.activeTab === tab.id ? 0 : -1,
385
+ class: normalizeClass(["mint-modal__tab", {
386
+ "mint-modal__tab--active": __props.activeTab === tab.id,
387
+ "mint-modal__tab--disabled": tab.disabled
388
+ }]),
389
+ onClick: ($event) => selectTab(tab),
390
+ onKeydown: [_cache[0] || (_cache[0] = withKeys(withModifiers(($event) => focusTab(-1), ["prevent"]), ["left"])), _cache[1] || (_cache[1] = withKeys(withModifiers(($event) => focusTab(1), ["prevent"]), ["right"]))]
391
+ }, [createTextVNode(toDisplayString(tab.label) + " ", 1), tab.meta ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(tab.meta), 1)) : createCommentVNode("", true)], 42, _hoisted_7);
392
+ }), 128))])) : createCommentVNode("", true),
393
+ __props.layout === "rail" ? (openBlock(), createElementBlock("div", _hoisted_9, [createElementVNode("div", _hoisted_10, [createElementVNode("div", _hoisted_11, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.tabs, (tab) => {
394
+ return openBlock(), createElementBlock("button", {
395
+ key: tab.id,
396
+ ref_for: true,
397
+ ref: (el) => setTabButtonRef(tab.id, el),
398
+ type: "button",
399
+ role: "tab",
400
+ "aria-selected": __props.activeTab === tab.id,
401
+ "aria-disabled": tab.disabled || void 0,
402
+ tabindex: __props.activeTab === tab.id ? 0 : -1,
403
+ class: normalizeClass(["mint-modal__rail-item", {
404
+ "mint-modal__rail-item--active": __props.activeTab === tab.id,
405
+ "mint-modal__rail-item--disabled": tab.disabled
406
+ }]),
407
+ onClick: ($event) => selectTab(tab),
408
+ onKeydown: [_cache[2] || (_cache[2] = withKeys(withModifiers(($event) => focusTab(-1), ["prevent"]), ["up"])), _cache[3] || (_cache[3] = withKeys(withModifiers(($event) => focusTab(1), ["prevent"]), ["down"]))]
409
+ }, [
410
+ tab.icon ? (openBlock(), createElementBlock("span", _hoisted_13, [isPathIcon(tab.icon) ? (openBlock(), createElementBlock("svg", _hoisted_14, [Array.isArray(tab.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(tab.icon, (d, index) => {
411
+ return openBlock(), createElementBlock("path", {
412
+ key: index,
413
+ d
414
+ }, null, 8, _hoisted_15);
415
+ }), 128)) : (openBlock(), createElementBlock("path", {
416
+ key: 1,
417
+ d: tab.icon
418
+ }, null, 8, _hoisted_16))])) : (openBlock(), createElementBlock("span", {
419
+ key: 1,
420
+ innerHTML: tab.icon
421
+ }, null, 8, _hoisted_17))])) : createCommentVNode("", true),
422
+ createElementVNode("span", _hoisted_18, [createElementVNode("span", _hoisted_19, toDisplayString(tab.label), 1), tab.description ? (openBlock(), createElementBlock("span", _hoisted_20, toDisplayString(tab.description), 1)) : createCommentVNode("", true)]),
423
+ tab.meta ? (openBlock(), createElementBlock("span", _hoisted_21, toDisplayString(tab.meta), 1)) : createCommentVNode("", true)
424
+ ], 42, _hoisted_12);
425
+ }), 128))]), renderSlot(_ctx.$slots, "rail-footer")]), createElementVNode("section", {
426
+ class: "mint-modal__pane",
427
+ role: "tabpanel",
428
+ "aria-label": activeTabMeta.value?.label,
429
+ tabindex: "0"
430
+ }, [activeTabMeta.value?.label ? (openBlock(), createElementBlock("header", _hoisted_23, [createElementVNode("h4", _hoisted_24, toDisplayString(activeTabMeta.value.label), 1), activeTabMeta.value.description ? (openBlock(), createElementBlock("p", _hoisted_25, toDisplayString(activeTabMeta.value.description), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("div", _hoisted_26, [renderSlot(_ctx.$slots, "default")])], 8, _hoisted_22)])) : (openBlock(), createElementBlock("div", {
431
+ key: 4,
432
+ class: normalizeClass(["mint-modal__body", __props.layout === "tabs" ? "mint-modal__body--tabbed" : null])
433
+ }, [renderSlot(_ctx.$slots, "default")], 2)),
434
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_27, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
278
435
  ], 2)], 2)) : createCommentVNode("", true)]),
279
436
  _: 3
280
437
  }, 8, ["name"])]);
@@ -403,4 +560,4 @@ var SORT_OPTIONS = [
403
560
  //#endregion
404
561
  export { SORT_OPTIONS as a, formatExperimentDate as c, resolveExperimentCode as d, BaseModal_default as f, EXPERIMENT_STATUS_VARIANT_MAP as i, formatExperimentStatus as l, BaseButton_default as m, EXPERIMENT_STATUS_LABELS as n, datePresetToISO as o, useEventListener as p, EXPERIMENT_STATUS_OPTIONS as r, experimentIdFromRoute as s, DATE_PRESET_OPTIONS as t, getExperimentStatusVariant as u };
405
562
 
406
- //# sourceMappingURL=experiment-utils-7Yw-h0tD.js.map
563
+ //# sourceMappingURL=experiment-utils-CLnzPPq5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment-utils-CLnzPPq5.js","names":["$slots"],"sources":["../src/components/BaseButton.vue","../src/components/BaseButton.vue","../src/composables/useEventListener.ts","../src/components/BaseModal.vue","../src/components/BaseModal.vue","../src/composables/experiment-utils.ts"],"sourcesContent":["<script setup lang=\"ts\">\n/** Renders a styled `<button>` with variant, size, loading spinner, and full-width options. */\nimport type { ButtonVariant, ButtonSize } from '../types'\n\ninterface Props {\n variant?: ButtonVariant\n size?: ButtonSize\n disabled?: boolean\n loading?: boolean\n type?: 'button' | 'submit' | 'reset'\n fullWidth?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'primary',\n size: 'md',\n disabled: false,\n loading: false,\n type: 'button',\n fullWidth: false,\n})\n\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\nfunction handleClick(event: MouseEvent) {\n if (!props.disabled && !props.loading) {\n emit('click', event)\n }\n}\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :class=\"[\n 'mint-button',\n `mint-button--${variant}`,\n `mint-button--${size}`,\n fullWidth ? 'mint-button--full-width' : '',\n (disabled || loading) ? 'mint-button--disabled' : '',\n ]\"\n @click=\"handleClick\"\n >\n <svg\n v-if=\"loading\"\n class=\"mint-button__spinner\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style=\"opacity: 0.25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n />\n <path\n style=\"opacity: 0.75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <slot name=\"icon-left\" />\n <slot />\n <slot name=\"icon-right\" />\n </button>\n</template>\n\n<style>\n@import '../styles/components/button.css';\n</style>\n","<script setup lang=\"ts\">\n/** Renders a styled `<button>` with variant, size, loading spinner, and full-width options. */\nimport type { ButtonVariant, ButtonSize } from '../types'\n\ninterface Props {\n variant?: ButtonVariant\n size?: ButtonSize\n disabled?: boolean\n loading?: boolean\n type?: 'button' | 'submit' | 'reset'\n fullWidth?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'primary',\n size: 'md',\n disabled: false,\n loading: false,\n type: 'button',\n fullWidth: false,\n})\n\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\nfunction handleClick(event: MouseEvent) {\n if (!props.disabled && !props.loading) {\n emit('click', event)\n }\n}\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :class=\"[\n 'mint-button',\n `mint-button--${variant}`,\n `mint-button--${size}`,\n fullWidth ? 'mint-button--full-width' : '',\n (disabled || loading) ? 'mint-button--disabled' : '',\n ]\"\n @click=\"handleClick\"\n >\n <svg\n v-if=\"loading\"\n class=\"mint-button__spinner\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style=\"opacity: 0.25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n />\n <path\n style=\"opacity: 0.75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <slot name=\"icon-left\" />\n <slot />\n <slot name=\"icon-right\" />\n </button>\n</template>\n\n<style>\n@import '../styles/components/button.css';\n</style>\n","import { isRef, onMounted, onUnmounted, watch, type Ref } from 'vue'\n\nexport type EventTargetGetter<TTarget extends EventTarget = EventTarget> =\n () => TTarget | null | undefined\n\nexport type EventTargetLike<TTarget extends EventTarget = EventTarget> =\n | TTarget\n | Ref<TTarget | null | undefined>\n | EventTargetGetter<TTarget>\n | null\n | undefined\n\nexport type EventListenerEnabled = boolean | Ref<boolean>\n\nexport interface UseEventListenerObjectOptions extends AddEventListenerOptions {\n enabled?: EventListenerEnabled\n}\n\nexport type UseEventListenerOptions = boolean | UseEventListenerObjectOptions\nexport type EventListenerStop = () => void\n\nexport type EventMapFor<TTarget extends EventTarget> =\n TTarget extends Window\n ? WindowEventMap\n : TTarget extends Document\n ? DocumentEventMap\n : TTarget extends HTMLElement\n ? HTMLElementEventMap\n : Record<string, Event>\n\nexport type EventFor<\n TTarget extends EventTarget,\n TType extends string,\n> = TType extends keyof EventMapFor<TTarget>\n ? EventMapFor<TTarget>[TType]\n : Event\n\n/** Bind a DOM event listener on mount, remove it on unmount, and rebind when a ref target changes. */\nexport function useEventListener<\n TTarget extends EventTarget = EventTarget,\n TType extends string = string,\n>(\n target: EventTargetLike<TTarget>,\n type: TType,\n listener: (event: EventFor<TTarget, TType>) => void,\n options?: UseEventListenerOptions,\n): EventListenerStop {\n let stopCurrent: EventListenerStop | undefined\n let mounted = false\n\n function stop(): void {\n stopCurrent?.()\n stopCurrent = undefined\n }\n\n function start(): void {\n stop()\n if (!mounted || !isEnabled(options)) return\n const resolvedTarget = resolveEventTarget(target)\n if (!resolvedTarget) return\n\n const eventListener = listener as EventListener\n const eventOptions = getEventOptions(options)\n resolvedTarget.addEventListener(type, eventListener, eventOptions)\n stopCurrent = () => {\n resolvedTarget.removeEventListener(type, eventListener, eventOptions)\n }\n }\n\n onMounted(() => {\n mounted = true\n start()\n })\n\n if (isRef(target)) {\n watch(target, start, { flush: 'post' })\n }\n const enabled = getEnabledOption(options)\n if (isRef(enabled)) {\n watch(enabled, start, { flush: 'post' })\n }\n\n onUnmounted(() => {\n mounted = false\n stop()\n })\n\n return stop\n}\n\nfunction resolveEventTarget(target: EventTargetLike): EventTarget | null | undefined {\n if (isRef(target)) return target.value\n if (typeof target === 'function') return target()\n return target\n}\n\nfunction getEnabledOption(options: UseEventListenerOptions | undefined): EventListenerEnabled | undefined {\n return typeof options === 'object' ? options.enabled : undefined\n}\n\nfunction isEnabled(options: UseEventListenerOptions | undefined): boolean {\n const enabled = getEnabledOption(options)\n if (isRef(enabled)) return enabled.value\n return enabled ?? true\n}\n\nfunction getEventOptions(options: UseEventListenerOptions | undefined): boolean | AddEventListenerOptions | undefined {\n if (typeof options !== 'object') return options\n const { enabled: _enabled, ...eventOptions } = options\n return eventOptions\n}\n","<script setup lang=\"ts\">\n/** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant/layout. */\nimport { computed, ref, watch, nextTick, onUnmounted, type ComponentPublicInstance } from 'vue'\nimport type { ModalLayout, ModalSize, ModalTab, ModalVariant } from '../types'\nimport { useEventListener } from '../composables/useEventListener'\n\ninterface Props {\n modelValue: boolean\n title?: string\n subtitle?: string\n size?: ModalSize\n variant?: ModalVariant\n closable?: boolean\n closeOnOverlay?: boolean\n closeOnEscape?: boolean\n /**\n * Shell layout. 'tabs' renders a tab strip between header and body;\n * 'rail' renders a sidebar rail + pane as the shell's middle row.\n * Both are shell regions — never part of the scrolling body content.\n */\n layout?: ModalLayout\n /** Sections for the tab strip / rail. The strip renders only with 2+ tabs. */\n tabs?: ModalTab[]\n /** Id of the selected tab. Two-way bindable via update:activeTab. */\n activeTab?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'centered',\n closable: true,\n closeOnOverlay: false,\n closeOnEscape: true,\n layout: 'plain',\n tabs: () => [],\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n 'update:activeTab': [id: string]\n close: []\n}>()\n\nconst activeTabMeta = computed(() => props.tabs.find((tab) => tab.id === props.activeTab))\n\nconst tabButtonRefs = new Map<string, HTMLElement>()\n\nfunction setTabButtonRef(id: string, el: Element | ComponentPublicInstance | null) {\n if (el instanceof HTMLElement) {\n tabButtonRefs.set(id, el)\n } else {\n tabButtonRefs.delete(id)\n }\n}\n\nfunction selectTab(tab: ModalTab) {\n if (tab.disabled || tab.id === props.activeTab) return\n emit('update:activeTab', tab.id)\n}\n\n/** ARIA tablist keyboard contract: arrows move selection to the next non-disabled tab, wrapping. */\nfunction focusTab(delta: number) {\n const enabled = props.tabs.filter((tab) => !tab.disabled)\n if (enabled.length === 0) return\n const currentIndex = enabled.findIndex((tab) => tab.id === props.activeTab)\n const next = enabled[(currentIndex + delta + enabled.length) % enabled.length]\n if (!next || next.id === props.activeTab) return\n emit('update:activeTab', next.id)\n tabButtonRefs.get(next.id)?.focus()\n}\n\nfunction isPathIcon(icon: ModalTab['icon']): icon is string | string[] {\n if (!icon) return false\n return Array.isArray(icon) || icon.trim().startsWith('M') || icon.trim().startsWith('m')\n}\n\nconst containerRef = ref<HTMLElement | null>(null)\nlet previouslyFocused: HTMLElement | null = null\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ')\n\nfunction getFocusableElements(): HTMLElement[] {\n if (!containerRef.value) return []\n return Array.from(containerRef.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n // Roving tabindex (inactive tabs/rail items) stays out of the Tab cycle.\n .filter((el) => el.tabIndex !== -1)\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && props.closeOnEscape && props.modelValue) {\n close()\n return\n }\n\n if (event.key !== 'Tab' || !containerRef.value) return\n\n const focusable = getFocusableElements()\n if (focusable.length === 0) {\n event.preventDefault()\n return\n }\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n\nfunction close() {\n if (props.closable) {\n emit('update:modelValue', false)\n emit('close')\n }\n}\n\nfunction handleOverlayClick(event: MouseEvent) {\n if (props.closeOnOverlay && event.target === event.currentTarget) {\n close()\n }\n}\n\nwatch(() => props.modelValue, async (isOpen) => {\n if (isOpen) {\n previouslyFocused = document.activeElement as HTMLElement | null\n document.body.style.overflow = 'hidden'\n await nextTick()\n const focusable = getFocusableElements()\n if (focusable.length > 0) {\n focusable[0].focus()\n } else {\n containerRef.value?.focus()\n }\n } else {\n document.body.style.overflow = ''\n previouslyFocused?.focus()\n previouslyFocused = null\n }\n})\n\nuseEventListener(() => document, 'keydown', handleKeydown)\n\nonUnmounted(() => {\n document.body.style.overflow = ''\n})\n</script>\n\n<template>\n <Teleport to=\"body\">\n <Transition :name=\"`modal-${variant}`\">\n <div\n v-if=\"modelValue\"\n :class=\"['mint-modal', `mint-modal--${variant}`]\"\n @click=\"handleOverlayClick\"\n >\n <!-- Overlay -->\n <div class=\"mint-modal__overlay\" />\n\n <!-- Modal -->\n <div\n ref=\"containerRef\"\n :class=\"[\n 'mint-modal__container',\n `mint-modal__container--${size}`,\n `mint-modal__container--${variant}`,\n `mint-modal__container--${layout}`,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n tabindex=\"-1\"\n >\n <!-- Sheet grab-hint bar (sheet variant only) -->\n <div v-if=\"variant === 'sheet'\" class=\"mint-modal__grab-hint\" aria-hidden=\"true\" />\n\n <!-- Header -->\n <div v-if=\"title || subtitle || closable || $slots.header\" class=\"mint-modal__header\">\n <div v-if=\"title || subtitle || $slots.header\" class=\"mint-modal__header-text\">\n <slot name=\"header\">\n <h3 v-if=\"title\" class=\"mint-modal__title\">\n {{ title }}\n </h3>\n <p v-if=\"subtitle\" class=\"mint-modal__subtitle\">\n {{ subtitle }}\n </p>\n </slot>\n </div>\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"mint-modal__close\"\n aria-label=\"Close modal\"\n @click=\"close\"\n >\n <svg class=\"mint-modal__close-icon\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n\n <!-- Tab strip — a shell region between header and body, flush with the modal edges -->\n <div\n v-if=\"layout === 'tabs' && tabs.length > 1\"\n class=\"mint-modal__tabs\"\n role=\"tablist\"\n >\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n :ref=\"(el) => setTabButtonRef(tab.id, el)\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"activeTab === tab.id\"\n :aria-disabled=\"tab.disabled || undefined\"\n :tabindex=\"activeTab === tab.id ? 0 : -1\"\n :class=\"['mint-modal__tab', {\n 'mint-modal__tab--active': activeTab === tab.id,\n 'mint-modal__tab--disabled': tab.disabled,\n }]\"\n @click=\"selectTab(tab)\"\n @keydown.left.prevent=\"focusTab(-1)\"\n @keydown.right.prevent=\"focusTab(1)\"\n >\n {{ tab.label }}\n <span v-if=\"tab.meta\" class=\"mint-modal__tab-meta\">{{ tab.meta }}</span>\n </button>\n </div>\n\n <!-- Rail layout: rail column + pane are the shell's middle row -->\n <div v-if=\"layout === 'rail'\" class=\"mint-modal__split\">\n <div class=\"mint-modal__rail\" role=\"tablist\" aria-orientation=\"vertical\">\n <div class=\"mint-modal__rail-items\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n :ref=\"(el) => setTabButtonRef(tab.id, el)\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"activeTab === tab.id\"\n :aria-disabled=\"tab.disabled || undefined\"\n :tabindex=\"activeTab === tab.id ? 0 : -1\"\n :class=\"['mint-modal__rail-item', {\n 'mint-modal__rail-item--active': activeTab === tab.id,\n 'mint-modal__rail-item--disabled': tab.disabled,\n }]\"\n @click=\"selectTab(tab)\"\n @keydown.up.prevent=\"focusTab(-1)\"\n @keydown.down.prevent=\"focusTab(1)\"\n >\n <span v-if=\"tab.icon\" class=\"mint-modal__rail-item-icon\" aria-hidden=\"true\">\n <svg\n v-if=\"isPathIcon(tab.icon)\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <template v-if=\"Array.isArray(tab.icon)\">\n <path v-for=\"(d, index) in tab.icon\" :key=\"index\" :d=\"d\" />\n </template>\n <path v-else :d=\"tab.icon\" />\n </svg>\n <!-- Trusted, author-controlled markup only — same contract as SettingsTab.icon. -->\n <span v-else v-html=\"tab.icon\" />\n </span>\n <span class=\"mint-modal__rail-item-text\">\n <span class=\"mint-modal__rail-item-label\">{{ tab.label }}</span>\n <span v-if=\"tab.description\" class=\"mint-modal__rail-item-description\">{{ tab.description }}</span>\n </span>\n <span v-if=\"tab.meta\" class=\"mint-modal__rail-item-meta\">{{ tab.meta }}</span>\n </button>\n </div>\n <!-- Quiet rail-bottom action (e.g. Log out) -->\n <slot name=\"rail-footer\" />\n </div>\n\n <section\n class=\"mint-modal__pane\"\n role=\"tabpanel\"\n :aria-label=\"activeTabMeta?.label\"\n tabindex=\"0\"\n >\n <header v-if=\"activeTabMeta?.label\" class=\"mint-modal__pane-header\">\n <h4 class=\"mint-modal__pane-title\">{{ activeTabMeta.label }}</h4>\n <p v-if=\"activeTabMeta.description\" class=\"mint-modal__pane-subtitle\">\n {{ activeTabMeta.description }}\n </p>\n </header>\n <div class=\"mint-modal__pane-body\">\n <slot />\n </div>\n </section>\n </div>\n\n <!-- Body -->\n <div\n v-else\n :class=\"['mint-modal__body', layout === 'tabs' ? 'mint-modal__body--tabbed' : null]\"\n >\n <slot />\n </div>\n\n <!-- Footer -->\n <div v-if=\"$slots.footer\" class=\"mint-modal__footer\">\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<style>\n@import '../styles/components/modal.css';\n</style>\n","<script setup lang=\"ts\">\n/** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant/layout. */\nimport { computed, ref, watch, nextTick, onUnmounted, type ComponentPublicInstance } from 'vue'\nimport type { ModalLayout, ModalSize, ModalTab, ModalVariant } from '../types'\nimport { useEventListener } from '../composables/useEventListener'\n\ninterface Props {\n modelValue: boolean\n title?: string\n subtitle?: string\n size?: ModalSize\n variant?: ModalVariant\n closable?: boolean\n closeOnOverlay?: boolean\n closeOnEscape?: boolean\n /**\n * Shell layout. 'tabs' renders a tab strip between header and body;\n * 'rail' renders a sidebar rail + pane as the shell's middle row.\n * Both are shell regions — never part of the scrolling body content.\n */\n layout?: ModalLayout\n /** Sections for the tab strip / rail. The strip renders only with 2+ tabs. */\n tabs?: ModalTab[]\n /** Id of the selected tab. Two-way bindable via update:activeTab. */\n activeTab?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'centered',\n closable: true,\n closeOnOverlay: false,\n closeOnEscape: true,\n layout: 'plain',\n tabs: () => [],\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n 'update:activeTab': [id: string]\n close: []\n}>()\n\nconst activeTabMeta = computed(() => props.tabs.find((tab) => tab.id === props.activeTab))\n\nconst tabButtonRefs = new Map<string, HTMLElement>()\n\nfunction setTabButtonRef(id: string, el: Element | ComponentPublicInstance | null) {\n if (el instanceof HTMLElement) {\n tabButtonRefs.set(id, el)\n } else {\n tabButtonRefs.delete(id)\n }\n}\n\nfunction selectTab(tab: ModalTab) {\n if (tab.disabled || tab.id === props.activeTab) return\n emit('update:activeTab', tab.id)\n}\n\n/** ARIA tablist keyboard contract: arrows move selection to the next non-disabled tab, wrapping. */\nfunction focusTab(delta: number) {\n const enabled = props.tabs.filter((tab) => !tab.disabled)\n if (enabled.length === 0) return\n const currentIndex = enabled.findIndex((tab) => tab.id === props.activeTab)\n const next = enabled[(currentIndex + delta + enabled.length) % enabled.length]\n if (!next || next.id === props.activeTab) return\n emit('update:activeTab', next.id)\n tabButtonRefs.get(next.id)?.focus()\n}\n\nfunction isPathIcon(icon: ModalTab['icon']): icon is string | string[] {\n if (!icon) return false\n return Array.isArray(icon) || icon.trim().startsWith('M') || icon.trim().startsWith('m')\n}\n\nconst containerRef = ref<HTMLElement | null>(null)\nlet previouslyFocused: HTMLElement | null = null\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ')\n\nfunction getFocusableElements(): HTMLElement[] {\n if (!containerRef.value) return []\n return Array.from(containerRef.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n // Roving tabindex (inactive tabs/rail items) stays out of the Tab cycle.\n .filter((el) => el.tabIndex !== -1)\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && props.closeOnEscape && props.modelValue) {\n close()\n return\n }\n\n if (event.key !== 'Tab' || !containerRef.value) return\n\n const focusable = getFocusableElements()\n if (focusable.length === 0) {\n event.preventDefault()\n return\n }\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n\nfunction close() {\n if (props.closable) {\n emit('update:modelValue', false)\n emit('close')\n }\n}\n\nfunction handleOverlayClick(event: MouseEvent) {\n if (props.closeOnOverlay && event.target === event.currentTarget) {\n close()\n }\n}\n\nwatch(() => props.modelValue, async (isOpen) => {\n if (isOpen) {\n previouslyFocused = document.activeElement as HTMLElement | null\n document.body.style.overflow = 'hidden'\n await nextTick()\n const focusable = getFocusableElements()\n if (focusable.length > 0) {\n focusable[0].focus()\n } else {\n containerRef.value?.focus()\n }\n } else {\n document.body.style.overflow = ''\n previouslyFocused?.focus()\n previouslyFocused = null\n }\n})\n\nuseEventListener(() => document, 'keydown', handleKeydown)\n\nonUnmounted(() => {\n document.body.style.overflow = ''\n})\n</script>\n\n<template>\n <Teleport to=\"body\">\n <Transition :name=\"`modal-${variant}`\">\n <div\n v-if=\"modelValue\"\n :class=\"['mint-modal', `mint-modal--${variant}`]\"\n @click=\"handleOverlayClick\"\n >\n <!-- Overlay -->\n <div class=\"mint-modal__overlay\" />\n\n <!-- Modal -->\n <div\n ref=\"containerRef\"\n :class=\"[\n 'mint-modal__container',\n `mint-modal__container--${size}`,\n `mint-modal__container--${variant}`,\n `mint-modal__container--${layout}`,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n tabindex=\"-1\"\n >\n <!-- Sheet grab-hint bar (sheet variant only) -->\n <div v-if=\"variant === 'sheet'\" class=\"mint-modal__grab-hint\" aria-hidden=\"true\" />\n\n <!-- Header -->\n <div v-if=\"title || subtitle || closable || $slots.header\" class=\"mint-modal__header\">\n <div v-if=\"title || subtitle || $slots.header\" class=\"mint-modal__header-text\">\n <slot name=\"header\">\n <h3 v-if=\"title\" class=\"mint-modal__title\">\n {{ title }}\n </h3>\n <p v-if=\"subtitle\" class=\"mint-modal__subtitle\">\n {{ subtitle }}\n </p>\n </slot>\n </div>\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"mint-modal__close\"\n aria-label=\"Close modal\"\n @click=\"close\"\n >\n <svg class=\"mint-modal__close-icon\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n\n <!-- Tab strip — a shell region between header and body, flush with the modal edges -->\n <div\n v-if=\"layout === 'tabs' && tabs.length > 1\"\n class=\"mint-modal__tabs\"\n role=\"tablist\"\n >\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n :ref=\"(el) => setTabButtonRef(tab.id, el)\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"activeTab === tab.id\"\n :aria-disabled=\"tab.disabled || undefined\"\n :tabindex=\"activeTab === tab.id ? 0 : -1\"\n :class=\"['mint-modal__tab', {\n 'mint-modal__tab--active': activeTab === tab.id,\n 'mint-modal__tab--disabled': tab.disabled,\n }]\"\n @click=\"selectTab(tab)\"\n @keydown.left.prevent=\"focusTab(-1)\"\n @keydown.right.prevent=\"focusTab(1)\"\n >\n {{ tab.label }}\n <span v-if=\"tab.meta\" class=\"mint-modal__tab-meta\">{{ tab.meta }}</span>\n </button>\n </div>\n\n <!-- Rail layout: rail column + pane are the shell's middle row -->\n <div v-if=\"layout === 'rail'\" class=\"mint-modal__split\">\n <div class=\"mint-modal__rail\" role=\"tablist\" aria-orientation=\"vertical\">\n <div class=\"mint-modal__rail-items\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n :ref=\"(el) => setTabButtonRef(tab.id, el)\"\n type=\"button\"\n role=\"tab\"\n :aria-selected=\"activeTab === tab.id\"\n :aria-disabled=\"tab.disabled || undefined\"\n :tabindex=\"activeTab === tab.id ? 0 : -1\"\n :class=\"['mint-modal__rail-item', {\n 'mint-modal__rail-item--active': activeTab === tab.id,\n 'mint-modal__rail-item--disabled': tab.disabled,\n }]\"\n @click=\"selectTab(tab)\"\n @keydown.up.prevent=\"focusTab(-1)\"\n @keydown.down.prevent=\"focusTab(1)\"\n >\n <span v-if=\"tab.icon\" class=\"mint-modal__rail-item-icon\" aria-hidden=\"true\">\n <svg\n v-if=\"isPathIcon(tab.icon)\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <template v-if=\"Array.isArray(tab.icon)\">\n <path v-for=\"(d, index) in tab.icon\" :key=\"index\" :d=\"d\" />\n </template>\n <path v-else :d=\"tab.icon\" />\n </svg>\n <!-- Trusted, author-controlled markup only — same contract as SettingsTab.icon. -->\n <span v-else v-html=\"tab.icon\" />\n </span>\n <span class=\"mint-modal__rail-item-text\">\n <span class=\"mint-modal__rail-item-label\">{{ tab.label }}</span>\n <span v-if=\"tab.description\" class=\"mint-modal__rail-item-description\">{{ tab.description }}</span>\n </span>\n <span v-if=\"tab.meta\" class=\"mint-modal__rail-item-meta\">{{ tab.meta }}</span>\n </button>\n </div>\n <!-- Quiet rail-bottom action (e.g. Log out) -->\n <slot name=\"rail-footer\" />\n </div>\n\n <section\n class=\"mint-modal__pane\"\n role=\"tabpanel\"\n :aria-label=\"activeTabMeta?.label\"\n tabindex=\"0\"\n >\n <header v-if=\"activeTabMeta?.label\" class=\"mint-modal__pane-header\">\n <h4 class=\"mint-modal__pane-title\">{{ activeTabMeta.label }}</h4>\n <p v-if=\"activeTabMeta.description\" class=\"mint-modal__pane-subtitle\">\n {{ activeTabMeta.description }}\n </p>\n </header>\n <div class=\"mint-modal__pane-body\">\n <slot />\n </div>\n </section>\n </div>\n\n <!-- Body -->\n <div\n v-else\n :class=\"['mint-modal__body', layout === 'tabs' ? 'mint-modal__body--tabbed' : null]\"\n >\n <slot />\n </div>\n\n <!-- Footer -->\n <div v-if=\"$slots.footer\" class=\"mint-modal__footer\">\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<style>\n@import '../styles/components/modal.css';\n</style>\n","import type { DatePreset, ExperimentStatus, SelectOption, PillVariant } from '../types'\n\ninterface ExperimentCodeSource {\n id?: number | null\n experiment_code?: string | null\n}\n\nexport function formatExperimentDate(dateStr: string): string {\n try {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n } catch {\n return dateStr\n }\n}\n\nexport function datePresetToISO(preset: DatePreset): string {\n const now = new Date()\n const days = preset === 'last_7_days' ? 7 : preset === 'last_30_days' ? 30 : 90\n const d = new Date(now.getTime() - days * 86_400_000)\n return d.toISOString()\n}\n\nexport const EXPERIMENT_STATUS_OPTIONS: SelectOption<string>[] = [\n { value: '', label: 'All statuses' },\n { value: 'planned', label: 'Planned' },\n { value: 'ongoing', label: 'Ongoing' },\n { value: 'completed', label: 'Completed' },\n { value: 'cancelled', label: 'Cancelled' },\n]\n\nexport const EXPERIMENT_STATUS_VARIANT_MAP: Record<ExperimentStatus, PillVariant> = {\n planned: 'default',\n ongoing: 'primary',\n completed: 'success',\n cancelled: 'error',\n}\n\nexport const EXPERIMENT_STATUS_LABELS: Record<ExperimentStatus, string> = {\n planned: 'Planned',\n ongoing: 'Ongoing',\n completed: 'Completed',\n cancelled: 'Cancelled',\n}\n\nexport function formatExperimentStatus(status?: ExperimentStatus | string | null): string {\n if (!status) return ''\n if (status in EXPERIMENT_STATUS_LABELS) {\n return EXPERIMENT_STATUS_LABELS[status as ExperimentStatus]\n }\n const label = String(status).replace(/[-_]+/g, ' ').trim()\n return label ? label.replace(/^\\w/, c => c.toUpperCase()) : ''\n}\n\nexport function getExperimentStatusVariant(status?: ExperimentStatus | string | null): PillVariant {\n if (status && status in EXPERIMENT_STATUS_VARIANT_MAP) {\n return EXPERIMENT_STATUS_VARIANT_MAP[status as ExperimentStatus]\n }\n return 'default'\n}\n\nexport function resolveExperimentCode(experiment: ExperimentCodeSource): string | undefined {\n if (experiment.experiment_code) return experiment.experiment_code\n return undefined\n}\n\n// Mirrors vue-router's LocationQuery, whose array members are `string | null`.\n// Declaring `string[]` here made the helper reject the very type every caller\n// passes it, so keep this assignable from LocationQuery without importing\n// vue-router (the SDK does not depend on it).\ntype RouteQueryValue = string | null | undefined | readonly (string | null | undefined)[]\ntype RouteQueryLike = Record<string, RouteQueryValue>\n\n/**\n * Reads the experiment id a deep link was opened with.\n *\n * Returns an id and never a label: a display name belongs to the platform, so\n * callers must resolve it (see `useExperimentStore().selectById`) rather than\n * derive one from the query or the id itself.\n */\nexport function experimentIdFromRoute(query: RouteQueryLike): number | null {\n const raw = query.experiment_id ?? query.experimentId\n const value = Array.isArray(raw) ? raw.find(item => typeof item === 'string') : raw\n if (typeof value !== 'string' || !value) return null\n const id = Number(value)\n return Number.isInteger(id) && id > 0 ? id : null\n}\n\nexport const DATE_PRESET_OPTIONS: SelectOption<string>[] = [\n { value: '', label: 'Any time' },\n { value: 'last_7_days', label: 'Last 7 days' },\n { value: 'last_30_days', label: 'Last 30 days' },\n { value: 'last_90_days', label: 'Last 90 days' },\n]\n\nexport const SORT_OPTIONS: SelectOption<string>[] = [\n { value: 'created_at:desc', label: 'Newest first' },\n { value: 'created_at:asc', label: 'Oldest first' },\n { value: 'updated_at:desc', label: 'Recently updated' },\n { value: 'name:asc', label: 'Name A\\u2013Z' },\n { value: 'name:desc', label: 'Name Z\\u2013A' },\n]\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
- import { a as SORT_OPTIONS, c as formatExperimentDate, d as resolveExperimentCode, f as BaseModal_default, i as EXPERIMENT_STATUS_VARIANT_MAP, l as formatExperimentStatus, m as BaseButton_default, n as EXPERIMENT_STATUS_LABELS, o as datePresetToISO, p as useEventListener, r as EXPERIMENT_STATUS_OPTIONS, s as experimentIdFromRoute, t as DATE_PRESET_OPTIONS, u as getExperimentStatusVariant } from "./experiment-utils-7Yw-h0tD.js";
2
- import { a as BaseSelect_default, i as BasePill_default, n as Skeleton_default, r as useRequestSyncState, s as BaseInput_default, t as EmptyState_default } from "./EmptyState-LMPS3keb.js";
3
- import { $ as normalizeJobState, A as useConcentrationUnits, At as BaseCheckbox_default, B as useAnalysisArtifacts, C as controlsToViewIds, Ct as DatePicker_default, D as getTypeDefault, Dt as BaseSlider_default, E as getFieldRegistryEntry, Et as useSelectionLimit, F as ATOMIC_WEIGHTS, G as resolveCurrentPluginId, I as useChemicalFormula, J as usePluginJobs, K as createGeneratedAnalysisTransport, L as GeneratedPathInput_default, M as SequenceInput_default, Mt as BaseTextarea_default, N as useSequenceUtils, O as ConcentrationInput_default, Ot as BaseRadioGroup_default, P as FormulaInput_default, Q as normalizeJobPercent, S as controlsToTopBarSettingsConfig, St as useTimeUtils, T as getDefaultControlView, Tt as useListSelection, X as isTerminalJobStatus, Y as isActiveJobStatus, Z as jobStatusLabel, _ as controlsToFormSchema, _t as isTimeInRange, a as defineDoseCalculatorControlProps, at as TagsInput_default, b as controlsToSettingsSchema, bt as snapToSlot, c as defineWellPlateDoseComponentBindings, ct as compareTime, d as defineControlModel, dt as findNearestTimeSlotIndex, et as resolveJobCapabilities, ft as formatDuration, gt as generateTimeSlots, h as controlValuesToComponentProps, ht as fromMinutes, i as useControlSchema, it as NumberInput_default, j as MoleculeInput_default, jt as Tooltip_default, k as UnitInput_default, kt as BaseToggle_default, l as defineWellPlateDoseControlProps, lt as durationMinutes, m as controlValuesToComponentBindingsById, mt as formatTimeSlot, n as defineControls, nt as AlertBox_default, o as defineDoseDesignControlModel, ot as TimePicker_default, p as controlValuesToComponentBindings, pt as formatTime, q as useGeneratedAnalysis, r as getControlDefaults, rt as FileUploader_default, s as defineWellPlateControlProps, st as addMinutes, t as defineControlComponentBindings, tt as DateTimePicker_default, u as useControlWorkspace, ut as findAvailableSlots, v as controlsToSectionFormSchema, vt as parseTime, w as controlsToViewItems, wt as MultiSelect_default, x as controlsToSidebarPanels, xt as toMinutes, y as controlsToSectionFormSchemas, yt as rangesOverlap, z as ArtifactSelectorModal_default } from "./useControlSchema-BEAgLyyx.js";
4
- import { $ as SmartGroupFieldRecipe_default, A as ProtocolStepEditor_default, At as DataFrame_default, B as Breadcrumb_default, C as estimateSequenceRemainingSeconds, Ct as AppPluginSwitcher_default, D as sequenceSamplesRemaining, Dt as ThemeToggle_default, E as sequenceProgressPercent, Et as CollapsibleCard_default, F as RackEditor_default, Ft as ColorSlider_default, G as AppContainer_default, H as ProgressBar_default, I as BioTemplatePresetWorkspaceView_default, J as ComponentBindingRenderer_default, K as DoseDesignWorkspaceView_default, L as BioTemplatePackWorkspaceView_default, M as ReagentEditor_default, Mt as DropdownButton_default, N as SmartGroupModal_default, Nt as SegmentedControl_default, O as ChemicalFormula_default, Ot as IconButton_default, P as GroupAssigner_default, Pt as BaseTabs_default, Q as SmartGroupManual_default, R as BioTemplateExperimentWorkspaceView_default, S as estimateSequenceFinishDate, St as AppTopBar_default, T as formatSequenceRemaining, Tt as PluginIcon_default, U as StatusIndicator_default, V as Avatar_default, W as Divider_default, X as SampleSelector_default, Y as ScheduleCalendar_default, Z as AutoGroupModal_default, _ as reconstructLcmsPlateCellsFromSequenceItems, _t as AppLayout_default, a as ResourceCard_default, at as DoseCalculator_default, b as InstrumentAlertLog_default, bt as FormActions_default, c as BatchProgressList_default, ct as GeneratedResultRenderer_default, d as DEFAULT_LCMS_SEQUENCE_COLUMNS, dt as LoadingSpinner_default, et as ReagentList_default, f as basenameFromWindowsPath, ft as generatedJobDefaults, g as lcmsWellIdFromPosition, gt as MobileSupportGate_default, h as inferLcmsPlateTypeFromWellIds, ht as PluginWorkspaceView_default, i as SectionCard_default, it as ExperimentTimeline_default, j as SampleHierarchyTree_default, jt as Calendar_default, k as ScientificNumber_default, kt as AppToastContainer_default, l as AuditTrail_default, lt as GeneratedPlotlyResult_default, m as extractLcmsSampleName, mt as normalizeGeneratedJobInput, n as FitPanel_default, nt as SampleLegend_default, o as TimeRangeInput_default, ot as GeneratedPluginView_default, p as extractLcmsCommonPrefix, pt as generatedJobFormSchema, q as ControlWorkspaceView_default, r as ArtifactSaveDialog_default, rt as WellPlate_default, s as ExperimentDataViewer_default, st as JobsStatusTray_default, tt as PlateMapEditor_default, u as LcmsSequenceTable_default, ut as ChartContainer_default, v as InstrumentStatusCard_default, vt as AppSidebar_default, w as formatSequenceEta, wt as AppAvatarMenu_default, x as SequenceProgressBar_default, xt as StepWizard_default, y as InstrumentStateBadge_default, yt as FormBuilder_default, z as BioTemplateRenderer_default } from "./components-CV5zuWa8.js";
5
- import { s as FormField_default, t as SettingsModal_default } from "./SettingsModal-Ccq2z-Ms.js";
6
- import { A as extractSamplesFromDesignData, B as useJobsStatusTray, C as hexToHsl, D as readFileAsText, E as parseDelimitedText, F as unwrapExperimentDesignData, G as useAppExperiment, H as DEFAULT_MOBILE_VIEWPORT_QUERY, I as DEFAULT_COLORS, J as candidateMatchesSearch, K as useTheme, L as useWellPlateEditor, N as extractSampleNamesFromDesignData, O as useFileImport, P as extractSampleOptionsFromDesignData, Q as useSortedItems, R as useDoseCalculator, S as deriveShade, T as detectDelimiter, U as useMobileSupportGate, V as usePluginJobCenter, W as APP_EXPERIMENT_KEY, X as useTextSearch, Y as normalizeSearchQuery, Z as compareSortValues, _ as useScheduleDrag, a as useReagentSeries, b as useExpansionSet, c as useBioTemplatePresetWorkspace, d as getBioTemplateComponentProps, f as toBioTemplateComponentPropsByComponent, g as useExperimentSave, h as useTemplateCollection, i as generateDilutionSeries, j as useAutoGroup, k as validateImportFile, l as useBioTemplatePackWorkspace, m as useBioTemplateControls, n as DEFAULT_PRESETS, o as useGroupAssignment, p as useBioTemplateComponents, q as useToast, r as DEFAULT_UNITS, s as useRackEditor, t as useProtocolTemplates, u as useBioTemplateWorkspace, v as useExperimentSamples, w as hslToHex, x as useSampleGroups, y as useExperimentData, z as combinePluginJobSources } from "./useProtocolTemplates-DXeIHMwV.js";
1
+ import { a as SORT_OPTIONS, c as formatExperimentDate, d as resolveExperimentCode, f as BaseModal_default, i as EXPERIMENT_STATUS_VARIANT_MAP, l as formatExperimentStatus, m as BaseButton_default, n as EXPERIMENT_STATUS_LABELS, o as datePresetToISO, p as useEventListener, r as EXPERIMENT_STATUS_OPTIONS, s as experimentIdFromRoute, t as DATE_PRESET_OPTIONS, u as getExperimentStatusVariant } from "./experiment-utils-CLnzPPq5.js";
2
+ import { a as BaseSelect_default, i as BasePill_default, n as Skeleton_default, r as useRequestSyncState, s as BaseInput_default, t as EmptyState_default } from "./EmptyState-p90quq8Z.js";
3
+ import { $ as normalizeJobState, A as useConcentrationUnits, At as BaseCheckbox_default, B as useAnalysisArtifacts, C as controlsToViewIds, Ct as DatePicker_default, D as getTypeDefault, Dt as BaseSlider_default, E as getFieldRegistryEntry, Et as useSelectionLimit, F as ATOMIC_WEIGHTS, G as resolveCurrentPluginId, I as useChemicalFormula, It as BaseTextarea_default, J as usePluginJobs, K as createGeneratedAnalysisTransport, L as GeneratedPathInput_default, M as SequenceInput_default, N as useSequenceUtils, O as ConcentrationInput_default, Ot as BaseRadioGroup_default, P as FormulaInput_default, Q as normalizeJobPercent, S as controlsToTopBarSettingsConfig, St as useTimeUtils, T as getDefaultControlView, Tt as useListSelection, X as isTerminalJobStatus, Y as isActiveJobStatus, Z as jobStatusLabel, _ as controlsToFormSchema, _t as isTimeInRange, a as defineDoseCalculatorControlProps, at as TagsInput_default, b as controlsToSettingsSchema, bt as snapToSlot, c as defineWellPlateDoseComponentBindings, ct as compareTime, d as defineControlModel, dt as findNearestTimeSlotIndex, et as resolveJobCapabilities, ft as formatDuration, gt as generateTimeSlots, h as controlValuesToComponentProps, ht as fromMinutes, i as useControlSchema, it as NumberInput_default, j as MoleculeInput_default, jt as Tooltip_default, k as UnitInput_default, kt as BaseToggle_default, l as defineWellPlateDoseControlProps, lt as durationMinutes, m as controlValuesToComponentBindingsById, mt as formatTimeSlot, n as defineControls, nt as AlertBox_default, o as defineDoseDesignControlModel, ot as TimePicker_default, p as controlValuesToComponentBindings, pt as formatTime, q as useGeneratedAnalysis, r as getControlDefaults, rt as FileUploader_default, s as defineWellPlateControlProps, st as addMinutes, t as defineControlComponentBindings, tt as DateTimePicker_default, u as useControlWorkspace, ut as findAvailableSlots, v as controlsToSectionFormSchema, vt as parseTime, w as controlsToViewItems, wt as MultiSelect_default, x as controlsToSidebarPanels, xt as toMinutes, y as controlsToSectionFormSchemas, yt as rangesOverlap, z as ArtifactSelectorModal_default } from "./useControlSchema-BMVb2XIQ.js";
4
+ import { $ as SmartGroupFieldRecipe_default, A as ProtocolStepEditor_default, At as AppToastContainer_default, B as Breadcrumb_default, C as estimateSequenceRemainingSeconds, Ct as AppPluginSwitcher_default, D as sequenceSamplesRemaining, Dt as ThemeToggle_default, E as sequenceProgressPercent, Et as CollapsibleCard_default, F as RackEditor_default, Ft as BaseTabs_default, G as AppContainer_default, H as ProgressBar_default, I as BioTemplatePresetWorkspaceView_default, It as ColorSlider_default, J as ComponentBindingRenderer_default, K as DoseDesignWorkspaceView_default, L as BioTemplatePackWorkspaceView_default, M as ReagentEditor_default, Mt as Calendar_default, N as SmartGroupModal_default, Nt as DropdownButton_default, O as ChemicalFormula_default, Ot as ActionMenu_default, P as GroupAssigner_default, Pt as SegmentedControl_default, Q as SmartGroupManual_default, R as BioTemplateExperimentWorkspaceView_default, S as estimateSequenceFinishDate, St as AppTopBar_default, T as formatSequenceRemaining, Tt as PluginIcon_default, U as StatusIndicator_default, V as Avatar_default, W as Divider_default, X as SampleSelector_default, Y as ScheduleCalendar_default, Z as AutoGroupModal_default, _ as reconstructLcmsPlateCellsFromSequenceItems, _t as AppLayout_default, a as ResourceCard_default, at as DoseCalculator_default, b as InstrumentAlertLog_default, bt as FormActions_default, c as BatchProgressList_default, ct as GeneratedResultRenderer_default, d as DEFAULT_LCMS_SEQUENCE_COLUMNS, dt as LoadingSpinner_default, et as ReagentList_default, f as basenameFromWindowsPath, ft as generatedJobDefaults, g as lcmsWellIdFromPosition, gt as MobileSupportGate_default, h as inferLcmsPlateTypeFromWellIds, ht as PluginWorkspaceView_default, i as SectionCard_default, it as ExperimentTimeline_default, j as SampleHierarchyTree_default, jt as DataFrame_default, k as ScientificNumber_default, kt as IconButton_default, l as AuditTrail_default, lt as GeneratedPlotlyResult_default, m as extractLcmsSampleName, mt as normalizeGeneratedJobInput, n as FitPanel_default, nt as SampleLegend_default, o as TimeRangeInput_default, ot as GeneratedPluginView_default, p as extractLcmsCommonPrefix, pt as generatedJobFormSchema, q as ControlWorkspaceView_default, r as ArtifactSaveDialog_default, rt as WellPlate_default, s as ExperimentDataViewer_default, st as JobsStatusTray_default, tt as PlateMapEditor_default, u as LcmsSequenceTable_default, ut as ChartContainer_default, v as InstrumentStatusCard_default, vt as AppSidebar_default, w as formatSequenceEta, wt as AppAvatarMenu_default, x as SequenceProgressBar_default, xt as StepWizard_default, y as InstrumentStateBadge_default, yt as FormBuilder_default, z as BioTemplateRenderer_default } from "./components-CDomhGSj.js";
5
+ import { s as FormField_default, t as SettingsModal_default } from "./SettingsModal-D7LFUokT.js";
6
+ import { A as extractSamplesFromDesignData, B as useJobsStatusTray, C as hexToHsl, D as readFileAsText, E as parseDelimitedText, F as unwrapExperimentDesignData, G as useAppExperiment, H as DEFAULT_MOBILE_VIEWPORT_QUERY, I as DEFAULT_COLORS, J as candidateMatchesSearch, K as useTheme, L as useWellPlateEditor, N as extractSampleNamesFromDesignData, O as useFileImport, P as extractSampleOptionsFromDesignData, Q as useSortedItems, R as useDoseCalculator, S as deriveShade, T as detectDelimiter, U as useMobileSupportGate, V as usePluginJobCenter, W as APP_EXPERIMENT_KEY, X as useTextSearch, Y as normalizeSearchQuery, Z as compareSortValues, _ as useScheduleDrag, a as useReagentSeries, b as useExpansionSet, c as useBioTemplatePresetWorkspace, d as getBioTemplateComponentProps, f as toBioTemplateComponentPropsByComponent, g as useExperimentSave, h as useTemplateCollection, i as generateDilutionSeries, j as useAutoGroup, k as validateImportFile, l as useBioTemplatePackWorkspace, m as useBioTemplateControls, n as DEFAULT_PRESETS, o as useGroupAssignment, p as useBioTemplateComponents, q as useToast, r as DEFAULT_UNITS, s as useRackEditor, t as useProtocolTemplates, u as useBioTemplateWorkspace, v as useExperimentSamples, w as hslToHex, x as useSampleGroups, y as useExperimentData, z as combinePluginJobSources } from "./useProtocolTemplates-BMt0LlXf.js";
7
7
  import { a as colorPalettes, i as useAuthStore, o as useSettingsStore, r as useApi, t as AuthenticationRequiredError } from "./useApi-CDBq6z23.js";
8
- import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "./useFormBuilder-CR9pBApW.js";
8
+ import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "./useFormBuilder-DG3HOFGA.js";
9
9
  import { ADMIN_PANEL_PERMISSIONS, ADMIN_ROLE, canAccessAdmin, canAccessByPolicy, canAccessPlugin, getAccessAudience, getRoleInfo, getUserPermissions, hasAllPermissions, hasAnyPermission, isAdminRole, isAdminUser, normalizeAccessPolicy } from "./permissions.js";
10
10
  import { t as useExperimentStore } from "./experiment-Y9Iz7KYi.js";
11
11
  import { t as ANALYSIS_FILE_ARTIFACT_SCHEMA } from "./analysisArtifactTypes-DQ0MjwHZ.js";
12
- import { r as ConfirmDialog_default, t as ExperimentPopover_default } from "./ExperimentPopover-D6_RGzTY.js";
13
- import { $ as toTimeCourseRows, $t as listBioTemplatePacks, A as createSamplePrepTemplate, At as toCalibrationCurveRows, B as toBioTemplateComponentProps, Bt as validatePlateMapData, C as createFlowCytometryPanelTemplate, Ct as toInstrumentRunScheduleEvents, D as createTimeCourseTemplate, Dt as toFlowPanelRows, E as createProtocolStepsTemplate, Et as toFlowPanelDataFrame, Ft as validateAssayMatrixData, G as toTemplateDataFrame, Gt as validateSampleSheetData, H as toBioTemplateComponentPropsById, Ht as validateQpcrPlateData, I as listBioTemplateComponentBindings, It as validateCalibrationCurveData, J as toDoseLayoutState, Jt as getBioTemplatePresetInfo, K as toWellMapArray, Kt as validateTimeCourseData, L as toBioTemplateComponentBindings, Lt as validateDoseResponseData, M as createPlateMapTemplate, Mt as toAssayMatrixDataFrame, N as bioTemplatePresetControlValuesToOptions, Nt as toAssayMatrixRows, O as createCalibrationCurveTemplate, Ot as toCalibrationCurveColumns, P as getBioTemplateComponentBindings, Pt as toAssayMatrixSampleOptions, Q as toTimeCourseDataFrame, Qt as getBioTemplatePackInfo, R as toBioTemplateComponentBindingsById, Rt as validateFlowCytometryPanelData, S as createInstrumentRunTemplate, St as toInstrumentRunRows, T as createAssayMatrixTemplate, Tt as toFlowPanelColumns, U as toBioTemplateComponentSnippets, Ut as validateReagentListData, Vt as validateProtocolStepsData, W as toBioTemplateComponentUsage, Wt as validateSamplePrepData, X as toWellPlateWells, Xt as searchBioTemplatePresets, Y as toPlateMapEditorState, Yt as listBioTemplatePresets, Z as toTimeCourseColumns, Zt as bioTemplatePacks, _ as createElisaAssayCollection, _t as toProtocolDataFrame, a as getBioTemplateControlDefaults, an as TEMPLATE_COLLECTION_KEY, at as toSamplePrepColumns, b as createQpcrExpressionCollection, bt as toInstrumentRunColumns, c as listBioTemplatePresetControlSchemas, cn as createTemplateEnvelope, ct as toReagentColumns, d as createBioTemplatePresetCollectionFromControls, dn as extractTemplateCollection, dt as toReagentRows, en as searchBioTemplatePacks, et as toTimeCourseSteps, f as createWellPlateScreenCollection, fn as getTemplateData, ft as toQpcrColumns, g as createFlowCytometryAssayCollection, gt as toProtocolColumns, h as createWesternBlotAssayCollection, ht as toQpcrWellPlateWells, i as createBioTemplateControlToolkit, in as searchBioTemplateCatalog, it as toSampleRows, j as createSampleSheetTemplate, jt as toAssayMatrixColumns, k as createDoseResponseTemplate, kt as toCalibrationCurveDataFrame, l as requireBioTemplateControlSchema, ln as ensureTemplateEnvelope, lt as toReagentDataFrame, m as createDefaultBioTemplate, mt as toQpcrRows, n as bioTemplateControlsToSectionFormSchemas, nn as getBioTemplateInfo, nt as toSampleDataFrame, o as getBioTemplateControlSchema, on as assertTemplateEnvelope, ot as toSamplePrepDataFrame, p as createBioTemplatePackCollection, pt as toQpcrDataFrame, q as toDoseConditions, qt as bioTemplatePresets, r as bioTemplateControlsToSidebarPanels, rn as listBioTemplateCatalog, rt as toSampleOptions, s as listBioTemplateControlSchemas, sn as createTemplateCollection, st as toSamplePrepRows, t as bioTemplateControlsToFormSchema, tn as bioTemplateCatalog, tt as toSampleColumns, u as createBioTemplatePresetCollection, un as ensureTemplateFromCollection, ut as toReagentListItems, v as createTargetedMetabolomicsCollection, vt as toProtocolRows, w as createReagentListTemplate, wt as toInstrumentRunSteps, x as createQpcrPlateTemplate, xt as toInstrumentRunDataFrame, y as createLcmsBatchCollection, yt as toProtocolSteps, z as toBioTemplateComponentImports, zt as validateInstrumentRunData } from "./templates-CJRFiWUX.js";
14
- import { r as ExperimentCodeBadge_default, t as ExperimentSelectorModal_default } from "./ExperimentSelectorModal-DcQ38zua.js";
15
- import { n as useDebouncedWatch, t as useExperimentSelector } from "./useExperimentSelector-DFg_iEHI.js";
12
+ import { r as ConfirmDialog_default, t as ExperimentPopover_default } from "./ExperimentPopover-tLwJ7XF4.js";
13
+ import { $ as toTimeCourseRows, $t as listBioTemplatePacks, A as createSamplePrepTemplate, At as toCalibrationCurveRows, B as toBioTemplateComponentProps, Bt as validatePlateMapData, C as createFlowCytometryPanelTemplate, Ct as toInstrumentRunScheduleEvents, D as createTimeCourseTemplate, Dt as toFlowPanelRows, E as createProtocolStepsTemplate, Et as toFlowPanelDataFrame, Ft as validateAssayMatrixData, G as toTemplateDataFrame, Gt as validateSampleSheetData, H as toBioTemplateComponentPropsById, Ht as validateQpcrPlateData, I as listBioTemplateComponentBindings, It as validateCalibrationCurveData, J as toDoseLayoutState, Jt as getBioTemplatePresetInfo, K as toWellMapArray, Kt as validateTimeCourseData, L as toBioTemplateComponentBindings, Lt as validateDoseResponseData, M as createPlateMapTemplate, Mt as toAssayMatrixDataFrame, N as bioTemplatePresetControlValuesToOptions, Nt as toAssayMatrixRows, O as createCalibrationCurveTemplate, Ot as toCalibrationCurveColumns, P as getBioTemplateComponentBindings, Pt as toAssayMatrixSampleOptions, Q as toTimeCourseDataFrame, Qt as getBioTemplatePackInfo, R as toBioTemplateComponentBindingsById, Rt as validateFlowCytometryPanelData, S as createInstrumentRunTemplate, St as toInstrumentRunRows, T as createAssayMatrixTemplate, Tt as toFlowPanelColumns, U as toBioTemplateComponentSnippets, Ut as validateReagentListData, Vt as validateProtocolStepsData, W as toBioTemplateComponentUsage, Wt as validateSamplePrepData, X as toWellPlateWells, Xt as searchBioTemplatePresets, Y as toPlateMapEditorState, Yt as listBioTemplatePresets, Z as toTimeCourseColumns, Zt as bioTemplatePacks, _ as createElisaAssayCollection, _t as toProtocolDataFrame, a as getBioTemplateControlDefaults, an as TEMPLATE_COLLECTION_KEY, at as toSamplePrepColumns, b as createQpcrExpressionCollection, bt as toInstrumentRunColumns, c as listBioTemplatePresetControlSchemas, cn as createTemplateEnvelope, ct as toReagentColumns, d as createBioTemplatePresetCollectionFromControls, dn as extractTemplateCollection, dt as toReagentRows, en as searchBioTemplatePacks, et as toTimeCourseSteps, f as createWellPlateScreenCollection, fn as getTemplateData, ft as toQpcrColumns, g as createFlowCytometryAssayCollection, gt as toProtocolColumns, h as createWesternBlotAssayCollection, ht as toQpcrWellPlateWells, i as createBioTemplateControlToolkit, in as searchBioTemplateCatalog, it as toSampleRows, j as createSampleSheetTemplate, jt as toAssayMatrixColumns, k as createDoseResponseTemplate, kt as toCalibrationCurveDataFrame, l as requireBioTemplateControlSchema, ln as ensureTemplateEnvelope, lt as toReagentDataFrame, m as createDefaultBioTemplate, mt as toQpcrRows, n as bioTemplateControlsToSectionFormSchemas, nn as getBioTemplateInfo, nt as toSampleDataFrame, o as getBioTemplateControlSchema, on as assertTemplateEnvelope, ot as toSamplePrepDataFrame, p as createBioTemplatePackCollection, pt as toQpcrDataFrame, q as toDoseConditions, qt as bioTemplatePresets, r as bioTemplateControlsToSidebarPanels, rn as listBioTemplateCatalog, rt as toSampleOptions, s as listBioTemplateControlSchemas, sn as createTemplateCollection, st as toSamplePrepRows, t as bioTemplateControlsToFormSchema, tn as bioTemplateCatalog, tt as toSampleColumns, u as createBioTemplatePresetCollection, un as ensureTemplateFromCollection, ut as toReagentListItems, v as createTargetedMetabolomicsCollection, vt as toProtocolRows, w as createReagentListTemplate, wt as toInstrumentRunSteps, x as createQpcrPlateTemplate, xt as toInstrumentRunDataFrame, y as createLcmsBatchCollection, yt as toProtocolSteps, z as toBioTemplateComponentImports, zt as validateInstrumentRunData } from "./templates-Cr-48-u2.js";
14
+ import { r as ExperimentCodeBadge_default, t as ExperimentSelectorModal_default } from "./ExperimentSelectorModal-B6P2msT4.js";
15
+ import { n as useDebouncedWatch, t as useExperimentSelector } from "./useExperimentSelector-D0pjj9WH.js";
16
16
  import { MINTSdk } from "./install.js";
17
- import { A as useAsync, C as createPluginResourceClient, D as buildAnalysisArtifactTargetQuery, E as useCommandHistory, M as resolvePluginFrontendBase, N as usePasskey, O as parseAnalysisArtifactTarget, P as useAuth, S as wellIdsInRectangle, T as useOptimisticMutation, _ as createWellPlateWells, a as pluginFormDataFromPayload, b as useWellPainting, c as usePluginClient, d as buildPluginEndpointUrl, f as resolvePluginBaseUrl, g as createRowConditions, h as createColumnConditions, i as getPluginPageSelectorItems, j as useAsyncBatch, k as usePluginConfig, l as usePluginEventStream, m as useWellPlateValidation, n as downloadBlob, o as uploadPluginEndpoint, p as runWellPlateValidation, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as usePluginSettings, v as useWellPlateAdapter, w as useResourceCrud, x as wellIdToCoordinate, y as coordinateToWellId } from "./composables-CW8NRXLB.js";
17
+ import { A as useAsync, C as createPluginResourceClient, D as buildAnalysisArtifactTargetQuery, E as useCommandHistory, M as resolvePluginFrontendBase, N as usePasskey, O as parseAnalysisArtifactTarget, P as useAuth, S as wellIdsInRectangle, T as useOptimisticMutation, _ as createWellPlateWells, a as pluginFormDataFromPayload, b as useWellPainting, c as usePluginClient, d as buildPluginEndpointUrl, f as resolvePluginBaseUrl, g as createRowConditions, h as createColumnConditions, i as getPluginPageSelectorItems, j as useAsyncBatch, k as usePluginConfig, l as usePluginEventStream, m as useWellPlateValidation, n as downloadBlob, o as uploadPluginEndpoint, p as runWellPlateValidation, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as usePluginSettings, v as useWellPlateAdapter, w as useResourceCrud, x as wellIdToCoordinate, y as coordinateToWellId } from "./composables-CRR_JxQD.js";
18
18
  import "./stores/index.js";
19
19
  //#region src/utils/rack.ts
20
20
  var LCMS_DEFAULT_CONTROL_POSITIONS = {
@@ -176,6 +176,6 @@ function comparePlateCells(a, b) {
176
176
  return rowDiff === 0 ? a.column - b.column : rowDiff;
177
177
  }
178
178
  //#endregion
179
- export { ADMIN_PANEL_PERMISSIONS, ADMIN_ROLE, ANALYSIS_FILE_ARTIFACT_SCHEMA, APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, AlertBox_default as AlertBox, AppAvatarMenu_default as AppAvatarMenu, AppContainer_default as AppContainer, AppLayout_default as AppLayout, AppPluginSwitcher_default as AppPluginSwitcher, AppSidebar_default as AppSidebar, AppToastContainer_default as AppToastContainer, AppTopBar_default as AppTopBar, ArtifactSaveDialog_default as ArtifactSaveDialog, ArtifactSelectorModal_default as ArtifactSelectorModal, AuditTrail_default as AuditTrail, AuthenticationRequiredError, AutoGroupModal_default as AutoGroupModal, Avatar_default as Avatar, BaseButton_default as BaseButton, BaseCheckbox_default as BaseCheckbox, BaseInput_default as BaseInput, BaseModal_default as BaseModal, BasePill_default as BasePill, BaseRadioGroup_default as BaseRadioGroup, BaseSelect_default as BaseSelect, BaseSlider_default as BaseSlider, BaseTabs_default as BaseTabs, BaseTextarea_default as BaseTextarea, BaseToggle_default as BaseToggle, BatchProgressList_default as BatchProgressList, BioTemplateExperimentWorkspaceView_default as BioTemplateExperimentWorkspaceView, BioTemplatePackWorkspaceView_default as BioTemplatePackWorkspaceView, BioTemplatePresetWorkspaceView_default as BioTemplatePresetWorkspaceView, BioTemplateRenderer_default as BioTemplateRenderer, Breadcrumb_default as Breadcrumb, Calendar_default as Calendar, ChartContainer_default as ChartContainer, ChemicalFormula_default as ChemicalFormula, CollapsibleCard_default as CollapsibleCard, ColorSlider_default as ColorSlider, ComponentBindingRenderer_default as ComponentBindingRenderer, ConcentrationInput_default as ConcentrationInput, ConfirmDialog_default as ConfirmDialog, ControlWorkspaceView_default as ControlWorkspaceView, DATE_PRESET_OPTIONS, DEFAULT_COLORS, DEFAULT_LCMS_SEQUENCE_COLUMNS, DEFAULT_MOBILE_VIEWPORT_QUERY, DEFAULT_PRESETS, DEFAULT_UNITS, DataFrame_default as DataFrame, DatePicker_default as DatePicker, DateTimePicker_default as DateTimePicker, Divider_default as Divider, DoseCalculator_default as DoseCalculator, DoseDesignWorkspaceView_default as DoseDesignWorkspaceView, DropdownButton_default as DropdownButton, EXPERIMENT_STATUS_LABELS, EXPERIMENT_STATUS_OPTIONS, EXPERIMENT_STATUS_VARIANT_MAP, EmptyState_default as EmptyState, ExperimentCodeBadge_default as ExperimentCodeBadge, ExperimentDataViewer_default as ExperimentDataViewer, ExperimentPopover_default as ExperimentPopover, ExperimentSelectorModal_default as ExperimentSelectorModal, ExperimentTimeline_default as ExperimentTimeline, FileUploader_default as FileUploader, FitPanel_default as FitPanel, FormActions_default as FormActions, FormBuilder_default as FormBuilder, FormField_default as FormField, FormulaInput_default as FormulaInput, GeneratedPathInput_default as GeneratedPathInput, GeneratedPlotlyResult_default as GeneratedPlotlyResult, GeneratedPluginView_default as GeneratedPluginView, GeneratedResultRenderer_default as GeneratedResultRenderer, GroupAssigner_default as GroupAssigner, IconButton_default as IconButton, InstrumentAlertLog_default as InstrumentAlertLog, InstrumentStateBadge_default as InstrumentStateBadge, InstrumentStatusCard_default as InstrumentStatusCard, JobsStatusTray_default as JobsStatusTray, LCMS_DEFAULT_CONTROL_POSITIONS, LcmsSequenceTable_default as LcmsSequenceTable, LoadingSpinner_default as LoadingSpinner, MINTSdk, MINTSdk as default, MobileSupportGate_default as MobileSupportGate, MoleculeInput_default as MoleculeInput, MultiSelect_default as MultiSelect, NumberInput_default as NumberInput, PlateMapEditor_default as PlateMapEditor, PluginIcon_default as PluginIcon, PluginWorkspaceView_default as PluginWorkspaceView, ProgressBar_default as ProgressBar, ProtocolStepEditor_default as ProtocolStepEditor, RackEditor_default as RackEditor, ReagentEditor_default as ReagentEditor, ReagentList_default as ReagentList, ResourceCard_default as ResourceCard, SORT_OPTIONS, SampleHierarchyTree_default as SampleHierarchyTree, SampleLegend_default as SampleLegend, SampleSelector_default as SampleSelector, ScheduleCalendar_default as ScheduleCalendar, ScientificNumber_default as ScientificNumber, SectionCard_default as SectionCard, SegmentedControl_default as SegmentedControl, SequenceInput_default as SequenceInput, SequenceProgressBar_default as SequenceProgressBar, SettingsModal_default as SettingsModal, Skeleton_default as Skeleton, SmartGroupFieldRecipe_default as SmartGroupFieldRecipe, SmartGroupManual_default as SmartGroupManual, SmartGroupModal_default as SmartGroupModal, StatusIndicator_default as StatusIndicator, StepWizard_default as StepWizard, TEMPLATE_COLLECTION_KEY, TagsInput_default as TagsInput, ThemeToggle_default as ThemeToggle, TimePicker_default as TimePicker, TimeRangeInput_default as TimeRangeInput, Tooltip_default as Tooltip, UnitInput_default as UnitInput, WellPlate_default as WellPlate, addMinutes, assertTemplateEnvelope, basenameFromWindowsPath, bioTemplateCatalog, bioTemplateControlsToFormSchema, bioTemplateControlsToSectionFormSchemas, bioTemplateControlsToSidebarPanels, bioTemplatePacks, bioTemplatePresetControlValuesToOptions, bioTemplatePresets, buildAnalysisArtifactTargetQuery, buildPluginEndpointUrl, canAccessAdmin, canAccessByPolicy, canAccessPlugin, candidateMatchesSearch, colorPalettes, combinePluginJobSources, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createAssayMatrixTemplate, createBioTemplateControlToolkit, createBioTemplatePackCollection, createBioTemplatePresetCollection, createBioTemplatePresetCollectionFromControls, createCalibrationCurveTemplate, createColumnConditions, createDefaultBioTemplate, createDoseResponseTemplate, createElisaAssayCollection, createFlowCytometryAssayCollection, createFlowCytometryPanelTemplate, createGeneratedAnalysisTransport, createInstrumentRunTemplate, createLcmsBatchCollection, createLcmsControlWellEditData, createPlateMapTemplate, createPluginClient, createPluginResourceClient, createProtocolStepsTemplate, createQpcrExpressionCollection, createQpcrPlateTemplate, createReagentListTemplate, createRowConditions, createSamplePrepTemplate, createSampleSheetTemplate, createTargetedMetabolomicsCollection, createTemplateCollection, createTemplateEnvelope, createTimeCourseTemplate, createWellPlateScreenCollection, createWellPlateWells, createWesternBlotAssayCollection, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, deriveShade, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, ensureTemplateEnvelope, ensureTemplateFromCollection, estimateSequenceFinishDate, estimateSequenceRemainingSeconds, evaluateCondition, experimentIdFromRoute, extractLcmsCommonPrefix, extractLcmsSampleName, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, extractTemplateCollection, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatSequenceEta, formatSequenceRemaining, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, generatedJobDefaults, generatedJobFormSchema, getAccessAudience, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlDefaults, getBioTemplateControlSchema, getBioTemplateInfo, getBioTemplatePackInfo, getBioTemplatePresetInfo, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getLcmsDefaultControlWellId, getPluginPageSelectorItems, getRoleInfo, getTemplateData, getTypeDefault, getUserPermissions, hasAllPermissions, hasAnyPermission, hexToHsl, hslToHex, inferLcmsPlateTypeFromWellIds, isActiveJobStatus, isAdminRole, isAdminUser, isTerminalJobStatus, isTimeInRange, jobStatusLabel, lcmsPlateCellsToRack, lcmsPlateCellsToRacks, lcmsPlateTypeToRackFormat, lcmsWellId, lcmsWellIdFromPosition, listBioTemplateCatalog, listBioTemplateComponentBindings, listBioTemplateControlSchemas, listBioTemplatePacks, listBioTemplatePresetControlSchemas, listBioTemplatePresets, normalizeAccessPolicy, normalizeGeneratedJobInput, normalizeJobPercent, normalizeJobState, normalizeSearchQuery, parseAnalysisArtifactTarget, parseDelimitedText, parseLcmsWellId, parseTime, pluginFormDataFromPayload, rackFormatToLcmsPlateType, rackToLcmsPlateCells, racksToLcmsPlateCells, rangesOverlap, readFileAsText, reconstructLcmsPlateCellsFromSequenceItems, requireBioTemplateControlSchema, resolveCurrentPluginId, resolveExperimentCode, resolveJobCapabilities, resolvePluginBaseUrl, resolvePluginFrontendBase, runWellPlateValidation, searchBioTemplateCatalog, searchBioTemplatePacks, searchBioTemplatePresets, sequenceProgressPercent, sequenceSamplesRemaining, snapToSlot, toAssayMatrixColumns, toAssayMatrixDataFrame, toAssayMatrixRows, toAssayMatrixSampleOptions, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentImports, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toBioTemplateComponentSnippets, toBioTemplateComponentUsage, toCalibrationCurveColumns, toCalibrationCurveDataFrame, toCalibrationCurveRows, toDoseConditions, toDoseLayoutState, toFlowPanelColumns, toFlowPanelDataFrame, toFlowPanelRows, toInstrumentRunColumns, toInstrumentRunDataFrame, toInstrumentRunRows, toInstrumentRunScheduleEvents, toInstrumentRunSteps, toMinutes, toPlateMapEditorState, toProtocolColumns, toProtocolDataFrame, toProtocolRows, toProtocolSteps, toQpcrColumns, toQpcrDataFrame, toQpcrRows, toQpcrWellPlateWells, toReagentColumns, toReagentDataFrame, toReagentListItems, toReagentRows, toSampleColumns, toSampleDataFrame, toSampleOptions, toSamplePrepColumns, toSamplePrepDataFrame, toSamplePrepRows, toSampleRows, toTemplateDataFrame, toTimeCourseColumns, toTimeCourseDataFrame, toTimeCourseRows, toTimeCourseSteps, toWellMapArray, toWellPlateWells, unwrapExperimentDesignData, uploadPluginEndpoint, useAnalysisArtifacts, useApi, useAppExperiment, useAsync, useAsyncBatch, useAuth, useAuthStore, useAutoGroup, useBioTemplateComponents, useBioTemplateControls, useBioTemplatePackWorkspace, useBioTemplatePresetWorkspace, useBioTemplateWorkspace, useChemicalFormula, useCommandHistory, useConcentrationUnits, useControlSchema, useControlWorkspace, useCurrentExperiment, useDebouncedWatch, useDoseCalculator, useEventListener, useExpansionSet, useExperimentData, useExperimentSamples, useExperimentSave, useExperimentSelector, useExperimentStore, useFileImport, useForm, useFormBuilder, useGeneratedAnalysis, useGroupAssignment, useJobsStatusTray, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginJobCenter, usePluginJobs, usePluginSettings, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSettingsStore, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateAssayMatrixData, validateCalibrationCurveData, validateDoseResponseData, validateFlowCytometryPanelData, validateImportFile, validateInstrumentRunData, validatePlateMapData, validateProtocolStepsData, validateQpcrPlateData, validateReagentListData, validateSamplePrepData, validateSampleSheetData, validateTimeCourseData, wellIdToCoordinate, wellIdsInRectangle };
179
+ export { ADMIN_PANEL_PERMISSIONS, ADMIN_ROLE, ANALYSIS_FILE_ARTIFACT_SCHEMA, APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, ActionMenu_default as ActionMenu, AlertBox_default as AlertBox, AppAvatarMenu_default as AppAvatarMenu, AppContainer_default as AppContainer, AppLayout_default as AppLayout, AppPluginSwitcher_default as AppPluginSwitcher, AppSidebar_default as AppSidebar, AppToastContainer_default as AppToastContainer, AppTopBar_default as AppTopBar, ArtifactSaveDialog_default as ArtifactSaveDialog, ArtifactSelectorModal_default as ArtifactSelectorModal, AuditTrail_default as AuditTrail, AuthenticationRequiredError, AutoGroupModal_default as AutoGroupModal, Avatar_default as Avatar, BaseButton_default as BaseButton, BaseCheckbox_default as BaseCheckbox, BaseInput_default as BaseInput, BaseModal_default as BaseModal, BasePill_default as BasePill, BaseRadioGroup_default as BaseRadioGroup, BaseSelect_default as BaseSelect, BaseSlider_default as BaseSlider, BaseTabs_default as BaseTabs, BaseTextarea_default as BaseTextarea, BaseToggle_default as BaseToggle, BatchProgressList_default as BatchProgressList, BioTemplateExperimentWorkspaceView_default as BioTemplateExperimentWorkspaceView, BioTemplatePackWorkspaceView_default as BioTemplatePackWorkspaceView, BioTemplatePresetWorkspaceView_default as BioTemplatePresetWorkspaceView, BioTemplateRenderer_default as BioTemplateRenderer, Breadcrumb_default as Breadcrumb, Calendar_default as Calendar, ChartContainer_default as ChartContainer, ChemicalFormula_default as ChemicalFormula, CollapsibleCard_default as CollapsibleCard, ColorSlider_default as ColorSlider, ComponentBindingRenderer_default as ComponentBindingRenderer, ConcentrationInput_default as ConcentrationInput, ConfirmDialog_default as ConfirmDialog, ControlWorkspaceView_default as ControlWorkspaceView, DATE_PRESET_OPTIONS, DEFAULT_COLORS, DEFAULT_LCMS_SEQUENCE_COLUMNS, DEFAULT_MOBILE_VIEWPORT_QUERY, DEFAULT_PRESETS, DEFAULT_UNITS, DataFrame_default as DataFrame, DatePicker_default as DatePicker, DateTimePicker_default as DateTimePicker, Divider_default as Divider, DoseCalculator_default as DoseCalculator, DoseDesignWorkspaceView_default as DoseDesignWorkspaceView, DropdownButton_default as DropdownButton, EXPERIMENT_STATUS_LABELS, EXPERIMENT_STATUS_OPTIONS, EXPERIMENT_STATUS_VARIANT_MAP, EmptyState_default as EmptyState, ExperimentCodeBadge_default as ExperimentCodeBadge, ExperimentDataViewer_default as ExperimentDataViewer, ExperimentPopover_default as ExperimentPopover, ExperimentSelectorModal_default as ExperimentSelectorModal, ExperimentTimeline_default as ExperimentTimeline, FileUploader_default as FileUploader, FitPanel_default as FitPanel, FormActions_default as FormActions, FormBuilder_default as FormBuilder, FormField_default as FormField, FormulaInput_default as FormulaInput, GeneratedPathInput_default as GeneratedPathInput, GeneratedPlotlyResult_default as GeneratedPlotlyResult, GeneratedPluginView_default as GeneratedPluginView, GeneratedResultRenderer_default as GeneratedResultRenderer, GroupAssigner_default as GroupAssigner, IconButton_default as IconButton, InstrumentAlertLog_default as InstrumentAlertLog, InstrumentStateBadge_default as InstrumentStateBadge, InstrumentStatusCard_default as InstrumentStatusCard, JobsStatusTray_default as JobsStatusTray, LCMS_DEFAULT_CONTROL_POSITIONS, LcmsSequenceTable_default as LcmsSequenceTable, LoadingSpinner_default as LoadingSpinner, MINTSdk, MINTSdk as default, MobileSupportGate_default as MobileSupportGate, MoleculeInput_default as MoleculeInput, MultiSelect_default as MultiSelect, NumberInput_default as NumberInput, PlateMapEditor_default as PlateMapEditor, PluginIcon_default as PluginIcon, PluginWorkspaceView_default as PluginWorkspaceView, ProgressBar_default as ProgressBar, ProtocolStepEditor_default as ProtocolStepEditor, RackEditor_default as RackEditor, ReagentEditor_default as ReagentEditor, ReagentList_default as ReagentList, ResourceCard_default as ResourceCard, SORT_OPTIONS, SampleHierarchyTree_default as SampleHierarchyTree, SampleLegend_default as SampleLegend, SampleSelector_default as SampleSelector, ScheduleCalendar_default as ScheduleCalendar, ScientificNumber_default as ScientificNumber, SectionCard_default as SectionCard, SegmentedControl_default as SegmentedControl, SequenceInput_default as SequenceInput, SequenceProgressBar_default as SequenceProgressBar, SettingsModal_default as SettingsModal, Skeleton_default as Skeleton, SmartGroupFieldRecipe_default as SmartGroupFieldRecipe, SmartGroupManual_default as SmartGroupManual, SmartGroupModal_default as SmartGroupModal, StatusIndicator_default as StatusIndicator, StepWizard_default as StepWizard, TEMPLATE_COLLECTION_KEY, TagsInput_default as TagsInput, ThemeToggle_default as ThemeToggle, TimePicker_default as TimePicker, TimeRangeInput_default as TimeRangeInput, Tooltip_default as Tooltip, UnitInput_default as UnitInput, WellPlate_default as WellPlate, addMinutes, assertTemplateEnvelope, basenameFromWindowsPath, bioTemplateCatalog, bioTemplateControlsToFormSchema, bioTemplateControlsToSectionFormSchemas, bioTemplateControlsToSidebarPanels, bioTemplatePacks, bioTemplatePresetControlValuesToOptions, bioTemplatePresets, buildAnalysisArtifactTargetQuery, buildPluginEndpointUrl, canAccessAdmin, canAccessByPolicy, canAccessPlugin, candidateMatchesSearch, colorPalettes, combinePluginJobSources, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createAssayMatrixTemplate, createBioTemplateControlToolkit, createBioTemplatePackCollection, createBioTemplatePresetCollection, createBioTemplatePresetCollectionFromControls, createCalibrationCurveTemplate, createColumnConditions, createDefaultBioTemplate, createDoseResponseTemplate, createElisaAssayCollection, createFlowCytometryAssayCollection, createFlowCytometryPanelTemplate, createGeneratedAnalysisTransport, createInstrumentRunTemplate, createLcmsBatchCollection, createLcmsControlWellEditData, createPlateMapTemplate, createPluginClient, createPluginResourceClient, createProtocolStepsTemplate, createQpcrExpressionCollection, createQpcrPlateTemplate, createReagentListTemplate, createRowConditions, createSamplePrepTemplate, createSampleSheetTemplate, createTargetedMetabolomicsCollection, createTemplateCollection, createTemplateEnvelope, createTimeCourseTemplate, createWellPlateScreenCollection, createWellPlateWells, createWesternBlotAssayCollection, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, deriveShade, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, ensureTemplateEnvelope, ensureTemplateFromCollection, estimateSequenceFinishDate, estimateSequenceRemainingSeconds, evaluateCondition, experimentIdFromRoute, extractLcmsCommonPrefix, extractLcmsSampleName, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, extractTemplateCollection, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatSequenceEta, formatSequenceRemaining, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, generatedJobDefaults, generatedJobFormSchema, getAccessAudience, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlDefaults, getBioTemplateControlSchema, getBioTemplateInfo, getBioTemplatePackInfo, getBioTemplatePresetInfo, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getLcmsDefaultControlWellId, getPluginPageSelectorItems, getRoleInfo, getTemplateData, getTypeDefault, getUserPermissions, hasAllPermissions, hasAnyPermission, hexToHsl, hslToHex, inferLcmsPlateTypeFromWellIds, isActiveJobStatus, isAdminRole, isAdminUser, isTerminalJobStatus, isTimeInRange, jobStatusLabel, lcmsPlateCellsToRack, lcmsPlateCellsToRacks, lcmsPlateTypeToRackFormat, lcmsWellId, lcmsWellIdFromPosition, listBioTemplateCatalog, listBioTemplateComponentBindings, listBioTemplateControlSchemas, listBioTemplatePacks, listBioTemplatePresetControlSchemas, listBioTemplatePresets, normalizeAccessPolicy, normalizeGeneratedJobInput, normalizeJobPercent, normalizeJobState, normalizeSearchQuery, parseAnalysisArtifactTarget, parseDelimitedText, parseLcmsWellId, parseTime, pluginFormDataFromPayload, rackFormatToLcmsPlateType, rackToLcmsPlateCells, racksToLcmsPlateCells, rangesOverlap, readFileAsText, reconstructLcmsPlateCellsFromSequenceItems, requireBioTemplateControlSchema, resolveCurrentPluginId, resolveExperimentCode, resolveJobCapabilities, resolvePluginBaseUrl, resolvePluginFrontendBase, runWellPlateValidation, searchBioTemplateCatalog, searchBioTemplatePacks, searchBioTemplatePresets, sequenceProgressPercent, sequenceSamplesRemaining, snapToSlot, toAssayMatrixColumns, toAssayMatrixDataFrame, toAssayMatrixRows, toAssayMatrixSampleOptions, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentImports, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toBioTemplateComponentSnippets, toBioTemplateComponentUsage, toCalibrationCurveColumns, toCalibrationCurveDataFrame, toCalibrationCurveRows, toDoseConditions, toDoseLayoutState, toFlowPanelColumns, toFlowPanelDataFrame, toFlowPanelRows, toInstrumentRunColumns, toInstrumentRunDataFrame, toInstrumentRunRows, toInstrumentRunScheduleEvents, toInstrumentRunSteps, toMinutes, toPlateMapEditorState, toProtocolColumns, toProtocolDataFrame, toProtocolRows, toProtocolSteps, toQpcrColumns, toQpcrDataFrame, toQpcrRows, toQpcrWellPlateWells, toReagentColumns, toReagentDataFrame, toReagentListItems, toReagentRows, toSampleColumns, toSampleDataFrame, toSampleOptions, toSamplePrepColumns, toSamplePrepDataFrame, toSamplePrepRows, toSampleRows, toTemplateDataFrame, toTimeCourseColumns, toTimeCourseDataFrame, toTimeCourseRows, toTimeCourseSteps, toWellMapArray, toWellPlateWells, unwrapExperimentDesignData, uploadPluginEndpoint, useAnalysisArtifacts, useApi, useAppExperiment, useAsync, useAsyncBatch, useAuth, useAuthStore, useAutoGroup, useBioTemplateComponents, useBioTemplateControls, useBioTemplatePackWorkspace, useBioTemplatePresetWorkspace, useBioTemplateWorkspace, useChemicalFormula, useCommandHistory, useConcentrationUnits, useControlSchema, useControlWorkspace, useCurrentExperiment, useDebouncedWatch, useDoseCalculator, useEventListener, useExpansionSet, useExperimentData, useExperimentSamples, useExperimentSave, useExperimentSelector, useExperimentStore, useFileImport, useForm, useFormBuilder, useGeneratedAnalysis, useGroupAssignment, useJobsStatusTray, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginJobCenter, usePluginJobs, usePluginSettings, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSettingsStore, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateAssayMatrixData, validateCalibrationCurveData, validateDoseResponseData, validateFlowCytometryPanelData, validateImportFile, validateInstrumentRunData, validatePlateMapData, validateProtocolStepsData, validateQpcrPlateData, validateReagentListData, validateSamplePrepData, validateSampleSheetData, validateTimeCourseData, wellIdToCoordinate, wellIdsInRectangle };
180
180
 
181
181
  //# sourceMappingURL=index.js.map
package/dist/install.js CHANGED
@@ -1,10 +1,10 @@
1
- import "./experiment-utils-7Yw-h0tD.js";
2
- import "./EmptyState-LMPS3keb.js";
3
- import "./useControlSchema-BEAgLyyx.js";
4
- import { t as components_exports } from "./components-CV5zuWa8.js";
5
- import "./SettingsModal-Ccq2z-Ms.js";
6
- import "./ExperimentPopover-D6_RGzTY.js";
7
- import "./ExperimentSelectorModal-DcQ38zua.js";
1
+ import "./experiment-utils-CLnzPPq5.js";
2
+ import "./EmptyState-p90quq8Z.js";
3
+ import "./useControlSchema-BMVb2XIQ.js";
4
+ import { t as components_exports } from "./components-CDomhGSj.js";
5
+ import "./SettingsModal-D7LFUokT.js";
6
+ import "./ExperimentPopover-tLwJ7XF4.js";
7
+ import "./ExperimentSelectorModal-B6P2msT4.js";
8
8
  //#region src/install.ts
9
9
  /**
10
10
  * Vue plugin that registers all MINT SDK components globally.