@morscherlab/mint-sdk 1.0.0 → 1.0.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.
Files changed (68) hide show
  1. package/dist/BaseModal-B9UA8Y_I.js +165 -0
  2. package/dist/BaseModal-B9UA8Y_I.js.map +1 -0
  3. package/dist/BaseSelect-DksaKYq_.js +176 -0
  4. package/dist/BaseSelect-DksaKYq_.js.map +1 -0
  5. package/dist/ExperimentPopover-CCYB1oWp.js +361 -0
  6. package/dist/ExperimentPopover-CCYB1oWp.js.map +1 -0
  7. package/dist/ExperimentPopover-D0bg_fqM.js +3 -0
  8. package/dist/ExperimentSelectorModal-B_kPbXcg.js +4 -0
  9. package/dist/ExperimentSelectorModal-wm7yUdAr.js +720 -0
  10. package/dist/ExperimentSelectorModal-wm7yUdAr.js.map +1 -0
  11. package/dist/SettingsModal-L7Ejny45.js +5 -0
  12. package/dist/SettingsModal-LEKI6Ebl.js +521 -0
  13. package/dist/SettingsModal-LEKI6Ebl.js.map +1 -0
  14. package/dist/{auth-BulIv_km.js → auth-D9q2GIcv.js} +3 -80
  15. package/dist/auth-D9q2GIcv.js.map +1 -0
  16. package/dist/components/DataFrame.vue.d.ts +3 -0
  17. package/dist/components/ExperimentDataViewer.vue.d.ts +2 -0
  18. package/dist/components/PluginWorkspaceView.vue.d.ts +2 -2
  19. package/dist/components/index.js +7 -2
  20. package/dist/{components-DtX3LDLq.js → components-CdjRzHI2.js} +533 -2025
  21. package/dist/components-CdjRzHI2.js.map +1 -0
  22. package/dist/composables/index.js +9 -3
  23. package/dist/composables/usePluginClient.d.ts +2 -1
  24. package/dist/{composables-wNt7VtkF.js → composables-DJgqPrlR.js} +7 -12
  25. package/dist/{composables-wNt7VtkF.js.map → composables-DJgqPrlR.js.map} +1 -1
  26. package/dist/experiment-utils-hGXMHlAc.js +109 -0
  27. package/dist/experiment-utils-hGXMHlAc.js.map +1 -0
  28. package/dist/index.js +16 -5
  29. package/dist/index.js.map +1 -1
  30. package/dist/install.js +7 -2
  31. package/dist/install.js.map +1 -1
  32. package/dist/permissions.js +81 -0
  33. package/dist/permissions.js.map +1 -0
  34. package/dist/stores/index.js +1 -1
  35. package/dist/styles.css +3233 -3185
  36. package/dist/templates/index.js +3 -1
  37. package/dist/templates-Do43ZIMb.js +5065 -0
  38. package/dist/templates-Do43ZIMb.js.map +1 -0
  39. package/dist/{templates-DSbHJC4v.js → useControlSchema-0n8Bcftq.js} +10 -5335
  40. package/dist/useControlSchema-0n8Bcftq.js.map +1 -0
  41. package/dist/useDropdownState-Ben4DnjJ.js +47 -0
  42. package/dist/useDropdownState-Ben4DnjJ.js.map +1 -0
  43. package/dist/useEventListener-CfVkP9Xz.js +57 -0
  44. package/dist/useEventListener-CfVkP9Xz.js.map +1 -0
  45. package/dist/useExperimentSelector-BpZklTbV.js +469 -0
  46. package/dist/useExperimentSelector-BpZklTbV.js.map +1 -0
  47. package/dist/useFormBuilder-COfYWDuC.js +729 -0
  48. package/dist/useFormBuilder-COfYWDuC.js.map +1 -0
  49. package/dist/{useProtocolTemplates-DwBhEPPU.js → useProtocolTemplates-TUQO_F3n.js} +8 -1298
  50. package/dist/useProtocolTemplates-TUQO_F3n.js.map +1 -0
  51. package/dist/utils/pluginIcon.d.ts +29 -2
  52. package/package.json +5 -1
  53. package/src/__tests__/components/DataFrame.test.ts +37 -0
  54. package/src/__tests__/components/PluginIcon.test.ts +77 -0
  55. package/src/__tests__/composables/usePluginClient.test.ts +11 -10
  56. package/src/components/AppTopBar.vue +7 -6
  57. package/src/components/DataFrame.vue +27 -2
  58. package/src/components/ExperimentDataViewer.vue +5 -1
  59. package/src/components/PluginIcon.story.vue +31 -1
  60. package/src/components/PluginIcon.vue +94 -4
  61. package/src/composables/usePluginClient.ts +3 -12
  62. package/src/styles/components/dataframe.css +26 -0
  63. package/src/styles/components/plugin-icon.css +5 -0
  64. package/src/utils/pluginIcon.ts +159 -2
  65. package/dist/auth-BulIv_km.js.map +0 -1
  66. package/dist/components-DtX3LDLq.js.map +0 -1
  67. package/dist/templates-DSbHJC4v.js.map +0 -1
  68. package/dist/useProtocolTemplates-DwBhEPPU.js.map +0 -1
