@morscherlab/mint-sdk 1.0.0-rc.2 → 1.0.0-rc.5

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 (443) hide show
  1. package/dist/__tests__/components/AppTopBar.navigation.test.d.ts +1 -0
  2. package/dist/__tests__/components/DoseCalculatorVolumeField.test.d.ts +1 -0
  3. package/dist/__tests__/components/PlateMapEditorToolbarInternal.test.d.ts +1 -0
  4. package/dist/__tests__/components/PluginWorkspaceView.controls.test.d.ts +1 -0
  5. package/dist/__tests__/components/PluginWorkspaceView.navigation.test.d.ts +1 -0
  6. package/dist/__tests__/components/PluginWorkspaceView.shell.test.d.ts +1 -0
  7. package/dist/__tests__/components/ProtocolStep.presentation.test.d.ts +1 -0
  8. package/dist/__tests__/components/ProtocolStepEditor.state.test.d.ts +1 -0
  9. package/dist/__tests__/components/ProtocolStepParameterField.test.d.ts +1 -0
  10. package/dist/__tests__/components/ReagentList.presentation.test.d.ts +1 -0
  11. package/dist/__tests__/components/SampleSelector.colors.test.d.ts +1 -0
  12. package/dist/__tests__/components/SampleSelector.drag.test.d.ts +1 -0
  13. package/dist/__tests__/components/SampleSelector.groups.test.d.ts +1 -0
  14. package/dist/__tests__/components/SampleSelector.selection.test.d.ts +1 -0
  15. package/dist/__tests__/components/SampleSelectorSampleRow.test.d.ts +1 -0
  16. package/dist/__tests__/components/ScheduleCalendar.test.d.ts +1 -0
  17. package/dist/__tests__/components/SettingsModal.schema.test.d.ts +1 -0
  18. package/dist/__tests__/components/WellPlate.colors.test.d.ts +1 -0
  19. package/dist/__tests__/components/WellPlate.conditions.test.d.ts +1 -0
  20. package/dist/__tests__/components/WellPlate.geometry.test.d.ts +1 -0
  21. package/dist/__tests__/components/WellPlate.interaction.test.d.ts +1 -0
  22. package/dist/__tests__/components/WellPlate.legend.test.d.ts +1 -0
  23. package/dist/__tests__/components/WellPlate.rendering.test.d.ts +1 -0
  24. package/dist/__tests__/components/WellPlate.sampleDrop.test.d.ts +1 -0
  25. package/dist/__tests__/composables/autoGroup/classify.test.d.ts +1 -0
  26. package/dist/__tests__/composables/autoGroup/columns.test.d.ts +1 -0
  27. package/dist/__tests__/composables/autoGroup/compose.test.d.ts +1 -0
  28. package/dist/__tests__/composables/autoGroup/cooccurrence.test.d.ts +1 -0
  29. package/dist/__tests__/composables/autoGroup/fingerprint.test.d.ts +1 -0
  30. package/dist/__tests__/composables/autoGroup/integration.test.d.ts +1 -0
  31. package/dist/__tests__/composables/autoGroup/template.test.d.ts +1 -0
  32. package/dist/__tests__/composables/autoGroup/tokenize.test.d.ts +1 -0
  33. package/dist/__tests__/composables/useAutoGroupInputSources.test.d.ts +1 -0
  34. package/dist/__tests__/composables/useScheduleCalendarLayout.test.d.ts +1 -0
  35. package/dist/__tests__/docs/extractDocsComponents.test.d.ts +1 -0
  36. package/dist/__tests__/docs/extractDocsExports.test.d.ts +1 -0
  37. package/dist/__tests__/docs/extractDocsParsing.test.d.ts +1 -0
  38. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +1 -0
  39. package/dist/__tests__/docs/extractDocsTheme.test.d.ts +1 -0
  40. package/dist/components/AppTopBar.navigation.d.ts +11 -0
  41. package/dist/components/BaseButton.vue.d.ts +1 -1
  42. package/dist/components/BaseCheckbox.vue.d.ts +1 -1
  43. package/dist/components/BaseInput.vue.d.ts +2 -2
  44. package/dist/components/BasePill.vue.d.ts +1 -1
  45. package/dist/components/BaseRadioGroup.vue.d.ts +1 -1
  46. package/dist/components/BaseSelect.vue.d.ts +1 -1
  47. package/dist/components/BaseSlider.vue.d.ts +2 -2
  48. package/dist/components/BaseTextarea.vue.d.ts +2 -2
  49. package/dist/components/BaseToggle.vue.d.ts +1 -1
  50. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  51. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
  52. package/dist/components/ColorSlider.vue.d.ts +2 -2
  53. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  54. package/dist/components/DatePicker.vue.d.ts +1 -1
  55. package/dist/components/DateTimePicker.vue.d.ts +2 -2
  56. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
  57. package/dist/components/DropdownButton.vue.d.ts +1 -1
  58. package/dist/components/FileUploader.vue.d.ts +2 -2
  59. package/dist/components/FormulaInput.vue.d.ts +2 -2
  60. package/dist/components/IconButton.vue.d.ts +1 -1
  61. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  62. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  63. package/dist/components/MultiSelect.vue.d.ts +1 -1
  64. package/dist/components/NumberInput.vue.d.ts +1 -1
  65. package/dist/components/PlateMapEditor.vue.d.ts +6 -6
  66. package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
  67. package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
  68. package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
  69. package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
  70. package/dist/components/PluginWorkspaceView.vue.d.ts +46 -195
  71. package/dist/components/ProgressBar.vue.d.ts +1 -1
  72. package/dist/components/ProtocolStep.presentation.d.ts +4 -0
  73. package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
  74. package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
  75. package/dist/components/ReagentList.presentation.d.ts +16 -0
  76. package/dist/components/ResourceCard.vue.d.ts +1 -1
  77. package/dist/components/SampleSelector.colors.d.ts +13 -0
  78. package/dist/components/SampleSelector.drag.d.ts +24 -0
  79. package/dist/components/SampleSelector.groups.d.ts +15 -0
  80. package/dist/components/SampleSelector.selection.d.ts +26 -0
  81. package/dist/components/SampleSelector.vue.d.ts +4 -1
  82. package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
  83. package/dist/components/SegmentedControl.vue.d.ts +1 -1
  84. package/dist/components/SequenceInput.vue.d.ts +2 -2
  85. package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
  86. package/dist/components/SettingsModal.schema.d.ts +9 -0
  87. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  88. package/dist/components/TagsInput.vue.d.ts +2 -2
  89. package/dist/components/TimePicker.vue.d.ts +2 -2
  90. package/dist/components/TimeRangeInput.vue.d.ts +1 -1
  91. package/dist/components/UnitInput.vue.d.ts +2 -2
  92. package/dist/components/WellPlate.colors.d.ts +9 -0
  93. package/dist/components/WellPlate.conditions.d.ts +26 -0
  94. package/dist/components/WellPlate.geometry.d.ts +23 -0
  95. package/dist/components/WellPlate.interaction.d.ts +71 -0
  96. package/dist/components/WellPlate.legend.d.ts +2 -0
  97. package/dist/components/WellPlate.rendering.d.ts +24 -0
  98. package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
  99. package/dist/components/WellPlate.vue.d.ts +1 -1
  100. package/dist/components/index.js +2 -2
  101. package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
  102. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
  103. package/dist/{components-BhK-dW99.js → components-DtHA2bgp.js} +3754 -2991
  104. package/dist/components-DtHA2bgp.js.map +1 -0
  105. package/dist/composables/autoGroup/classKey.d.ts +4 -0
  106. package/dist/composables/autoGroup/classify.d.ts +28 -0
  107. package/dist/composables/autoGroup/colors.d.ts +2 -0
  108. package/dist/composables/autoGroup/columns.d.ts +10 -0
  109. package/dist/composables/autoGroup/compose.d.ts +8 -0
  110. package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
  111. package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
  112. package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
  113. package/dist/composables/autoGroup/index.d.ts +16 -0
  114. package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
  115. package/dist/composables/autoGroup/template.d.ts +15 -0
  116. package/dist/composables/autoGroup/tokenize.d.ts +8 -0
  117. package/dist/composables/autoGroupConstants.d.ts +1 -0
  118. package/dist/composables/autoGroupGrouping.d.ts +3 -0
  119. package/dist/composables/controlComponentBindings.d.ts +7 -0
  120. package/dist/composables/controlSchemaAdapters.d.ts +20 -0
  121. package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
  122. package/dist/composables/controlSchemaFormFields.d.ts +3 -0
  123. package/dist/composables/controlSchemaLayout.d.ts +7 -0
  124. package/dist/composables/controlSchemaModel.d.ts +5 -0
  125. package/dist/composables/controlSchemaNormalize.d.ts +15 -0
  126. package/dist/composables/controlSchemaTypes.d.ts +305 -0
  127. package/dist/composables/controlSchemaUtils.d.ts +9 -0
  128. package/dist/composables/controlWorkspaceOptions.d.ts +2 -0
  129. package/dist/composables/formBuilderSchema.d.ts +18 -0
  130. package/dist/composables/index.js +3 -3
  131. package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
  132. package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
  133. package/dist/composables/useAutoGroup.d.ts +61 -74
  134. package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
  135. package/dist/composables/useBioTemplateControls.d.ts +1 -1
  136. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
  137. package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
  138. package/dist/composables/useControlSchema.d.ts +8 -346
  139. package/dist/composables/useControlWorkspace.d.ts +5 -0
  140. package/dist/composables/useForm.d.ts +2 -33
  141. package/dist/composables/useFormBuilder.d.ts +2 -9
  142. package/dist/composables/useFormValidation.d.ts +34 -0
  143. package/dist/composables/usePluginClient.d.ts +1 -4
  144. package/dist/composables/useProtocolTemplates.d.ts +2 -24
  145. package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
  146. package/dist/{composables-Bg7CFuNz.js → composables-Dlg8jenH.js} +33 -31
  147. package/dist/composables-Dlg8jenH.js.map +1 -0
  148. package/dist/index.js +4 -4
  149. package/dist/install.js +2 -2
  150. package/dist/styles.css +547 -516
  151. package/dist/templates/adapters.d.ts +14 -47
  152. package/dist/templates/assayLookups.d.ts +3 -0
  153. package/dist/templates/assayMatrixAdapters.d.ts +6 -0
  154. package/dist/templates/assayMatrixBuilder.d.ts +2 -0
  155. package/dist/templates/assayNormalizers.d.ts +4 -0
  156. package/dist/templates/builderDefaults.d.ts +1 -0
  157. package/dist/templates/builderIdUtils.d.ts +4 -0
  158. package/dist/templates/builderPresetControls.d.ts +10 -0
  159. package/dist/templates/builderReadUtils.d.ts +8 -0
  160. package/dist/templates/builders.d.ts +26 -67
  161. package/dist/templates/calibrationCurveAdapters.d.ts +4 -0
  162. package/dist/templates/calibrationCurveBuilder.d.ts +2 -0
  163. package/dist/templates/calibrationNormalizers.d.ts +5 -0
  164. package/dist/templates/componentBindingCatalog.d.ts +25 -0
  165. package/dist/templates/componentBindingHelpers.d.ts +17 -0
  166. package/dist/templates/componentDoseResponseProps.d.ts +3 -0
  167. package/dist/templates/componentGenericProps.d.ts +8 -0
  168. package/dist/templates/componentPlateHelpers.d.ts +5 -0
  169. package/dist/templates/componentPlateMapProps.d.ts +3 -0
  170. package/dist/templates/componentPropsFactory.d.ts +3 -0
  171. package/dist/templates/componentQpcrPlateProps.d.ts +3 -0
  172. package/dist/templates/componentTargetResolvers.d.ts +5 -0
  173. package/dist/templates/componentTemplateProps.d.ts +3 -0
  174. package/dist/templates/controlSchemaClone.d.ts +4 -0
  175. package/dist/templates/controlSchemaConstants.d.ts +10 -0
  176. package/dist/templates/controlSchemaMerge.d.ts +3 -0
  177. package/dist/templates/controlSchemaTargets.d.ts +17 -0
  178. package/dist/templates/controlSchemaTypes.d.ts +4 -0
  179. package/dist/templates/controlSchemas.d.ts +4 -4
  180. package/dist/templates/defaultBioTemplateBuilder.d.ts +2 -0
  181. package/dist/templates/doseResponseAdapters.d.ts +4 -0
  182. package/dist/templates/doseResponseBuilder.d.ts +2 -0
  183. package/dist/templates/elisaAssayCollectionBuilder.d.ts +2 -0
  184. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +2 -0
  185. package/dist/templates/flowCytometryPanelBuilder.d.ts +2 -0
  186. package/dist/templates/flowNormalizers.d.ts +8 -0
  187. package/dist/templates/flowPanelAdapters.d.ts +4 -0
  188. package/dist/templates/index.js +1 -1
  189. package/dist/templates/instrumentRunAdapterHelpers.d.ts +8 -0
  190. package/dist/templates/instrumentRunAdapters.d.ts +8 -0
  191. package/dist/templates/instrumentRunBuilder.d.ts +2 -0
  192. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +2 -0
  193. package/dist/templates/plateGeometry.d.ts +4 -0
  194. package/dist/templates/plateMapAdapters.d.ts +3 -0
  195. package/dist/templates/plateMapBuilder.d.ts +2 -0
  196. package/dist/templates/presetControlSchemas.d.ts +534 -0
  197. package/dist/templates/protocolAdapters.d.ts +5 -0
  198. package/dist/templates/protocolNormalizers.d.ts +6 -0
  199. package/dist/templates/protocolStepsBuilder.d.ts +2 -0
  200. package/dist/templates/qpcrAdapters.d.ts +5 -0
  201. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +2 -0
  202. package/dist/templates/qpcrPlateBuilder.d.ts +2 -0
  203. package/dist/templates/reagentAdapters.d.ts +5 -0
  204. package/dist/templates/reagentListBuilder.d.ts +2 -0
  205. package/dist/templates/runNormalizers.d.ts +10 -0
  206. package/dist/templates/sampleNormalizers.d.ts +4 -0
  207. package/dist/templates/samplePrepAdapters.d.ts +4 -0
  208. package/dist/templates/samplePrepBuilder.d.ts +2 -0
  209. package/dist/templates/sampleSheetAdapters.d.ts +5 -0
  210. package/dist/templates/sampleSheetBuilder.d.ts +2 -0
  211. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +2 -0
  212. package/dist/templates/targetedMetabolomicsHelpers.d.ts +5 -0
  213. package/dist/templates/templateAdapterTypes.d.ts +48 -0
  214. package/dist/templates/templateControlSchemas.d.ts +400 -0
  215. package/dist/templates/templateCreateOptions.d.ts +165 -0
  216. package/dist/templates/templateEnvelopes.d.ts +9 -0
  217. package/dist/templates/templatePackCollectionBuilder.d.ts +2 -0
  218. package/dist/templates/templatePresetCollectionBuilder.d.ts +18 -0
  219. package/dist/templates/templateQpcrTypes.d.ts +42 -0
  220. package/dist/templates/templateValidators.d.ts +13 -0
  221. package/dist/templates/timeCourseAdapters.d.ts +5 -0
  222. package/dist/templates/timeCourseBuilder.d.ts +2 -0
  223. package/dist/templates/types.d.ts +5 -250
  224. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +2 -0
  225. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +2 -0
  226. package/dist/{templates-BorLR_7p.js → templates-DtdUvJ4c.js} +3565 -3411
  227. package/dist/templates-DtdUvJ4c.js.map +1 -0
  228. package/dist/types/auto-group.d.ts +79 -9
  229. package/dist/types/componentLabTypes.d.ts +161 -0
  230. package/dist/types/componentWorkflowTypes.d.ts +150 -0
  231. package/dist/types/components.d.ts +2 -311
  232. package/dist/{useProtocolTemplates-n6AJqSqv.js → useProtocolTemplates-Bm5vyH4_.js} +1220 -454
  233. package/dist/useProtocolTemplates-Bm5vyH4_.js.map +1 -0
  234. package/package.json +1 -1
  235. package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
  236. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
  237. package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
  238. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
  239. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
  240. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +41 -0
  241. package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
  242. package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
  243. package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
  244. package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
  245. package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
  246. package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
  247. package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
  248. package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
  249. package/src/__tests__/components/SampleSelector.test.ts +32 -0
  250. package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
  251. package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
  252. package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
  253. package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
  254. package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
  255. package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
  256. package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
  257. package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
  258. package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
  259. package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
  260. package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
  261. package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
  262. package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
  263. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
  264. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
  265. package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
  266. package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
  267. package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
  268. package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
  269. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
  270. package/src/__tests__/composables/useControlSchema.test.ts +23 -0
  271. package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
  272. package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
  273. package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
  274. package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
  275. package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
  276. package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
  277. package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
  278. package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
  279. package/src/components/AppSidebar.vue +2 -6
  280. package/src/components/AppTopBar.navigation.ts +62 -0
  281. package/src/components/AppTopBar.vue +17 -44
  282. package/src/components/AutoGroupModal.story.vue +50 -0
  283. package/src/components/AutoGroupModal.vue +441 -158
  284. package/src/components/ControlWorkspaceView.vue +2 -6
  285. package/src/components/DoseCalculator.vue +13 -73
  286. package/src/components/DoseCalculatorVolumeField.vue +61 -0
  287. package/src/components/ExperimentTimeline.vue +6 -31
  288. package/src/components/FormBuilder.vue +2 -7
  289. package/src/components/PlateMapEditor.vue +32 -106
  290. package/src/components/PluginWorkspaceView.controls.ts +182 -0
  291. package/src/components/PluginWorkspaceView.navigation.ts +106 -0
  292. package/src/components/PluginWorkspaceView.props.ts +174 -0
  293. package/src/components/PluginWorkspaceView.shell.ts +66 -0
  294. package/src/components/PluginWorkspaceView.vue +85 -404
  295. package/src/components/ProtocolStep.presentation.ts +31 -0
  296. package/src/components/ProtocolStepEditor.state.ts +104 -0
  297. package/src/components/ProtocolStepEditor.vue +48 -179
  298. package/src/components/ProtocolStepParameterField.vue +134 -0
  299. package/src/components/ReagentList.presentation.ts +105 -0
  300. package/src/components/ReagentList.vue +16 -79
  301. package/src/components/SampleSelector.colors.ts +43 -0
  302. package/src/components/SampleSelector.drag.ts +164 -0
  303. package/src/components/SampleSelector.groups.ts +109 -0
  304. package/src/components/SampleSelector.selection.ts +103 -0
  305. package/src/components/SampleSelector.vue +82 -349
  306. package/src/components/SampleSelectorSampleRow.vue +64 -0
  307. package/src/components/ScheduleCalendar.vue +44 -199
  308. package/src/components/SettingsModal.schema.ts +71 -0
  309. package/src/components/SettingsModal.vue +16 -46
  310. package/src/components/WellPlate.colors.ts +56 -0
  311. package/src/components/WellPlate.conditions.ts +100 -0
  312. package/src/components/WellPlate.geometry.ts +91 -0
  313. package/src/components/WellPlate.interaction.ts +272 -0
  314. package/src/components/WellPlate.legend.ts +8 -0
  315. package/src/components/WellPlate.rendering.ts +105 -0
  316. package/src/components/WellPlate.sampleDrop.ts +73 -0
  317. package/src/components/WellPlate.vue +102 -550
  318. package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
  319. package/src/composables/autoGroup/classKey.ts +5 -0
  320. package/src/composables/autoGroup/classify.ts +205 -0
  321. package/src/composables/autoGroup/colors.ts +6 -0
  322. package/src/composables/autoGroup/columns.ts +226 -0
  323. package/src/composables/autoGroup/compose.ts +156 -0
  324. package/src/composables/autoGroup/cooccurrence.ts +46 -0
  325. package/src/composables/autoGroup/csv-shim.ts +44 -0
  326. package/src/composables/autoGroup/fingerprint.ts +49 -0
  327. package/src/composables/autoGroup/index.ts +20 -0
  328. package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
  329. package/src/composables/autoGroup/template.ts +126 -0
  330. package/src/composables/autoGroup/tokenize.ts +41 -0
  331. package/src/composables/autoGroup/vocab.json +67 -0
  332. package/src/composables/autoGroupConstants.ts +4 -0
  333. package/src/composables/autoGroupGrouping.ts +148 -0
  334. package/src/composables/controlComponentBindings.ts +80 -0
  335. package/src/composables/controlSchemaAdapters.ts +196 -0
  336. package/src/composables/controlSchemaDoseDesign.ts +215 -0
  337. package/src/composables/controlSchemaFormFields.ts +61 -0
  338. package/src/composables/controlSchemaLayout.ts +59 -0
  339. package/src/composables/controlSchemaModel.ts +163 -0
  340. package/src/composables/controlSchemaNormalize.ts +101 -0
  341. package/src/composables/controlSchemaTypes.ts +364 -0
  342. package/src/composables/controlSchemaUtils.ts +36 -0
  343. package/src/composables/controlWorkspaceOptions.ts +21 -0
  344. package/src/composables/formBuilderSchema.ts +153 -0
  345. package/src/composables/pluginEndpointBuilder.ts +203 -0
  346. package/src/composables/protocolTemplateCatalog.ts +325 -0
  347. package/src/composables/useAutoGroup.ts +395 -549
  348. package/src/composables/useAutoGroupInputSources.ts +147 -0
  349. package/src/composables/useBioTemplateControls.ts +1 -1
  350. package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
  351. package/src/composables/useBioTemplateWorkspace.ts +1 -1
  352. package/src/composables/useControlSchema.ts +64 -1312
  353. package/src/composables/useControlWorkspace.ts +201 -0
  354. package/src/composables/useForm.ts +5 -187
  355. package/src/composables/useFormBuilder.ts +11 -153
  356. package/src/composables/useFormValidation.ts +154 -0
  357. package/src/composables/usePluginClient.ts +10 -193
  358. package/src/composables/useProtocolTemplates.ts +10 -328
  359. package/src/composables/useScheduleCalendarLayout.ts +287 -0
  360. package/src/styles/components/auto-group-modal.css +248 -310
  361. package/src/templates/adapters.ts +89 -930
  362. package/src/templates/assayLookups.ts +33 -0
  363. package/src/templates/assayMatrixAdapters.ts +78 -0
  364. package/src/templates/assayMatrixBuilder.ts +59 -0
  365. package/src/templates/assayNormalizers.ts +34 -0
  366. package/src/templates/builderDefaults.ts +11 -0
  367. package/src/templates/builderIdUtils.ts +20 -0
  368. package/src/templates/builderPresetControls.ts +165 -0
  369. package/src/templates/builderReadUtils.ts +57 -0
  370. package/src/templates/builders.ts +122 -2350
  371. package/src/templates/calibrationCurveAdapters.ts +59 -0
  372. package/src/templates/calibrationCurveBuilder.ts +99 -0
  373. package/src/templates/calibrationNormalizers.ts +60 -0
  374. package/src/templates/componentBindingCatalog.ts +90 -0
  375. package/src/templates/componentBindingHelpers.ts +93 -0
  376. package/src/templates/componentBindings.ts +12 -461
  377. package/src/templates/componentDoseResponseProps.ts +42 -0
  378. package/src/templates/componentGenericProps.ts +77 -0
  379. package/src/templates/componentPlateHelpers.ts +29 -0
  380. package/src/templates/componentPlateMapProps.ts +32 -0
  381. package/src/templates/componentPropsFactory.ts +21 -0
  382. package/src/templates/componentQpcrPlateProps.ts +28 -0
  383. package/src/templates/componentTargetResolvers.ts +69 -0
  384. package/src/templates/componentTemplateProps.ts +78 -0
  385. package/src/templates/controlSchemaClone.ts +32 -0
  386. package/src/templates/controlSchemaConstants.ts +11 -0
  387. package/src/templates/controlSchemaMerge.ts +40 -0
  388. package/src/templates/controlSchemaTargets.ts +87 -0
  389. package/src/templates/controlSchemaTypes.ts +20 -0
  390. package/src/templates/controlSchemas.ts +22 -704
  391. package/src/templates/defaultBioTemplateBuilder.ts +124 -0
  392. package/src/templates/doseResponseAdapters.ts +45 -0
  393. package/src/templates/doseResponseBuilder.ts +44 -0
  394. package/src/templates/elisaAssayCollectionBuilder.ts +62 -0
  395. package/src/templates/flowCytometryAssayCollectionBuilder.ts +41 -0
  396. package/src/templates/flowCytometryPanelBuilder.ts +53 -0
  397. package/src/templates/flowNormalizers.ts +58 -0
  398. package/src/templates/flowPanelAdapters.ts +58 -0
  399. package/src/templates/instrumentRunAdapterHelpers.ts +94 -0
  400. package/src/templates/instrumentRunAdapters.ts +163 -0
  401. package/src/templates/instrumentRunBuilder.ts +97 -0
  402. package/src/templates/lcmsBatchCollectionBuilder.ts +38 -0
  403. package/src/templates/plateGeometry.ts +62 -0
  404. package/src/templates/plateMapAdapters.ts +36 -0
  405. package/src/templates/plateMapBuilder.ts +43 -0
  406. package/src/templates/presetControlSchemas.ts +258 -0
  407. package/src/templates/protocolAdapters.ts +69 -0
  408. package/src/templates/protocolNormalizers.ts +37 -0
  409. package/src/templates/protocolStepsBuilder.ts +36 -0
  410. package/src/templates/qpcrAdapters.ts +104 -0
  411. package/src/templates/qpcrExpressionCollectionBuilder.ts +33 -0
  412. package/src/templates/qpcrPlateBuilder.ts +96 -0
  413. package/src/templates/reagentAdapters.ts +77 -0
  414. package/src/templates/reagentListBuilder.ts +30 -0
  415. package/src/templates/runNormalizers.ts +63 -0
  416. package/src/templates/sampleNormalizers.ts +58 -0
  417. package/src/templates/samplePrepAdapters.ts +63 -0
  418. package/src/templates/samplePrepBuilder.ts +51 -0
  419. package/src/templates/sampleSheetAdapters.ts +75 -0
  420. package/src/templates/sampleSheetBuilder.ts +23 -0
  421. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +79 -0
  422. package/src/templates/targetedMetabolomicsHelpers.ts +102 -0
  423. package/src/templates/templateAdapterTypes.ts +58 -0
  424. package/src/templates/templateControlSchemas.ts +320 -0
  425. package/src/templates/templateCreateOptions.ts +208 -0
  426. package/src/templates/templateEnvelopes.ts +137 -0
  427. package/src/templates/templatePackCollectionBuilder.ts +23 -0
  428. package/src/templates/templatePresetCollectionBuilder.ts +139 -0
  429. package/src/templates/templateQpcrTypes.ts +48 -0
  430. package/src/templates/templateValidators.ts +414 -0
  431. package/src/templates/timeCourseAdapters.ts +73 -0
  432. package/src/templates/timeCourseBuilder.ts +64 -0
  433. package/src/templates/types.ts +79 -275
  434. package/src/templates/wellPlateScreenCollectionBuilder.ts +36 -0
  435. package/src/templates/westernBlotAssayCollectionBuilder.ts +68 -0
  436. package/src/types/auto-group.ts +107 -9
  437. package/src/types/componentLabTypes.ts +235 -0
  438. package/src/types/componentWorkflowTypes.ts +190 -0
  439. package/src/types/components.ts +74 -424
  440. package/dist/components-BhK-dW99.js.map +0 -1
  441. package/dist/composables-Bg7CFuNz.js.map +0 -1
  442. package/dist/templates-BorLR_7p.js.map +0 -1
  443. package/dist/useProtocolTemplates-n6AJqSqv.js.map +0 -1
