@morscherlab/mint-sdk 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EmptyState-DgBRoYAy.js → EmptyState-LMPS3keb.js} +3 -193
- package/dist/EmptyState-LMPS3keb.js.map +1 -0
- package/dist/{ExperimentPopover-BFw3QX8L.js → ExperimentPopover-D6_RGzTY.js} +113 -35
- package/dist/ExperimentPopover-D6_RGzTY.js.map +1 -0
- package/dist/{ExperimentSelectorModal-BBWXC7KW.js → ExperimentSelectorModal-CDNsNudn.js} +9 -11
- package/dist/ExperimentSelectorModal-CDNsNudn.js.map +1 -0
- package/dist/{SettingsModal-Dpg-X1OM.js → SettingsModal-BGBimSIA.js} +5 -5
- package/dist/{SettingsModal-Dpg-X1OM.js.map → SettingsModal-BGBimSIA.js.map} +1 -1
- package/dist/__stories__/experiment-helpers.d.ts +3 -0
- package/dist/__tests__/stores/experiment.test.d.ts +1 -0
- package/dist/{analysisArtifactTypes-ejqR8MX3.js → analysisArtifactTypes-DQ0MjwHZ.js} +1 -1
- package/dist/{analysisArtifactTypes-ejqR8MX3.js.map → analysisArtifactTypes-DQ0MjwHZ.js.map} +1 -1
- package/dist/components/ExperimentPopover.vue.d.ts +5 -0
- package/dist/components/ExperimentSelectorModal.vue.d.ts +1 -5
- package/dist/components/PluginWorkspaceView.props.d.ts +1 -4
- package/dist/components/PluginWorkspaceView.vue.d.ts +0 -1
- package/dist/components/SmartGroupFieldRecipe.vue.d.ts +2 -2
- package/dist/components/index.js +7 -7
- package/dist/{components-Ci_BTx00.js → components-BbOyjE2T.js} +24 -29
- package/dist/components-BbOyjE2T.js.map +1 -0
- package/dist/composables/experiment-utils.d.ts +10 -0
- package/dist/composables/index.d.ts +2 -2
- package/dist/composables/index.js +11 -10
- package/dist/composables/useAppExperiment.d.ts +29 -17
- package/dist/composables/usePlatformContext.d.ts +3 -3
- package/dist/{composables-C0VEJ73O.js → composables-CW8NRXLB.js} +5 -5
- package/dist/{composables-C0VEJ73O.js.map → composables-CW8NRXLB.js.map} +1 -1
- package/dist/experiment-Y9Iz7KYi.js +95 -0
- package/dist/experiment-Y9Iz7KYi.js.map +1 -0
- package/dist/{experiment-utils-CxkruZ3G.js → experiment-utils-7Yw-h0tD.js} +16 -2
- package/dist/{experiment-utils-CxkruZ3G.js.map → experiment-utils-7Yw-h0tD.js.map} +1 -1
- package/dist/index.js +16 -15
- package/dist/index.js.map +1 -1
- package/dist/install.js +7 -7
- package/dist/{plotly.min-BR53hja4.js → plotly.min-c2Sez60c.js} +1 -1
- package/dist/{plotly.min-BR53hja4.js.map → plotly.min-c2Sez60c.js.map} +1 -1
- package/dist/stores/auth.d.ts +6 -6
- package/dist/stores/experiment.d.ts +166 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.js +3 -2
- package/dist/styles.css +188 -0
- package/dist/templates/index.js +4 -4
- package/dist/{templates-Cdj93S9C.js → templates-CJRFiWUX.js} +2 -2
- package/dist/{templates-Cdj93S9C.js.map → templates-CJRFiWUX.js.map} +1 -1
- package/dist/types/auth.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/platform.d.ts +1 -1
- package/dist/{auth-B87xM--s.js → useApi-CDBq6z23.js} +191 -2
- package/dist/useApi-CDBq6z23.js.map +1 -0
- package/dist/{useControlSchema-B_qgU4rW.js → useControlSchema-BEAgLyyx.js} +5 -4
- package/dist/{useControlSchema-B_qgU4rW.js.map → useControlSchema-BEAgLyyx.js.map} +1 -1
- package/dist/{useDropdownState-gVaMXtwW.js → useDropdownState-Be-ug_ci.js} +2 -2
- package/dist/{useDropdownState-gVaMXtwW.js.map → useDropdownState-Be-ug_ci.js.map} +1 -1
- package/dist/{useExperimentSelector-BuQZRgMt.js → useExperimentSelector-Dld4841S.js} +4 -3
- package/dist/{useExperimentSelector-BuQZRgMt.js.map → useExperimentSelector-Dld4841S.js.map} +1 -1
- package/dist/{useFormBuilder-D1G5J5Z5.js → useFormBuilder-CR9pBApW.js} +2 -2
- package/dist/{useFormBuilder-D1G5J5Z5.js.map → useFormBuilder-CR9pBApW.js.map} +1 -1
- package/dist/{useProtocolTemplates-DeaOmMaw.js → useProtocolTemplates-DXeIHMwV.js} +38 -42
- package/dist/useProtocolTemplates-DXeIHMwV.js.map +1 -0
- package/package.json +1 -1
- package/src/__stories__/experiment-helpers.ts +12 -9
- package/src/__tests__/components/AppTopBar.test.ts +10 -6
- package/src/__tests__/components/ExperimentPopover.test.ts +64 -0
- package/src/__tests__/components/ExperimentSelectorModal.test.ts +86 -41
- package/src/__tests__/components/PluginWorkspaceView.test.ts +103 -19
- package/src/__tests__/components/SettingsModal.test.ts +1 -1
- package/src/__tests__/composables/experiment-utils.test.ts +33 -0
- package/src/__tests__/composables/useAppExperiment.test.ts +331 -92
- package/src/__tests__/composables/useAuth.test.ts +2 -2
- package/src/__tests__/composables/usePlatformContext.test.ts +5 -1
- package/src/__tests__/stores/experiment.test.ts +300 -0
- package/src/components/AppTopBar.vue +0 -2
- package/src/components/ExperimentPopover.story.vue +59 -0
- package/src/components/ExperimentPopover.vue +96 -6
- package/src/components/ExperimentSelectorModal.story.vue +6 -16
- package/src/components/ExperimentSelectorModal.vue +8 -4
- package/src/components/PluginWorkspaceView.props.ts +1 -4
- package/src/components/PluginWorkspaceView.story.vue +12 -5
- package/src/components/PluginWorkspaceView.vue +0 -2
- package/src/composables/experiment-utils.ts +22 -0
- package/src/composables/index.ts +1 -2
- package/src/composables/useAppExperiment.ts +57 -67
- package/src/composables/useAuth.ts +1 -1
- package/src/stores/experiment.ts +120 -0
- package/src/stores/index.ts +1 -0
- package/src/styles/components/experiment-popover.css +105 -0
- package/src/types/auth.ts +1 -1
- package/src/types/platform.ts +1 -1
- package/dist/EmptyState-DgBRoYAy.js.map +0 -1
- package/dist/ExperimentPopover-BFw3QX8L.js.map +0 -1
- package/dist/ExperimentSelectorModal-BBWXC7KW.js.map +0 -1
- package/dist/auth-B87xM--s.js.map +0 -1
- package/dist/components-Ci_BTx00.js.map +0 -1
- package/dist/useProtocolTemplates-DeaOmMaw.js.map +0 -1
package/dist/types/auth.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as ANALYSIS_FILE_ARTIFACT_SCHEMA } from "../analysisArtifactTypes-
|
|
1
|
+
import { t as ANALYSIS_FILE_ARTIFACT_SCHEMA } from "../analysisArtifactTypes-DQ0MjwHZ.js";
|
|
2
2
|
export { ANALYSIS_FILE_ARTIFACT_SCHEMA };
|
package/dist/types/platform.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { canAccessAdmin, canAccessPlugin, getAccessAudience, getUserPermissions, hasAllPermissions, hasAnyPermission, isAdminUser } from "./permissions.js";
|
|
2
2
|
import { computed, ref, watch } from "vue";
|
|
3
3
|
import { defineStore } from "pinia";
|
|
4
|
+
import axios from "axios";
|
|
4
5
|
//#region src/stores/settings.ts
|
|
5
6
|
var STORAGE_KEY = "mint-settings";
|
|
6
7
|
var LEGACY_STORAGE_KEY = "mld-settings";
|
|
@@ -347,6 +348,194 @@ var useAuthStore = defineStore("mint-auth", () => {
|
|
|
347
348
|
};
|
|
348
349
|
});
|
|
349
350
|
//#endregion
|
|
350
|
-
|
|
351
|
+
//#region src/composables/useApi.ts
|
|
352
|
+
var apiClientInstance = null;
|
|
353
|
+
var interceptorAttached = false;
|
|
354
|
+
function joinUrlPath(baseUrl, path) {
|
|
355
|
+
if (/^https?:\/\//i.test(path)) return path;
|
|
356
|
+
if (!path) return baseUrl;
|
|
357
|
+
if (path.startsWith("?") || path.startsWith("#")) return `${baseUrl.replace(/\/+$/, "")}${path}`;
|
|
358
|
+
const normalizedBase = baseUrl.replace(/\/+$/, "");
|
|
359
|
+
const normalizedPath = path.replace(/^\/+/, "/");
|
|
360
|
+
return `${normalizedBase}${normalizedPath.startsWith("/") ? normalizedPath : `/${normalizedPath}`}`;
|
|
361
|
+
}
|
|
362
|
+
function getBasePath(baseUrl) {
|
|
363
|
+
if (!baseUrl) return "/";
|
|
364
|
+
try {
|
|
365
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "http://localhost";
|
|
366
|
+
return new URL(baseUrl, origin).pathname.replace(/\/+$/, "") || "/";
|
|
367
|
+
} catch {
|
|
368
|
+
return baseUrl.replace(/^https?:\/\/[^/]+/i, "").replace(/\/+$/, "") || "/";
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function normalizeRequestUrl(baseUrl, url) {
|
|
372
|
+
if (!url || /^https?:\/\//.test(url)) return url;
|
|
373
|
+
const basePath = getBasePath(baseUrl);
|
|
374
|
+
if (basePath === "/") return url;
|
|
375
|
+
const normalizedUrl = url.startsWith("/") ? url : `/${url}`;
|
|
376
|
+
if (normalizedUrl === basePath || normalizedUrl.startsWith(`${basePath}?`) || normalizedUrl.startsWith(`${basePath}#`)) return normalizedUrl.slice(basePath.length);
|
|
377
|
+
if (normalizedUrl.startsWith(`${basePath}/`)) return normalizedUrl.slice(basePath.length) || "";
|
|
378
|
+
return url;
|
|
379
|
+
}
|
|
380
|
+
function asMutableHeaders(headers) {
|
|
381
|
+
return headers ? headers : null;
|
|
382
|
+
}
|
|
383
|
+
function hasAuthorizationHeader(headers) {
|
|
384
|
+
const bag = asMutableHeaders(headers);
|
|
385
|
+
if (!bag) return false;
|
|
386
|
+
if (typeof bag.has === "function") return bag.has("Authorization");
|
|
387
|
+
return Object.keys(bag).some((key) => key.toLowerCase() === "authorization");
|
|
388
|
+
}
|
|
389
|
+
function setAuthorizationHeader(headers, value) {
|
|
390
|
+
const bag = asMutableHeaders(headers);
|
|
391
|
+
if (!bag) return;
|
|
392
|
+
if (typeof bag.set === "function") {
|
|
393
|
+
bag.set("Authorization", value);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
bag.Authorization = value;
|
|
397
|
+
}
|
|
398
|
+
function deleteAuthorizationHeader(headers) {
|
|
399
|
+
const bag = asMutableHeaders(headers);
|
|
400
|
+
if (!bag) return;
|
|
401
|
+
if (typeof bag.delete === "function") {
|
|
402
|
+
bag.delete("Authorization");
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
for (const key of Object.keys(bag)) if (key.toLowerCase() === "authorization") delete bag[key];
|
|
406
|
+
}
|
|
407
|
+
function getAuthorizationHeader(headers) {
|
|
408
|
+
const bag = asMutableHeaders(headers);
|
|
409
|
+
if (!bag) return void 0;
|
|
410
|
+
if (typeof bag.get === "function") return bag.get("Authorization");
|
|
411
|
+
const key = Object.keys(bag).find((candidate) => candidate.toLowerCase() === "authorization");
|
|
412
|
+
return key ? bag[key] : void 0;
|
|
413
|
+
}
|
|
414
|
+
/** Raised when an authenticated SDK request is rejected because the login is no longer valid. */
|
|
415
|
+
var AuthenticationRequiredError = class extends Error {
|
|
416
|
+
code = "AUTHENTICATION_REQUIRED";
|
|
417
|
+
status = 401;
|
|
418
|
+
constructor(cause) {
|
|
419
|
+
super("Authentication required. Please sign in again.");
|
|
420
|
+
this.cause = cause;
|
|
421
|
+
this.name = "AuthenticationRequiredError";
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
/** @internal Convert a rejected authenticated request into the SDK's public auth error. */
|
|
425
|
+
function authenticationRequiredError(cause, rejectedToken) {
|
|
426
|
+
const currentAuthStore = useAuthStore();
|
|
427
|
+
if (rejectedToken && currentAuthStore.token === rejectedToken) currentAuthStore.clearToken();
|
|
428
|
+
return new AuthenticationRequiredError(cause);
|
|
429
|
+
}
|
|
430
|
+
function getApiClient() {
|
|
431
|
+
if (!apiClientInstance) apiClientInstance = axios.create({ headers: { "Content-Type": "application/json" } });
|
|
432
|
+
return apiClientInstance;
|
|
433
|
+
}
|
|
434
|
+
/** Axios-based API client that injects the plugin base URL and JWT auth header on every request. */
|
|
435
|
+
function useApi(options = {}) {
|
|
436
|
+
const settingsStore = useSettingsStore();
|
|
437
|
+
const authStore = useAuthStore();
|
|
438
|
+
const apiClient = getApiClient();
|
|
439
|
+
if (!authStore.isInitialized) authStore.initialize();
|
|
440
|
+
if (!interceptorAttached) {
|
|
441
|
+
apiClient.interceptors.request.use((config) => {
|
|
442
|
+
const request = config;
|
|
443
|
+
if (request._mintSkipAuth) {
|
|
444
|
+
deleteAuthorizationHeader(request.headers);
|
|
445
|
+
return request;
|
|
446
|
+
}
|
|
447
|
+
const currentAuthStore = useAuthStore();
|
|
448
|
+
if (currentAuthStore.token && config.headers && !hasAuthorizationHeader(config.headers)) setAuthorizationHeader(config.headers, `Bearer ${currentAuthStore.token}`);
|
|
449
|
+
if (getAuthorizationHeader(config.headers) === `Bearer ${currentAuthStore.token}`) request._mintAuthToken = currentAuthStore.token ?? void 0;
|
|
450
|
+
return config;
|
|
451
|
+
});
|
|
452
|
+
apiClient.interceptors.response.use((response) => response, (error) => {
|
|
453
|
+
if (axios.isAxiosError(error) && error.response?.status === 401) {
|
|
454
|
+
const request = error.config;
|
|
455
|
+
if (request?._mintSkipAuth !== true) return Promise.reject(authenticationRequiredError(error, request?._mintAuthToken));
|
|
456
|
+
}
|
|
457
|
+
return Promise.reject(error);
|
|
458
|
+
});
|
|
459
|
+
interceptorAttached = true;
|
|
460
|
+
}
|
|
461
|
+
function getBaseUrl() {
|
|
462
|
+
return options.baseUrl ?? settingsStore.getApiBaseUrl();
|
|
463
|
+
}
|
|
464
|
+
function normalizeUrl(url) {
|
|
465
|
+
return normalizeRequestUrl(getBaseUrl(), url);
|
|
466
|
+
}
|
|
467
|
+
function requestConfig(config) {
|
|
468
|
+
const base = {
|
|
469
|
+
baseURL: getBaseUrl(),
|
|
470
|
+
timeout: options.timeout ?? settingsStore.requestTimeout,
|
|
471
|
+
...config
|
|
472
|
+
};
|
|
473
|
+
if (options.withAuth === false) {
|
|
474
|
+
base._mintSkipAuth = true;
|
|
475
|
+
deleteAuthorizationHeader(base.headers);
|
|
476
|
+
}
|
|
477
|
+
return base;
|
|
478
|
+
}
|
|
479
|
+
async function get(url, config) {
|
|
480
|
+
return (await apiClient.get(normalizeUrl(url), requestConfig(config))).data;
|
|
481
|
+
}
|
|
482
|
+
async function post(url, data, config) {
|
|
483
|
+
return (await apiClient.post(normalizeUrl(url), data, requestConfig(config))).data;
|
|
484
|
+
}
|
|
485
|
+
async function put(url, data, config) {
|
|
486
|
+
return (await apiClient.put(normalizeUrl(url), data, requestConfig(config))).data;
|
|
487
|
+
}
|
|
488
|
+
async function patch(url, data, config) {
|
|
489
|
+
return (await apiClient.patch(normalizeUrl(url), data, requestConfig(config))).data;
|
|
490
|
+
}
|
|
491
|
+
async function del(url, config) {
|
|
492
|
+
return (await apiClient.delete(normalizeUrl(url), requestConfig(config))).data;
|
|
493
|
+
}
|
|
494
|
+
async function upload(url, file, fieldName = "file", additionalData) {
|
|
495
|
+
const formData = new FormData();
|
|
496
|
+
formData.append(fieldName, file);
|
|
497
|
+
if (additionalData) Object.entries(additionalData).forEach(([key, value]) => {
|
|
498
|
+
if (value !== void 0 && value !== null) formData.append(key, typeof value === "object" ? JSON.stringify(value) : String(value));
|
|
499
|
+
});
|
|
500
|
+
return (await apiClient.post(normalizeUrl(url), formData, requestConfig({ headers: { "Content-Type": void 0 } }))).data;
|
|
501
|
+
}
|
|
502
|
+
async function download(url, filename) {
|
|
503
|
+
const response = await apiClient.get(normalizeUrl(url), requestConfig({ responseType: "blob" }));
|
|
504
|
+
const blob = new Blob([response.data]);
|
|
505
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
506
|
+
if (filename) {
|
|
507
|
+
const link = document.createElement("a");
|
|
508
|
+
link.href = blobUrl;
|
|
509
|
+
link.download = filename;
|
|
510
|
+
document.body.appendChild(link);
|
|
511
|
+
link.click();
|
|
512
|
+
document.body.removeChild(link);
|
|
513
|
+
setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
|
|
514
|
+
return "";
|
|
515
|
+
}
|
|
516
|
+
return blobUrl;
|
|
517
|
+
}
|
|
518
|
+
function buildUrl(path) {
|
|
519
|
+
const baseUrl = getBaseUrl();
|
|
520
|
+
return joinUrlPath(baseUrl, normalizeRequestUrl(baseUrl, path));
|
|
521
|
+
}
|
|
522
|
+
function buildWsUrl(path) {
|
|
523
|
+
return joinUrlPath(settingsStore.getWsBaseUrl(), path);
|
|
524
|
+
}
|
|
525
|
+
return {
|
|
526
|
+
client: apiClient,
|
|
527
|
+
get,
|
|
528
|
+
post,
|
|
529
|
+
put,
|
|
530
|
+
patch,
|
|
531
|
+
delete: del,
|
|
532
|
+
upload,
|
|
533
|
+
download,
|
|
534
|
+
buildUrl,
|
|
535
|
+
buildWsUrl
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
//#endregion
|
|
539
|
+
export { colorPalettes as a, useAuthStore as i, authenticationRequiredError as n, useSettingsStore as o, useApi as r, AuthenticationRequiredError as t };
|
|
351
540
|
|
|
352
|
-
//# sourceMappingURL=
|
|
541
|
+
//# sourceMappingURL=useApi-CDBq6z23.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useApi-CDBq6z23.js","names":[],"sources":["../src/stores/settings.ts","../src/stores/auth.ts","../src/composables/useApi.ts"],"sourcesContent":["import { defineStore } from 'pinia'\nimport { ref, watch } from 'vue'\nimport type { ThemeMode, ColorPalette, TableDensity } from '../types'\n\ndeclare global {\n interface ImportMetaEnv {\n readonly VITE_API_PREFIX?: string\n }\n\n interface ImportMeta {\n readonly env: ImportMetaEnv\n }\n}\n\nexport interface SettingsState {\n serverHost: string\n serverPort: number\n requestTimeout: number\n wsAutoReconnect: boolean\n wsReconnectInterval: number\n theme: ThemeMode\n colorPalette: ColorPalette\n tableDensity: TableDensity\n}\n\nconst STORAGE_KEY = 'mint-settings'\nconst LEGACY_STORAGE_KEY = 'mld-settings'\n\nfunction getDefaultServerHost(): string {\n if (typeof window !== 'undefined' && window.location.hostname !== 'localhost') {\n return window.location.hostname\n }\n return 'localhost'\n}\n\nfunction getDefaultServerPort(): number {\n if (typeof window !== 'undefined') {\n if (window.location.port) {\n return parseInt(window.location.port, 10)\n }\n // Standard ports: 443 for HTTPS, 80 for HTTP (browser omits from location.port)\n return window.location.protocol === 'https:' ? 443 : 80\n }\n return 8000\n}\n\nconst defaultSettings: SettingsState = {\n serverHost: getDefaultServerHost(),\n serverPort: getDefaultServerPort(),\n requestTimeout: 120000,\n wsAutoReconnect: true,\n wsReconnectInterval: 5000,\n theme: 'system',\n colorPalette: 'default',\n tableDensity: 'normal',\n}\n\nexport const colorPalettes: Record<ColorPalette, { name: string; hues: [number, number] }> = {\n default: { name: 'Default (Cyan-Pink)', hues: [180, 320] },\n colorblind: { name: 'Colorblind-friendly', hues: [45, 260] },\n viridis: { name: 'Viridis', hues: [280, 80] },\n pastel: { name: 'Pastel', hues: [200, 340] },\n}\n\nfunction loadSettings(): SettingsState {\n try {\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored) {\n const parsed = JSON.parse(stored)\n return { ...defaultSettings, ...parsed }\n }\n\n const legacyStored = localStorage.getItem(LEGACY_STORAGE_KEY)\n if (legacyStored) {\n const parsed = JSON.parse(legacyStored)\n const migrated = { ...defaultSettings, ...parsed }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(migrated))\n localStorage.removeItem(LEGACY_STORAGE_KEY)\n return migrated\n }\n } catch (e) {\n console.warn('Failed to load settings from localStorage:', e)\n }\n return { ...defaultSettings }\n}\n\nfunction saveSettings(settings: SettingsState): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings))\n } catch (e) {\n console.warn('Failed to save settings to localStorage:', e)\n }\n}\n\nfunction getSystemPrefersDark(): boolean {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return false\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n}\n\nexport const useSettingsStore = defineStore('mint-settings', () => {\n // State\n const serverHost = ref(defaultSettings.serverHost)\n const serverPort = ref(defaultSettings.serverPort)\n const requestTimeout = ref(defaultSettings.requestTimeout)\n const wsAutoReconnect = ref(defaultSettings.wsAutoReconnect)\n const wsReconnectInterval = ref(defaultSettings.wsReconnectInterval)\n const theme = ref<ThemeMode>(defaultSettings.theme)\n const systemPrefersDark = ref(getSystemPrefersDark())\n const colorPalette = ref<ColorPalette>(defaultSettings.colorPalette)\n const tableDensity = ref<TableDensity>(defaultSettings.tableDensity)\n\n // API prefix - can be configured via env variable VITE_API_PREFIX\n const apiPrefix: string = (import.meta.env?.VITE_API_PREFIX as string | undefined) ?? '/api'\n\n function _isSameOrigin(): { same: boolean; currentHost: string; currentPort: string } {\n const currentHost = typeof window !== 'undefined' ? window.location.hostname : 'localhost'\n const currentPort = typeof window !== 'undefined' ? window.location.port : '8000'\n const effectivePort = currentPort || (window.location.protocol === 'https:' ? '443' : '80')\n const same =\n (serverHost.value === currentHost && String(serverPort.value) === effectivePort) ||\n (serverHost.value === 'localhost' && currentHost !== 'localhost')\n return { same, currentHost, currentPort }\n }\n\n function getApiBaseUrl(): string {\n const { same } = _isSameOrigin()\n if (same) return apiPrefix\n return `http://${serverHost.value}:${serverPort.value}${apiPrefix}`\n }\n\n function getWsBaseUrl(): string {\n const { same, currentHost, currentPort } = _isSameOrigin()\n const protocol = typeof window !== 'undefined' && window.location.protocol === 'https:' ? 'wss:' : 'ws:'\n if (same) return `${protocol}//${currentHost}${currentPort ? ':' + currentPort : ''}${apiPrefix}`\n return `ws://${serverHost.value}:${serverPort.value}${apiPrefix}`\n }\n\n let _initialized = false\n\n function initialize() {\n if (_initialized) return\n _initialized = true\n\n const loaded = loadSettings()\n serverHost.value = loaded.serverHost\n serverPort.value = loaded.serverPort\n requestTimeout.value = loaded.requestTimeout\n wsAutoReconnect.value = loaded.wsAutoReconnect\n wsReconnectInterval.value = loaded.wsReconnectInterval\n theme.value = loaded.theme\n colorPalette.value = loaded.colorPalette\n tableDensity.value = loaded.tableDensity\n\n applyTheme()\n }\n\n function applyTheme() {\n if (typeof document === 'undefined') return\n const dark = theme.value === 'system' ? systemPrefersDark.value : theme.value === 'dark'\n document.documentElement.classList.toggle('dark', dark)\n }\n\n watch(theme, () => {\n applyTheme()\n persistSettings()\n })\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {\n systemPrefersDark.value = event.matches\n if (theme.value === 'system') {\n applyTheme()\n }\n })\n }\n\n function persistSettings() {\n saveSettings({\n serverHost: serverHost.value,\n serverPort: serverPort.value,\n requestTimeout: requestTimeout.value,\n wsAutoReconnect: wsAutoReconnect.value,\n wsReconnectInterval: wsReconnectInterval.value,\n theme: theme.value,\n colorPalette: colorPalette.value,\n tableDensity: tableDensity.value,\n })\n }\n\n watch([serverHost, serverPort, requestTimeout, wsAutoReconnect, wsReconnectInterval, colorPalette, tableDensity], () => {\n persistSettings()\n })\n\n function resetToDefaults() {\n serverHost.value = defaultSettings.serverHost\n serverPort.value = defaultSettings.serverPort\n requestTimeout.value = defaultSettings.requestTimeout\n wsAutoReconnect.value = defaultSettings.wsAutoReconnect\n wsReconnectInterval.value = defaultSettings.wsReconnectInterval\n theme.value = defaultSettings.theme\n colorPalette.value = defaultSettings.colorPalette\n tableDensity.value = defaultSettings.tableDensity\n }\n\n function getPaletteHues(): [number, number] {\n return colorPalettes[colorPalette.value].hues\n }\n\n function isDark(): boolean {\n return theme.value === 'system' ? systemPrefersDark.value : theme.value === 'dark'\n }\n\n return {\n serverHost,\n serverPort,\n requestTimeout,\n wsAutoReconnect,\n wsReconnectInterval,\n theme,\n systemPrefersDark,\n colorPalette,\n tableDensity,\n initialize,\n applyTheme,\n persistSettings,\n resetToDefaults,\n getPaletteHues,\n isDark,\n getApiBaseUrl,\n getWsBaseUrl,\n }\n})\n","import { defineStore } from 'pinia'\nimport { ref, computed } from 'vue'\nimport type { AuthConfig, UserInfo } from '../types'\nimport {\n canAccessAdmin as canUserAccessAdmin,\n canAccessPlugin as canUserAccessPlugin,\n getAccessAudience,\n getUserPermissions,\n hasAllPermissions,\n hasAnyPermission,\n isAdminUser,\n} from '../permissions'\n\nconst AUTH_TOKEN_KEY = 'mint-auth-token'\nconst AUTH_EXPIRES_KEY = 'mint-auth-expires'\n\nfunction getLocalStorage(): Storage | null {\n try {\n const storage = globalThis.localStorage\n return typeof storage?.getItem === 'function' ? storage : null\n } catch {\n return null\n }\n}\n\nfunction readStoredItem(key: string): string | null {\n try {\n return getLocalStorage()?.getItem(key) ?? null\n } catch {\n return null\n }\n}\n\nfunction writeStoredItem(key: string, value: string): void {\n try {\n getLocalStorage()?.setItem(key, value)\n } catch {\n // Keep auth usable in-memory when browser storage is blocked.\n }\n}\n\nfunction removeStoredItem(key: string): void {\n try {\n getLocalStorage()?.removeItem(key)\n } catch {\n // Keep auth cleanup usable in-memory when browser storage is blocked.\n }\n}\n\nexport const useAuthStore = defineStore('mint-auth', () => {\n // State\n const token = ref<string | null>(null)\n const tokenExpires = ref<Date | null>(null)\n const username = ref<string | null>(null)\n const userInfo = ref<UserInfo | null>(null)\n const authConfig = ref<AuthConfig>({\n authRequired: true,\n passkeyEnabled: false,\n passkeyRegistered: false,\n registrationEnabled: false,\n databaseMode: 'none',\n experimentVisibilityMode: 'open',\n })\n const isInitialized = ref(false)\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // Computed\n const isAuthenticated = computed(() => {\n if (!authConfig.value.authRequired) {\n return true\n }\n if (!token.value) {\n return false\n }\n if (tokenExpires.value && tokenExpires.value < new Date()) {\n return false\n }\n return true\n })\n\n const needsAuth = computed(() => {\n return authConfig.value.authRequired && !isAuthenticated.value\n })\n\n const isAdmin = computed(() => isAdminUser(userInfo.value))\n const userType = computed(() => getAccessAudience(userInfo.value))\n const permissions = computed(() => getUserPermissions(userInfo.value))\n const canAccessAdmin = computed(() => canUserAccessAdmin(userInfo.value))\n\n const canRegister = computed(() => {\n return authConfig.value.registrationEnabled\n })\n\n // Actions\n function initialize() {\n const storedToken = readStoredItem(AUTH_TOKEN_KEY)\n const storedExpires = readStoredItem(AUTH_EXPIRES_KEY)\n\n if (storedToken) {\n token.value = storedToken\n\n if (storedExpires) {\n const expires = new Date(storedExpires)\n if (expires > new Date()) {\n tokenExpires.value = expires\n } else {\n clearToken()\n }\n }\n }\n\n isInitialized.value = true\n }\n\n function setToken(accessToken: string, expiresIn: number) {\n token.value = accessToken\n const expires = new Date(Date.now() + expiresIn * 1000)\n tokenExpires.value = expires\n\n writeStoredItem(AUTH_TOKEN_KEY, accessToken)\n writeStoredItem(AUTH_EXPIRES_KEY, expires.toISOString())\n }\n\n function clearToken() {\n token.value = null\n tokenExpires.value = null\n username.value = null\n userInfo.value = null\n\n removeStoredItem(AUTH_TOKEN_KEY)\n removeStoredItem(AUTH_EXPIRES_KEY)\n }\n\n function setUserInfo(info: UserInfo) {\n userInfo.value = info\n username.value = info.username\n }\n\n function hasPermission(...perms: string[]): boolean {\n return hasAllPermissions(userInfo.value, perms)\n }\n\n function hasAnyPermissionForUser(...perms: string[]): boolean {\n return hasAnyPermission(userInfo.value, perms)\n }\n\n function canAccessPlugin(pluginName: string): boolean {\n return canUserAccessPlugin(userInfo.value, pluginName)\n }\n\n function setAuthConfig(config: AuthConfig) {\n authConfig.value = config\n }\n\n function setUsername(name: string) {\n username.value = name\n }\n\n function setError(message: string | null) {\n error.value = message\n }\n\n function setLoading(loading: boolean) {\n isLoading.value = loading\n }\n\n function logout() {\n clearToken()\n }\n\n return {\n // State\n token,\n tokenExpires,\n username,\n userInfo,\n authConfig,\n isInitialized,\n isLoading,\n error,\n\n // Computed\n isAuthenticated,\n needsAuth,\n isAdmin,\n userType,\n permissions,\n canAccessAdmin,\n canRegister,\n\n // Actions\n initialize,\n setToken,\n clearToken,\n setAuthConfig,\n setUsername,\n setUserInfo,\n setError,\n setLoading,\n hasPermission,\n hasAnyPermission: hasAnyPermissionForUser,\n canAccessPlugin,\n logout,\n }\n})\n","import axios, { type AxiosInstance, type AxiosRequestConfig, type InternalAxiosRequestConfig } from 'axios'\nimport { useSettingsStore } from '../stores/settings'\nimport { useAuthStore } from '../stores/auth'\n\nlet apiClientInstance: AxiosInstance | null = null\nlet interceptorAttached = false\n\ninterface MintAxiosRequestConfig extends AxiosRequestConfig {\n _mintSkipAuth?: boolean\n _mintAuthToken?: string\n}\n\ninterface MintInternalAxiosRequestConfig extends InternalAxiosRequestConfig {\n _mintSkipAuth?: boolean\n _mintAuthToken?: string\n}\n\ntype MutableHeaders = Record<string, unknown> & {\n has?: (header: string) => boolean\n set?: (header: string, value: string) => void\n delete?: (header: string) => void\n}\n\nfunction joinUrlPath(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path\n if (!path) return baseUrl\n if (path.startsWith('?') || path.startsWith('#')) return `${baseUrl.replace(/\\/+$/, '')}${path}`\n const normalizedBase = baseUrl.replace(/\\/+$/, '')\n const normalizedPath = path.replace(/^\\/+/, '/')\n return `${normalizedBase}${normalizedPath.startsWith('/') ? normalizedPath : `/${normalizedPath}`}`\n}\n\nfunction getBasePath(baseUrl: string): string {\n if (!baseUrl) return '/'\n\n try {\n const origin = typeof window !== 'undefined' ? window.location.origin : 'http://localhost'\n return new URL(baseUrl, origin).pathname.replace(/\\/+$/, '') || '/'\n } catch {\n const path = baseUrl.replace(/^https?:\\/\\/[^/]+/i, '')\n return path.replace(/\\/+$/, '') || '/'\n }\n}\n\nfunction normalizeRequestUrl(baseUrl: string, url: string): string {\n if (!url || /^https?:\\/\\//.test(url)) return url\n\n const basePath = getBasePath(baseUrl)\n if (basePath === '/') return url\n\n const normalizedUrl = url.startsWith('/') ? url : `/${url}`\n if (\n normalizedUrl === basePath\n || normalizedUrl.startsWith(`${basePath}?`)\n || normalizedUrl.startsWith(`${basePath}#`)\n ) {\n return normalizedUrl.slice(basePath.length)\n }\n if (normalizedUrl.startsWith(`${basePath}/`)) {\n return normalizedUrl.slice(basePath.length) || ''\n }\n return url\n}\n\nfunction asMutableHeaders(headers: AxiosRequestConfig['headers']): MutableHeaders | null {\n return headers ? (headers as MutableHeaders) : null\n}\n\nfunction hasAuthorizationHeader(headers: AxiosRequestConfig['headers']): boolean {\n const bag = asMutableHeaders(headers)\n if (!bag) return false\n if (typeof bag.has === 'function') return bag.has('Authorization')\n return Object.keys(bag).some((key) => key.toLowerCase() === 'authorization')\n}\n\nfunction setAuthorizationHeader(headers: AxiosRequestConfig['headers'], value: string): void {\n const bag = asMutableHeaders(headers)\n if (!bag) return\n if (typeof bag.set === 'function') {\n bag.set('Authorization', value)\n return\n }\n bag.Authorization = value\n}\n\nfunction deleteAuthorizationHeader(headers: AxiosRequestConfig['headers']): void {\n const bag = asMutableHeaders(headers)\n if (!bag) return\n if (typeof bag.delete === 'function') {\n bag.delete('Authorization')\n return\n }\n for (const key of Object.keys(bag)) {\n if (key.toLowerCase() === 'authorization') delete bag[key]\n }\n}\n\nfunction getAuthorizationHeader(headers: AxiosRequestConfig['headers']): unknown {\n const bag = asMutableHeaders(headers) as (MutableHeaders & { get?: (header: string) => unknown }) | null\n if (!bag) return undefined\n if (typeof bag.get === 'function') return bag.get('Authorization')\n const key = Object.keys(bag).find((candidate) => candidate.toLowerCase() === 'authorization')\n return key ? bag[key] : undefined\n}\n\n/** Raised when an authenticated SDK request is rejected because the login is no longer valid. */\nexport class AuthenticationRequiredError extends Error {\n readonly code = 'AUTHENTICATION_REQUIRED'\n readonly status = 401\n\n constructor(readonly cause?: unknown) {\n super('Authentication required. Please sign in again.')\n this.name = 'AuthenticationRequiredError'\n }\n}\n\n/** @internal Convert a rejected authenticated request into the SDK's public auth error. */\nexport function authenticationRequiredError(\n cause: unknown,\n rejectedToken?: string,\n): AuthenticationRequiredError {\n const currentAuthStore = useAuthStore()\n if (rejectedToken && currentAuthStore.token === rejectedToken) {\n currentAuthStore.clearToken()\n }\n return new AuthenticationRequiredError(cause)\n}\n\nfunction getApiClient(): AxiosInstance {\n if (!apiClientInstance) {\n apiClientInstance = axios.create({\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n }\n return apiClientInstance\n}\n\nexport interface ApiClientOptions {\n baseUrl?: string\n timeout?: number\n withAuth?: boolean\n}\n\nexport interface UseApiReturn {\n client: AxiosInstance\n get: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>\n post: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n put: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n patch: <T>(url: string, data?: unknown, config?: AxiosRequestConfig) => Promise<T>\n delete: <T>(url: string, config?: AxiosRequestConfig) => Promise<T>\n upload: <T>(url: string, file: File, fieldName?: string, additionalData?: Record<string, unknown>) => Promise<T>\n download: (url: string, filename?: string) => Promise<string>\n buildUrl: (path: string) => string\n buildWsUrl: (path: string) => string\n}\n\n/** Axios-based API client that injects the plugin base URL and JWT auth header on every request. */\nexport function useApi(options: ApiClientOptions = {}): UseApiReturn {\n const settingsStore = useSettingsStore()\n const authStore = useAuthStore()\n const apiClient = getApiClient()\n\n // Ensure auth store is initialized (reads token from localStorage)\n if (!authStore.isInitialized) {\n authStore.initialize()\n }\n\n // Attach auth interceptor only once (reads token dynamically, not from closure)\n if (!interceptorAttached) {\n apiClient.interceptors.request.use((config) => {\n const request = config as MintInternalAxiosRequestConfig\n if (request._mintSkipAuth) {\n deleteAuthorizationHeader(request.headers)\n return request\n }\n\n const currentAuthStore = useAuthStore()\n if (currentAuthStore.token && config.headers && !hasAuthorizationHeader(config.headers)) {\n setAuthorizationHeader(config.headers, `Bearer ${currentAuthStore.token}`)\n }\n if (getAuthorizationHeader(config.headers) === `Bearer ${currentAuthStore.token}`) {\n request._mintAuthToken = currentAuthStore.token ?? undefined\n }\n return config\n })\n apiClient.interceptors.response.use(\n (response) => response,\n (error: unknown) => {\n if (axios.isAxiosError(error) && error.response?.status === 401) {\n const request = error.config as MintInternalAxiosRequestConfig | undefined\n if (request?._mintSkipAuth !== true) {\n return Promise.reject(authenticationRequiredError(error, request?._mintAuthToken))\n }\n }\n return Promise.reject(error)\n },\n )\n interceptorAttached = true\n }\n\n function getBaseUrl(): string {\n return options.baseUrl ?? settingsStore.getApiBaseUrl()\n }\n\n function normalizeUrl(url: string): string {\n return normalizeRequestUrl(getBaseUrl(), url)\n }\n\n // Build per-request config that applies this caller's options\n function requestConfig(config?: AxiosRequestConfig): MintAxiosRequestConfig {\n const base: MintAxiosRequestConfig = {\n baseURL: getBaseUrl(),\n timeout: options.timeout ?? settingsStore.requestTimeout,\n ...config,\n }\n // Strip auth header if explicitly disabled\n if (options.withAuth === false) {\n base._mintSkipAuth = true\n deleteAuthorizationHeader(base.headers)\n }\n return base\n }\n\n // Generic request methods\n async function get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.get<T>(normalizeUrl(url), requestConfig(config))\n return response.data\n }\n\n async function post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.post<T>(normalizeUrl(url), data, requestConfig(config))\n return response.data\n }\n\n async function put<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.put<T>(normalizeUrl(url), data, requestConfig(config))\n return response.data\n }\n\n async function patch<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.patch<T>(normalizeUrl(url), data, requestConfig(config))\n return response.data\n }\n\n async function del<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response = await apiClient.delete<T>(normalizeUrl(url), requestConfig(config))\n return response.data\n }\n\n // File upload helper\n async function upload<T>(url: string, file: File, fieldName = 'file', additionalData?: Record<string, unknown>): Promise<T> {\n const formData = new FormData()\n formData.append(fieldName, file)\n\n if (additionalData) {\n Object.entries(additionalData).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n formData.append(key, typeof value === 'object' ? JSON.stringify(value) : String(value))\n }\n })\n }\n\n const response = await apiClient.post<T>(normalizeUrl(url), formData, requestConfig({\n // Let Axios set Content-Type with the correct multipart boundary\n headers: { 'Content-Type': undefined },\n }))\n return response.data\n }\n\n // Download helper - returns blob URL\n async function download(url: string, filename?: string): Promise<string> {\n const response = await apiClient.get(normalizeUrl(url), requestConfig({ responseType: 'blob' }))\n const blob = new Blob([response.data])\n const blobUrl = URL.createObjectURL(blob)\n\n // Optionally trigger download\n if (filename) {\n const link = document.createElement('a')\n link.href = blobUrl\n link.download = filename\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n // Revoke after a short delay to allow download to start;\n // return empty string since the URL will be invalidated\n setTimeout(() => URL.revokeObjectURL(blobUrl), 100)\n return ''\n }\n\n // Caller is responsible for revoking when no filename is provided\n return blobUrl\n }\n\n // Build full URL for external use (e.g., <a href=\"...\">)\n function buildUrl(path: string): string {\n const baseUrl = getBaseUrl()\n return joinUrlPath(baseUrl, normalizeRequestUrl(baseUrl, path))\n }\n\n // WebSocket URL builder\n function buildWsUrl(path: string): string {\n return joinUrlPath(settingsStore.getWsBaseUrl(), path)\n }\n\n return {\n client: apiClient,\n get,\n post,\n put,\n patch,\n delete: del,\n upload,\n download,\n buildUrl,\n buildWsUrl,\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as useDropdownState } from "./useDropdownState-
|
|
1
|
+
import { c as formatExperimentDate, f as BaseModal_default, m as BaseButton_default, p as useEventListener } from "./experiment-utils-7Yw-h0tD.js";
|
|
2
|
+
import { a as BaseSelect_default, i as BasePill_default, n as Skeleton_default, o as normalizeOptionInput, r as useRequestSyncState, s as BaseInput_default, t as EmptyState_default } from "./EmptyState-LMPS3keb.js";
|
|
3
|
+
import { t as useDropdownState } from "./useDropdownState-Be-ug_ci.js";
|
|
4
|
+
import { r as useApi } from "./useApi-CDBq6z23.js";
|
|
4
5
|
import { hasAllPermissions } from "./permissions.js";
|
|
5
6
|
import { Fragment, Teleport, Transition, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, isRef, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, shallowRef, toDisplayString, toValue, unref, useSlots, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
|
|
6
7
|
//#region src/components/BaseTextarea.vue?vue&type=script&setup=true&lang.ts
|
|
@@ -7663,4 +7664,4 @@ function useControlSchema(controls, options = {}) {
|
|
|
7663
7664
|
//#endregion
|
|
7664
7665
|
export { normalizeJobState as $, useConcentrationUnits as A, BaseCheckbox_default as At, useAnalysisArtifacts as B, controlsToViewIds as C, DatePicker_default as Ct, getTypeDefault as D, BaseSlider_default as Dt, getFieldRegistryEntry as E, useSelectionLimit as Et, ATOMIC_WEIGHTS as F, resolveCurrentPluginId as G, getInjectedPlatformContext as H, useChemicalFormula as I, usePluginJobs as J, createGeneratedAnalysisTransport as K, GeneratedPathInput_default as L, SequenceInput_default as M, BaseTextarea_default as Mt, useSequenceUtils as N, ConcentrationInput_default as O, BaseRadioGroup_default as Ot, FormulaInput_default as P, normalizeJobPercent as Q, _plugin_vue_export_helper_default as R, controlsToTopBarSettingsConfig as S, useTimeUtils as St, getDefaultControlView as T, useListSelection as Tt, parseExperimentId as U, currentExperimentFromContext as V, resolveCurrentExperimentId as W, isTerminalJobStatus as X, isActiveJobStatus as Y, jobStatusLabel as Z, controlsToFormSchema as _, isTimeInRange as _t, defineDoseCalculatorControlProps as a, TagsInput_default as at, controlsToSettingsSchema as b, snapToSlot as bt, defineWellPlateDoseComponentBindings as c, compareTime as ct, defineControlModel as d, findNearestTimeSlotIndex as dt, resolveJobCapabilities as et, resolveControlModel as f, formatDuration as ft, mergeControlWorkspaceOptions as g, generateTimeSlots as gt, controlValuesToComponentProps as h, fromMinutes as ht, useControlSchema as i, NumberInput_default as it, MoleculeInput_default as j, Tooltip_default as jt, UnitInput_default as k, BaseToggle_default as kt, defineWellPlateDoseControlProps as l, durationMinutes as lt, controlValuesToComponentBindingsById as m, formatTimeSlot as mt, defineControls as n, AlertBox_default as nt, defineDoseDesignControlModel as o, TimePicker_default as ot, controlValuesToComponentBindings as p, formatTime as pt, useGeneratedAnalysis as q, getControlDefaults as r, FileUploader_default as rt, defineWellPlateControlProps as s, addMinutes as st, defineControlComponentBindings as t, DateTimePicker_default as tt, useControlWorkspace as u, findAvailableSlots as ut, controlsToSectionFormSchema as v, parseTime as vt, controlsToViewItems as w, MultiSelect_default as wt, controlsToSidebarPanels as x, toMinutes as xt, controlsToSectionFormSchemas as y, rangesOverlap as yt, ArtifactSelectorModal_default as z };
|
|
7665
7666
|
|
|
7666
|
-
//# sourceMappingURL=useControlSchema-
|
|
7667
|
+
//# sourceMappingURL=useControlSchema-BEAgLyyx.js.map
|