@@ -0,0 +1,165 @@
1
+ import { t as useEventListener } from "./useEventListener-CfVkP9Xz.js";
2
+ import { Teleport, Transition, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, nextTick, normalizeClass, onUnmounted, openBlock, ref, renderSlot, toDisplayString, watch, withCtx } from "vue";
3
+ //#region src/components/BaseModal.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = {
5
+ key: 0,
6
+ class: "mint-modal__grab-hint",
7
+ "aria-hidden": "true"
8
+ };
9
+ var _hoisted_2 = {
10
+ key: 1,
11
+ class: "mint-modal__header"
12
+ };
13
+ var _hoisted_3 = {
14
+ key: 0,
15
+ class: "mint-modal__header-text"
16
+ };
17
+ var _hoisted_4 = {
18
+ key: 0,
19
+ class: "mint-modal__title"
20
+ };
21
+ var _hoisted_5 = {
22
+ key: 1,
23
+ class: "mint-modal__subtitle"
24
+ };
25
+ var _hoisted_6 = { class: "mint-modal__body" };
26
+ var _hoisted_7 = {
27
+ key: 2,
28
+ class: "mint-modal__footer"
29
+ };
30
+ //#endregion
31
+ //#region src/components/BaseModal.vue
32
+ var BaseModal_default = /* @__PURE__ */ defineComponent({
33
+ __name: "BaseModal",
34
+ props: {
35
+ modelValue: { type: Boolean },
36
+ title: {},
37
+ subtitle: {},
38
+ size: { default: "md" },
39
+ variant: { default: "centered" },
40
+ closable: {
41
+ type: Boolean,
42
+ default: true
43
+ },
44
+ closeOnOverlay: {
45
+ type: Boolean,
46
+ default: false
47
+ },
48
+ closeOnEscape: {
49
+ type: Boolean,
50
+ default: true
51
+ }
52
+ },
53
+ emits: ["update:modelValue", "close"],
54
+ setup(__props, { emit: __emit }) {
55
+ /** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant. */
56
+ const props = __props;
57
+ const emit = __emit;
58
+ const containerRef = ref(null);
59
+ let previouslyFocused = null;
60
+ const FOCUSABLE_SELECTOR = [
61
+ "a[href]",
62
+ "button:not([disabled])",
63
+ "input:not([disabled])",
64
+ "select:not([disabled])",
65
+ "textarea:not([disabled])",
66
+ "[tabindex]:not([tabindex=\"-1\"])"
67
+ ].join(", ");
68
+ function getFocusableElements() {
69
+ if (!containerRef.value) return [];
70
+ return Array.from(containerRef.value.querySelectorAll(FOCUSABLE_SELECTOR));
71
+ }
72
+ function handleKeydown(event) {
73
+ if (event.key === "Escape" && props.closeOnEscape && props.modelValue) {
74
+ close();
75
+ return;
76
+ }
77
+ if (event.key !== "Tab" || !containerRef.value) return;
78
+ const focusable = getFocusableElements();
79
+ if (focusable.length === 0) {
80
+ event.preventDefault();
81
+ return;
82
+ }
83
+ const first = focusable[0];
84
+ const last = focusable[focusable.length - 1];
85
+ if (event.shiftKey && document.activeElement === first) {
86
+ event.preventDefault();
87
+ last.focus();
88
+ } else if (!event.shiftKey && document.activeElement === last) {
89
+ event.preventDefault();
90
+ first.focus();
91
+ }
92
+ }
93
+ function close() {
94
+ if (props.closable) {
95
+ emit("update:modelValue", false);
96
+ emit("close");
97
+ }
98
+ }
99
+ function handleOverlayClick(event) {
100
+ if (props.closeOnOverlay && event.target === event.currentTarget) close();
101
+ }
102
+ watch(() => props.modelValue, async (isOpen) => {
103
+ if (isOpen) {
104
+ previouslyFocused = document.activeElement;
105
+ document.body.style.overflow = "hidden";
106
+ await nextTick();
107
+ const focusable = getFocusableElements();
108
+ if (focusable.length > 0) focusable[0].focus();
109
+ else containerRef.value?.focus();
110
+ } else {
111
+ document.body.style.overflow = "";
112
+ previouslyFocused?.focus();
113
+ previouslyFocused = null;
114
+ }
115
+ });
116
+ useEventListener(() => document, "keydown", handleKeydown);
117
+ onUnmounted(() => {
118
+ document.body.style.overflow = "";
119
+ });
120
+ return (_ctx, _cache) => {
121
+ return openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, { name: `modal-${__props.variant}` }, {
122
+ default: withCtx(() => [__props.modelValue ? (openBlock(), createElementBlock("div", {
123
+ key: 0,
124
+ class: normalizeClass(["mint-modal", `mint-modal--${__props.variant}`]),
125
+ onClick: handleOverlayClick
126
+ }, [_cache[1] || (_cache[1] = createElementVNode("div", { class: "mint-modal__overlay" }, null, -1)), createElementVNode("div", {
127
+ ref_key: "containerRef",
128
+ ref: containerRef,
129
+ class: normalizeClass([
130
+ "mint-modal__container",
131
+ `mint-modal__container--${__props.size}`,
132
+ `mint-modal__container--${__props.variant}`
133
+ ]),
134
+ role: "dialog",
135
+ "aria-modal": "true",
136
+ tabindex: "-1"
137
+ }, [
138
+ __props.variant === "sheet" ? (openBlock(), createElementBlock("div", _hoisted_1)) : createCommentVNode("", true),
139
+ __props.title || __props.subtitle || __props.closable || _ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_2, [__props.title || __props.subtitle || _ctx.$slots.header ? (openBlock(), createElementBlock("div", _hoisted_3, [renderSlot(_ctx.$slots, "header", {}, () => [__props.title ? (openBlock(), createElementBlock("h3", _hoisted_4, toDisplayString(__props.title), 1)) : createCommentVNode("", true), __props.subtitle ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true)])])) : createCommentVNode("", true), __props.closable ? (openBlock(), createElementBlock("button", {
140
+ key: 1,
141
+ type: "button",
142
+ class: "mint-modal__close",
143
+ "aria-label": "Close modal",
144
+ onClick: close
145
+ }, [..._cache[0] || (_cache[0] = [createElementVNode("svg", {
146
+ class: "mint-modal__close-icon",
147
+ fill: "none",
148
+ stroke: "currentColor",
149
+ "stroke-width": "2",
150
+ "stroke-linecap": "round",
151
+ "stroke-linejoin": "round",
152
+ viewBox: "0 0 24 24"
153
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])])) : createCommentVNode("", true)])) : createCommentVNode("", true),
154
+ createElementVNode("div", _hoisted_6, [renderSlot(_ctx.$slots, "default")]),
155
+ _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_7, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
156
+ ], 2)], 2)) : createCommentVNode("", true)]),
157
+ _: 3
158
+ }, 8, ["name"])]);
159
+ };
160
+ }
161
+ });
162
+ //#endregion
163
+ export { BaseModal_default as t };
164
+
165
+ //# sourceMappingURL=BaseModal-B9UA8Y_I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseModal-B9UA8Y_I.js","names":["$slots"],"sources":["../src/components/BaseModal.vue","../src/components/BaseModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant. */\nimport { ref, watch, nextTick, onUnmounted } from 'vue'\nimport type { ModalSize, ModalVariant } from '../types'\nimport { useEventListener } from '../composables/useEventListener'\n\ninterface Props {\n modelValue: boolean\n title?: string\n subtitle?: string\n size?: ModalSize\n variant?: ModalVariant\n closable?: boolean\n closeOnOverlay?: boolean\n closeOnEscape?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'centered',\n closable: true,\n closeOnOverlay: false,\n closeOnEscape: true,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n close: []\n}>()\n\nconst containerRef = ref<HTMLElement | null>(null)\nlet previouslyFocused: HTMLElement | null = null\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ')\n\nfunction getFocusableElements(): HTMLElement[] {\n if (!containerRef.value) return []\n return Array.from(containerRef.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && props.closeOnEscape && props.modelValue) {\n close()\n return\n }\n\n if (event.key !== 'Tab' || !containerRef.value) return\n\n const focusable = getFocusableElements()\n if (focusable.length === 0) {\n event.preventDefault()\n return\n }\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n\nfunction close() {\n if (props.closable) {\n emit('update:modelValue', false)\n emit('close')\n }\n}\n\nfunction handleOverlayClick(event: MouseEvent) {\n if (props.closeOnOverlay && event.target === event.currentTarget) {\n close()\n }\n}\n\nwatch(() => props.modelValue, async (isOpen) => {\n if (isOpen) {\n previouslyFocused = document.activeElement as HTMLElement | null\n document.body.style.overflow = 'hidden'\n await nextTick()\n const focusable = getFocusableElements()\n if (focusable.length > 0) {\n focusable[0].focus()\n } else {\n containerRef.value?.focus()\n }\n } else {\n document.body.style.overflow = ''\n previouslyFocused?.focus()\n previouslyFocused = null\n }\n})\n\nuseEventListener(() => document, 'keydown', handleKeydown)\n\nonUnmounted(() => {\n document.body.style.overflow = ''\n})\n</script>\n\n<template>\n <Teleport to=\"body\">\n <Transition :name=\"`modal-${variant}`\">\n <div\n v-if=\"modelValue\"\n :class=\"['mint-modal', `mint-modal--${variant}`]\"\n @click=\"handleOverlayClick\"\n >\n <!-- Overlay -->\n <div class=\"mint-modal__overlay\" />\n\n <!-- Modal -->\n <div\n ref=\"containerRef\"\n :class=\"[\n 'mint-modal__container',\n `mint-modal__container--${size}`,\n `mint-modal__container--${variant}`,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n tabindex=\"-1\"\n >\n <!-- Sheet grab-hint bar (sheet variant only) -->\n <div v-if=\"variant === 'sheet'\" class=\"mint-modal__grab-hint\" aria-hidden=\"true\" />\n\n <!-- Header -->\n <div v-if=\"title || subtitle || closable || $slots.header\" class=\"mint-modal__header\">\n <div v-if=\"title || subtitle || $slots.header\" class=\"mint-modal__header-text\">\n <slot name=\"header\">\n <h3 v-if=\"title\" class=\"mint-modal__title\">\n {{ title }}\n </h3>\n <p v-if=\"subtitle\" class=\"mint-modal__subtitle\">\n {{ subtitle }}\n </p>\n </slot>\n </div>\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"mint-modal__close\"\n aria-label=\"Close modal\"\n @click=\"close\"\n >\n <svg class=\"mint-modal__close-icon\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"mint-modal__body\">\n <slot />\n </div>\n\n <!-- Footer -->\n <div v-if=\"$slots.footer\" class=\"mint-modal__footer\">\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<style>\n@import '../styles/components/modal.css';\n</style>\n","<script setup lang=\"ts\">\n/** Modal dialog with backdrop, focus trap, Escape-to-close, and configurable size/variant. */\nimport { ref, watch, nextTick, onUnmounted } from 'vue'\nimport type { ModalSize, ModalVariant } from '../types'\nimport { useEventListener } from '../composables/useEventListener'\n\ninterface Props {\n modelValue: boolean\n title?: string\n subtitle?: string\n size?: ModalSize\n variant?: ModalVariant\n closable?: boolean\n closeOnOverlay?: boolean\n closeOnEscape?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'md',\n variant: 'centered',\n closable: true,\n closeOnOverlay: false,\n closeOnEscape: true,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean]\n close: []\n}>()\n\nconst containerRef = ref<HTMLElement | null>(null)\nlet previouslyFocused: HTMLElement | null = null\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ')\n\nfunction getFocusableElements(): HTMLElement[] {\n if (!containerRef.value) return []\n return Array.from(containerRef.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && props.closeOnEscape && props.modelValue) {\n close()\n return\n }\n\n if (event.key !== 'Tab' || !containerRef.value) return\n\n const focusable = getFocusableElements()\n if (focusable.length === 0) {\n event.preventDefault()\n return\n }\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n\nfunction close() {\n if (props.closable) {\n emit('update:modelValue', false)\n emit('close')\n }\n}\n\nfunction handleOverlayClick(event: MouseEvent) {\n if (props.closeOnOverlay && event.target === event.currentTarget) {\n close()\n }\n}\n\nwatch(() => props.modelValue, async (isOpen) => {\n if (isOpen) {\n previouslyFocused = document.activeElement as HTMLElement | null\n document.body.style.overflow = 'hidden'\n await nextTick()\n const focusable = getFocusableElements()\n if (focusable.length > 0) {\n focusable[0].focus()\n } else {\n containerRef.value?.focus()\n }\n } else {\n document.body.style.overflow = ''\n previouslyFocused?.focus()\n previouslyFocused = null\n }\n})\n\nuseEventListener(() => document, 'keydown', handleKeydown)\n\nonUnmounted(() => {\n document.body.style.overflow = ''\n})\n</script>\n\n<template>\n <Teleport to=\"body\">\n <Transition :name=\"`modal-${variant}`\">\n <div\n v-if=\"modelValue\"\n :class=\"['mint-modal', `mint-modal--${variant}`]\"\n @click=\"handleOverlayClick\"\n >\n <!-- Overlay -->\n <div class=\"mint-modal__overlay\" />\n\n <!-- Modal -->\n <div\n ref=\"containerRef\"\n :class=\"[\n 'mint-modal__container',\n `mint-modal__container--${size}`,\n `mint-modal__container--${variant}`,\n ]\"\n role=\"dialog\"\n aria-modal=\"true\"\n tabindex=\"-1\"\n >\n <!-- Sheet grab-hint bar (sheet variant only) -->\n <div v-if=\"variant === 'sheet'\" class=\"mint-modal__grab-hint\" aria-hidden=\"true\" />\n\n <!-- Header -->\n <div v-if=\"title || subtitle || closable || $slots.header\" class=\"mint-modal__header\">\n <div v-if=\"title || subtitle || $slots.header\" class=\"mint-modal__header-text\">\n <slot name=\"header\">\n <h3 v-if=\"title\" class=\"mint-modal__title\">\n {{ title }}\n </h3>\n <p v-if=\"subtitle\" class=\"mint-modal__subtitle\">\n {{ subtitle }}\n </p>\n </slot>\n </div>\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"mint-modal__close\"\n aria-label=\"Close modal\"\n @click=\"close\"\n >\n <svg class=\"mint-modal__close-icon\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div class=\"mint-modal__body\">\n <slot />\n </div>\n\n <!-- Footer -->\n <div v-if=\"$slots.footer\" class=\"mint-modal__footer\">\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<style>\n@import '../styles/components/modal.css';\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECiBA,MAAM,QAAQ;EAQd,MAAM,OAAO;EAKb,MAAM,eAAe,IAAwB,KAAI;EACjD,IAAI,oBAAwC;EAE5C,MAAM,qBAAqB;GACzB;GACA;GACA;GACA;GACA;GACA;GACD,CAAC,KAAK,KAAI;EAEX,SAAS,uBAAsC;AAC7C,OAAI,CAAC,aAAa,MAAO,QAAO,EAAC;AACjC,UAAO,MAAM,KAAK,aAAa,MAAM,iBAA8B,mBAAmB,CAAA;;EAGxF,SAAS,cAAc,OAAsB;AAC3C,OAAI,MAAM,QAAQ,YAAY,MAAM,iBAAiB,MAAM,YAAY;AACrE,WAAM;AACN;;AAGF,OAAI,MAAM,QAAQ,SAAS,CAAC,aAAa,MAAO;GAEhD,MAAM,YAAY,sBAAqB;AACvC,OAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,gBAAe;AACrB;;GAGF,MAAM,QAAQ,UAAU;GACxB,MAAM,OAAO,UAAU,UAAU,SAAS;AAE1C,OAAI,MAAM,YAAY,SAAS,kBAAkB,OAAO;AACtD,UAAM,gBAAe;AACrB,SAAK,OAAM;cACF,CAAC,MAAM,YAAY,SAAS,kBAAkB,MAAM;AAC7D,UAAM,gBAAe;AACrB,UAAM,OAAM;;;EAIhB,SAAS,QAAQ;AACf,OAAI,MAAM,UAAU;AAClB,SAAK,qBAAqB,MAAK;AAC/B,SAAK,QAAO;;;EAIhB,SAAS,mBAAmB,OAAmB;AAC7C,OAAI,MAAM,kBAAkB,MAAM,WAAW,MAAM,cACjD,QAAM;;AAIV,cAAY,MAAM,YAAY,OAAO,WAAW;AAC9C,OAAI,QAAQ;AACV,wBAAoB,SAAS;AAC7B,aAAS,KAAK,MAAM,WAAW;AAC/B,UAAM,UAAS;IACf,MAAM,YAAY,sBAAqB;AACvC,QAAI,UAAU,SAAS,EACrB,WAAU,GAAG,OAAM;QAEnB,cAAa,OAAO,OAAM;UAEvB;AACL,aAAS,KAAK,MAAM,WAAW;AAC/B,uBAAmB,OAAM;AACzB,wBAAoB;;IAEvB;AAED,yBAAuB,UAAU,WAAW,cAAa;AAEzD,oBAAkB;AAChB,YAAS,KAAK,MAAM,WAAW;IAChC;;uBAIC,YA8DW,UAAA,EA9DD,IAAG,QAAM,EAAA,CACjB,YA4Da,YAAA,EA5DA,MAAI,SAAW,QAAA,WAAA,EAAA;2BA2DpB,CAzDE,QAAA,cAAA,WAAA,EADR,mBA0DM,OAAA;;KAxDH,OAAK,eAAA,CAAA,cAAA,eAAgC,QAAA,UAAO,CAAA;KAC5C,SAAO;kCAGR,mBAAmC,OAAA,EAA9B,OAAM,uBAAqB,EAAA,MAAA,GAAA,GAGhC,mBAgDM,OAAA;cA/CA;KAAJ,KAAI;KACH,OAAK,eAAA;;gCAA+E,QAAA;gCAA8C,QAAA;;KAKnI,MAAK;KACL,cAAW;KACX,UAAS;;KAGE,QAAA,YAAO,WAAA,WAAA,EAAlB,mBAAmF,OAAnF,WAAmF,IAAA,mBAAA,IAAA,KAAA;KAGxE,QAAA,SAAS,QAAA,YAAY,QAAA,YAAYA,KAAAA,OAAO,UAAA,WAAA,EAAnD,mBAsBM,OAtBN,YAsBM,CArBO,QAAA,SAAS,QAAA,YAAYA,KAAAA,OAAO,UAAA,WAAA,EAAvC,mBASM,OATN,YASM,CARJ,WAOO,KAAA,QAAA,UAAA,EAAA,QAAA,CANK,QAAA,SAAA,WAAA,EAAV,mBAEK,MAFL,YAEK,gBADA,QAAA,MAAK,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,EAED,QAAA,YAAA,WAAA,EAAT,mBAEI,KAFJ,YAEI,gBADC,QAAA,SAAQ,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,EAKT,QAAA,YAAA,WAAA,EADR,mBAUS,UAAA;;MARP,MAAK;MACL,OAAM;MACN,cAAW;MACV,SAAO;uCAER,mBAEM,OAAA;MAFD,OAAM;MAAyB,MAAK;MAAO,QAAO;MAAe,gBAAa;MAAI,kBAAe;MAAQ,mBAAgB;MAAQ,SAAQ;SAC5I,mBAAuB,QAAA,EAAjB,GAAE,cAAY,CAAA,EAAG,mBAAuB,QAAA,EAAjB,GAAE,cAAY,CAAA,CAAA,EAAA,GAAA,CAAA,EAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA;KAMjD,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;KAICA,KAAAA,OAAO,UAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAsB,KAAA,QAAA,SAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA"}
@@ -0,0 +1,176 @@
1
+ import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderList, toDisplayString } from "vue";
2
+ //#region src/components/BaseInput.vue?vue&type=script&setup=true&lang.ts
3
+ var _hoisted_1$1 = [
4
+ "type",
5
+ "value",
6
+ "placeholder",
7
+ "disabled",
8
+ "readonly",
9
+ "autocomplete",
10
+ "autofocus",
11
+ "min",
12
+ "max",
13
+ "step",
14
+ "aria-invalid",
15
+ "aria-describedby"
16
+ ];
17
+ //#endregion
18
+ //#region src/components/BaseInput.vue
19
+ var BaseInput_default = /* @__PURE__ */ defineComponent({
20
+ __name: "BaseInput",
21
+ props: {
22
+ modelValue: {},
23
+ type: { default: "text" },
24
+ placeholder: {},
25
+ disabled: {
26
+ type: Boolean,
27
+ default: false
28
+ },
29
+ readonly: {
30
+ type: Boolean,
31
+ default: false
32
+ },
33
+ error: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+ size: { default: "md" },
38
+ autocomplete: {},
39
+ autofocus: { type: Boolean },
40
+ min: {},
41
+ max: {},
42
+ step: {},
43
+ ariaDescribedby: {}
44
+ },
45
+ emits: [
46
+ "update:modelValue",
47
+ "focus",
48
+ "blur",
49
+ "keydown"
50
+ ],
51
+ setup(__props, { emit: __emit }) {
52
+ /** Renders a styled `<input>` supporting text/number/email types, size, error, and readonly states. */
53
+ const props = __props;
54
+ const emit = __emit;
55
+ function handleInput(event) {
56
+ const target = event.target;
57
+ emit("update:modelValue", props.type === "number" ? target.value === "" ? null : Number(target.value) : target.value);
58
+ }
59
+ return (_ctx, _cache) => {
60
+ return openBlock(), createElementBlock("input", {
61
+ type: __props.type,
62
+ value: __props.modelValue,
63
+ placeholder: __props.placeholder,
64
+ disabled: __props.disabled,
65
+ readonly: __props.readonly,
66
+ autocomplete: __props.autocomplete,
67
+ autofocus: __props.autofocus,
68
+ min: __props.min,
69
+ max: __props.max,
70
+ step: __props.step,
71
+ "aria-invalid": __props.error || void 0,
72
+ "aria-describedby": __props.ariaDescribedby || void 0,
73
+ class: normalizeClass([
74
+ "mint-input",
75
+ `mint-input--${__props.size}`,
76
+ __props.error ? "mint-input--error" : "",
77
+ __props.disabled ? "mint-input--disabled" : ""
78
+ ]),
79
+ onInput: handleInput,
80
+ onFocus: _cache[0] || (_cache[0] = ($event) => emit("focus", $event)),
81
+ onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event)),
82
+ onKeydown: _cache[2] || (_cache[2] = ($event) => emit("keydown", $event))
83
+ }, null, 42, _hoisted_1$1);
84
+ };
85
+ }
86
+ });
87
+ //#endregion
88
+ //#region src/utils/options.ts
89
+ function normalizeOptionInput(option) {
90
+ if (typeof option === "object") return option;
91
+ return {
92
+ value: option,
93
+ label: String(option)
94
+ };
95
+ }
96
+ function findOptionByDomValue(options, value) {
97
+ return options.find((option) => String(option.value) === value);
98
+ }
99
+ //#endregion
100
+ //#region src/components/BaseSelect.vue?vue&type=script&setup=true&lang.ts
101
+ var _hoisted_1 = { class: "mint-select" };
102
+ var _hoisted_2 = [
103
+ "value",
104
+ "disabled",
105
+ "aria-invalid",
106
+ "aria-describedby"
107
+ ];
108
+ var _hoisted_3 = {
109
+ key: 0,
110
+ value: "",
111
+ disabled: ""
112
+ };
113
+ var _hoisted_4 = ["value", "disabled"];
114
+ //#endregion
115
+ //#region src/components/BaseSelect.vue
116
+ var BaseSelect_default = /* @__PURE__ */ defineComponent({
117
+ __name: "BaseSelect",
118
+ props: {
119
+ modelValue: {},
120
+ options: {},
121
+ placeholder: {},
122
+ disabled: {
123
+ type: Boolean,
124
+ default: false
125
+ },
126
+ error: {
127
+ type: Boolean,
128
+ default: false
129
+ },
130
+ size: { default: "md" },
131
+ ariaDescribedby: {}
132
+ },
133
+ emits: ["update:modelValue"],
134
+ setup(__props, { emit: __emit }) {
135
+ /** Renders a native `<select>` element with size, error, and disabled states. */
136
+ const props = __props;
137
+ const emit = __emit;
138
+ const normalizedOptions = computed(() => props.options.map(normalizeOptionInput));
139
+ function handleChange(event) {
140
+ const target = event.target;
141
+ emit("update:modelValue", findOptionByDomValue(normalizedOptions.value, target.value)?.value ?? target.value);
142
+ }
143
+ return (_ctx, _cache) => {
144
+ return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("select", {
145
+ value: __props.modelValue,
146
+ disabled: __props.disabled,
147
+ "aria-invalid": __props.error || void 0,
148
+ "aria-describedby": __props.ariaDescribedby || void 0,
149
+ class: normalizeClass([
150
+ "mint-select__control",
151
+ `mint-select__control--${__props.size}`,
152
+ __props.error ? "mint-select__control--error" : "",
153
+ __props.disabled ? "mint-select__control--disabled" : ""
154
+ ]),
155
+ onChange: handleChange
156
+ }, [__props.placeholder ? (openBlock(), createElementBlock("option", _hoisted_3, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
157
+ return openBlock(), createElementBlock("option", {
158
+ key: String(option.value),
159
+ value: option.value,
160
+ disabled: option.disabled
161
+ }, toDisplayString(option.label), 9, _hoisted_4);
162
+ }), 128))], 42, _hoisted_2), _cache[0] || (_cache[0] = createElementVNode("div", { class: "mint-select__icon" }, [createElementVNode("svg", {
163
+ fill: "none",
164
+ stroke: "currentColor",
165
+ "stroke-width": "2",
166
+ "stroke-linecap": "round",
167
+ "stroke-linejoin": "round",
168
+ viewBox: "0 0 24 24"
169
+ }, [createElementVNode("path", { d: "m6 9 6 6 6-6" })])], -1))]);
170
+ };
171
+ }
172
+ });
173
+ //#endregion
174
+ export { normalizeOptionInput as n, BaseInput_default as r, BaseSelect_default as t };
175
+
176
+ //# sourceMappingURL=BaseSelect-DksaKYq_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseSelect-DksaKYq_.js","names":[],"sources":["../src/components/BaseInput.vue","../src/components/BaseInput.vue","../src/utils/options.ts","../src/components/BaseSelect.vue","../src/components/BaseSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Renders a styled `<input>` supporting text/number/email types, size, error, and readonly states. */\nimport type { InputType } from '../types'\n\ninterface Props {\n modelValue?: string | number\n type?: InputType\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n autocomplete?: string\n autofocus?: boolean\n min?: number\n max?: number\n step?: number\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'text',\n disabled: false,\n readonly: false,\n error: false,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number | null]\n focus: [event: FocusEvent]\n blur: [event: FocusEvent]\n keydown: [event: KeyboardEvent]\n}>()\n\nfunction handleInput(event: Event) {\n const target = event.target as HTMLInputElement\n const value = props.type === 'number'\n ? (target.value === '' ? null : Number(target.value))\n : target.value\n emit('update:modelValue', value as string | number)\n}\n</script>\n\n<template>\n <input\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :autocomplete=\"autocomplete\"\n :autofocus=\"autofocus\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-input',\n `mint-input--${size}`,\n error ? 'mint-input--error' : '',\n disabled ? 'mint-input--disabled' : '',\n ]\"\n @input=\"handleInput\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @keydown=\"emit('keydown', $event)\"\n />\n</template>\n\n<style>\n@import '../styles/components/input.css';\n</style>\n","<script setup lang=\"ts\">\n/** Renders a styled `<input>` supporting text/number/email types, size, error, and readonly states. */\nimport type { InputType } from '../types'\n\ninterface Props {\n modelValue?: string | number\n type?: InputType\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n autocomplete?: string\n autofocus?: boolean\n min?: number\n max?: number\n step?: number\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'text',\n disabled: false,\n readonly: false,\n error: false,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number | null]\n focus: [event: FocusEvent]\n blur: [event: FocusEvent]\n keydown: [event: KeyboardEvent]\n}>()\n\nfunction handleInput(event: Event) {\n const target = event.target as HTMLInputElement\n const value = props.type === 'number'\n ? (target.value === '' ? null : Number(target.value))\n : target.value\n emit('update:modelValue', value as string | number)\n}\n</script>\n\n<template>\n <input\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :autocomplete=\"autocomplete\"\n :autofocus=\"autofocus\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-input',\n `mint-input--${size}`,\n error ? 'mint-input--error' : '',\n disabled ? 'mint-input--disabled' : '',\n ]\"\n @input=\"handleInput\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n @keydown=\"emit('keydown', $event)\"\n />\n</template>\n\n<style>\n@import '../styles/components/input.css';\n</style>\n","export type OptionLike<TValue extends string | number> = {\n value: TValue\n label: string\n}\n\nexport function normalizeOptionInput<\n TValue extends string | number,\n TOption extends OptionLike<TValue>,\n>(option: TOption | TValue): TOption {\n if (typeof option === 'object') return option\n\n return {\n value: option,\n label: String(option),\n } as TOption\n}\n\nexport function findOptionByDomValue<\n TValue extends string | number,\n TOption extends OptionLike<TValue>,\n>(options: TOption[], value: string): TOption | undefined {\n return options.find(option => String(option.value) === value)\n}\n","<script setup lang=\"ts\">\n/** Renders a native `<select>` element with size, error, and disabled states. */\nimport { computed } from 'vue'\nimport type { SelectOption, SelectOptionInput } from '../types'\nimport { findOptionByDomValue, normalizeOptionInput } from '../utils/options'\n\ninterface Props {\n modelValue?: string | number\n options: SelectOptionInput<string | number>[]\n placeholder?: string\n disabled?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n error: false,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n}>()\n\nconst normalizedOptions = computed<SelectOption<string | number>[]>(() =>\n props.options.map(normalizeOptionInput)\n)\n\nfunction handleChange(event: Event) {\n const target = event.target as HTMLSelectElement\n const option = findOptionByDomValue(normalizedOptions.value, target.value)\n emit('update:modelValue', option?.value ?? target.value)\n}\n</script>\n\n<template>\n <div class=\"mint-select\">\n <select\n :value=\"modelValue\"\n :disabled=\"disabled\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-select__control',\n `mint-select__control--${size}`,\n error ? 'mint-select__control--error' : '',\n disabled ? 'mint-select__control--disabled' : '',\n ]\"\n @change=\"handleChange\"\n >\n <option v-if=\"placeholder\" value=\"\" disabled>\n {{ placeholder }}\n </option>\n <option\n v-for=\"option in normalizedOptions\"\n :key=\"String(option.value)\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n <div class=\"mint-select__icon\">\n <svg fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </div>\n </div>\n</template>\n\n<style>\n@import '../styles/components/select.css';\n</style>\n","<script setup lang=\"ts\">\n/** Renders a native `<select>` element with size, error, and disabled states. */\nimport { computed } from 'vue'\nimport type { SelectOption, SelectOptionInput } from '../types'\nimport { findOptionByDomValue, normalizeOptionInput } from '../utils/options'\n\ninterface Props {\n modelValue?: string | number\n options: SelectOptionInput<string | number>[]\n placeholder?: string\n disabled?: boolean\n error?: boolean\n size?: 'sm' | 'md' | 'lg'\n ariaDescribedby?: string\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n error: false,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n}>()\n\nconst normalizedOptions = computed<SelectOption<string | number>[]>(() =>\n props.options.map(normalizeOptionInput)\n)\n\nfunction handleChange(event: Event) {\n const target = event.target as HTMLSelectElement\n const option = findOptionByDomValue(normalizedOptions.value, target.value)\n emit('update:modelValue', option?.value ?? target.value)\n}\n</script>\n\n<template>\n <div class=\"mint-select\">\n <select\n :value=\"modelValue\"\n :disabled=\"disabled\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"ariaDescribedby || undefined\"\n :class=\"[\n 'mint-select__control',\n `mint-select__control--${size}`,\n error ? 'mint-select__control--error' : '',\n disabled ? 'mint-select__control--disabled' : '',\n ]\"\n @change=\"handleChange\"\n >\n <option v-if=\"placeholder\" value=\"\" disabled>\n {{ placeholder }}\n </option>\n <option\n v-for=\"option in normalizedOptions\"\n :key=\"String(option.value)\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n <div class=\"mint-select__icon\">\n <svg fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\">\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </div>\n </div>\n</template>\n\n<style>\n@import '../styles/components/select.css';\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECoBA,MAAM,QAAQ;EAQd,MAAM,OAAO;EAOb,SAAS,YAAY,OAAc;GACjC,MAAM,SAAS,MAAM;AAIrB,QAAK,qBAHS,MAAM,SAAS,WACxB,OAAO,UAAU,KAAK,OAAO,OAAO,OAAO,MAAM,GAClD,OAAO,MACuC;;;uBAKlD,mBAuBE,SAAA;IAtBC,MAAM,QAAA;IACN,OAAO,QAAA;IACP,aAAa,QAAA;IACb,UAAU,QAAA;IACV,UAAU,QAAA;IACV,cAAc,QAAA;IACd,WAAW,QAAA;IACX,KAAK,QAAA;IACL,KAAK,QAAA;IACL,MAAM,QAAA;IACN,gBAAc,QAAA,SAAS,KAAA;IACvB,oBAAkB,QAAA,mBAAmB,KAAA;IACrC,OAAK,eAAA;;oBAA6C,QAAA;KAAc,QAAA,QAAK,sBAAA;KAAmC,QAAA,WAAQ,yBAAA;;IAMhH,SAAO;IACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,SAAU,OAAM;IAC3B,QAAI,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,QAAS,OAAM;IACzB,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,WAAY,OAAM;;;;;;;AC9DpC,SAAgB,qBAGd,QAAmC;AACnC,KAAI,OAAO,WAAW,SAAU,QAAO;AAEvC,QAAO;EACL,OAAO;EACP,OAAO,OAAO,OAAO;EACtB;;AAGH,SAAgB,qBAGd,SAAoB,OAAoC;AACxD,QAAO,QAAQ,MAAK,WAAU,OAAO,OAAO,MAAM,KAAK,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEL/D,MAAM,QAAQ;EAMd,MAAM,OAAO;EAIb,MAAM,oBAAoB,eACxB,MAAM,QAAQ,IAAI,qBAAoB,CACxC;EAEA,SAAS,aAAa,OAAc;GAClC,MAAM,SAAS,MAAM;AAErB,QAAK,qBADU,qBAAqB,kBAAkB,OAAO,OAAO,MAAK,EACvC,SAAS,OAAO,MAAK;;;uBAKvD,mBA+BM,OA/BN,YA+BM,CA9BJ,mBAwBS,UAAA;IAvBN,OAAO,QAAA;IACP,UAAU,QAAA;IACV,gBAAc,QAAA,SAAS,KAAA;IACvB,oBAAkB,QAAA,mBAAmB,KAAA;IACrC,OAAK,eAAA;;8BAAqE,QAAA;KAAgB,QAAA,QAAK,gCAAA;KAA+C,QAAA,WAAQ,mCAAA;;IAMtJ,UAAQ;OAEK,QAAA,eAAA,WAAA,EAAd,mBAES,UAFT,YAES,gBADJ,QAAA,YAAW,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,GAAA,UAAA,KAAA,EAEhB,mBAOS,UAAA,MAAA,WANU,kBAAA,QAAV,WAAM;wBADf,mBAOS,UAAA;KALN,KAAK,OAAO,OAAO,MAAK;KACxB,OAAO,OAAO;KACd,UAAU,OAAO;uBAEf,OAAO,MAAK,EAAA,GAAA,WAAA;0DAGnB,mBAIM,OAAA,EAJD,OAAM,qBAAmB,EAAA,CAC5B,mBAEM,OAAA;IAFD,MAAK;IAAO,QAAO;IAAe,gBAAa;IAAI,kBAAe;IAAQ,mBAAgB;IAAQ,SAAQ;OAC7G,mBAAyB,QAAA,EAAnB,GAAE,gBAAc,CAAA,CAAA,CAAA,CAAA,EAAA,GAAA,EAAA,CAAA"}