@otl-core/forms 1.1.19 → 1.1.21

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 (43) hide show
  1. package/dist/form-context.cjs +99 -0
  2. package/dist/form-context.cjs.map +1 -0
  3. package/dist/form-context.d.cts +55 -0
  4. package/dist/form-context.d.ts +55 -0
  5. package/dist/form-context.js +80 -0
  6. package/dist/form-context.js.map +1 -0
  7. package/dist/index.cjs +25 -943
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.cts +6 -84
  10. package/dist/index.d.ts +6 -84
  11. package/dist/index.js +3 -939
  12. package/dist/index.js.map +1 -1
  13. package/dist/use-form-action.cjs +281 -0
  14. package/dist/use-form-action.cjs.map +1 -0
  15. package/dist/use-form-action.d.cts +12 -0
  16. package/dist/use-form-action.d.ts +12 -0
  17. package/dist/use-form-action.js +264 -0
  18. package/dist/use-form-action.js.map +1 -0
  19. package/dist/use-form-field.cjs +181 -0
  20. package/dist/use-form-field.cjs.map +1 -0
  21. package/dist/use-form-field.d.cts +19 -0
  22. package/dist/use-form-field.d.ts +19 -0
  23. package/dist/use-form-field.js +160 -0
  24. package/dist/use-form-field.js.map +1 -0
  25. package/dist/utils/page.utils.cjs +76 -0
  26. package/dist/utils/page.utils.cjs.map +1 -0
  27. package/dist/utils/page.utils.d.cts +7 -0
  28. package/dist/utils/page.utils.d.ts +7 -0
  29. package/dist/utils/page.utils.js +50 -0
  30. package/dist/utils/page.utils.js.map +1 -0
  31. package/dist/utils/rule.utils.cjs +94 -0
  32. package/dist/utils/rule.utils.cjs.map +1 -0
  33. package/dist/utils/rule.utils.d.cts +6 -0
  34. package/dist/utils/rule.utils.d.ts +6 -0
  35. package/dist/utils/rule.utils.js +69 -0
  36. package/dist/utils/rule.utils.js.map +1 -0
  37. package/dist/utils/validation.utils.cjs +391 -0
  38. package/dist/utils/validation.utils.cjs.map +1 -0
  39. package/dist/utils/validation.utils.d.cts +15 -0
  40. package/dist/utils/validation.utils.d.ts +15 -0
  41. package/dist/utils/validation.utils.js +366 -0
  42. package/dist/utils/validation.utils.js.map +1 -0
  43. package/package.json +2 -2