@@ -0,0 +1,139 @@
1
+ import { bioTemplatePresetControlValuesToOptions } from './builderPresetControls'
2
+ import type { BioTemplateControlValues } from './builderPresetControls'
3
+ import { createElisaAssayCollection } from './elisaAssayCollectionBuilder'
4
+ import { createFlowCytometryAssayCollection } from './flowCytometryAssayCollectionBuilder'
5
+ import { createLcmsBatchCollection } from './lcmsBatchCollectionBuilder'
6
+ import { getBioTemplatePresetInfo } from './presets'
7
+ import { createQpcrExpressionCollection } from './qpcrExpressionCollectionBuilder'
8
+ import { createTargetedMetabolomicsCollection } from './targetedMetabolomicsCollectionBuilder'
9
+ import { createWellPlateScreenCollection } from './wellPlateScreenCollectionBuilder'
10
+ import { createWesternBlotAssayCollection } from './westernBlotAssayCollectionBuilder'
11
+ import type {
12
+ CreateElisaAssayCollectionOptions,
13
+ CreateFlowCytometryAssayCollectionOptions,
14
+ CreateLcmsBatchCollectionOptions,
15
+ CreateQpcrExpressionCollectionOptions,
16
+ CreateTargetedMetabolomicsCollectionOptions,
17
+ CreateWellPlateScreenCollectionOptions,
18
+ CreateWesternBlotAssayCollectionOptions,
19
+ TemplateCollectionEnvelope,
20
+ TemplatePresetId,
21
+ } from './types'
22
+
23
+ export function createBioTemplatePresetCollection(
24
+ name: 'wellplate-screen',
25
+ options?: CreateWellPlateScreenCollectionOptions
26
+ ): TemplateCollectionEnvelope
27
+ export function createBioTemplatePresetCollection(
28
+ name: 'qpcr-expression',
29
+ options?: CreateQpcrExpressionCollectionOptions
30
+ ): TemplateCollectionEnvelope
31
+ export function createBioTemplatePresetCollection(
32
+ name: 'lcms-batch',
33
+ options?: CreateLcmsBatchCollectionOptions
34
+ ): TemplateCollectionEnvelope
35
+ export function createBioTemplatePresetCollection(
36
+ name: 'targeted-metabolomics',
37
+ options?: CreateTargetedMetabolomicsCollectionOptions
38
+ ): TemplateCollectionEnvelope
39
+ export function createBioTemplatePresetCollection(
40
+ name: 'elisa-assay',
41
+ options?: CreateElisaAssayCollectionOptions
42
+ ): TemplateCollectionEnvelope
43
+ export function createBioTemplatePresetCollection(
44
+ name: 'flow-cytometry-assay',
45
+ options?: CreateFlowCytometryAssayCollectionOptions
46
+ ): TemplateCollectionEnvelope
47
+ export function createBioTemplatePresetCollection(
48
+ name: 'western-blot-assay',
49
+ options?: CreateWesternBlotAssayCollectionOptions
50
+ ): TemplateCollectionEnvelope
51
+ export function createBioTemplatePresetCollection(
52
+ name: string,
53
+ options?:
54
+ | CreateWellPlateScreenCollectionOptions
55
+ | CreateQpcrExpressionCollectionOptions
56
+ | CreateLcmsBatchCollectionOptions
57
+ | CreateTargetedMetabolomicsCollectionOptions
58
+ | CreateElisaAssayCollectionOptions
59
+ | CreateFlowCytometryAssayCollectionOptions
60
+ | CreateWesternBlotAssayCollectionOptions
61
+ ): TemplateCollectionEnvelope
62
+ export function createBioTemplatePresetCollection(
63
+ name: TemplatePresetId | string,
64
+ options:
65
+ | CreateWellPlateScreenCollectionOptions
66
+ | CreateQpcrExpressionCollectionOptions
67
+ | CreateLcmsBatchCollectionOptions
68
+ | CreateTargetedMetabolomicsCollectionOptions
69
+ | CreateElisaAssayCollectionOptions
70
+ | CreateFlowCytometryAssayCollectionOptions
71
+ | CreateWesternBlotAssayCollectionOptions = {}
72
+ ): TemplateCollectionEnvelope {
73
+ const preset = getBioTemplatePresetInfo(name)
74
+ if (!preset) {
75
+ throw new Error(`Unknown template preset '${name}'.`)
76
+ }
77
+ if (preset.name === 'wellplate-screen') {
78
+ return createWellPlateScreenCollection(options as CreateWellPlateScreenCollectionOptions)
79
+ }
80
+ if (preset.name === 'qpcr-expression') {
81
+ return createQpcrExpressionCollection(options as CreateQpcrExpressionCollectionOptions)
82
+ }
83
+ if (preset.name === 'lcms-batch') {
84
+ return createLcmsBatchCollection(options as CreateLcmsBatchCollectionOptions)
85
+ }
86
+ if (preset.name === 'targeted-metabolomics') {
87
+ return createTargetedMetabolomicsCollection(options as CreateTargetedMetabolomicsCollectionOptions)
88
+ }
89
+ if (preset.name === 'elisa-assay') {
90
+ return createElisaAssayCollection(options as CreateElisaAssayCollectionOptions)
91
+ }
92
+ if (preset.name === 'flow-cytometry-assay') {
93
+ return createFlowCytometryAssayCollection(options as CreateFlowCytometryAssayCollectionOptions)
94
+ }
95
+ if (preset.name === 'western-blot-assay') {
96
+ return createWesternBlotAssayCollection(options as CreateWesternBlotAssayCollectionOptions)
97
+ }
98
+ throw new Error(`Unknown template preset '${name}'.`)
99
+ }
100
+
101
+ export function createBioTemplatePresetCollectionFromControls(
102
+ name: 'wellplate-screen',
103
+ values: BioTemplateControlValues
104
+ ): TemplateCollectionEnvelope
105
+ export function createBioTemplatePresetCollectionFromControls(
106
+ name: 'qpcr-expression',
107
+ values: BioTemplateControlValues
108
+ ): TemplateCollectionEnvelope
109
+ export function createBioTemplatePresetCollectionFromControls(
110
+ name: 'lcms-batch',
111
+ values: BioTemplateControlValues
112
+ ): TemplateCollectionEnvelope
113
+ export function createBioTemplatePresetCollectionFromControls(
114
+ name: 'targeted-metabolomics',
115
+ values: BioTemplateControlValues
116
+ ): TemplateCollectionEnvelope
117
+ export function createBioTemplatePresetCollectionFromControls(
118
+ name: 'elisa-assay',
119
+ values: BioTemplateControlValues
120
+ ): TemplateCollectionEnvelope
121
+ export function createBioTemplatePresetCollectionFromControls(
122
+ name: 'flow-cytometry-assay',
123
+ values: BioTemplateControlValues
124
+ ): TemplateCollectionEnvelope
125
+ export function createBioTemplatePresetCollectionFromControls(
126
+ name: 'western-blot-assay',
127
+ values: BioTemplateControlValues
128
+ ): TemplateCollectionEnvelope
129
+ export function createBioTemplatePresetCollectionFromControls(
130
+ name: TemplatePresetId | string,
131
+ values: BioTemplateControlValues
132
+ ): TemplateCollectionEnvelope
133
+ export function createBioTemplatePresetCollectionFromControls(
134
+ name: TemplatePresetId | string,
135
+ values: BioTemplateControlValues
136
+ ): TemplateCollectionEnvelope {
137
+ const options = bioTemplatePresetControlValuesToOptions(name, values)
138
+ return createBioTemplatePresetCollection(name, options)
139
+ }
@@ -0,0 +1,48 @@
1
+ import type { WellPlateFormat } from '../types'
2
+ import type { BioTemplateEnvelope } from './types'
3
+
4
+ export type QpcrChemistry = 'sybr' | 'taqman' | 'probe' | 'evagreen' | 'other'
5
+ export type QpcrControlKind = 'sample' | 'no-template' | 'no-rt' | 'positive' | 'standard' | 'calibrator'
6
+
7
+ export interface QpcrSample {
8
+ sampleId: string
9
+ name?: string
10
+ group?: string
11
+ metadata?: Record<string, unknown>
12
+ }
13
+
14
+ export interface QpcrTarget {
15
+ id: string
16
+ name: string
17
+ assayId?: string
18
+ reporter?: string
19
+ quencher?: string
20
+ ampliconBp?: number
21
+ metadata?: Record<string, unknown>
22
+ }
23
+
24
+ export interface QpcrReaction {
25
+ id: string
26
+ wellId: string
27
+ sampleId?: string
28
+ targetId: string
29
+ replicate: number
30
+ controlKind: QpcrControlKind
31
+ cq?: number | null
32
+ quantity?: number | null
33
+ flags: string[]
34
+ metadata?: Record<string, unknown>
35
+ }
36
+
37
+ export interface QpcrPlateTemplateData {
38
+ plateId: string
39
+ format: WellPlateFormat
40
+ samples: QpcrSample[]
41
+ targets: QpcrTarget[]
42
+ reactions: QpcrReaction[]
43
+ instrument?: string
44
+ chemistry: QpcrChemistry
45
+ metadata: Record<string, unknown>
46
+ }
47
+
48
+ export type QpcrPlateTemplate = BioTemplateEnvelope<QpcrPlateTemplateData>
@@ -0,0 +1,414 @@
1
+ import type {
2
+ AssayMatrixTemplateData,
3
+ CalibrationCurveTemplateData,
4
+ DoseResponseTemplateData,
5
+ FlowCytometryPanelTemplateData,
6
+ InstrumentRunTemplateData,
7
+ PlateMapTemplateData,
8
+ ProtocolStepsTemplateData,
9
+ QpcrPlateTemplateData,
10
+ ReagentListTemplateData,
11
+ SamplePrepTemplateData,
12
+ SampleSheetTemplateData,
13
+ TimeCourseTemplateData,
14
+ } from './types'
15
+ import { assertWellInFormat } from './plateGeometry'
16
+
17
+ export function validatePlateMapData(data: PlateMapTemplateData): void {
18
+ if (!Array.isArray(data.plates) || data.plates.length === 0) {
19
+ throw new Error('Plate-map template requires at least one plate.')
20
+ }
21
+ const sampleIds = new Set(data.samples.map(sample => sample.id))
22
+ if (sampleIds.size !== data.samples.length) {
23
+ throw new Error('Plate-map sample ids must be unique.')
24
+ }
25
+ for (const plate of data.plates) {
26
+ for (const [wellId, well] of Object.entries(plate.wells)) {
27
+ if (well.id !== wellId) {
28
+ throw new Error(`Well key '${wellId}' does not match well id '${well.id}'.`)
29
+ }
30
+ if (well.sampleType && !sampleIds.has(well.sampleType)) {
31
+ throw new Error(`Well '${well.id}' references unknown sample '${well.sampleType}'.`)
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ export function validateSampleSheetData(data: SampleSheetTemplateData): void {
38
+ if (!Array.isArray(data.samples) || data.samples.length === 0) {
39
+ throw new Error('Sample-sheet template requires at least one sample.')
40
+ }
41
+ const sampleIds = new Set(data.samples.map(sample => sample.sampleId))
42
+ if (sampleIds.size !== data.samples.length) {
43
+ throw new Error('Sample-sheet sample ids must be unique.')
44
+ }
45
+ for (const group of data.groups) {
46
+ for (const sampleId of group.samples) {
47
+ if (!sampleIds.has(sampleId)) {
48
+ throw new Error(`Group '${group.name}' references unknown sample '${sampleId}'.`)
49
+ }
50
+ }
51
+ }
52
+ }
53
+
54
+ export function validateSamplePrepData(data: SamplePrepTemplateData): void {
55
+ if (!data.protocolName) {
56
+ throw new Error('Sample-prep template requires protocolName.')
57
+ }
58
+ if (!Array.isArray(data.steps) || data.steps.length === 0) {
59
+ throw new Error('Sample-prep template requires at least one step.')
60
+ }
61
+ const stepIds = new Set(data.steps.map(step => step.id))
62
+ if (stepIds.size !== data.steps.length) {
63
+ throw new Error('Sample-prep step ids must be unique.')
64
+ }
65
+ const orders = new Set(data.steps.map(step => step.order))
66
+ if (orders.size !== data.steps.length) {
67
+ throw new Error('Sample-prep step orders must be unique.')
68
+ }
69
+ for (const step of data.steps) {
70
+ if (!step.id || !step.name) {
71
+ throw new Error('Sample-prep steps require id and name.')
72
+ }
73
+ if (step.order < 0) {
74
+ throw new Error(`Sample-prep step '${step.id}' has a negative order.`)
75
+ }
76
+ if (!step.volumeUnit) {
77
+ throw new Error(`Sample-prep step '${step.id}' requires volumeUnit.`)
78
+ }
79
+ if (step.inputVolume !== undefined && step.inputVolume < 0) {
80
+ throw new Error(`Sample-prep step '${step.id}' has a negative input volume.`)
81
+ }
82
+ if (step.outputVolume !== undefined && step.outputVolume < 0) {
83
+ throw new Error(`Sample-prep step '${step.id}' has a negative output volume.`)
84
+ }
85
+ if (step.durationMin !== undefined && step.durationMin < 0) {
86
+ throw new Error(`Sample-prep step '${step.id}' has a negative duration.`)
87
+ }
88
+ if (!step.sourceSampleId && !step.destinationSampleId && !step.reagentId) {
89
+ throw new Error(`Sample-prep step '${step.id}' requires a source, destination, or reagent.`)
90
+ }
91
+ }
92
+ }
93
+
94
+ export function validateDoseResponseData(data: DoseResponseTemplateData): void {
95
+ if (!Array.isArray(data.compounds) || data.compounds.length === 0) {
96
+ throw new Error('Dose-response template requires at least one compound.')
97
+ }
98
+ if (!data.unit) {
99
+ throw new Error('Dose-response template requires a unit.')
100
+ }
101
+ if (data.replicates < 1) {
102
+ throw new Error('Dose-response replicates must be at least 1.')
103
+ }
104
+ for (const compound of data.compounds) {
105
+ if (compound.concentrations.length === 0) {
106
+ throw new Error(`Compound '${compound.name}' requires at least one concentration.`)
107
+ }
108
+ if (compound.concentrations.some(value => value < 0)) {
109
+ throw new Error(`Compound '${compound.name}' has a negative concentration.`)
110
+ }
111
+ }
112
+ }
113
+
114
+ export function validateCalibrationCurveData(data: CalibrationCurveTemplateData): void {
115
+ if (!data.analyte) {
116
+ throw new Error('Calibration-curve template requires an analyte.')
117
+ }
118
+ if (!data.xUnit) {
119
+ throw new Error('Calibration-curve template requires xUnit.')
120
+ }
121
+ if (!data.responseUnit) {
122
+ throw new Error('Calibration-curve template requires responseUnit.')
123
+ }
124
+ if (!Array.isArray(data.points) || data.points.length === 0) {
125
+ throw new Error('Calibration-curve template requires at least one point.')
126
+ }
127
+ if (data.acceptance.minRSquared < 0 || data.acceptance.minRSquared > 1) {
128
+ throw new Error('Calibration-curve minRSquared must be between 0 and 1.')
129
+ }
130
+ if (data.acceptance.standardTolerancePercent < 0 || data.acceptance.qcTolerancePercent < 0) {
131
+ throw new Error('Calibration-curve tolerances cannot be negative.')
132
+ }
133
+
134
+ const pointIds = new Set(data.points.map(point => point.id))
135
+ if (pointIds.size !== data.points.length) {
136
+ throw new Error('Calibration-curve point ids must be unique.')
137
+ }
138
+ const orders = new Set(data.points.map(point => point.order))
139
+ if (orders.size !== data.points.length) {
140
+ throw new Error('Calibration-curve point orders must be unique.')
141
+ }
142
+
143
+ let standards = 0
144
+ for (const point of data.points) {
145
+ if (!point.id || !point.level) {
146
+ throw new Error('Calibration-curve points require id and level.')
147
+ }
148
+ if (!point.unit) {
149
+ throw new Error(`Calibration-curve point '${point.id}' requires unit.`)
150
+ }
151
+ if (point.order < 0) {
152
+ throw new Error(`Calibration-curve point '${point.id}' has a negative order.`)
153
+ }
154
+ if (point.concentration < 0) {
155
+ throw new Error(`Calibration-curve point '${point.id}' has a negative concentration.`)
156
+ }
157
+ if ((point.role === 'standard' || point.role === 'qc') && point.concentration <= 0) {
158
+ throw new Error(`Calibration-curve point '${point.id}' requires positive concentration.`)
159
+ }
160
+ if (point.replicate < 1) {
161
+ throw new Error(`Calibration-curve point '${point.id}' replicate must be at least 1.`)
162
+ }
163
+ if (point.role === 'standard' && point.include) {
164
+ standards += 1
165
+ }
166
+ }
167
+
168
+ if (standards < 2) {
169
+ throw new Error('Calibration-curve template requires at least two included standards.')
170
+ }
171
+ if (data.acceptance.requireBlank && !data.points.some(point => point.role === 'blank')) {
172
+ throw new Error('Calibration-curve template requires a blank point when requireBlank is true.')
173
+ }
174
+ }
175
+
176
+ export function validateTimeCourseData(data: TimeCourseTemplateData): void {
177
+ if (!Array.isArray(data.timepoints) || data.timepoints.length === 0) {
178
+ throw new Error('Time-course template requires at least one time point.')
179
+ }
180
+ if (!Array.isArray(data.conditions) || data.conditions.length === 0) {
181
+ throw new Error('Time-course template requires at least one condition.')
182
+ }
183
+ const timepointIds = new Set(data.timepoints.map(timepoint => timepoint.id))
184
+ if (timepointIds.size !== data.timepoints.length) {
185
+ throw new Error('Time-course time point ids must be unique.')
186
+ }
187
+ const conditionIds = new Set(data.conditions.map(condition => condition.id))
188
+ if (conditionIds.size !== data.conditions.length) {
189
+ throw new Error('Time-course condition ids must be unique.')
190
+ }
191
+ const sampleIds = new Set(data.samples.map(sample => sample.sampleId))
192
+ if (sampleIds.size !== data.samples.length) {
193
+ throw new Error('Time-course sample ids must be unique.')
194
+ }
195
+ for (const sample of data.samples) {
196
+ if (!timepointIds.has(sample.timepointId)) {
197
+ throw new Error(`Sample '${sample.sampleId}' references unknown time point.`)
198
+ }
199
+ if (!conditionIds.has(sample.conditionId)) {
200
+ throw new Error(`Sample '${sample.sampleId}' references unknown condition.`)
201
+ }
202
+ }
203
+ }
204
+
205
+ export function validateProtocolStepsData(data: ProtocolStepsTemplateData): void {
206
+ if (!Array.isArray(data.steps) || data.steps.length === 0) {
207
+ throw new Error('Protocol-steps template requires at least one step.')
208
+ }
209
+ const stepIds = new Set(data.steps.map(step => step.id))
210
+ if (stepIds.size !== data.steps.length) {
211
+ throw new Error('Protocol-steps ids must be unique.')
212
+ }
213
+ const orders = new Set(data.steps.map(step => step.order))
214
+ if (orders.size !== data.steps.length) {
215
+ throw new Error('Protocol-steps orders must be unique.')
216
+ }
217
+ for (const step of data.steps) {
218
+ if (!step.id) {
219
+ throw new Error('Protocol step id is required.')
220
+ }
221
+ if (!step.name) {
222
+ throw new Error(`Protocol step '${step.id}' requires a name.`)
223
+ }
224
+ if (step.duration !== undefined && step.duration < 0) {
225
+ throw new Error(`Protocol step '${step.id}' has a negative duration.`)
226
+ }
227
+ if (step.order < 0) {
228
+ throw new Error(`Protocol step '${step.id}' has a negative order.`)
229
+ }
230
+ }
231
+ }
232
+
233
+ export function validateAssayMatrixData(data: AssayMatrixTemplateData): void {
234
+ if (!Array.isArray(data.samples) || data.samples.length === 0) {
235
+ throw new Error('Assay-matrix template requires at least one sample.')
236
+ }
237
+ if (!Array.isArray(data.features) || data.features.length === 0) {
238
+ throw new Error('Assay-matrix template requires at least one feature.')
239
+ }
240
+ const sampleIds = new Set(data.samples.map(sample => sample.sampleId))
241
+ if (sampleIds.size !== data.samples.length) {
242
+ throw new Error('Assay-matrix sample ids must be unique.')
243
+ }
244
+ const featureIds = new Set(data.features.map(feature => feature.id))
245
+ if (featureIds.size !== data.features.length) {
246
+ throw new Error('Assay-matrix feature ids must be unique.')
247
+ }
248
+ const measurementIds = new Set<string>()
249
+ for (const measurement of data.measurements) {
250
+ const key = `${measurement.sampleId}:${measurement.featureId}`
251
+ if (measurementIds.has(key)) {
252
+ throw new Error(`Duplicate assay measurement for '${key}'.`)
253
+ }
254
+ measurementIds.add(key)
255
+ if (!sampleIds.has(measurement.sampleId)) {
256
+ throw new Error(`Measurement references unknown sample '${measurement.sampleId}'.`)
257
+ }
258
+ if (!featureIds.has(measurement.featureId)) {
259
+ throw new Error(`Measurement references unknown feature '${measurement.featureId}'.`)
260
+ }
261
+ }
262
+ }
263
+
264
+ export function validateReagentListData(data: ReagentListTemplateData): void {
265
+ if (!Array.isArray(data.reagents) || data.reagents.length === 0) {
266
+ throw new Error('Reagent-list template requires at least one reagent.')
267
+ }
268
+ const reagentIds = new Set(data.reagents.map(reagent => reagent.id))
269
+ if (reagentIds.size !== data.reagents.length) {
270
+ throw new Error('Reagent-list reagent ids must be unique.')
271
+ }
272
+ for (const reagent of data.reagents) {
273
+ if (!reagent.id) {
274
+ throw new Error('Reagent-list reagent id is required.')
275
+ }
276
+ if (!reagent.name) {
277
+ throw new Error(`Reagent '${reagent.id}' requires a name.`)
278
+ }
279
+ if (reagent.stockLevel !== undefined && reagent.stockLevel < 0) {
280
+ throw new Error(`Reagent '${reagent.id}' has a negative stock level.`)
281
+ }
282
+ }
283
+ }
284
+
285
+ export function validateFlowCytometryPanelData(data: FlowCytometryPanelTemplateData): void {
286
+ if (!Array.isArray(data.markers) || data.markers.length === 0) {
287
+ throw new Error('Flow-cytometry panel template requires at least one marker.')
288
+ }
289
+ const markerIds = new Set(data.markers.map(marker => marker.id))
290
+ if (markerIds.size !== data.markers.length) {
291
+ throw new Error('Flow-cytometry panel marker ids must be unique.')
292
+ }
293
+ const controlIds = new Set(data.controls.map(control => control.id))
294
+ if (controlIds.size !== data.controls.length) {
295
+ throw new Error('Flow-cytometry panel control ids must be unique.')
296
+ }
297
+ for (const marker of data.markers) {
298
+ if (!marker.id) {
299
+ throw new Error('Flow-cytometry panel marker id is required.')
300
+ }
301
+ if (!marker.marker) {
302
+ throw new Error(`Flow-cytometry panel marker '${marker.id}' requires a marker name.`)
303
+ }
304
+ }
305
+ for (const control of data.controls) {
306
+ if (!control.id) {
307
+ throw new Error('Flow-cytometry panel control id is required.')
308
+ }
309
+ if (!control.name) {
310
+ throw new Error(`Flow-cytometry panel control '${control.id}' requires a name.`)
311
+ }
312
+ if (control.markerId && !markerIds.has(control.markerId)) {
313
+ throw new Error(`Flow-cytometry panel control '${control.id}' references unknown marker '${control.markerId}'.`)
314
+ }
315
+ }
316
+ }
317
+
318
+ export function validateInstrumentRunData(data: InstrumentRunTemplateData): void {
319
+ if (!Array.isArray(data.methods) || data.methods.length === 0) {
320
+ throw new Error('Instrument-run template requires at least one method.')
321
+ }
322
+ if (!Array.isArray(data.items) || data.items.length === 0) {
323
+ throw new Error('Instrument-run template requires at least one run item.')
324
+ }
325
+ const methodIds = new Set(data.methods.map(method => method.id))
326
+ if (methodIds.size !== data.methods.length) {
327
+ throw new Error('Instrument-run method ids must be unique.')
328
+ }
329
+ for (const method of data.methods) {
330
+ if (!method.id || !method.name) {
331
+ throw new Error('Instrument-run methods require id and name.')
332
+ }
333
+ }
334
+ const itemIds = new Set(data.items.map(item => item.id))
335
+ if (itemIds.size !== data.items.length) {
336
+ throw new Error('Instrument-run item ids must be unique.')
337
+ }
338
+ const orders = new Set(data.items.map(item => item.order))
339
+ if (orders.size !== data.items.length) {
340
+ throw new Error('Instrument-run item orders must be unique.')
341
+ }
342
+ for (const item of data.items) {
343
+ if (!item.id) {
344
+ throw new Error('Instrument-run items require id.')
345
+ }
346
+ if (!methodIds.has(item.methodId)) {
347
+ throw new Error(`Instrument-run item '${item.id}' references unknown method '${item.methodId}'.`)
348
+ }
349
+ if (item.kind === 'sample' && !item.sampleId) {
350
+ throw new Error(`Instrument-run sample item '${item.id}' requires sampleId.`)
351
+ }
352
+ if (item.order < 0) {
353
+ throw new Error(`Instrument-run item '${item.id}' has a negative order.`)
354
+ }
355
+ if (item.injectionVolume !== undefined && item.injectionVolume < 0) {
356
+ throw new Error(`Instrument-run item '${item.id}' has a negative injection volume.`)
357
+ }
358
+ if (item.expectedDurationMin !== undefined && item.expectedDurationMin < 0) {
359
+ throw new Error(`Instrument-run item '${item.id}' has a negative expected duration.`)
360
+ }
361
+ }
362
+ }
363
+
364
+ export function validateQpcrPlateData(data: QpcrPlateTemplateData): void {
365
+ if (!Array.isArray(data.samples) || data.samples.length === 0) {
366
+ throw new Error('qPCR plate template requires at least one sample.')
367
+ }
368
+ if (!Array.isArray(data.targets) || data.targets.length === 0) {
369
+ throw new Error('qPCR plate template requires at least one target.')
370
+ }
371
+ if (!Array.isArray(data.reactions) || data.reactions.length === 0) {
372
+ throw new Error('qPCR plate template requires at least one reaction.')
373
+ }
374
+ const sampleIds = new Set(data.samples.map(sample => sample.sampleId))
375
+ if (sampleIds.size !== data.samples.length) {
376
+ throw new Error('qPCR plate sample ids must be unique.')
377
+ }
378
+ const targetIds = new Set(data.targets.map(target => target.id))
379
+ if (targetIds.size !== data.targets.length) {
380
+ throw new Error('qPCR plate target ids must be unique.')
381
+ }
382
+ const reactionIds = new Set(data.reactions.map(reaction => reaction.id))
383
+ if (reactionIds.size !== data.reactions.length) {
384
+ throw new Error('qPCR plate reaction ids must be unique.')
385
+ }
386
+ const wellIds = new Set(data.reactions.map(reaction => reaction.wellId))
387
+ if (wellIds.size !== data.reactions.length) {
388
+ throw new Error('qPCR plate reaction wells must be unique.')
389
+ }
390
+ for (const reaction of data.reactions) {
391
+ assertWellInFormat(reaction.wellId, data.format)
392
+ if (!reaction.id) {
393
+ throw new Error('qPCR reaction id is required.')
394
+ }
395
+ if (!reaction.targetId || !targetIds.has(reaction.targetId)) {
396
+ throw new Error(`qPCR reaction '${reaction.id}' references unknown target '${reaction.targetId}'.`)
397
+ }
398
+ if (reaction.sampleId && !sampleIds.has(reaction.sampleId)) {
399
+ throw new Error(`qPCR reaction '${reaction.id}' references unknown sample '${reaction.sampleId}'.`)
400
+ }
401
+ if (reaction.controlKind === 'sample' && !reaction.sampleId) {
402
+ throw new Error(`qPCR sample reaction '${reaction.id}' requires sampleId.`)
403
+ }
404
+ if (reaction.replicate < 1) {
405
+ throw new Error(`qPCR reaction '${reaction.id}' replicate must be at least 1.`)
406
+ }
407
+ if (reaction.cq !== undefined && reaction.cq !== null && reaction.cq < 0) {
408
+ throw new Error(`qPCR reaction '${reaction.id}' has a negative Cq.`)
409
+ }
410
+ if (reaction.quantity !== undefined && reaction.quantity !== null && reaction.quantity < 0) {
411
+ throw new Error(`qPCR reaction '${reaction.id}' has a negative quantity.`)
412
+ }
413
+ }
414
+ }
@@ -0,0 +1,73 @@
1
+ import { getTemplateData } from './templateEnvelopes'
2
+ import { validateTimeCourseData } from './templateValidators'
3
+ import type {
4
+ TimeCourseColumnsAdapterResult,
5
+ TimeCourseDataFrameAdapterResult,
6
+ TimeCourseRowsAdapterResult,
7
+ TimeCourseStepsAdapterResult,
8
+ TimeCourseTemplate,
9
+ TimeCourseTemplateData,
10
+ } from './types'
11
+
12
+ export function toTimeCourseRows(
13
+ template: TimeCourseTemplate | TimeCourseTemplateData
14
+ ): TimeCourseRowsAdapterResult {
15
+ const data = getTemplateData(template, 'time-course')
16
+ validateTimeCourseData(data)
17
+ const timepoints = new Map(data.timepoints.map(timepoint => [timepoint.id, timepoint]))
18
+ const conditions = new Map(data.conditions.map(condition => [condition.id, condition]))
19
+
20
+ return data.samples.map(sample => {
21
+ const timepoint = timepoints.get(sample.timepointId)
22
+ const condition = conditions.get(sample.conditionId)
23
+ return {
24
+ sampleId: sample.sampleId,
25
+ condition: condition?.name ?? sample.conditionId,
26
+ timepoint: timepoint?.label ?? sample.timepointId,
27
+ value: timepoint?.value,
28
+ unit: timepoint?.unit,
29
+ replicate: sample.replicate,
30
+ ...(sample.metadata ?? {}),
31
+ }
32
+ })
33
+ }
34
+
35
+ export function toTimeCourseColumns(): TimeCourseColumnsAdapterResult {
36
+ return [
37
+ { key: 'sampleId', label: 'Sample ID', sortable: true },
38
+ { key: 'condition', label: 'Condition', sortable: true },
39
+ { key: 'timepoint', label: 'Time Point', sortable: true },
40
+ { key: 'value', label: 'Value', sortable: true, align: 'right' },
41
+ { key: 'unit', label: 'Unit', sortable: true },
42
+ { key: 'replicate', label: 'Replicate', sortable: true, align: 'right' },
43
+ ]
44
+ }
45
+
46
+ export function toTimeCourseDataFrame(
47
+ template: TimeCourseTemplate | TimeCourseTemplateData
48
+ ): TimeCourseDataFrameAdapterResult {
49
+ return {
50
+ data: toTimeCourseRows(template),
51
+ columns: toTimeCourseColumns(),
52
+ rowKey: 'sampleId',
53
+ }
54
+ }
55
+
56
+ export function toTimeCourseSteps(
57
+ template: TimeCourseTemplate | TimeCourseTemplateData
58
+ ): TimeCourseStepsAdapterResult {
59
+ const data = getTemplateData(template, 'time-course')
60
+ validateTimeCourseData(data)
61
+ return data.timepoints.map((timepoint, index) => ({
62
+ id: timepoint.id,
63
+ type: 'measurement',
64
+ name: timepoint.label,
65
+ description: `${data.conditions.length} condition${data.conditions.length === 1 ? '' : 's'}`,
66
+ status: 'pending',
67
+ order: index,
68
+ parameters: {
69
+ value: timepoint.value,
70
+ unit: timepoint.unit,
71
+ },
72
+ }))
73
+ }