@@ -0,0 +1,160 @@
1
+ "use client";
2
+ import { useCallback, useMemo } from "react";
3
+ import { useForm } from "./form-context";
4
+ import { findBlockInDocument } from "./utils/page.utils";
5
+ import {
6
+ evaluateDisabledRules,
7
+ evaluateVisibilityRules
8
+ } from "./utils/rule.utils";
9
+ import { validateField } from "./utils/validation.utils";
10
+ function useFormField(id) {
11
+ const {
12
+ formId,
13
+ document,
14
+ settings,
15
+ loading,
16
+ formValues,
17
+ setFormValues,
18
+ errors,
19
+ setErrors,
20
+ analyticsSettings,
21
+ onAnalyticsEvent,
22
+ formName,
23
+ hasStarted,
24
+ setHasStarted
25
+ } = useForm();
26
+ const block = useMemo(() => {
27
+ return findBlockInDocument(id, document);
28
+ }, [document, id]);
29
+ const fieldId = useMemo(() => {
30
+ if (!block) return null;
31
+ return typeof block.config.field_id === "string" ? block.config.field_id : block.id;
32
+ }, [block]);
33
+ const initialValue = useMemo(() => {
34
+ if (!block) {
35
+ return void 0;
36
+ }
37
+ if (typeof block.config.initialValue === "string") {
38
+ return String(block.config.initialValue);
39
+ } else if (typeof block.config.initialValue === "number") {
40
+ return Number(block.config.initialValue);
41
+ } else if (typeof block.config.initialValue === "boolean") {
42
+ return Boolean(block.config.initialValue);
43
+ }
44
+ if (block.config.initialValue !== void 0) {
45
+ return block.config.initialValue;
46
+ }
47
+ return void 0;
48
+ }, [block]);
49
+ const value = useMemo(() => {
50
+ if (!fieldId) {
51
+ return void 0;
52
+ }
53
+ return formValues[fieldId] ?? initialValue;
54
+ }, [fieldId, formValues, initialValue]);
55
+ const setValue = useCallback(
56
+ (value2) => {
57
+ if (!fieldId) {
58
+ return;
59
+ }
60
+ setFormValues((prev) => ({ ...prev, [fieldId]: value2 }));
61
+ setErrors((prev) => {
62
+ if (!prev || !prev[fieldId]) return prev;
63
+ const { [fieldId]: _, ...rest } = prev;
64
+ return Object.keys(rest).length > 0 ? rest : null;
65
+ });
66
+ if (!hasStarted && analyticsSettings?.track_form_start && onAnalyticsEvent) {
67
+ setHasStarted(true);
68
+ onAnalyticsEvent("form_start", {
69
+ form_id: formId,
70
+ form_name: formName
71
+ });
72
+ }
73
+ },
74
+ [
75
+ fieldId,
76
+ setFormValues,
77
+ setErrors,
78
+ hasStarted,
79
+ setHasStarted,
80
+ analyticsSettings,
81
+ onAnalyticsEvent,
82
+ formId,
83
+ formName
84
+ ]
85
+ );
86
+ const handleBlur = useCallback(() => {
87
+ if (!(settings.validate_on_blur ?? false) || !block || !fieldId) {
88
+ return;
89
+ }
90
+ const currentValue = formValues[fieldId] ?? initialValue;
91
+ const error = validateField(block, currentValue, settings);
92
+ if (error) {
93
+ setErrors((prev) => ({ ...prev, [fieldId]: error }));
94
+ } else {
95
+ setErrors((prev) => {
96
+ if (!prev || !prev[fieldId]) return prev;
97
+ const { [fieldId]: _, ...rest } = prev;
98
+ return Object.keys(rest).length > 0 ? rest : null;
99
+ });
100
+ }
101
+ }, [settings, block, fieldId, formValues, initialValue, setErrors]);
102
+ const display = useMemo(() => {
103
+ if (!block) {
104
+ return "none";
105
+ }
106
+ const rules = block.config.advanced_options?.rules;
107
+ if (!rules) {
108
+ return "block";
109
+ }
110
+ return evaluateVisibilityRules(rules, formValues);
111
+ }, [block, formValues]);
112
+ const disabled = useMemo(() => {
113
+ if (!block) {
114
+ return false;
115
+ }
116
+ if (loading) {
117
+ return true;
118
+ }
119
+ if (typeof block.config.disabled === "boolean" && block.config.disabled) {
120
+ return block.config.disabled;
121
+ }
122
+ const rules = block.config.advanced_options?.rules;
123
+ if (!rules) {
124
+ return false;
125
+ }
126
+ return evaluateDisabledRules(rules, formValues);
127
+ }, [block, formValues, loading]);
128
+ if (!block || !fieldId) {
129
+ return null;
130
+ }
131
+ return {
132
+ name: fieldId,
133
+ label: typeof block.config.label === "string" ? block.config.label : "",
134
+ type: typeof block.config.input_type === "string" ? block.config.input_type : typeof block.config.type === "string" ? block.config.type : "",
135
+ helperText: typeof block.config.help_text === "string" ? block.config.help_text : typeof block.config.helperText === "string" ? block.config.helperText : "",
136
+ placeholder: typeof block.config.placeholder === "string" ? block.config.placeholder : null,
137
+ additionalSettings: {
138
+ rows: typeof block.config.rows === "number" ? block.config.rows : void 0,
139
+ options: block.config.options || void 0,
140
+ multiple: typeof block.config.multiple === "boolean" ? block.config.multiple : void 0,
141
+ min: typeof block.config.min === "number" ? block.config.min : void 0,
142
+ max: typeof block.config.max === "number" ? block.config.max : void 0,
143
+ step: typeof block.config.step === "number" ? block.config.step : void 0,
144
+ blocks: block.config.blocks || void 0,
145
+ gap: block.config.gap || void 0
146
+ },
147
+ loading,
148
+ disabled,
149
+ display,
150
+ required: typeof block.config.required === "boolean" ? block.config.required : false,
151
+ error: errors?.[fieldId] || errors?.[block.id] || void 0,
152
+ value,
153
+ onChange: setValue,
154
+ onBlur: handleBlur
155
+ };
156
+ }
157
+ export {
158
+ useFormField
159
+ };
160
+ //# sourceMappingURL=use-form-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/use-form-field.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BlockInstance, FormAdvancedOptions } from \"@otl-core/cms-types\";\nimport { useCallback, useMemo } from \"react\";\nimport { useForm } from \"./form-context\";\nimport { findBlockInDocument } from \"./utils/page.utils\";\nimport {\n evaluateDisabledRules,\n evaluateVisibilityRules,\n} from \"./utils/rule.utils\";\nimport { validateField } from \"./utils/validation.utils\";\n\ninterface FormField<T> {\n name: string;\n label: string;\n type: string;\n helperText: string;\n placeholder: string | null;\n additionalSettings: Record<string, unknown>;\n\n loading: boolean;\n\n display: \"block\" | \"none\";\n required: boolean;\n disabled: boolean;\n error?: string;\n\n value: T;\n onChange: React.Dispatch<React.SetStateAction<T>>;\n onBlur: () => void;\n}\n\nexport function useFormField<T>(id: string): FormField<T> | null {\n const {\n formId,\n document,\n settings,\n loading,\n formValues,\n setFormValues,\n errors,\n setErrors,\n analyticsSettings,\n onAnalyticsEvent,\n formName,\n hasStarted,\n setHasStarted,\n } = useForm();\n\n const block: BlockInstance | null = useMemo(() => {\n return findBlockInDocument(id, document);\n }, [document, id]);\n\n const fieldId = useMemo(() => {\n if (!block) return null;\n return typeof block.config.field_id === \"string\"\n ? block.config.field_id\n : block.id;\n }, [block]);\n\n const initialValue: T | undefined = useMemo(() => {\n if (!block) {\n return undefined;\n }\n\n if (typeof block.config.initialValue === \"string\") {\n return String(block.config.initialValue) as T;\n } else if (typeof block.config.initialValue === \"number\") {\n return Number(block.config.initialValue) as T;\n } else if (typeof block.config.initialValue === \"boolean\") {\n return Boolean(block.config.initialValue) as T;\n }\n\n if (block.config.initialValue !== undefined) {\n return block.config.initialValue as T;\n }\n\n return undefined;\n }, [block]);\n\n const value = useMemo<T | undefined>(() => {\n if (!fieldId) {\n return undefined;\n }\n return (formValues[fieldId] as T) ?? initialValue;\n }, [fieldId, formValues, initialValue]);\n\n const setValue = useCallback(\n (value: T) => {\n if (!fieldId) {\n return;\n }\n setFormValues((prev) => ({ ...prev, [fieldId]: value }));\n // Clear error for this field when value changes\n setErrors((prev) => {\n if (!prev || !prev[fieldId]) return prev;\n const { [fieldId]: _, ...rest } = prev;\n return Object.keys(rest).length > 0 ? rest : null;\n });\n\n // Emit form_start on first interaction\n if (\n !hasStarted &&\n analyticsSettings?.track_form_start &&\n onAnalyticsEvent\n ) {\n setHasStarted(true);\n onAnalyticsEvent(\"form_start\", {\n form_id: formId,\n form_name: formName,\n });\n }\n },\n [\n fieldId,\n setFormValues,\n setErrors,\n hasStarted,\n setHasStarted,\n analyticsSettings,\n onAnalyticsEvent,\n formId,\n formName,\n ],\n );\n\n const handleBlur = useCallback(() => {\n // Only validate on blur if the setting is enabled\n if (!(settings.validate_on_blur ?? false) || !block || !fieldId) {\n return;\n }\n\n const currentValue = formValues[fieldId] ?? initialValue;\n const error = validateField(block, currentValue, settings);\n\n if (error) {\n setErrors((prev) => ({ ...prev, [fieldId]: error }));\n } else {\n // Clear error if validation passes\n setErrors((prev) => {\n if (!prev || !prev[fieldId]) return prev;\n const { [fieldId]: _, ...rest } = prev;\n return Object.keys(rest).length > 0 ? rest : null;\n });\n }\n }, [settings, block, fieldId, formValues, initialValue, setErrors]);\n\n const display: \"block\" | \"none\" = useMemo(() => {\n if (!block) {\n return \"none\";\n }\n\n // check logic\n const rules = (block.config.advanced_options as FormAdvancedOptions)?.rules;\n if (!rules) {\n return \"block\";\n }\n\n return evaluateVisibilityRules(rules, formValues);\n }, [block, formValues]);\n\n const disabled: boolean = useMemo(() => {\n if (!block) {\n return false;\n }\n\n if (loading) {\n return true;\n }\n\n if (typeof block.config.disabled === \"boolean\" && block.config.disabled) {\n return block.config.disabled;\n }\n\n // check logic\n const rules = (block.config.advanced_options as FormAdvancedOptions)?.rules;\n if (!rules) {\n return false;\n }\n\n return evaluateDisabledRules(rules, formValues);\n }, [block, formValues, loading]);\n\n if (!block || !fieldId) {\n return null;\n }\n\n return {\n name: fieldId,\n label: typeof block.config.label === \"string\" ? block.config.label : \"\",\n type:\n typeof block.config.input_type === \"string\"\n ? block.config.input_type\n : typeof block.config.type === \"string\"\n ? block.config.type\n : \"\",\n helperText:\n typeof block.config.help_text === \"string\"\n ? block.config.help_text\n : typeof block.config.helperText === \"string\"\n ? block.config.helperText\n : \"\",\n placeholder:\n typeof block.config.placeholder === \"string\"\n ? block.config.placeholder\n : null,\n\n additionalSettings: {\n rows:\n typeof block.config.rows === \"number\" ? block.config.rows : undefined,\n options: block.config.options || undefined,\n multiple:\n typeof block.config.multiple === \"boolean\"\n ? block.config.multiple\n : undefined,\n min: typeof block.config.min === \"number\" ? block.config.min : undefined,\n max: typeof block.config.max === \"number\" ? block.config.max : undefined,\n step:\n typeof block.config.step === \"number\" ? block.config.step : undefined,\n blocks: block.config.blocks || undefined,\n gap: block.config.gap || undefined,\n },\n\n loading,\n\n disabled,\n display,\n required:\n typeof block.config.required === \"boolean\"\n ? block.config.required\n : false,\n error: errors?.[fieldId] || errors?.[block.id] || undefined,\n\n value: value as T,\n onChange: setValue as React.Dispatch<React.SetStateAction<T>>,\n onBlur: handleBlur,\n };\n}\n"],"mappings":"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","names":["value"]}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var page_utils_exports = {};
20
+ __export(page_utils_exports, {
21
+ findBlockInDocument: () => findBlockInDocument,
22
+ getNextPage: () => getNextPage,
23
+ getPreviousPage: () => getPreviousPage
24
+ });
25
+ module.exports = __toCommonJS(page_utils_exports);
26
+ function getPreviousPage(currentPage, formDocument) {
27
+ const index = formDocument.pages.findIndex(
28
+ (page) => page.id === currentPage.id
29
+ );
30
+ if (index === 0) {
31
+ return null;
32
+ }
33
+ return formDocument.pages[index - 1];
34
+ }
35
+ function getNextPage(currentPage, formDocument) {
36
+ const index = formDocument.pages.findIndex(
37
+ (page) => page.id === currentPage.id
38
+ );
39
+ if (index === formDocument.pages.length - 1) {
40
+ return null;
41
+ }
42
+ return formDocument.pages[index + 1];
43
+ }
44
+ function findBlockInDocument(blockId, document) {
45
+ for (const page of document.pages) {
46
+ const block = findBlockRecursive(blockId, page.blocks);
47
+ if (block) return block;
48
+ }
49
+ return null;
50
+ }
51
+ function findBlockRecursive(blockId, blocks) {
52
+ for (const block of blocks) {
53
+ if (block.id === blockId) {
54
+ return block;
55
+ }
56
+ if (block.config.blocks && Array.isArray(block.config.blocks)) {
57
+ const nestedBlocks = block.config.blocks.map(
58
+ (b) => ({
59
+ id: b.id,
60
+ type: b.type,
61
+ config: b.config || {}
62
+ })
63
+ );
64
+ const found = findBlockRecursive(blockId, nestedBlocks);
65
+ if (found) return found;
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ // Annotate the CommonJS export names for ESM import in node:
71
+ 0 && (module.exports = {
72
+ findBlockInDocument,
73
+ getNextPage,
74
+ getPreviousPage
75
+ });
76
+ //# sourceMappingURL=page.utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/page.utils.ts"],"sourcesContent":["import { BlockInstance, FormDocument, FormPage } from \"@otl-core/cms-types\";\n\nexport function getPreviousPage(\n currentPage: FormPage,\n formDocument: FormDocument,\n) {\n const index = formDocument.pages.findIndex(\n (page) => page.id === currentPage.id,\n );\n if (index === 0) {\n return null;\n }\n return formDocument.pages[index - 1];\n}\n\nexport function getNextPage(currentPage: FormPage, formDocument: FormDocument) {\n const index = formDocument.pages.findIndex(\n (page) => page.id === currentPage.id,\n );\n if (index === formDocument.pages.length - 1) {\n return null;\n }\n return formDocument.pages[index + 1];\n}\n\nexport function findBlockInDocument(\n blockId: string,\n document: FormDocument,\n): BlockInstance | null {\n for (const page of document.pages) {\n const block = findBlockRecursive(blockId, page.blocks);\n if (block) return block;\n }\n return null;\n}\n\nfunction findBlockRecursive(\n blockId: string,\n blocks: BlockInstance[],\n): BlockInstance | null {\n for (const block of blocks) {\n if (block.id === blockId) {\n return block;\n }\n\n // Check nested blocks (e.g., in form-inline-group)\n if (block.config.blocks && Array.isArray(block.config.blocks)) {\n const nestedBlocks = block.config.blocks.map(\n (b) =>\n ({\n id: b.id,\n type: b.type,\n config: b.config || {},\n }) as BlockInstance,\n );\n\n const found = findBlockRecursive(blockId, nestedBlocks);\n if (found) return found;\n }\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,SAAS,gBACd,aACA,cACA;AACA,QAAM,QAAQ,aAAa,MAAM;AAAA,IAC/B,CAAC,SAAS,KAAK,OAAO,YAAY;AAAA,EACpC;AACA,MAAI,UAAU,GAAG;AACf,WAAO;AAAA,EACT;AACA,SAAO,aAAa,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,YAAY,aAAuB,cAA4B;AAC7E,QAAM,QAAQ,aAAa,MAAM;AAAA,IAC/B,CAAC,SAAS,KAAK,OAAO,YAAY;AAAA,EACpC;AACA,MAAI,UAAU,aAAa,MAAM,SAAS,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,SAAO,aAAa,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,oBACd,SACA,UACsB;AACtB,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,QAAQ,mBAAmB,SAAS,KAAK,MAAM;AACrD,QAAI,MAAO,QAAO;AAAA,EACpB;AACA,SAAO;AACT;AAEA,SAAS,mBACP,SACA,QACsB;AACtB,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,OAAO,SAAS;AACxB,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,OAAO,UAAU,MAAM,QAAQ,MAAM,OAAO,MAAM,GAAG;AAC7D,YAAM,eAAe,MAAM,OAAO,OAAO;AAAA,QACvC,CAAC,OACE;AAAA,UACC,IAAI,EAAE;AAAA,UACN,MAAM,EAAE;AAAA,UACR,QAAQ,EAAE,UAAU,CAAC;AAAA,QACvB;AAAA,MACJ;AAEA,YAAM,QAAQ,mBAAmB,SAAS,YAAY;AACtD,UAAI,MAAO,QAAO;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,7 @@
1
+ import { FormDocument, BlockInstance, FormPage } from '@otl-core/cms-types';
2
+
3
+ declare function getPreviousPage(currentPage: FormPage, formDocument: FormDocument): FormPage | null;
4
+ declare function getNextPage(currentPage: FormPage, formDocument: FormDocument): FormPage | null;
5
+ declare function findBlockInDocument(blockId: string, document: FormDocument): BlockInstance | null;
6
+
7
+ export { findBlockInDocument, getNextPage, getPreviousPage };
@@ -0,0 +1,7 @@
1
+ import { FormDocument, BlockInstance, FormPage } from '@otl-core/cms-types';
2
+
3
+ declare function getPreviousPage(currentPage: FormPage, formDocument: FormDocument): FormPage | null;
4
+ declare function getNextPage(currentPage: FormPage, formDocument: FormDocument): FormPage | null;
5
+ declare function findBlockInDocument(blockId: string, document: FormDocument): BlockInstance | null;
6
+
7
+ export { findBlockInDocument, getNextPage, getPreviousPage };
@@ -0,0 +1,50 @@
1
+ function getPreviousPage(currentPage, formDocument) {
2
+ const index = formDocument.pages.findIndex(
3
+ (page) => page.id === currentPage.id
4
+ );
5
+ if (index === 0) {
6
+ return null;
7
+ }
8
+ return formDocument.pages[index - 1];
9
+ }
10
+ function getNextPage(currentPage, formDocument) {
11
+ const index = formDocument.pages.findIndex(
12
+ (page) => page.id === currentPage.id
13
+ );
14
+ if (index === formDocument.pages.length - 1) {
15
+ return null;
16
+ }
17
+ return formDocument.pages[index + 1];
18
+ }
19
+ function findBlockInDocument(blockId, document) {
20
+ for (const page of document.pages) {
21
+ const block = findBlockRecursive(blockId, page.blocks);
22
+ if (block) return block;
23
+ }
24
+ return null;
25
+ }
26
+ function findBlockRecursive(blockId, blocks) {
27
+ for (const block of blocks) {
28
+ if (block.id === blockId) {
29
+ return block;
30
+ }
31
+ if (block.config.blocks && Array.isArray(block.config.blocks)) {
32
+ const nestedBlocks = block.config.blocks.map(
33
+ (b) => ({
34
+ id: b.id,
35
+ type: b.type,
36
+ config: b.config || {}
37
+ })
38
+ );
39
+ const found = findBlockRecursive(blockId, nestedBlocks);
40
+ if (found) return found;
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ export {
46
+ findBlockInDocument,
47
+ getNextPage,
48
+ getPreviousPage
49
+ };
50
+ //# sourceMappingURL=page.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/page.utils.ts"],"sourcesContent":["import { BlockInstance, FormDocument, FormPage } from \"@otl-core/cms-types\";\n\nexport function getPreviousPage(\n currentPage: FormPage,\n formDocument: FormDocument,\n) {\n const index = formDocument.pages.findIndex(\n (page) => page.id === currentPage.id,\n );\n if (index === 0) {\n return null;\n }\n return formDocument.pages[index - 1];\n}\n\nexport function getNextPage(currentPage: FormPage, formDocument: FormDocument) {\n const index = formDocument.pages.findIndex(\n (page) => page.id === currentPage.id,\n );\n if (index === formDocument.pages.length - 1) {\n return null;\n }\n return formDocument.pages[index + 1];\n}\n\nexport function findBlockInDocument(\n blockId: string,\n document: FormDocument,\n): BlockInstance | null {\n for (const page of document.pages) {\n const block = findBlockRecursive(blockId, page.blocks);\n if (block) return block;\n }\n return null;\n}\n\nfunction findBlockRecursive(\n blockId: string,\n blocks: BlockInstance[],\n): BlockInstance | null {\n for (const block of blocks) {\n if (block.id === blockId) {\n return block;\n }\n\n // Check nested blocks (e.g., in form-inline-group)\n if (block.config.blocks && Array.isArray(block.config.blocks)) {\n const nestedBlocks = block.config.blocks.map(\n (b) =>\n ({\n id: b.id,\n type: b.type,\n config: b.config || {},\n }) as BlockInstance,\n );\n\n const found = findBlockRecursive(blockId, nestedBlocks);\n if (found) return found;\n }\n }\n\n return null;\n}\n"],"mappings":"AAEO,SAAS,gBACd,aACA,cACA;AACA,QAAM,QAAQ,aAAa,MAAM;AAAA,IAC/B,CAAC,SAAS,KAAK,OAAO,YAAY;AAAA,EACpC;AACA,MAAI,UAAU,GAAG;AACf,WAAO;AAAA,EACT;AACA,SAAO,aAAa,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,YAAY,aAAuB,cAA4B;AAC7E,QAAM,QAAQ,aAAa,MAAM;AAAA,IAC/B,CAAC,SAAS,KAAK,OAAO,YAAY;AAAA,EACpC;AACA,MAAI,UAAU,aAAa,MAAM,SAAS,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,SAAO,aAAa,MAAM,QAAQ,CAAC;AACrC;AAEO,SAAS,oBACd,SACA,UACsB;AACtB,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,QAAQ,mBAAmB,SAAS,KAAK,MAAM;AACrD,QAAI,MAAO,QAAO;AAAA,EACpB;AACA,SAAO;AACT;AAEA,SAAS,mBACP,SACA,QACsB;AACtB,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,OAAO,SAAS;AACxB,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,OAAO,UAAU,MAAM,QAAQ,MAAM,OAAO,MAAM,GAAG;AAC7D,YAAM,eAAe,MAAM,OAAO,OAAO;AAAA,QACvC,CAAC,OACE;AAAA,UACC,IAAI,EAAE;AAAA,UACN,MAAM,EAAE;AAAA,UACR,QAAQ,EAAE,UAAU,CAAC;AAAA,QACvB;AAAA,MACJ;AAEA,YAAM,QAAQ,mBAAmB,SAAS,YAAY;AACtD,UAAI,MAAO,QAAO;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var rule_utils_exports = {};
20
+ __export(rule_utils_exports, {
21
+ evaluateDisabledRules: () => evaluateDisabledRules,
22
+ evaluateVisibilityRules: () => evaluateVisibilityRules
23
+ });
24
+ module.exports = __toCommonJS(rule_utils_exports);
25
+ function evaluateCondition(operator, fieldValue, ruleValue) {
26
+ switch (operator) {
27
+ case "equals":
28
+ return fieldValue === ruleValue;
29
+ case "not_equals":
30
+ return fieldValue !== ruleValue;
31
+ case "contains":
32
+ return String(fieldValue || "").includes(String(ruleValue));
33
+ case "not_contains":
34
+ return !String(fieldValue || "").includes(String(ruleValue));
35
+ case "starts_with":
36
+ return String(fieldValue || "").startsWith(String(ruleValue));
37
+ case "ends_with":
38
+ return String(fieldValue || "").endsWith(String(ruleValue));
39
+ case "greater_than":
40
+ return Number(fieldValue) > Number(ruleValue);
41
+ case "less_than":
42
+ return Number(fieldValue) < Number(ruleValue);
43
+ case "greater_than_or_equal":
44
+ return Number(fieldValue) >= Number(ruleValue);
45
+ case "less_than_or_equal":
46
+ return Number(fieldValue) <= Number(ruleValue);
47
+ case "is_empty":
48
+ return !fieldValue || fieldValue === "" || Array.isArray(fieldValue) && fieldValue.length === 0;
49
+ case "is_not_empty":
50
+ return !!fieldValue && fieldValue !== "" && (!Array.isArray(fieldValue) || fieldValue.length > 0);
51
+ case "is_checked":
52
+ return fieldValue === true;
53
+ case "is_not_checked":
54
+ return fieldValue !== true;
55
+ case "includes":
56
+ return Array.isArray(fieldValue) && fieldValue.includes(ruleValue);
57
+ case "not_includes":
58
+ return !Array.isArray(fieldValue) || !fieldValue.includes(ruleValue);
59
+ default:
60
+ return false;
61
+ }
62
+ }
63
+ function evaluateVisibilityRules(rules, formValues) {
64
+ const visibilityRules = rules.filter((r) => r.type === "visible_when");
65
+ if (visibilityRules.length === 0) {
66
+ return "block";
67
+ }
68
+ for (const rule of visibilityRules) {
69
+ const fieldValue = formValues[rule.field];
70
+ if (evaluateCondition(rule.operator, fieldValue, rule.value)) {
71
+ return "block";
72
+ }
73
+ }
74
+ return "none";
75
+ }
76
+ function evaluateDisabledRules(rules, formValues) {
77
+ const disabledRules = rules.filter((r) => r.type === "disabled_when");
78
+ if (disabledRules.length === 0) {
79
+ return false;
80
+ }
81
+ for (const rule of disabledRules) {
82
+ const fieldValue = formValues[rule.field];
83
+ if (evaluateCondition(rule.operator, fieldValue, rule.value)) {
84
+ return true;
85
+ }
86
+ }
87
+ return false;
88
+ }
89
+ // Annotate the CommonJS export names for ESM import in node:
90
+ 0 && (module.exports = {
91
+ evaluateDisabledRules,
92
+ evaluateVisibilityRules
93
+ });
94
+ //# sourceMappingURL=rule.utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/rule.utils.ts"],"sourcesContent":["import { ConditionOperator, Rule } from \"@otl-core/cms-types\";\n\nfunction evaluateCondition(\n operator: ConditionOperator,\n fieldValue: unknown,\n ruleValue: unknown,\n): boolean {\n switch (operator) {\n case \"equals\":\n return fieldValue === ruleValue;\n case \"not_equals\":\n return fieldValue !== ruleValue;\n case \"contains\":\n return String(fieldValue || \"\").includes(String(ruleValue));\n case \"not_contains\":\n return !String(fieldValue || \"\").includes(String(ruleValue));\n case \"starts_with\":\n return String(fieldValue || \"\").startsWith(String(ruleValue));\n case \"ends_with\":\n return String(fieldValue || \"\").endsWith(String(ruleValue));\n case \"greater_than\":\n return Number(fieldValue) > Number(ruleValue);\n case \"less_than\":\n return Number(fieldValue) < Number(ruleValue);\n case \"greater_than_or_equal\":\n return Number(fieldValue) >= Number(ruleValue);\n case \"less_than_or_equal\":\n return Number(fieldValue) <= Number(ruleValue);\n case \"is_empty\":\n return (\n !fieldValue ||\n fieldValue === \"\" ||\n (Array.isArray(fieldValue) && fieldValue.length === 0)\n );\n case \"is_not_empty\":\n return (\n !!fieldValue &&\n fieldValue !== \"\" &&\n (!Array.isArray(fieldValue) || fieldValue.length > 0)\n );\n case \"is_checked\":\n return fieldValue === true;\n case \"is_not_checked\":\n return fieldValue !== true;\n case \"includes\":\n return Array.isArray(fieldValue) && fieldValue.includes(ruleValue);\n case \"not_includes\":\n return !Array.isArray(fieldValue) || !fieldValue.includes(ruleValue);\n default:\n return false;\n }\n}\n\nexport function evaluateVisibilityRules(\n rules: Rule[],\n formValues: Record<string, unknown>,\n): \"block\" | \"none\" {\n const visibilityRules = rules.filter((r) => r.type === \"visible_when\");\n\n // If no visibility rules, show by default\n if (visibilityRules.length === 0) {\n return \"block\";\n }\n\n // If any visibility rule matches, show the field\n for (const rule of visibilityRules) {\n const fieldValue = formValues[rule.field];\n if (evaluateCondition(rule.operator, fieldValue, rule.value)) {\n return \"block\";\n }\n }\n\n return \"none\";\n}\n\nexport function evaluateDisabledRules(\n rules: Rule[],\n formValues: Record<string, unknown>,\n): boolean {\n const disabledRules = rules.filter((r) => r.type === \"disabled_when\");\n\n // If no disabled rules, not disabled\n if (disabledRules.length === 0) {\n return false;\n }\n\n // If any disabled rule matches, disable the field\n for (const rule of disabledRules) {\n const fieldValue = formValues[rule.field];\n if (evaluateCondition(rule.operator, fieldValue, rule.value)) {\n return true;\n }\n }\n\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,SAAS,kBACP,UACA,YACA,WACS;AACT,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,OAAO,cAAc,EAAE,EAAE,SAAS,OAAO,SAAS,CAAC;AAAA,IAC5D,KAAK;AACH,aAAO,CAAC,OAAO,cAAc,EAAE,EAAE,SAAS,OAAO,SAAS,CAAC;AAAA,IAC7D,KAAK;AACH,aAAO,OAAO,cAAc,EAAE,EAAE,WAAW,OAAO,SAAS,CAAC;AAAA,IAC9D,KAAK;AACH,aAAO,OAAO,cAAc,EAAE,EAAE,SAAS,OAAO,SAAS,CAAC;AAAA,IAC5D,KAAK;AACH,aAAO,OAAO,UAAU,IAAI,OAAO,SAAS;AAAA,IAC9C,KAAK;AACH,aAAO,OAAO,UAAU,IAAI,OAAO,SAAS;AAAA,IAC9C,KAAK;AACH,aAAO,OAAO,UAAU,KAAK,OAAO,SAAS;AAAA,IAC/C,KAAK;AACH,aAAO,OAAO,UAAU,KAAK,OAAO,SAAS;AAAA,IAC/C,KAAK;AACH,aACE,CAAC,cACD,eAAe,MACd,MAAM,QAAQ,UAAU,KAAK,WAAW,WAAW;AAAA,IAExD,KAAK;AACH,aACE,CAAC,CAAC,cACF,eAAe,OACd,CAAC,MAAM,QAAQ,UAAU,KAAK,WAAW,SAAS;AAAA,IAEvD,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,MAAM,QAAQ,UAAU,KAAK,WAAW,SAAS,SAAS;AAAA,IACnE,KAAK;AACH,aAAO,CAAC,MAAM,QAAQ,UAAU,KAAK,CAAC,WAAW,SAAS,SAAS;AAAA,IACrE;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,wBACd,OACA,YACkB;AAClB,QAAM,kBAAkB,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc;AAGrE,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAGA,aAAW,QAAQ,iBAAiB;AAClC,UAAM,aAAa,WAAW,KAAK,KAAK;AACxC,QAAI,kBAAkB,KAAK,UAAU,YAAY,KAAK,KAAK,GAAG;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,sBACd,OACA,YACS;AACT,QAAM,gBAAgB,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,eAAe;AAGpE,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,EACT;AAGA,aAAW,QAAQ,eAAe;AAChC,UAAM,aAAa,WAAW,KAAK,KAAK;AACxC,QAAI,kBAAkB,KAAK,UAAU,YAAY,KAAK,KAAK,GAAG;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,6 @@
1
+ import { Rule } from '@otl-core/cms-types';
2
+
3
+ declare function evaluateVisibilityRules(rules: Rule[], formValues: Record<string, unknown>): "block" | "none";
4
+ declare function evaluateDisabledRules(rules: Rule[], formValues: Record<string, unknown>): boolean;
5
+
6
+ export { evaluateDisabledRules, evaluateVisibilityRules };
@@ -0,0 +1,6 @@
1
+ import { Rule } from '@otl-core/cms-types';
2
+
3
+ declare function evaluateVisibilityRules(rules: Rule[], formValues: Record<string, unknown>): "block" | "none";
4
+ declare function evaluateDisabledRules(rules: Rule[], formValues: Record<string, unknown>): boolean;
5
+
6
+ export { evaluateDisabledRules, evaluateVisibilityRules };
@@ -0,0 +1,69 @@
1
+ function evaluateCondition(operator, fieldValue, ruleValue) {
2
+ switch (operator) {
3
+ case "equals":
4
+ return fieldValue === ruleValue;
5
+ case "not_equals":
6
+ return fieldValue !== ruleValue;
7
+ case "contains":
8
+ return String(fieldValue || "").includes(String(ruleValue));
9
+ case "not_contains":
10
+ return !String(fieldValue || "").includes(String(ruleValue));
11
+ case "starts_with":
12
+ return String(fieldValue || "").startsWith(String(ruleValue));
13
+ case "ends_with":
14
+ return String(fieldValue || "").endsWith(String(ruleValue));
15
+ case "greater_than":
16
+ return Number(fieldValue) > Number(ruleValue);
17
+ case "less_than":
18
+ return Number(fieldValue) < Number(ruleValue);
19
+ case "greater_than_or_equal":
20
+ return Number(fieldValue) >= Number(ruleValue);
21
+ case "less_than_or_equal":
22
+ return Number(fieldValue) <= Number(ruleValue);
23
+ case "is_empty":
24
+ return !fieldValue || fieldValue === "" || Array.isArray(fieldValue) && fieldValue.length === 0;
25
+ case "is_not_empty":
26
+ return !!fieldValue && fieldValue !== "" && (!Array.isArray(fieldValue) || fieldValue.length > 0);
27
+ case "is_checked":
28
+ return fieldValue === true;
29
+ case "is_not_checked":
30
+ return fieldValue !== true;
31
+ case "includes":
32
+ return Array.isArray(fieldValue) && fieldValue.includes(ruleValue);
33
+ case "not_includes":
34
+ return !Array.isArray(fieldValue) || !fieldValue.includes(ruleValue);
35
+ default:
36
+ return false;
37
+ }
38
+ }
39
+ function evaluateVisibilityRules(rules, formValues) {
40
+ const visibilityRules = rules.filter((r) => r.type === "visible_when");
41
+ if (visibilityRules.length === 0) {
42
+ return "block";
43
+ }
44
+ for (const rule of visibilityRules) {
45
+ const fieldValue = formValues[rule.field];
46
+ if (evaluateCondition(rule.operator, fieldValue, rule.value)) {
47
+ return "block";
48
+ }
49
+ }
50
+ return "none";
51
+ }
52
+ function evaluateDisabledRules(rules, formValues) {
53
+ const disabledRules = rules.filter((r) => r.type === "disabled_when");
54
+ if (disabledRules.length === 0) {
55
+ return false;
56
+ }
57
+ for (const rule of disabledRules) {
58
+ const fieldValue = formValues[rule.field];
59
+ if (evaluateCondition(rule.operator, fieldValue, rule.value)) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+ export {
66
+ evaluateDisabledRules,
67
+ evaluateVisibilityRules
68
+ };
69
+ //# sourceMappingURL=rule.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/rule.utils.ts"],"sourcesContent":["import { ConditionOperator, Rule } from \"@otl-core/cms-types\";\n\nfunction evaluateCondition(\n operator: ConditionOperator,\n fieldValue: unknown,\n ruleValue: unknown,\n): boolean {\n switch (operator) {\n case \"equals\":\n return fieldValue === ruleValue;\n case \"not_equals\":\n return fieldValue !== ruleValue;\n case \"contains\":\n return String(fieldValue || \"\").includes(String(ruleValue));\n case \"not_contains\":\n return !String(fieldValue || \"\").includes(String(ruleValue));\n case \"starts_with\":\n return String(fieldValue || \"\").startsWith(String(ruleValue));\n case \"ends_with\":\n return String(fieldValue || \"\").endsWith(String(ruleValue));\n case \"greater_than\":\n return Number(fieldValue) > Number(ruleValue);\n case \"less_than\":\n return Number(fieldValue) < Number(ruleValue);\n case \"greater_than_or_equal\":\n return Number(fieldValue) >= Number(ruleValue);\n case \"less_than_or_equal\":\n return Number(fieldValue) <= Number(ruleValue);\n case \"is_empty\":\n return (\n !fieldValue ||\n fieldValue === \"\" ||\n (Array.isArray(fieldValue) && fieldValue.length === 0)\n );\n case \"is_not_empty\":\n return (\n !!fieldValue &&\n fieldValue !== \"\" &&\n (!Array.isArray(fieldValue) || fieldValue.length > 0)\n );\n case \"is_checked\":\n return fieldValue === true;\n case \"is_not_checked\":\n return fieldValue !== true;\n case \"includes\":\n return Array.isArray(fieldValue) && fieldValue.includes(ruleValue);\n case \"not_includes\":\n return !Array.isArray(fieldValue) || !fieldValue.includes(ruleValue);\n default:\n return false;\n }\n}\n\nexport function evaluateVisibilityRules(\n rules: Rule[],\n formValues: Record<string, unknown>,\n): \"block\" | \"none\" {\n const visibilityRules = rules.filter((r) => r.type === \"visible_when\");\n\n // If no visibility rules, show by default\n if (visibilityRules.length === 0) {\n return \"block\";\n }\n\n // If any visibility rule matches, show the field\n for (const rule of visibilityRules) {\n const fieldValue = formValues[rule.field];\n if (evaluateCondition(rule.operator, fieldValue, rule.value)) {\n return \"block\";\n }\n }\n\n return \"none\";\n}\n\nexport function evaluateDisabledRules(\n rules: Rule[],\n formValues: Record<string, unknown>,\n): boolean {\n const disabledRules = rules.filter((r) => r.type === \"disabled_when\");\n\n // If no disabled rules, not disabled\n if (disabledRules.length === 0) {\n return false;\n }\n\n // If any disabled rule matches, disable the field\n for (const rule of disabledRules) {\n const fieldValue = formValues[rule.field];\n if (evaluateCondition(rule.operator, fieldValue, rule.value)) {\n return true;\n }\n }\n\n return false;\n}\n"],"mappings":"AAEA,SAAS,kBACP,UACA,YACA,WACS;AACT,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,OAAO,cAAc,EAAE,EAAE,SAAS,OAAO,SAAS,CAAC;AAAA,IAC5D,KAAK;AACH,aAAO,CAAC,OAAO,cAAc,EAAE,EAAE,SAAS,OAAO,SAAS,CAAC;AAAA,IAC7D,KAAK;AACH,aAAO,OAAO,cAAc,EAAE,EAAE,WAAW,OAAO,SAAS,CAAC;AAAA,IAC9D,KAAK;AACH,aAAO,OAAO,cAAc,EAAE,EAAE,SAAS,OAAO,SAAS,CAAC;AAAA,IAC5D,KAAK;AACH,aAAO,OAAO,UAAU,IAAI,OAAO,SAAS;AAAA,IAC9C,KAAK;AACH,aAAO,OAAO,UAAU,IAAI,OAAO,SAAS;AAAA,IAC9C,KAAK;AACH,aAAO,OAAO,UAAU,KAAK,OAAO,SAAS;AAAA,IAC/C,KAAK;AACH,aAAO,OAAO,UAAU,KAAK,OAAO,SAAS;AAAA,IAC/C,KAAK;AACH,aACE,CAAC,cACD,eAAe,MACd,MAAM,QAAQ,UAAU,KAAK,WAAW,WAAW;AAAA,IAExD,KAAK;AACH,aACE,CAAC,CAAC,cACF,eAAe,OACd,CAAC,MAAM,QAAQ,UAAU,KAAK,WAAW,SAAS;AAAA,IAEvD,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,eAAe;AAAA,IACxB,KAAK;AACH,aAAO,MAAM,QAAQ,UAAU,KAAK,WAAW,SAAS,SAAS;AAAA,IACnE,KAAK;AACH,aAAO,CAAC,MAAM,QAAQ,UAAU,KAAK,CAAC,WAAW,SAAS,SAAS;AAAA,IACrE;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,wBACd,OACA,YACkB;AAClB,QAAM,kBAAkB,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc;AAGrE,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,EACT;AAGA,aAAW,QAAQ,iBAAiB;AAClC,UAAM,aAAa,WAAW,KAAK,KAAK;AACxC,QAAI,kBAAkB,KAAK,UAAU,YAAY,KAAK,KAAK,GAAG;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,sBACd,OACA,YACS;AACT,QAAM,gBAAgB,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,eAAe;AAGpE,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,EACT;AAGA,aAAW,QAAQ,eAAe;AAChC,UAAM,aAAa,WAAW,KAAK,KAAK;AACxC,QAAI,kBAAkB,KAAK,UAAU,YAAY,KAAK,KAAK,GAAG;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}