@bach.software/vue-dynamic-form 0.7.0 → 0.8.0

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 (31) hide show
  1. package/dist/examples.cjs.js +8 -8
  2. package/dist/examples.cjs.js.map +1 -1
  3. package/dist/examples.es.js +689 -542
  4. package/dist/examples.es.js.map +1 -1
  5. package/dist/mapEachMetadataItem-CZmoxEoA.js +1234 -0
  6. package/dist/mapEachMetadataItem-CZmoxEoA.js.map +1 -0
  7. package/dist/mapEachMetadataItem-Dw1U9jf2.cjs +2 -0
  8. package/dist/mapEachMetadataItem-Dw1U9jf2.cjs.map +1 -0
  9. package/dist/src/components/__tests__/DynamicFormItem.test-helpers.d.ts +8 -0
  10. package/dist/src/components/__tests__/DynamicFormItemArray.test-helpers.d.ts +2 -0
  11. package/dist/src/components/__tests__/DynamicFormItemChoice.test-helpers.d.ts +9 -0
  12. package/dist/src/examples/__tests__/TestFormTemplate.testcases.d.ts +233 -0
  13. package/dist/src/index.d.ts +1 -0
  14. package/dist/src/types/FieldMetadata.d.ts +32 -1
  15. package/dist/src/utils/__tests__/deepEqual.test.d.ts +1 -0
  16. package/dist/src/utils/__tests__/hashField.test.d.ts +1 -0
  17. package/dist/src/utils/__tests__/isPathInSection.test.d.ts +1 -0
  18. package/dist/src/utils/buildRestrictionValidations.d.ts +11 -0
  19. package/dist/src/utils/deepEqual.d.ts +9 -0
  20. package/dist/src/utils/isPathInSection.d.ts +9 -0
  21. package/dist/src/utils/removeNullValues.d.ts +4 -0
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/dist/vue-dynamic-form.cjs.js +1 -1
  24. package/dist/vue-dynamic-form.cjs.js.map +1 -1
  25. package/dist/vue-dynamic-form.es.js +22 -21
  26. package/dist/vue-dynamic-form.es.js.map +1 -1
  27. package/package.json +2 -1
  28. package/dist/mapEachMetadataItem-DwSDJyzo.cjs +0 -2
  29. package/dist/mapEachMetadataItem-DwSDJyzo.cjs.map +0 -1
  30. package/dist/mapEachMetadataItem-DxEO1PDs.js +0 -1186
  31. package/dist/mapEachMetadataItem-DxEO1PDs.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"mapEachMetadataItem-DxEO1PDs.js","sources":["../src/core/useFieldArrayExtended.ts","../src/core/useIsResetPending.ts","../src/core/useIsValidationSuppressed.ts","../src/types/DynamicFormSettings.ts","../../../node_modules/.pnpm/@vee-validate+rules@4.15.1_vue@3.5.44_typescript@5.9.2_/node_modules/@vee-validate/rules/dist/vee-validate-rules.mjs","../src/utils/checkTreeHasValue.ts","../src/utils/resolveMessage.ts","../src/core/validation.ts","../src/utils/getFieldLabel.ts","../src/utils/createValidation.ts","../src/utils/normalizePath.ts","../src/utils/overridePath.ts","../src/utils/splitValidationFunctions.ts","../src/components/DynamicFormItemArray.vue","../src/utils/deepCloneValue.ts","../src/components/DynamicFormItemChoice.vue","../src/core/useValidatePartialForm.ts","../src/components/DynamicFormItemWizard.vue","../src/utils/hashField.ts","../src/components/DynamicFormItem.vue","../src/components/DynamicForm.vue","../src/utils/camelize.ts","../src/components/DynamicFormTemplate.vue","../src/core/defineMetadata.ts","../src/core/useDynamicForm.ts","../src/utils/mapEachMetadataItem.ts"],"sourcesContent":["import type { MaybeRefOrGetter } from 'vue';\nimport { useFieldArray } from 'vee-validate';\nimport { computed } from 'vue';\n\n/**\n * Wraps vee-validate's `useFieldArray`, adding a `values` computed shorthand for\n * `fields.value.map(f => f.value)` so callers don't need to unwrap each keyed field object.\n */\nexport function useFieldArrayExtended(arrayPath: MaybeRefOrGetter<string>) {\n const { fields, ...originalFieldArray } = useFieldArray(arrayPath);\n const values = computed(() => fields.value.map(({ value }) => value));\n\n return {\n fields,\n values,\n ...originalFieldArray,\n };\n}\n","import type { MaybeRefOrGetter } from 'vue';\nimport { useFormContext } from 'vee-validate';\nimport { toValue } from 'vue';\n\ninterface PathStateWithFlags {\n __flags?: { pendingReset?: boolean }\n}\n\n/**\n * While `resetForm()` / `resetField()` flushes, vee-validate marks every affected path state\n * with a private `pendingReset` flag (cleared again on the next tick) so that its own value\n * watchers skip validation during the reset. Our components own their validation timing through\n * custom value watchers, so they must honour the same flag; otherwise the reset-triggered value\n * change would validate the freshly reset value and write the just-cleared errors straight back.\n *\n * `getPathState` and `__flags` are deliberately left off vee-validate's public FormContext type,\n * so they are read through a loosely typed access (the same way DynamicFormItem reads\n * `keepValuesOnUnmount`).\n */\nexport function useIsResetPending(path: MaybeRefOrGetter<string>): () => boolean {\n const formContext = useFormContext() as {\n getPathState?: (path: string) => PathStateWithFlags | undefined\n } | undefined;\n\n return () => formContext?.getPathState?.(toValue(path))?.__flags?.pendingReset === true;\n}\n","import type { MaybeRefOrGetter } from 'vue';\nimport { useFormContext } from 'vee-validate';\nimport { nextTick } from 'vue';\nimport { useIsResetPending } from '@/core/useIsResetPending';\n\ninterface PatchableFormContext {\n setFieldValue?: (field: unknown, value: unknown, shouldValidate?: boolean) => void\n setValues?: (fields: unknown, shouldValidate?: boolean) => void\n}\n\n// Suppression is form-wide and lasts a single tick: the window in which the write's own value\n// change flushes through the value watchers. Per-path tracking is deliberately avoided: user\n// input is event-driven and cannot land in the same microtask flush as a programmatic write,\n// and a validation skipped during the window re-runs on the field's next value change anyway.\nconst suppressedForms = new WeakSet<object>();\nconst patchedForms = new WeakSet<object>();\n\nfunction suppress(form: object) {\n suppressedForms.add(form);\n // Cleared once the write has flushed, mirroring how vee-validate clears `pendingReset`.\n // Must be scheduled after the value write: only then does nextTick chain behind the\n // pending watcher flush instead of resolving on an earlier microtask.\n nextTick(() => suppressedForms.delete(form));\n}\n\n/**\n * Makes a form context's `shouldValidate: false` argument actually stick: wraps `setFieldValue`\n * and `setValues` so that writes which ask to skip validation are remembered until their flush\n * settles. vee-validate only skips its *own* validation for such writes; our components run their\n * validation from custom value watchers, which would otherwise fire regardless.\n *\n * Mutates the context in place (vee-validate provides the very object it returns from `useForm`),\n * so the consumer's handle and every injected `useFormContext()` share the wrapped functions.\n * Safe to call multiple times on the same form.\n */\nexport function trackNonValidatingWrites(form: unknown): void {\n if (!form || typeof form !== 'object' || patchedForms.has(form))\n return;\n patchedForms.add(form);\n\n const context = form as PatchableFormContext;\n\n const originalSetFieldValue = context.setFieldValue?.bind(context);\n if (originalSetFieldValue) {\n context.setFieldValue = (field, value, shouldValidate = true) => {\n originalSetFieldValue(field, value, shouldValidate);\n if (!shouldValidate)\n suppress(form);\n };\n }\n\n const originalSetValues = context.setValues?.bind(context);\n if (originalSetValues) {\n context.setValues = (fields, shouldValidate = true) => {\n originalSetValues(fields, shouldValidate);\n if (!shouldValidate)\n suppress(form);\n };\n }\n}\n\n/**\n * True while the field's value is changing through a programmatic write that asked not to\n * validate: a `resetForm()`/`resetField()` flush (vee-validate's `pendingReset` window) or a\n * `setFieldValue`/`setValues` call with `shouldValidate: false` on a form wrapped by\n * `trackNonValidatingWrites`. Value watchers that own validation timing must skip validation\n * while this returns true, otherwise they would override the caller's explicit intent.\n */\nexport function useIsValidationSuppressed(path: MaybeRefOrGetter<string>): () => boolean {\n const isResetPending = useIsResetPending(path);\n const formContext = useFormContext() as object | undefined;\n\n return () => isResetPending() || (!!formContext && suppressedForms.has(formContext));\n}\n","import type { ValidationMessage } from '@/types/ValidationMessage';\n\nexport const dynamicFormSettingsKey = Symbol('dynamicFormSettings');\n\nexport type DynamicFormSettings<\n ExtendedProperties extends object = object,\n> = {\n /**\n * Enables diagnostic data output via concealed DOM elements for reactivity testing\n */\n analytics?: boolean\n\n /**\n * In case of a complex type the value is stored in a value property, i.e. { value: 'the actual value' }\n * Use complexTypeValueProperty to change the property name, for example 'myValue' will result in { myValue: 'the actual value' }\n */\n complexTypeValueProperty?: string\n\n /**\n * When true, validates fields on every value change.\n * When false, only validates on submit.\n *\n * Defaults to true.\n */\n validateOnValueUpdate?: boolean\n\n /**\n * When true, validates fields on every value change after the first submit.\n * When false, listen to the validateOnValueUpdate.\n *\n * Defaults to false.\n */\n validateOnValueUpdateAfterSubmit?: boolean\n\n /**\n * When true, validates fields on blur.\n *\n * Defaults to false.\n */\n validateOnBlur?: boolean\n\n /**\n * When true, validates fields on every value change when the field has an error.\n *\n * Defaults to true (applied by DynamicForm).\n */\n validateWhenInError?: boolean\n\n /**\n * Use this setting to override the default text of the validation messages.\n *\n * Each message accepts either a `string` template or a `(ctx) => string` function.\n *\n * String templates support the following placeholders:\n * - `{field}` — the field label\n * - `{value}` — the current field value\n * - `{0}`, `{1}`, ... — rule params by position (e.g. `{0}` = the limit value)\n * - Named params where supported (e.g. `{min}`, `{max}`)\n *\n * Examples:\n * ```ts\n * required: 'The {field} field is required'\n * minLength: 'The {field} must be at least {0} characters'\n * minLength: (ctx) => `${ctx.field} is too short`\n * ```\n */\n messages?: {\n /** XSD: required. Available placeholders: `{field}` */\n required?: ValidationMessage\n /** XSD: minOccurs. Available placeholders: `{field}`, `{0}` or `{min}` (min number of filled items) */\n minOccurs?: ValidationMessage\n /** XSD: maxOccurs. Available placeholders: `{field}`, `{0}` or `{max}` (max number of allowed items) */\n maxOccurs?: ValidationMessage\n /** XSD: choiceMinOccurs. Available placeholders: `{field}`, `{0}` or `{min}` (min number of filled items) */\n choiceMinOccurs?: ValidationMessage\n /** XSD: choiceMaxOccurs. Available placeholders: `{field}`, `{0}` or `{max}` (max number of choice occurrences allowed) */\n choiceMaxOccurs?: ValidationMessage\n /**\n * Non-XSD: maxOccursTotal, a choice branch's opt-in cap on its own total raw occurrence\n * count. Available placeholders: `{field}`, `{0}` or `{max}` (the offending branch's cap).\n *\n * This is a single choice-level aggregate, not a per-branch error: `{field}` resolves to the\n * choice's own anchor label, never the branch's, so the message cannot name which branch is\n * over its cap. When several branches breach their own `maxOccursTotal` at once, `{max}`/`{0}`\n * carry the cap of the first offending branch in declaration order only, not every breached\n * cap. A single-branch choice skips choice-level validation entirely; there a breach surfaces\n * as the branch's own `maxOccurs` message instead.\n */\n maxOccursTotal?: ValidationMessage\n /** XSD: minLength. Available placeholders: `{field}`, `{0}` or `{length}` (min length) */\n minLength?: ValidationMessage\n /** XSD: maxLength. Available placeholders: `{field}`, `{0}` or `{length}` (max length) */\n maxLength?: ValidationMessage\n /** XSD: length. Available placeholders: `{field}`, `{0}` or `{length}` (exact length) */\n length?: ValidationMessage\n /** XSD: pattern. Available placeholders: `{field}`, `{0}` or `{pattern}` (regex pattern) */\n pattern?: ValidationMessage\n /** XSD: minInclusive. Available placeholders: `{field}`, `{0}` or `{min}` (min value, inclusive) */\n minInclusive?: ValidationMessage\n /** XSD: maxInclusive. Available placeholders: `{field}`, `{0}` or `{max}` (max value, inclusive) */\n maxInclusive?: ValidationMessage\n /** XSD: minExclusive. Available placeholders: `{field}`, `{0}` or `{min}` (min value, exclusive) */\n minExclusive?: ValidationMessage\n /** XSD: maxExclusive. Available placeholders: `{field}`, `{0}` or `{max}` (max value, exclusive) */\n maxExclusive?: ValidationMessage\n /** XSD: enumeration. Available placeholders: `{field}` */\n enumeration?: ValidationMessage\n /** XSD: whiteSpace. Available placeholders: `{field}`, `{0}` or `{mode}` (preserve | replace | collapse) */\n whiteSpace?: ValidationMessage\n /** XSD: fractionDigits. Available placeholders: `{field}`, `{0}` or `{digits}` (max decimal places) */\n fractionDigits?: ValidationMessage\n /** XSD: totalDigits. Available placeholders: `{field}`, `{0}` or `{digits}` (max total digits) */\n totalDigits?: ValidationMessage\n }\n} & ExtendedProperties;\n","/**\n * vee-validate v4.15.1\n * (c) 2025 Abdelrahman Awad\n * @license MIT\n */\nimport 'vue';\nimport { validate, validateObject } from 'vee-validate';\n\n/* eslint-disable no-misleading-character-class */\n/**\n * Some Alpha Regex helpers.\n * https://github.com/chriso/validator.js/blob/master/src/lib/alpha.js\n */\nconst alpha = {\n en: /^[A-Z]*$/i,\n cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i,\n da: /^[A-ZÆØÅ]*$/i,\n de: /^[A-ZÄÖÜß]*$/i,\n es: /^[A-ZÁÉÍÑÓÚÜ]*$/i,\n fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i,\n it: /^[A-Z\\xC0-\\xFF]*$/i,\n lt: /^[A-ZĄČĘĖĮŠŲŪŽ]*$/i,\n nl: /^[A-ZÉËÏÓÖÜ]*$/i,\n hu: /^[A-ZÁÉÍÓÖŐÚÜŰ]*$/i,\n pl: /^[A-ZĄĆĘŚŁŃÓŻŹ]*$/i,\n pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i,\n ru: /^[А-ЯЁ]*$/i,\n kz: /^[А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA]*$/i,\n sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i,\n sr: /^[A-ZČĆŽŠĐ]*$/i,\n sv: /^[A-ZÅÄÖ]*$/i,\n tr: /^[A-ZÇĞİıÖŞÜ]*$/i,\n uk: /^[А-ЩЬЮЯЄІЇҐ]*$/i,\n ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/,\n az: /^[A-ZÇƏĞİıÖŞÜ]*$/i,\n ug: /^[A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ]*$/i,\n};\nconst alphaSpaces = {\n en: /^[A-Z\\s]*$/i,\n cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\\s]*$/i,\n da: /^[A-ZÆØÅ\\s]*$/i,\n de: /^[A-ZÄÖÜß\\s]*$/i,\n es: /^[A-ZÁÉÍÑÓÚÜ\\s]*$/i,\n fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ\\s]*$/i,\n it: /^[A-Z\\xC0-\\xFF\\s]*$/i,\n lt: /^[A-ZĄČĘĖĮŠŲŪŽ\\s]*$/i,\n nl: /^[A-ZÉËÏÓÖÜ\\s]*$/i,\n hu: /^[A-ZÁÉÍÓÖŐÚÜŰ\\s]*$/i,\n pl: /^[A-ZĄĆĘŚŁŃÓŻŹ\\s]*$/i,\n pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ\\s]*$/i,\n ru: /^[А-ЯЁ\\s]*$/i,\n kz: /^[А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA\\s]*$/i,\n sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ\\s]*$/i,\n sr: /^[A-ZČĆŽŠĐ\\s]*$/i,\n sv: /^[A-ZÅÄÖ\\s]*$/i,\n tr: /^[A-ZÇĞİıÖŞÜ\\s]*$/i,\n uk: /^[А-ЩЬЮЯЄІЇҐ\\s]*$/i,\n ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ\\s]*$/,\n az: /^[A-ZÇƏĞİıÖŞÜ\\s]*$/i,\n ug: /^[A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ\\s]*$/i,\n};\nconst alphanumeric = {\n en: /^[0-9A-Z]*$/i,\n cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i,\n da: /^[0-9A-ZÆØÅ]$/i,\n de: /^[0-9A-ZÄÖÜß]*$/i,\n es: /^[0-9A-ZÁÉÍÑÓÚÜ]*$/i,\n fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i,\n it: /^[0-9A-Z\\xC0-\\xFF]*$/i,\n lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ]*$/i,\n hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]*$/i,\n nl: /^[0-9A-ZÉËÏÓÖÜ]*$/i,\n pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]*$/i,\n pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i,\n ru: /^[0-9А-ЯЁ]*$/i,\n kz: /^[0-9А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA]*$/i,\n sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i,\n sr: /^[0-9A-ZČĆŽŠĐ]*$/i,\n sv: /^[0-9A-ZÅÄÖ]*$/i,\n tr: /^[0-9A-ZÇĞİıÖŞÜ]*$/i,\n uk: /^[0-9А-ЩЬЮЯЄІЇҐ]*$/i,\n ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/,\n az: /^[0-9A-ZÇƏĞİıÖŞÜ]*$/i,\n ug: /^[0-9A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ]*$/i,\n};\nconst alphaDash = {\n en: /^[0-9A-Z_-]*$/i,\n cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ_-]*$/i,\n da: /^[0-9A-ZÆØÅ_-]*$/i,\n de: /^[0-9A-ZÄÖÜß_-]*$/i,\n es: /^[0-9A-ZÁÉÍÑÓÚÜ_-]*$/i,\n fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ_-]*$/i,\n it: /^[0-9A-Z\\xC0-\\xFF_-]*$/i,\n lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ_-]*$/i,\n nl: /^[0-9A-ZÉËÏÓÖÜ_-]*$/i,\n hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ_-]*$/i,\n pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ_-]*$/i,\n pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ_-]*$/i,\n ru: /^[0-9А-ЯЁ_-]*$/i,\n kz: /^[0-9А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA_-]*$/i,\n sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ_-]*$/i,\n sr: /^[0-9A-ZČĆŽŠĐ_-]*$/i,\n sv: /^[0-9A-ZÅÄÖ_-]*$/i,\n tr: /^[0-9A-ZÇĞİıÖŞÜ_-]*$/i,\n uk: /^[0-9А-ЩЬЮЯЄІЇҐ_-]*$/i,\n ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ_-]*$/,\n az: /^[0-9A-ZÇƏĞİıÖŞÜ_-]*$/i,\n ug: /^[0-9A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ_-]*$/i,\n};\nconst getLocale = (params) => {\n if (!params) {\n return undefined;\n }\n return Array.isArray(params) ? params[0] : params.locale;\n};\n\nfunction getSingleParam(params, paramName) {\n return Array.isArray(params) ? params[0] : params[paramName];\n}\nfunction isEmpty(value) {\n if (value === null || value === undefined || value === '') {\n return true;\n }\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n return false;\n}\n\nconst alphaValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alpha).some(loc => alpha[loc].test(valueAsString));\n }\n return (alpha[locale] || alpha.en).test(valueAsString);\n};\n\nconst alphaDashValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaDashValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alphaDash).some(loc => alphaDash[loc].test(valueAsString));\n }\n return (alphaDash[locale] || alphaDash.en).test(valueAsString);\n};\n\nconst alphaNumValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaNumValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alphanumeric).some(loc => alphanumeric[loc].test(valueAsString));\n }\n return (alphanumeric[locale] || alphanumeric.en).test(valueAsString);\n};\n\nconst alphaSpacesValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaSpacesValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alphaSpaces).some(loc => alphaSpaces[loc].test(valueAsString));\n }\n return (alphaSpaces[locale] || alphaSpaces.en).test(valueAsString);\n};\n\nfunction getParams$1(params) {\n if (Array.isArray(params)) {\n return { min: params[0], max: params[1] };\n }\n return params;\n}\nconst betweenValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const { min, max } = getParams$1(params);\n if (Array.isArray(value)) {\n return value.every(val => betweenValidator(val, { min, max }));\n }\n const valueAsNumber = Number(value);\n return Number(min) <= valueAsNumber && Number(max) >= valueAsNumber;\n};\n\nconst confirmedValidator = (value, params) => {\n const target = getSingleParam(params, 'target');\n return String(value) === String(target);\n};\n\nconst digitsValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const length = getSingleParam(params, 'length');\n if (Array.isArray(value)) {\n return value.every(val => digitsValidator(val, { length }));\n }\n const strVal = String(value);\n return /^[0-9]*$/.test(strVal) && strVal.length === Number(length);\n};\n\nconst validateImage = (file, width, height) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const URL = window.URL || window.webkitURL;\n return new Promise(resolve => {\n const image = new Image();\n image.onerror = () => resolve(false);\n image.onload = () => resolve(image.width === width && image.height === height);\n image.src = URL.createObjectURL(file);\n });\n};\nfunction getParams(params) {\n if (!params) {\n return { width: 0, height: 0 };\n }\n if (Array.isArray(params)) {\n return { width: Number(params[0]), height: Number(params[1]) };\n }\n return {\n width: Number(params.width),\n height: Number(params.height),\n };\n}\nconst dimensionsValidator = (files, params) => {\n if (isEmpty(files)) {\n return true;\n }\n const { width, height } = getParams(params);\n const list = [];\n const fileList = Array.isArray(files) ? files : [files];\n for (let i = 0; i < fileList.length; i++) {\n // if file is not an image, reject.\n if (!/\\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(fileList[i].name)) {\n return Promise.resolve(false);\n }\n list.push(fileList[i]);\n }\n return Promise.all(list.map(file => validateImage(file, width, height))).then(values => {\n return values.every(v => v);\n });\n};\n\n/* eslint-disable no-useless-escape */\n// https://github.com/colinhacks/zod/blob/40e72f9eaf576985f876d1afc2dbc22f73abc1ba/src/types.ts#L595\nconst emailRE = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\nconst emailValidator = (value) => {\n if (isEmpty(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(val => emailRE.test(String(val)));\n }\n return emailRE.test(String(value));\n};\n\nconst extValidator = (files, extensions) => {\n if (isEmpty(files)) {\n return true;\n }\n const regex = new RegExp(`\\\\.(${extensions.join('|')})$`, 'i');\n if (Array.isArray(files)) {\n return files.every(file => regex.test(file.name));\n }\n return regex.test(files.name);\n};\n\nconst imageValidator = (files) => {\n if (isEmpty(files)) {\n return true;\n }\n const regex = /\\.(jpg|svg|jpeg|png|bmp|gif|webp)$/i;\n if (Array.isArray(files)) {\n return files.every(file => regex.test(file.name));\n }\n return regex.test(files.name);\n};\n\nconst integerValidator = (value) => {\n if (isEmpty(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(val => /^-?[0-9]+$/.test(String(val)));\n }\n return /^-?[0-9]+$/.test(String(value));\n};\n\nconst isValidator = (value, params) => {\n const other = getSingleParam(params, 'other');\n return value === other;\n};\n\nconst isNotValidator = (value, params) => {\n const other = getSingleParam(params, 'other');\n return value !== other;\n};\n\nconst lengthValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n // Normalize the length value\n const length = getSingleParam(params, 'length');\n if (typeof value === 'number') {\n value = String(value);\n }\n if (!value.length) {\n value = Array.from(value);\n }\n return value.length === Number(length);\n};\n\nconst maxLengthValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const length = getSingleParam(params, 'length');\n if (Array.isArray(value)) {\n return value.every(val => maxLengthValidator(val, { length }));\n }\n return [...String(value)].length <= Number(length);\n};\n\nconst maxValueValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const max = getSingleParam(params, 'max');\n if (Array.isArray(value)) {\n return value.length > 0 && value.every(val => maxValueValidator(val, { max }));\n }\n return Number(value) <= Number(max);\n};\n\nconst ADDED_MIME_RE = /\\+(.+)?/;\nfunction buildRegExp(mime) {\n let strPattern = mime;\n if (ADDED_MIME_RE.test(mime)) {\n strPattern = mime.replace(ADDED_MIME_RE, '(\\\\+$1)?');\n }\n return new RegExp(strPattern.replace('*', '.+'), 'i');\n}\nconst mimesValidator = (files, mimes) => {\n if (isEmpty(files)) {\n return true;\n }\n if (!mimes) {\n mimes = [];\n }\n const patterns = mimes.map(buildRegExp);\n if (Array.isArray(files)) {\n return files.every(file => patterns.some(p => p.test(file.type)));\n }\n return patterns.some(p => p.test(files.type));\n};\n\nconst minValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const length = getSingleParam(params, 'length');\n if (Array.isArray(value)) {\n return value.every(val => minValidator(val, { length }));\n }\n return [...String(value)].length >= Number(length);\n};\n\nconst minValueValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const min = getSingleParam(params, 'min');\n if (Array.isArray(value)) {\n return value.length > 0 && value.every(val => minValueValidator(val, { min }));\n }\n return Number(value) >= Number(min);\n};\n\nconst oneOfValidator = (value, list) => {\n if (isEmpty(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(val => oneOfValidator(val, list));\n }\n return Array.from(list).some(item => {\n return item == value;\n });\n};\n\nconst notOneOfValidator = (value, list) => {\n if (isEmpty(value)) {\n return true;\n }\n return !oneOfValidator(value, list);\n};\n\nconst ar = /^[٠١٢٣٤٥٦٧٨٩]+$/;\nconst en = /^[0-9]+$/;\nconst numericValidator = (value) => {\n if (isEmpty(value)) {\n return true;\n }\n const testValue = (val) => {\n const strValue = String(val);\n return en.test(strValue) || ar.test(strValue);\n };\n if (Array.isArray(value)) {\n return value.every(testValue);\n }\n return testValue(value);\n};\n\nconst regexValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n let regex = getSingleParam(params, 'regex');\n if (typeof regex === 'string') {\n regex = new RegExp(regex);\n }\n if (Array.isArray(value)) {\n return value.every(val => regexValidator(val, { regex }));\n }\n return regex.test(String(value));\n};\n\nfunction isNullOrUndefined(value) {\n return value === null || value === undefined;\n}\nfunction isEmptyArray(arr) {\n return Array.isArray(arr) && arr.length === 0;\n}\nconst isObject = (obj) => obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj);\n\nconst requiredValidator = (value) => {\n if (isNullOrUndefined(value) || isEmptyArray(value) || value === false) {\n return false;\n }\n return !!String(value).trim().length;\n};\n\nconst sizeValidator = (files, params) => {\n if (isEmpty(files)) {\n return true;\n }\n let size = getSingleParam(params, 'size');\n size = Number(size);\n if (isNaN(size)) {\n return false;\n }\n const nSize = size * 1024;\n if (!Array.isArray(files)) {\n return files.size <= nSize;\n }\n for (let i = 0; i < files.length; i++) {\n if (files[i].size > nSize) {\n return false;\n }\n }\n return true;\n};\n\nconst urlValidator = (value, params) => {\n var _a;\n if (isEmpty(value)) {\n return true;\n }\n let pattern = getSingleParam(params, 'pattern');\n if (typeof pattern === 'string') {\n pattern = new RegExp(pattern);\n }\n try {\n new URL(value);\n }\n catch (_b) {\n return false;\n }\n return (_a = pattern === null || pattern === void 0 ? void 0 : pattern.test(value)) !== null && _a !== void 0 ? _a : true;\n};\n\n/**\n * A typed version of Object.keys\n */\nfunction keysOf(record) {\n return Object.keys(record);\n}\n\nfunction toTypedSchema(rawSchema) {\n const schema = {\n __type: 'VVTypedSchema',\n async parse(values) {\n // single field\n if (typeof rawSchema === 'string') {\n const result = await validate(values, rawSchema);\n return {\n errors: [\n {\n errors: result.errors,\n },\n ],\n };\n }\n const result = await validateObject(rawSchema, values);\n return {\n errors: keysOf(result.errors).map(path => {\n var _a;\n const error = {\n path: path,\n errors: ((_a = result.results[path]) === null || _a === void 0 ? void 0 : _a.errors) || [],\n };\n return error;\n }),\n };\n },\n describe(path) {\n if (!path) {\n return getDescriptionFromExpression(rawSchema);\n }\n if (isObject(rawSchema) && path in rawSchema) {\n return getDescriptionFromExpression(rawSchema[path]);\n }\n return {\n required: false,\n exists: false,\n };\n },\n };\n return schema;\n}\nfunction getDescriptionFromExpression(rules) {\n if (typeof rules === 'string') {\n return {\n exists: true,\n required: rules.includes('required'),\n };\n }\n if (isObject(rules)) {\n return {\n exists: true,\n required: !!rules.required,\n };\n }\n return {\n required: false,\n exists: true,\n };\n}\n\nconst all = {\n alpha_dash: alphaDashValidator,\n alpha_num: alphaNumValidator,\n alpha_spaces: alphaSpacesValidator,\n alpha: alphaValidator,\n between: betweenValidator,\n confirmed: confirmedValidator,\n digits: digitsValidator,\n dimensions: dimensionsValidator,\n email: emailValidator,\n ext: extValidator,\n image: imageValidator,\n integer: integerValidator,\n is_not: isNotValidator,\n is: isValidator,\n length: lengthValidator,\n max_value: maxValueValidator,\n max: maxLengthValidator,\n mimes: mimesValidator,\n min_value: minValueValidator,\n min: minValidator,\n not_one_of: notOneOfValidator,\n numeric: numericValidator,\n one_of: oneOfValidator,\n regex: regexValidator,\n required: requiredValidator,\n size: sizeValidator,\n url: urlValidator,\n};\n\nexport { all, alphaValidator as alpha, alphaDashValidator as alpha_dash, alphaNumValidator as alpha_num, alphaSpacesValidator as alpha_spaces, betweenValidator as between, confirmedValidator as confirmed, digitsValidator as digits, dimensionsValidator as dimensions, emailValidator as email, extValidator as ext, imageValidator as image, integerValidator as integer, isValidator as is, isNotValidator as is_not, lengthValidator as length, maxLengthValidator as max, maxValueValidator as max_value, mimesValidator as mimes, minValidator as min, minValueValidator as min_value, notOneOfValidator as not_one_of, numericValidator as numeric, oneOfValidator as one_of, regexValidator as regex, requiredValidator as required, sizeValidator as size, toTypedSchema, urlValidator as url };\n","/**\n * Recursively traverses a data structure to determine if it holds any meaningful data.\n * Returns false only when the entire structure consists of null/undefined values.\n * Particularly useful for validation frameworks to detect populated form fields.\n *\n * @param element Data structure to analyze (supports primitives, objects, arrays)\n * @returns Boolean indicating presence of non-nullish values\n */\nexport function checkTreeHasValue(element: unknown): boolean {\n if (element === null || element === undefined) {\n return false;\n }\n\n if (Array.isArray(element)) {\n return element.some((value: unknown) => checkTreeHasValue(value));\n }\n if (typeof element === 'object') {\n return Object.values(element).some((value: unknown) => checkTreeHasValue(value));\n }\n\n return true;\n}\n","import type { FieldValidationMetaInfo, ValidationMessage } from '@/types/ValidationMessage';\n\n/**\n * Helper function to resolve a validation message, with parameters.\n *\n * All three param styles work:\n * 'Must be at least {0} characters' // positional\n * 'Must be at least {min} characters' // named (object params)\n * 'The {field} value {value} is invalid' // context properties\n *\n * This is exactly how @vee-validate/i18n handles it internally.\n * @param message - The message template or function\n * @param ctx - The vee-validate field validation context\n * @param params - Optional param override. Array for positional `{0}, {1}`, or object for\n * named `{min}, {length}` (also supports positional via numeric keys). Falls back to ctx.rule.params if not provided.\n * @returns The resolved message string\n */\nexport function resolveMessage(message: ValidationMessage, ctx: FieldValidationMetaInfo, params?: unknown[] | Record<string, unknown>): string {\n if (typeof message === 'function')\n return message(ctx);\n return message.replace(/\\{(\\w+)\\}/g, (_, key) => {\n // Named context properties: {field}, {value}\n if (key in ctx)\n return String((ctx as any)[key]);\n // Named or positional from explicit params object: {min}, {length}, {0}\n if (params && !Array.isArray(params) && key in params)\n return String(params[key]);\n // Positional from explicit params array: {0}, {1}\n const index = Number(key);\n if (!Number.isNaN(index)) {\n if (Array.isArray(params) && params[index] !== undefined)\n return String(params[index]);\n return String((ctx.rule?.params as unknown[])?.[index] ?? `{${key}}`);\n }\n // Named from ctx.rule.params object: {min}, {max}\n if (ctx.rule?.params && !Array.isArray(ctx.rule.params))\n return String(ctx.rule.params[key] ?? `{${key}}`);\n return `{${key}}`;\n });\n}\n","import { max, max_value, min, min_value, one_of, regex } from '@vee-validate/rules';\nimport { defineRule } from 'vee-validate';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\n\nexport { resolveMessage } from '@/utils/resolveMessage';\n\n/**\n * XSD-derived rule names registered globally via vee-validate's `defineRule`, plus one\n * non-XSD occurrence extension (`vdf_maxOccursTotal`, a per-branch choice cap with no XSD\n * equivalent). Every name is prefixed (`xsd_` or `vdf_`): `defineRule` is a last-write-wins\n * global registry shared with the consuming app, so an unprefixed name could silently\n * collide with a consumer-defined rule.\n */\nexport type ValidationRule = 'xsd_required'\n | 'xsd_minOccurs'\n | 'xsd_maxOccurs'\n | 'xsd_choiceMinOccurs'\n | 'xsd_choiceMaxOccurs'\n | 'vdf_maxOccursTotal'\n | 'xsd_minLength'\n | 'xsd_maxLength'\n | 'xsd_pattern'\n | 'xsd_minInclusive'\n | 'xsd_maxInclusive'\n | 'xsd_minExclusive'\n | 'xsd_maxExclusive'\n | 'xsd_enumeration'\n | 'xsd_length'\n | 'xsd_whiteSpace'\n | 'xsd_fractionDigits'\n | 'xsd_totalDigits';\n\n// XSD: required — null/undefined/empty string are invalid; false is a valid boolean value\ndefineRule('xsd_required' as ValidationRule, (value: unknown) => value !== null && value !== undefined && value !== '');\n\n// XSD: minOccurs — minimum number of array items that have a value\ndefineRule('xsd_minOccurs' as ValidationRule, (value: unknown, [min]: [number]) => {\n if (!Array.isArray(value))\n return Number(min) <= 0;\n return value.filter(checkTreeHasValue).length >= Number(min);\n});\n\n// XSD: maxOccurs: maximum number of raw array items, including empty placeholders.\n// Counts the same quantity the array's own \"add\" affordance limits, not the filled count\n// xsd_minOccurs uses, so the rule and the UI cap never disagree.\ndefineRule('xsd_maxOccurs' as ValidationRule, (value: unknown, [max]: [number]) => {\n if (!Array.isArray(value))\n return true;\n return value.length <= Number(max);\n});\n\n// A choice field has no entry in the vee-validate value tree, so its rules cannot inspect a\n// value: the real comparison lives in the choice component's guard, which only pushes the rule\n// once it has already failed. The rule itself must therefore always fail.\nconst failChoiceRule = () => false;\n\n// XSD: choiceMinOccurs: minimum number of choice items that have a value\ndefineRule('xsd_choiceMinOccurs' as ValidationRule, failChoiceRule);\n\n// XSD: choiceMaxOccurs: maximum number of choice-occurrence units in use\ndefineRule('xsd_choiceMaxOccurs' as ValidationRule, failChoiceRule);\n\n// Non-XSD: a choice branch's own opt-in cap on its raw occurrence count, aggregated and\n// reported at the choice level\ndefineRule('vdf_maxOccursTotal' as ValidationRule, failChoiceRule);\n\n// XSD: minLength / maxLength — maps to vee-validate's min/max (string length)\ndefineRule('xsd_minLength' as ValidationRule, min);\ndefineRule('xsd_maxLength' as ValidationRule, max);\n\n// XSD: length — exact string length\ndefineRule('xsd_length' as ValidationRule, (value: unknown, [length]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n return String(value).length === Number(length);\n});\n\n// XSD: pattern — maps to vee-validate's regex\ndefineRule('xsd_pattern' as ValidationRule, regex);\n\n// XSD: minInclusive / maxInclusive (value >= min, value <= max)\ndefineRule('xsd_minInclusive' as ValidationRule, min_value);\ndefineRule('xsd_maxInclusive' as ValidationRule, max_value);\n\n// XSD: minExclusive / maxExclusive (value > min, value < max)\ndefineRule('xsd_minExclusive' as ValidationRule, (value: unknown, [min]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n return Number(value) > Number(min);\n});\ndefineRule('xsd_maxExclusive' as ValidationRule, (value: unknown, [max]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n return Number(value) < Number(max);\n});\n\n// XSD: enumeration — maps to vee-validate's one_of\ndefineRule('xsd_enumeration' as ValidationRule, one_of);\n\n// XSD: whiteSpace — validates the value conforms to the given whitespace mode\n// Modes: 'preserve' (no restriction), 'replace' (no tabs/newlines), 'collapse' (no leading/trailing/multiple spaces)\ndefineRule('xsd_whiteSpace' as ValidationRule, (value: unknown, [mode]: [string]) => {\n if (value === null || value === undefined || value === '')\n return true;\n const str = String(value);\n if (mode === 'replace')\n return !/[\\t\\n\\r]/.test(str);\n if (mode === 'collapse')\n return str === str.trim() && !/\\s{2,}/.test(str);\n return true; // 'preserve' — no restriction\n});\n\n// XSD: fractionDigits — maximum number of decimal places\ndefineRule('xsd_fractionDigits' as ValidationRule, (value: unknown, [digits]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n const decimalIndex = String(value).indexOf('.');\n if (decimalIndex === -1)\n return true;\n return String(value).length - decimalIndex - 1 <= Number(digits);\n});\n\n// XSD: totalDigits — maximum total number of significant digits (excluding sign and decimal point)\ndefineRule('xsd_totalDigits' as ValidationRule, (value: unknown, [digits]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n const significant = String(value).replace(/^-/, '').replace('.', '').replace(/^0+/, '') || '0';\n return significant.length <= Number(digits);\n});\n\n/**\n * Maps each rule to its semantic parameter name, enabling named placeholder\n * interpolation (e.g. `{length}`, `{min}`) alongside positional `{0}` in messages.\n */\nexport const ruleParamNames: Partial<Record<ValidationRule, string>> = {\n xsd_minOccurs: 'min',\n xsd_maxOccurs: 'max',\n xsd_choiceMinOccurs: 'min',\n xsd_choiceMaxOccurs: 'max',\n vdf_maxOccursTotal: 'max',\n xsd_minLength: 'length',\n xsd_maxLength: 'length',\n xsd_length: 'length',\n xsd_pattern: 'pattern',\n xsd_minInclusive: 'min',\n xsd_maxInclusive: 'max',\n xsd_minExclusive: 'min',\n xsd_maxExclusive: 'max',\n xsd_whiteSpace: 'mode',\n xsd_fractionDigits: 'digits',\n xsd_totalDigits: 'digits',\n};\n","import type { FieldValidationMetaInfo } from '@/types/ValidationMessage';\n\n/**\n * Resolves the most user-friendly label for a field validation context.\n *\n * Most components (e.g. DynamicFormItem, DynamicFormItemArray) call `useField`\n * with the field's `fieldOptions`, so vee-validate already sets `ctx.label`\n * and `ctx.field` to a human-readable name. Choice fields are special: they\n * validate at the root path (`''`) and historically registered without any\n * `fieldOptions`, which left vee-validate with the literal placeholder\n * string `{field}`. Normalizing the label here ensures shared helpers like\n * createValidation/splitValidationFunctions always receive a real display name\n * even for those “virtual” fields.\n *\n * Preference order: explicit label → ctx.field → ctx.name → empty string.\n */\nexport function getFieldLabel(ctx: FieldValidationMetaInfo): string {\n return ctx.label ?? ctx.field ?? ctx.name ?? '';\n}\n","import type { ValidationRule } from '@/core/validation';\nimport type { FieldValidationMetaInfo, ValidationMessage } from '@/types/ValidationMessage';\nimport { validate } from 'vee-validate';\nimport { resolveMessage, ruleParamNames } from '@/core/validation';\nimport { getFieldLabel } from '@/utils/getFieldLabel';\n\n// Memoized per (rule, param, customMessage) so identical inputs return the identical closure.\n// Components rebuild their validation arrays inside computeds; without a stable identity every\n// rebuild looks like a rules change to vee-validate's deep rules watcher (functions compare by\n// reference) and triggers a validation pass the field's own timing settings meant to suppress.\nconst validationCache = new Map<string, Map<unknown, Map<unknown, ReturnType<typeof buildValidation>>>>();\n\n/**\n * Creates a validation that uses a globally defined rule in our 'vdf' namespace.\n * When the validation fails we either show the message override from the settings.messages\n * or let the user override the message using the configure.generateMessage\n *\n * @param rule\n * @param param\n * @param customMessage\n */\nexport function createValidation(rule: ValidationRule, param?: unknown, customMessage?: ValidationMessage) {\n let byParam = validationCache.get(rule);\n if (!byParam)\n validationCache.set(rule, byParam = new Map());\n let byMessage = byParam.get(param);\n if (!byMessage)\n byParam.set(param, byMessage = new Map());\n let validation = byMessage.get(customMessage);\n if (!validation)\n byMessage.set(customMessage, validation = buildValidation(rule, param, customMessage));\n return validation;\n}\n\nfunction buildValidation(rule: ValidationRule, param?: unknown, customMessage?: ValidationMessage) {\n // Build params as an object so both positional ({0}) and named ({length}, {min}, ...) placeholders work\n const paramName = ruleParamNames[rule];\n const params: Record<string, unknown> = param !== undefined\n ? { 0: param, ...(paramName ? { [paramName]: param } : {}) }\n : {};\n return async (value: unknown, ctx: FieldValidationMetaInfo) => {\n const fieldName = getFieldLabel(ctx);\n const validateOptions = fieldName ? { name: fieldName } : undefined;\n const normalizedCtx = fieldName && ctx.field !== fieldName\n ? { ...ctx, field: fieldName }\n : ctx;\n\n const result = await validate(\n value,\n param !== undefined ? { [rule]: param } : rule,\n validateOptions,\n );\n if (result.valid)\n return true;\n return customMessage ? resolveMessage(customMessage, normalizedCtx, params) : result.errors[0];\n };\n}\n","/**\n * Helper function that converts a path with bracket notation to a dot notation.\n * When adding an extra path segment, we do this by using the bracket notation, i.e.: person['value'].\n *\n * Vee-validate can't work with this notation, therefore this function fixes those cases.\n *\n * const actualPath = normalizePath(\n * 'this.is[\"added\"].to.my.path.and.more',\n * )\n *\n * console.log(actualPath) // 'this.is.added.to.my.path.and.more'\n *\n * @param path to be normalized\n */\nexport function normalizePath(path: string) {\n return path?.replaceAll(/\\[[`'\"](.*?)[`'\"]\\]/g, '.$1') ?? '';\n}\n","/**\n * Merges two dot-notation paths by replacing leading segments of the base path\n * with segments from the replacement path. Useful for resolving array indices\n * in nested field paths where parent context contains array positions.\n *\n * @example\n * // Given a generic path and an indexed parent path, produce the indexed child path\n * const result = overridePath(\n * 'data.users.contact.email',\n * 'data.users[2]'\n * )\n *\n * console.log(result) // 'data.users[2].contact.email'\n *\n * @param path Base path string to be modified\n * @param overrideWithPath Replacement path that will substitute initial segments\n * @returns Modified path with replaced segments\n */\nexport function overridePath(path: string, overrideWithPath: string | undefined) {\n if (!path || !overrideWithPath)\n return path;\n\n // Split both paths and substitute leading segments from the replacement path\n const parentSegments = overrideWithPath.split('.') ?? [];\n const childSegments = path.split('.') ?? [];\n for (let index = 0; index < parentSegments.length; index++) {\n childSegments[index] = parentSegments[index];\n }\n return childSegments.join('.');\n}\n","import type { GenericValidateFunction, RuleExpression } from 'vee-validate';\nimport type { FieldValidationMetaInfo } from '@/types/ValidationMessage';\nimport { validate } from 'vee-validate';\nimport { getFieldLabel } from '@/utils/getFieldLabel';\n\n/**\n * Splits a vee-validate `RuleExpression` into an array of individual `GenericValidateFunction`s,\n * one per rule. This allows vee-validate to run each rule independently and collect all errors\n * when `bails: false` is configured.\n *\n * Handles all `RuleExpression` formats:\n * - **Function** — returned as-is in a single-element array\n * - **Array** — each element is recursively split\n * - **String** — pipe-separated rules (e.g. `'required|email'`) are split into separate functions,\n * each delegating to vee-validate's `validate()`\n * - **Object** — each key/value pair (e.g. `{ required: true, min: 3 }`) becomes a separate function,\n * each delegating to vee-validate's `validate()`\n */\nexport function splitToValidationFunctions(userRules: RuleExpression<unknown>):\nGenericValidateFunction[] {\n if (!userRules)\n return [];\n if (typeof userRules === 'function')\n return [userRules];\n if (Array.isArray(userRules))\n return userRules.flatMap(splitToValidationFunctions);\n\n if (typeof userRules === 'string') {\n return userRules.split('|').map(rule => async (value: unknown, ctx: FieldValidationMetaInfo) => {\n const fieldName = getFieldLabel(ctx);\n const result = await validate(value, rule, fieldName ? { name: fieldName } : undefined);\n return result.valid ? true : result.errors[0];\n });\n }\n\n // Object format: { required: true, email: true }\n return Object.entries(userRules).map(([key, val]) => async (value: unknown, ctx: FieldValidationMetaInfo) => {\n const fieldName = getFieldLabel(ctx);\n const result = await validate(value, { [key]: val }, fieldName ? { name: fieldName } : undefined);\n return result.valid ? true : result.errors[0];\n });\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { GenericValidateFunction } from 'vee-validate';\nimport type { ComputedRef } from 'vue';\nimport type { LimitedFieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField, useSubmitCount, useValidateField } from 'vee-validate';\nimport { computed, inject, ref, watch, watchEffect } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { useFieldArrayExtended } from '@/core/useFieldArrayExtended';\nimport { useIsValidationSuppressed } from '@/core/useIsValidationSuppressed';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { createValidation } from '@/utils/createValidation';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\nimport { splitToValidationFunctions } from '@/utils/splitValidationFunctions';\n\n// #region Interfaces\nexport interface Emit {\n /** Emitted whenever array values change (item added, removed, or updated); payload is the full array value. */\n (e: 'update:modelValue', value: unknown): void\n /** Bubbled up from child `DynamicFormItem` instances; carries the updated computed field metadata. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\n// #endregion\n\n// #region Internal tracking\n// Plain variables (not reactive) to avoid triggering renders when measuring analytics.\n// eslint-disable-next-line prefer-const\nlet _analytics_renderCount = 0;\nlet _analytics_constructValidationCount = 0;\nlet _analytics_fieldChangedCount = 0;\n// #endregion\n\n// #region Computed state\n\n// --- Path ---\n\nconst field = computed(() => {\n _analytics_fieldChangedCount++;\n return props.fieldMetadata;\n});\n\nconst path = computed(() => {\n if (!field.value?.path)\n return '';\n\n return overridePath(field.value.path, props.pathOverride);\n});\n\nconst normalizedPath = computed(() => normalizePath(path.value));\n\n// --- Vee-Validate field array ---\n\nconst validate = useValidateField(normalizedPath);\nconst { remove, push, fields, update, values, replace } = useFieldArrayExtended(normalizedPath);\nconst isValidationSuppressed = useIsValidationSuppressed(normalizedPath);\n\n// --- Occurrence limits ---\n\n// minOccurs determines how many items must exist at minimum.\nconst minOccurs = computed(() =>\n props.minOccursOverride !== undefined\n ? props.minOccursOverride\n : (field.value?.minOccurs ?? 1),\n);\n\n// maxOccurs determines how many items may exist at maximum.\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined\n ? props.maxOccursOverride\n : (field.value?.maxOccurs ?? 1),\n);\n\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// Each individual array item is rendered as a single-occurrence field, not another array.\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : 1,\n);\n\nconst _canAddItems = computed(() => maxOccurs.value > fields.value?.length);\nconst _canRemoveItems = computed(() => {\n // Choice-field children can be removed down to 0.\n if (props.partOfChoiceField)\n return fields.value?.length > 0;\n\n // Or when we choose to not automatically add items\n if (field.value?.autoAddMinOccurs === false)\n return fields.value?.length > 0;\n\n // Otherwise, keep at least minOccurs items and never go below 1.\n return fields.value?.length > minOccurs.value && fields.value?.length > 1;\n});\n\n// --- Validation ---\n\n// Validation is built as a computed (not watchEffect) because there is no circular dependency\n// to break here — the array field does not depend on its own validation value.\nconst combinedValidation = computed<GenericValidateFunction[]>(() => {\n _analytics_constructValidationCount++;\n\n const _validations: GenericValidateFunction[] = [];\n const _messages = settings?.value?.messages;\n\n if (required.value)\n _validations.push(createValidation('xsd_minOccurs', minOccurs.value, _messages?.minOccurs));\n\n // Skipped for malformed metadata (minOccurs > maxOccurs): auto-add fills to minOccurs and\n // removal is blocked below it, so the rule could never be satisfied and would brick the form.\n // Such metadata stays silently tolerated, as it always was.\n if (!disabled.value && maxOccurs.value >= minOccurs.value)\n _validations.push(createValidation('xsd_maxOccurs', maxOccurs.value, _messages?.maxOccurs));\n\n if (field.value?.validation)\n _validations.push(...splitToValidationFunctions(field.value?.validation));\n\n return _validations;\n});\n\nconst { label, errors, errorMessage, handleBlur } = useField(normalizedPath, combinedValidation, {\n ...(field.value?.fieldOptions ?? {}),\n validateOnValueUpdate: false, // validation timing is owned by this component\n});\nconst fieldContext: LimitedFieldContext = { label, errors, errorMessage, value: values };\n\n// Delay validation until after the first real value is set — empty placeholder items\n// (added to satisfy minOccurs) should not trigger errors before the user has interacted.\nconst submitCount = useSubmitCount();\nconst firstValueSet = ref(false);\nconst shouldValidateOnValueUpdate = computed(() => {\n if (!firstValueSet.value)\n return;\n\n const validateOnValueUpdateAfterSubmit = settings?.value?.validateOnValueUpdateAfterSubmit === true\n ? (submitCount.value > 0 && settings?.value?.validateOnValueUpdateAfterSubmit)\n : undefined;\n\n const validateWhenInError = settings?.value?.validateWhenInError && fieldContext?.errors.value?.length > 0\n ? true\n : undefined;\n\n // Priority: field-level option → in-error state → after-submit setting → global setting\n return field.value?.fieldOptions?.validateOnValueUpdate\n ?? validateWhenInError\n ?? validateOnValueUpdateAfterSubmit\n ?? settings?.value?.validateOnValueUpdate;\n});\n\n// #endregion\n\n// #region Watchers and lifecycle events\n\nwatch(\n values,\n (v) => {\n // Skipped while a programmatic write that asked not to validate is flushing: a\n // resetForm/resetField (its value change would write the just-cleared errors back)\n // or a setFieldValue/setValues call with shouldValidate: false.\n if (shouldValidateOnValueUpdate.value && !isValidationSuppressed()) {\n validate();\n }\n emits('update:modelValue', v);\n },\n { immediate: true },\n);\n\n// Auto-add empty placeholder items to satisfy minOccurs.\n// Skipped for choice-field children — the choice manages their count.\n// Skipped when autoAddMinOccurs is explicitly set to false.\nwatchEffect(() => {\n if (props.partOfChoiceField)\n return;\n\n if (field.value?.autoAddMinOccurs === false)\n return;\n\n if (fields.value?.length < 1 || fields.value?.length < minOccurs.value) {\n _addItem();\n }\n});\n\n// #endregion\n\n// #region Methods\n\nfunction _addItem() {\n push(null); // empty placeholder\n emits('update:modelValue', values.value);\n}\n\nfunction _removeItem(index?: number) {\n if (_canRemoveItems.value) {\n remove(index ?? fields.value.length - 1);\n }\n else {\n // Below the allowed minimum — clear the item instead of removing it.\n replace(values.value?.map((x, i) => i === index ? null : x));\n }\n\n emits('update:modelValue', values.value);\n}\n\nfunction guardAndNotifyItemUpdate(value: any, index: number) {\n if (!firstValueSet.value) {\n // Now that a real value exists, enable validation going forward.\n firstValueSet.value = true;\n if (shouldValidateOnValueUpdate.value && !isValidationSuppressed()) {\n validate();\n }\n }\n\n // Workaround: when an array item has attributes, the complexType wrapper may retain\n // attribute values even after the main value is cleared. This causes checkTreeHasValue()\n // to return true and bypasses required validation. Explicitly calling update() with undefined\n // ensures vee-validate clears the entry and required validation can fire correctly.\n if (value === undefined && index >= 0) {\n update(index, undefined);\n }\n\n emits('update:modelValue', values.value);\n};\n\n// #endregion\n</script>\n\n<template>\n <div v-if=\"settings?.analytics\" v-show=\"false\">\n <span :data-testid=\"`${path}-analytics-render-count`\">{{\n ++_analytics_renderCount\n }}</span>\n </div>\n <component\n :is=\"template\"\n :type=\"`${fieldMetadata.type}-array`\"\n :field-metadata\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items=\"_canAddItems\"\n :can-remove-items=\"_canRemoveItems\"\n :add-item=\"_addItem\"\n :remove-item=\"_removeItem\"\n >\n <template #default=\"slotProps\">\n <DynamicFormItem\n v-for=\"({ key }, arrayIndex) in fields ?? []\"\n :key=\"key\"\n :field-metadata\n :path-override=\"`${path}[${arrayIndex}]`\"\n :index=\"arrayIndex\"\n :template=\"template\"\n :slot-props\n :max-occurs-override=\"_maxOccursOverride\"\n :can-add-items=\"_canAddItems\"\n :can-remove-items=\"_canRemoveItems\"\n :add-item=\"_addItem\"\n :remove-item=\"() => _removeItem(arrayIndex)\"\n part-of-array-field\n is-array-override=\"single\"\n\n @update:model-value=\"guardAndNotifyItemUpdate($event, arrayIndex)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n @blur=\"handleBlur\"\n />\n </template>\n </component>\n</template>\n","/**\n * Deep-clones a form value tree (plain objects, arrays, Dates and primitives) into plain,\n * non-reactive data.\n *\n * Exists because `structuredClone` cannot be used on values read from the vee-validate form\n * context: those are Vue reactive Proxies (any branch value that is an object, i.e. a node with\n * `children`), and `structuredClone` throws a `DataCloneError` on a Proxy. Recursively copying\n * by property instead reads *through* the proxy, so the clone comes out raw.\n */\nexport function deepCloneValue<T>(value: T): T {\n if (value === null || typeof value !== 'object')\n return value;\n\n if (value instanceof Date)\n return new Date(value) as T;\n\n if (Array.isArray(value))\n return value.map(item => deepCloneValue(item)) as T;\n\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(value))\n clone[key] = deepCloneValue((value as Record<string, unknown>)[key]);\n\n return clone as T;\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { GenericValidateFunction } from 'vee-validate';\nimport type { ComputedRef } from 'vue';\nimport type { ChoiceOccurrence, LimitedFieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField, useFieldValue, useFormContext } from 'vee-validate';\nimport { computed, inject, ref, watch } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { useFieldArrayExtended } from '@/core/useFieldArrayExtended';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\nimport { createValidation } from '@/utils/createValidation';\nimport { deepCloneValue } from '@/utils/deepCloneValue';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\n\n// #region Interfaces\nexport interface Emit {\n /** Emitted whenever any child option's value changes; payload is the array of all child values in choice-option order. */\n (e: 'update:modelValue', value: unknown): void\n /** Bubbled up from child `DynamicFormItem` instances; carries the updated computed field metadata. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n\n// Tracks how much of the choice \"budget\" each child is consuming.\ninterface ChildValue {\n value: any\n occurrences: number // how many instances of this child are currently shown\n valuesCount: number // how many of those instances actually have a value\n maxOccurrences: number // the child's own maxOccurs\n}\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\n// #endregion\n\n// #region Internal tracking\n// Plain variables (not reactive) to avoid triggering renders when measuring analytics.\nlet _analytics_updateCallCount = 0;\nlet _analytics_occurrencesCalculatedCount = 0;\nlet _analytics_activeChoiceOccurrencesCalculatedCount = 0;\nlet _analytics_renderedChoiceOccurrencesCalculatedCount = 0;\n// #endregion\n\n// #region Computed state\n\n// --- Path ---\n\nconst field = computed(() => props.fieldMetadata);\n\n// A choice field itself has no path in the XML/json hierarchy, so we use the nearest ancestor's path\n// for vee-validate registration and for passing down to children as pathOverride.\nconst closestPath = computed(() =>\n overridePath(field.value.path ?? '', props.pathOverride));\n\nconst normalizedPath = computed(() => normalizePath(closestPath.value));\n\n// Read once at setup, not reactively: flipping the render mode mid-form would cause a\n// mount-unmount storm, and a whole watcher below is only registered when it is true.\nconst explicitChoiceSelection = props.fieldMetadata?.explicitChoiceSelection === true;\n\n// The ordering flags, by contrast, are read reactively: none of them changes the shape of the\n// stored values or requires setup-time structure, so a consumer may flip them live through the\n// metadata prop and the choice adjusts in place, without a remount. They stay excluded from\n// ComputedPropsFieldType, so the metadata prop (not computedProps) is the sanctioned channel.\nconst preserveOnSwitch = computed(() => field.value?.preserveOnSwitch === true);\n// Only 'added' is meaningful; absent or 'grouped' fall through to the identity path below.\nconst displayOrder = computed(() => field.value?.displayOrder === 'added');\nconst preserveOrderRequested = computed(() => field.value?.preserveOrder === true);\n\n// preserveOrder is all-or-nothing: `order` can only live inside an object (a branch with\n// children), and persisting it for some branches but not others would leave a sequence that is\n// only half reconstructable after a reload. One scalar-leaf branch therefore disables the\n// persisted tier for the whole choice (with a dev warning below); the ephemeral insertionOrder\n// tier still covers every branch shape. The branch list is static metadata, so the shape gate is\n// a plain setup-time constant.\nconst allBranchesObjectShaped = (field.value?.choice ?? []).every(child => (child.children?.length ?? 0) > 0);\nconst preserveOrderEffective = computed(() => preserveOrderRequested.value && allBranchesObjectShaped);\n\n// Used to clear a deselected branch's data on switch. A plain useFormContext() resolves here\n// since this component is always a descendant of the useForm() call in useDynamicForm.\nconst formContext = useFormContext();\n\n// The three refs below are ephemeral UI state, never written to form `values`.\n\n// Which branch is active in the maxOccurs:1 explicit case.\nconst explicitlySelectedBranch = ref<string | null>(null);\n\n// preserve-on-switch stash, keyed by branchKey so its size stays bounded by the branch count.\nconst stashedBranchValues = ref<Record<string, unknown>>({});\n\n// Add-press order for the repeatable explicit case, keyed by the stable occurrenceKey so it\n// survives an ancestor reindex. insertionCounter is plain (like the analytics counters): only\n// the Map write needs to be reactive, not the counter.\nconst insertionOrders = ref<Map<string, number>>(new Map());\nlet insertionCounter = 0;\n\n// Per-branch value, read straight from the value tree so an unmounted branch's pre-loaded data\n// still reads as selected (childValues only hears from a branch once it mounts). Via a getter,\n// not a string, so it keeps tracking the right path when pathOverride reindexes.\nconst branchValueRefs = (field.value?.choice ?? []).map(child =>\n useFieldValue(() => child.path ? overridePath(child.path, props.pathOverride) : ''),\n);\n\n// Per-branch reactive path + field array for the repeatable case. Each path is a computed, not a\n// setup-time string, so the field array keeps following a pathOverride that reindexes when an\n// earlier sibling array item is removed.\nconst branchPaths = (field.value?.choice ?? []).map(child =>\n computed(() => child.path ? normalizePath(overridePath(child.path, props.pathOverride)) : ''));\nconst branchFieldArrays = branchPaths.map(branchPath => useFieldArrayExtended(branchPath));\n\n// --- Occurrence limits ---\n\nconst minOccurs = computed(() =>\n props.minOccursOverride !== undefined\n ? props.minOccursOverride\n : (field.value?.minOccurs ?? 1),\n);\n\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined\n ? props.maxOccursOverride\n : (field.value?.maxOccurs ?? 1),\n);\n\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// Propagate optional/disabled state to children.\nconst _minOccursOverride = computed(() =>\n minOccurs.value === 0 ? 0 : undefined,\n);\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : undefined,\n);\n\n// When the choice itself may occur more than once, its children become array fields too.\nconst childrenAreArrays = computed(() => field.value?.maxOccurs > 1 ? 'array' : undefined);\n\n// A repeatable choice renders through the -choice-array slot family, a single one through\n// -choice. Keyed off the declared maxOccurs (not the overridable budget) so disabling via a\n// maxOccursOverride of 0 cannot flip an otherwise repeatable choice into the single family.\nconst slotType = computed(() =>\n `${field.value?.type}${field.value?.maxOccurs > 1 ? '-choice-array' : '-choice'}`);\n\n// --- Child value tracking ---\n\n// Each child reports its current value here so we can calculate the shared occurrence budget.\nconst childValues = ref<{ [index: string]: ChildValue }>({});\n\n// Raw child values are emitted upward as-is; occurrence-aware counting happens below.\nconst values = computed(() => Object.values(childValues.value).map(x => x.value));\n\n// --- Single-child shortcut ---\n\n// One option means no real branching: skip the occurrence math and render it directly. Not\n// applied under explicitChoiceSelection, where it behaves as an \"add this block / remove it\".\nconst singleChild = computed(() =>\n (!explicitChoiceSelection && field.value?.choice?.length === 1) ? field.value?.choice[0] as InternalMetadata : undefined,\n);\n\n// The single branch's cap: its declared maxOccurs, tightened by its opt-in maxOccursTotal.\n// Without this the singleChild shortcut would be the one render path where maxOccursTotal is\n// silently ignored, in the UI cap and in validation alike (the branch's own xsd_maxOccurs\n// picks up loaded data over the cap).\nconst singleChildMaxOccursOverride = computed(() => {\n if (_maxOccursOverride.value === 0)\n return 0;\n const child = singleChild.value;\n if (child?.maxOccursTotal === undefined)\n return _maxOccursOverride.value;\n return Math.min(child.maxOccursTotal, child.maxOccurs ?? 1);\n});\n\n// --- Occurrence budget calculation ---\n\n/**\n * For each child, computes how many of the shared choice occurrences it consumes and the\n * min/max overrides to pass down. Children compete for one shared budget: with choice\n * maxOccurs=4 and two children each maxOccurs=2, every 2 child items count as 1 choice\n * occurrence, so the more one child uses the less the others may.\n */\nconst occurrences = computed(() => {\n _analytics_occurrencesCalculatedCount++;\n\n const _occurrences: {\n [index: string]: {\n childValuesCount: number\n childOccurrences: number\n childMaxOccurrences: number\n choiceValuesCount: number\n choiceOccurrences: number\n overrideChildMaxOccurrences: number | undefined\n overrideChildMinOccurrences: number | undefined\n // The branch's opt-in total cap, carried here so pass 2 can clamp to it directly.\n maxOccursTotal: number | undefined\n }\n } = {};\n\n // Initialise defaults for every child upfront so all indices exist even if no value arrived yet.\n field.value?.choice?.forEach((child, i) => {\n _occurrences[i] = {\n childValuesCount: 0,\n childOccurrences: 0,\n childMaxOccurrences: 1,\n choiceValuesCount: 0,\n choiceOccurrences: 0,\n overrideChildMaxOccurrences: undefined,\n overrideChildMinOccurrences: 0, // children are optional by default inside a choice\n maxOccursTotal: child.maxOccursTotal,\n };\n });\n\n const _maxOccurs = maxOccurs.value ?? 1;\n\n // When the whole choice is disabled (maxOccurs=0), disable all children immediately.\n if (_maxOccurs === 0) {\n field.value?.choice?.forEach((_, i) => {\n _occurrences[i].overrideChildMaxOccurrences = 0;\n _occurrences[i].overrideChildMinOccurrences = 0;\n });\n return _occurrences;\n }\n\n // Pass 1: convert each child's raw item count into choice-occurrence units.\n for (const [key, child] of Object.entries(childValues.value ?? {})) {\n // e.g. choice.maxOccurs=4, child.maxOccurs=2: every 2 child items = 1 choice occurrence.\n let choiceOccurrences = Math.ceil(child.occurrences / child.maxOccurrences);\n const choiceValuesCount = Math.ceil(child.valuesCount / child.maxOccurrences);\n\n // A non-array child is always shown, so its occupancy is whether it has a value, not that\n // it is shown.\n const totalChildOccurrences = _maxOccurs * child.maxOccurrences;\n if (totalChildOccurrences === 1) {\n choiceOccurrences = choiceValuesCount;\n }\n\n _occurrences[key] = {\n childValuesCount: child.valuesCount,\n childOccurrences: child.occurrences,\n childMaxOccurrences: child.maxOccurrences,\n choiceOccurrences,\n choiceValuesCount,\n overrideChildMinOccurrences: child.valuesCount === 0 ? 0 : undefined, // optional when empty\n overrideChildMaxOccurrences: undefined, // calculated in pass 2\n maxOccursTotal: field.value?.choice?.[Number(key)]?.maxOccursTotal,\n };\n }\n\n const totalChoiceOccurrences = Object.values(_occurrences).reduce(\n (acc, value) => acc + value.choiceOccurrences,\n 0,\n );\n\n // Pass 2: derive each child's remaining headroom from what the others are using. We work\n // backwards from the combined total to stay accurate despite the Math.ceil() rounding above.\n Object.values(_occurrences).forEach((value) => {\n const othersChoiceOccurrences = totalChoiceOccurrences - value.choiceOccurrences;\n const othersAsChildOccurrences = othersChoiceOccurrences * value.childMaxOccurrences;\n const totalChildOccurrences = _maxOccurs * value.childMaxOccurrences;\n\n // A budget shortfall caused by siblings may disable an empty branch, but never drops a\n // branch below its filled item count (which would disable or falsely flag loaded data with\n // a shifting budget-relative cap, possibly even a negative one). Over-budget states are\n // reported by the choice-level rules instead.\n let overrideChildMaxOccurrences = Math.max(\n totalChildOccurrences - othersAsChildOccurrences,\n value.childValuesCount,\n );\n\n // maxOccursTotal is a raw-item cap independent of the shared budget; it can only tighten.\n if (value.maxOccursTotal !== undefined)\n overrideChildMaxOccurrences = Math.min(overrideChildMaxOccurrences, value.maxOccursTotal);\n\n value.overrideChildMaxOccurrences = overrideChildMaxOccurrences;\n });\n\n return _occurrences;\n});\n\n// Total number of filled choices (in choice-occurrence units, not raw item counts).\nconst valuesCount = computed(() =>\n Object.values(occurrences.value).reduce(\n (acc, c) => acc + c.choiceValuesCount,\n 0,\n ),\n);\n\n// --- Explicit selection (maxOccurs: 1) ---\n\n// The active branch(es), merging the value-driven view (a branch that holds real data) with the\n// explicit view (explicitlySelectedBranch). Loaded data reads as selected for free: a branch\n// with a value appears here even if it was never explicitly selected.\nconst activeChoiceOccurrences = computed<ChoiceOccurrence[]>(() => {\n _analytics_activeChoiceOccurrencesCalculatedCount++;\n\n const active: ChoiceOccurrence[] = [];\n\n field.value?.choice?.forEach((child, index) => {\n // Repeatable case: every item in the branch's field array is an active occurrence, filled or\n // not (an empty placeholder is a committed occurrence, like an unfilled array item). Grouped\n // by branch order then by index, derived purely from the value tree.\n if (explicitChoiceSelection && maxOccurs.value > 1) {\n const branchFields = branchFieldArrays[index]?.fields.value ?? [];\n branchFields.forEach((_, occurrenceIndex) => {\n active.push({ branchKey: child.name as string, index: occurrenceIndex });\n });\n return;\n }\n\n const valueDriven = checkTreeHasValue(branchValueRefs[index]?.value);\n const isExplicitlySelected = explicitChoiceSelection && explicitlySelectedBranch.value === child.name;\n\n if (valueDriven || isExplicitlySelected) {\n active.push({ branchKey: child.name as string, index: 0 });\n }\n });\n\n return active;\n});\n\n// The list the `-choice-array-item` v-for renders. Identical to activeChoiceOccurrences unless\n// displayOrder is 'added' (the early return adds no reactive dependency otherwise). When 'added':\n// keyless occurrences (loaded data) sort first in grouped order, then keyed ones ascending. The\n// key is the persisted `order` under preserveOrder (survives a remount), else insertionOrder.\nconst renderedChoiceOccurrences = computed<ChoiceOccurrence[]>(() => {\n _analytics_renderedChoiceOccurrencesCalculatedCount++;\n\n if (!displayOrder.value)\n return activeChoiceOccurrences.value;\n\n function sortKeyFor(occurrence: ChoiceOccurrence): number | undefined {\n if (preserveOrderEffective.value)\n return (occurrenceValue(occurrence) as { order?: number } | null)?.order;\n return insertionOrders.value.get(occurrenceKey(occurrence));\n }\n\n return activeChoiceOccurrences.value\n .map(occurrence => ({ occurrence, sortKey: sortKeyFor(occurrence) }))\n .sort((a, b) => {\n const aAdded = a.sortKey !== undefined;\n const bAdded = b.sortKey !== undefined;\n if (aAdded !== bAdded)\n return aAdded ? 1 : -1;\n if (!aAdded)\n return 0; // both keyless: keep grouped order (sort is stable)\n return a.sortKey! - b.sortKey!;\n })\n .map(entry => entry.occurrence);\n});\n\n// Choice-occurrence-unit count of what is consumed, derived from each branch's field array\n// length. In the repeatable case a branch's maxOccurs batches its items into slots\n// (ceil(items / branchMax)), the same unit xsd_choiceMinOccurs counts in, so an \"N of maxOccurs\"\n// indicator built on this never over-counts.\nconst usedChoiceOccurrences = computed(() => {\n if (disabled.value)\n return 0;\n\n if (explicitChoiceSelection && maxOccurs.value > 1) {\n // maxOccurs is non-null: correctMetadataAndSetDefaults has defaulted every branch's.\n return branchFieldArrays.reduce((total, fieldArray, index) => {\n const branchMaxOccurrences = field.value!.choice![index].maxOccurs!;\n return total + Math.ceil(fieldArray.fields.value.length / branchMaxOccurrences);\n }, 0);\n }\n\n if (explicitChoiceSelection)\n return activeChoiceOccurrences.value.length;\n\n return valuesCount.value;\n});\n\n// In explicit mode a selected branch (maxOccurs:1) or an added occurrence (maxOccurs > 1) counts\n// toward xsd_choiceMinOccurs even while empty; its own required fields validate separately. Auto\n// mode stays value-driven.\nconst effectiveValuesCount = computed(() => {\n if (explicitChoiceSelection && maxOccurs.value === 1)\n return Math.max(valuesCount.value, explicitlySelectedBranch.value ? 1 : 0);\n\n if (explicitChoiceSelection && maxOccurs.value > 1)\n return Math.max(valuesCount.value, usedChoiceOccurrences.value);\n\n return valuesCount.value;\n});\n\n// The offending branch's maxOccursTotal cap, or undefined when no branch breaches its own\n// cap. Reads occurrences (already a transitive dependency of combinedValidation below), so this\n// adds no new reactive source. Returns the first offending branch's cap in declaration order:\n// a later breach on a different branch is never reached once an earlier one is found.\nconst maxOccursTotalBreach = computed(() =>\n Object.values(occurrences.value)\n .find(o => o.maxOccursTotal !== undefined && o.childOccurrences > o.maxOccursTotal)\n ?.maxOccursTotal,\n);\n\n// --- Vee-Validate field context ---\n\nconst combinedValidation = computed(() => {\n if (singleChild.value)\n return; // single-child choices are validated by the child itself\n\n if (disabled.value)\n return;\n\n const _messages = settings?.value?.messages;\n const _validations: GenericValidateFunction[] = [];\n\n // Two independent guards, not else-if: the list shape must be able to hold both rules if the\n // minOccurs <= maxOccurs invariant is ever relaxed by a caller's metadata.\n if (effectiveValuesCount.value < minOccurs.value)\n _validations.push(createValidation('xsd_choiceMinOccurs', minOccurs.value, _messages?.choiceMinOccurs));\n if (usedChoiceOccurrences.value > maxOccurs.value)\n _validations.push(createValidation('xsd_choiceMaxOccurs', maxOccurs.value, _messages?.choiceMaxOccurs));\n\n // Pushed last so a co-occurring choice-occurrence rule above wins the displayed errorMessage.\n if (maxOccursTotalBreach.value !== undefined)\n _validations.push(createValidation('vdf_maxOccursTotal', maxOccursTotalBreach.value, _messages?.maxOccursTotal));\n\n return _validations.length ? _validations : undefined;\n});\n\n// A choice field has no entry in the values tree, so validation anchors to the nearest parent\n// path to give errors a home.\nconst { errors, errorMessage } = useField(normalizedPath, combinedValidation, field.value?.fieldOptions);\nconst fieldContext: LimitedFieldContext = { label: field.value?.fieldOptions?.label, errors, errorMessage, value: values };\n\n// #endregion\n\n// #region Watchers and lifecycle events\n\n// Seed childValues so every child index exists from the start, so occurrences never returns\n// undefined for a child that hasn't emitted yet. Existing indices are skipped so a metadata\n// change (e.g. a recomputed metadataWithEdit) does not reset values the user has entered.\nwatch(field, (_field) => {\n if (!_field)\n return;\n\n _field.choice?.forEach((child, index) => {\n if (!(index in childValues.value))\n updateChildValue(undefined, index, child.maxOccurs);\n });\n}, { immediate: true });\n\n// Repeatable case: keep childValues in sync with each branch's field array so the occurrences /\n// valuesCount machinery (and the shared budget it feeds) reflects reality without every\n// occurrence emitting update:modelValue. The branch's maxOccurs is the batch size: every group of\n// that many raw items consumes one shared choice slot, as a repeated element does in <xs:choice>.\nif (explicitChoiceSelection) {\n watch(\n () => branchFieldArrays.map(fieldArray => fieldArray.values.value),\n (allBranchValues) => {\n if (maxOccurs.value <= 1)\n return;\n\n allBranchValues.forEach((branchValues, index) => {\n const branchMaxOccurrences = field.value!.choice![index].maxOccurs!;\n updateChildValue(branchValues, index, branchMaxOccurrences);\n });\n },\n { immediate: true },\n );\n}\n\n// #endregion\n\n// #region Methods\n\nfunction updateChildValue(\n value: any,\n childIndex: number | undefined,\n maxOccurrences: number = 1,\n skipCalculations: boolean = false,\n) {\n // Used by singleChild to forward value updates without recalculating the occurrence budget.\n if (skipCalculations) {\n emits('update:modelValue', values.value);\n return;\n }\n\n _analytics_updateCallCount++;\n\n if (childIndex === undefined)\n return;\n\n let calculateValues = Array.isArray(value) ? value : [value];\n\n // For a non-array child an undefined means \"no value\"; filter it out so it doesn't inflate\n // the occurrence count.\n const _maxOccurs = maxOccurs.value ?? 1;\n const totalChildOccurrences = _maxOccurs * maxOccurrences;\n if (totalChildOccurrences === 1) {\n calculateValues = calculateValues.filter(x => x !== undefined);\n }\n\n const occurrences = calculateValues.length;\n const valuesCount = calculateValues.filter(v => checkTreeHasValue(v)).length;\n\n const childValue = childValues.value[childIndex] ?? ({} as ChildValue);\n childValue.value = value;\n childValue.occurrences = occurrences;\n childValue.valuesCount = valuesCount;\n childValue.maxOccurrences = maxOccurrences;\n\n if (!childValues.value[childIndex]) {\n childValues.value[childIndex] = childValue;\n }\n\n emits('update:modelValue', values.value);\n};\n\n// --- Explicit selection primitives ---\n\nfunction branchIndexOf(branchKey: string): number {\n return field.value?.choice?.findIndex(child => child.name === branchKey) ?? -1;\n}\n\n// Max-occurs override for the single active branch (maxOccurs:1). Only one branch is ever active,\n// so there is no shared budget to contend for, only the branch's own maxOccursTotal. Read from\n// static metadata, not the reactive `occurrences`, so it stays stable as the branch populates\n// (no extra render) while still applying the cap. maxOccursTotal can only tighten the branch's\n// declared maxOccurs, never widen it past the XSD ceiling.\nfunction branchMaxOccursOverride(branchKey: string): number | undefined {\n if (_maxOccursOverride.value === 0)\n return 0; // whole choice disabled\n const branch = branchByKey(branchKey);\n if (branch?.maxOccursTotal === undefined)\n return _maxOccursOverride.value;\n return Math.min(branch.maxOccursTotal, branch.maxOccurs ?? 1);\n}\n\nfunction branchByKey(branchKey: string): InternalMetadata | undefined {\n const index = branchIndexOf(branchKey);\n return index >= 0 ? (field.value?.choice?.[index] as InternalMetadata) : undefined;\n}\n\n// Clears a deselected branch's data through the form context. The residual undefined-valued key\n// setInPath leaves behind is the accepted contract; callers wanting a clean tree run\n// removeNullValues at submit time. The childValues entry is reset synchronously here (not left to\n// the branch's unmount) so valuesCount/combinedValidation settle in one tick.\n//\n// When `stash` is true (only the switch-away path opts in) the branch's current values are\n// deep-cloned into stashedBranchValues before the clear.\nfunction clearBranch(branchKey: string, options: { stash?: boolean } = {}) {\n const index = branchIndexOf(branchKey);\n if (index < 0)\n return;\n\n const branchChild = field.value?.choice?.[index];\n const branchPath = branchChild?.path ? overridePath(branchChild.path, props.pathOverride) : undefined;\n\n if (options.stash) {\n // deepCloneValue, not structuredClone: a branch with children reads back as a reactive Proxy,\n // and structuredClone throws DataCloneError on a Proxy, which would abort the switch.\n stashedBranchValues.value[branchKey] = deepCloneValue(branchValueRefs[index]?.value ?? undefined);\n }\n else if (branchKey in stashedBranchValues.value) {\n // A non-preserving clear (explicit remove/deselect) drops any earlier stash, so re-selecting\n // the branch later starts empty instead of resurrecting discarded data.\n delete stashedBranchValues.value[branchKey];\n }\n\n if (branchPath) {\n formContext?.setFieldValue(branchPath as any, undefined, false);\n }\n\n const existing = childValues.value[index];\n if (existing) {\n existing.value = undefined;\n existing.occurrences = 0;\n existing.valuesCount = 0;\n }\n}\n\n// Restores a stashed branch's values, if any, just before the branch is marked active again, so\n// its DynamicFormItem mounts with the data already present (the value lands in the values tree\n// before the branch reads it). shouldValidate: false mirrors clearBranch so a restored-but-empty\n// required field does not flash an error. Membership is checked with `in`, not truthiness, since\n// an empty branch can be stashed as `undefined`. No branchPath fallback: the only caller\n// (addChoiceOccurrence) has already confirmed the branch exists.\nfunction restoreStashedBranch(branchKey: string) {\n if (!preserveOnSwitch.value || !(branchKey in stashedBranchValues.value))\n return;\n\n const index = branchIndexOf(branchKey);\n const branchPath = overridePath(field.value!.choice![index].path as string, props.pathOverride);\n formContext?.setFieldValue(branchPath as any, stashedBranchValues.value[branchKey], false);\n}\n\n/** Mark a branch active (maxOccurs:1) or add one occurrence of it (maxOccurs > 1). No-op when canAddChoiceOccurrence is false, or the branchKey is unknown. */\nfunction addChoiceOccurrence(branchKey: string) {\n // Also covers an unknown branchKey (canAddChoiceOccurrence returns false when branchIndexOf < 0).\n if (!canAddChoiceOccurrence(branchKey))\n return;\n\n const index = branchIndexOf(branchKey);\n\n if (maxOccurs.value > 1) {\n // Repeatable case: push a real (possibly empty) item into the branch's field array, mirroring\n // DynamicFormItemArray's _addItem. The pushed item IS the selection, so activeChoiceOccurrences\n // picks it up on the next recompute. Insertion order is assigned here, at press time, not\n // lazily over the grouped activeChoiceOccurrences list (which would encode grouped order).\n const newOccurrenceIndex = branchFieldArrays[index]?.fields.value.length ?? 0;\n\n // Cross-branch count before the push. When the persisted tier is active every branch is\n // object-shaped, and normalizeOrder keeps the existing orders contiguous 1..N, so count + 1\n // is always the next rank.\n const activeCountBeforePush = activeChoiceOccurrences.value.length;\n\n if (preserveOrderEffective.value) {\n // Seeded in the push so the entry is born holding `order`, with no null-to-object transition.\n branchFieldArrays[index]?.push({ order: activeCountBeforePush + 1 });\n }\n else {\n branchFieldArrays[index]?.push(null); // empty placeholder\n }\n\n insertionOrders.value.set(occurrenceKey({ branchKey, index: newOccurrenceIndex }), ++insertionCounter);\n return;\n }\n\n // maxOccurs: 1: mark a single branch active, clearing any other currently-active branch.\n if (explicitlySelectedBranch.value === branchKey)\n return; // idempotent: already selected\n\n // Iterate activeChoiceOccurrences, not explicitlySelectedBranch: a branch can be active purely\n // from loaded values, and switching away must still clear it or two branches end up active.\n for (const occurrence of activeChoiceOccurrences.value) {\n if (occurrence.branchKey !== branchKey) {\n clearBranch(occurrence.branchKey, { stash: preserveOnSwitch.value });\n }\n }\n\n restoreStashedBranch(branchKey);\n\n explicitlySelectedBranch.value = branchKey;\n}\n\n/** Remove a previously added occurrence. In maxOccurs > 1 the index selects which occurrence to remove; omitting it removes the last one, mirroring addChoiceOccurrence(branchKey) which appends with only a branchKey. In maxOccurs:1 the index is ignored and it deselects the active branch. No-op for an unknown branchKey, an inactive branch, an empty branch, or an out-of-range index. */\nfunction removeChoiceOccurrence(branchKey: string, index?: number) {\n const branchIdx = branchIndexOf(branchKey);\n if (branchIdx < 0)\n return;\n\n if (maxOccurs.value > 1) {\n const fieldsLength = branchFieldArrays[branchIdx]?.fields.value.length ?? 0;\n\n // Default to the last occurrence so a template can offer a plain \"remove one\" control\n // symmetric with addChoiceOccurrence(branchKey), without tracking indices itself.\n const targetIndex = index ?? fieldsLength - 1;\n if (targetIndex < 0 || targetIndex >= fieldsLength)\n return; // empty branch or out-of-range: no-op, no throw\n\n // Drop the removed occurrence's ephemeral add-order before it leaves the field array, so the\n // Map stays bounded by the live occurrence count over a long add/remove session instead of\n // accumulating an entry per press. Resolved off the still-present entry's stable key.\n const removedKey = occurrenceKey({ branchKey, index: targetIndex });\n\n branchFieldArrays[branchIdx]?.remove(targetIndex);\n insertionOrders.value.delete(removedKey);\n\n if (preserveOrderEffective.value)\n normalizeOrder();\n\n return;\n }\n\n // maxOccurs: 1: index is ignored; deselect the active branch.\n const isActive = activeChoiceOccurrences.value.some(occurrence => occurrence.branchKey === branchKey);\n if (!isActive)\n return;\n\n clearBranch(branchKey);\n\n if (explicitlySelectedBranch.value === branchKey) {\n explicitlySelectedBranch.value = null;\n }\n}\n\n/**\n * Per-branch \"may add\" guard: false when the choice is disabled or branchKey is unknown.\n * maxOccurs:1 has no per-branch budget. maxOccurs > 1 checks the shared budget via the\n * occurrences computed's overrideChildMaxOccurrences, which already folds in the branch's\n * maxOccurs batch size and its optional maxOccursTotal cap, so no separate check is needed.\n */\nfunction canAddChoiceOccurrence(branchKey: string): boolean {\n if (disabled.value)\n return false;\n\n const index = branchIndexOf(branchKey);\n if (index < 0)\n return false;\n\n if (maxOccurs.value <= 1)\n return true; // no per-branch budget in the single case\n\n const branchCount = branchFieldArrays[index].fields.value.length;\n\n const remainingSharedBudget = occurrences.value[index]?.overrideChildMaxOccurrences;\n return remainingSharedBudget === undefined || branchCount < remainingSharedBudget;\n}\n\n// Per-branch field array helper for a branchKey. An unknown key yields undefined via plain\n// negative-index semantics (branchFieldArrays[-1]), no explicit guard needed.\nfunction branchFieldArrayFor(branchKey: string) {\n return branchFieldArrays[branchIndexOf(branchKey)];\n}\n\n// The raw field-array key of an occurrence. Each branch generates these independently, so the same\n// raw key can recur across branches; namespace it (see occurrenceKey) for a whole-list-unique key.\nfunction rawOccurrenceKey(occurrence: ChoiceOccurrence): string | number {\n return branchFieldArrayFor(occurrence.branchKey).fields.value[occurrence.index].key;\n}\n\n// The Vue :key for an occurrence, namespaced with branchKey so two branches' occurrences can't\n// collide on the same raw key and make v-for reuse one branch's instance for another's.\nfunction occurrenceKey(occurrence: ChoiceOccurrence): string {\n return `${occurrence.branchKey}:${rawOccurrenceKey(occurrence)}`;\n}\n\n/** The resolved pathOverride for a single repeatable-choice occurrence, e.g. `pick.apiEndpoint[0]`. */\nfunction occurrencePathOverride(occurrence: ChoiceOccurrence): string {\n return `${branchPaths[branchIndexOf(occurrence.branchKey)].value}[${occurrence.index}]`;\n}\n\n/** The occurrence's own current value, read directly off its branch's field array. */\nfunction occurrenceValue(occurrence: ChoiceOccurrence): unknown {\n return branchFieldArrayFor(occurrence.branchKey).fields.value[occurrence.index].value;\n}\n\n// Re-ranks every occurrence's `order` to a contiguous 1..N, preserving the relative order the\n// existing values encode: an occurrence keeps its position by its current `order`, one missing\n// it seeds from this session's add-order (insertionOrder) when it has one, else from its grouped\n// position. The stable sort keeps grouped order between equal keys, so gapped, duplicated and\n// missing values all resolve deterministically. Only occurrences whose rank changed are written.\n// Runs at mount, after a removal, and when preserveOrder flips on, so `order` is contiguous\n// 1..N at every point the add path relies on it.\n//\n// Seeding a missing `order` from insertionOrder is what makes a live preserveOrder flip-on keep\n// the sequence the user built rather than snapping back to grouped order. The two seed sources\n// never clash: an occurrence added this session under an active persisted tier is born holding\n// `order`, so an occurrence with an insertionOrder but no `order` only exists while the tier is\n// off, and at that moment no occurrence has an `order` at all. Offsetting session seeds past\n// `total` keeps a loaded occurrence (no add-press this session) ahead of session-added ones, in\n// its grouped position, matching the ephemeral tier's fallback. With no session adds (mount /\n// reload) every seed is grouped position, unchanged.\nfunction normalizeOrder() {\n const occurrences = activeChoiceOccurrences.value;\n const total = occurrences.length;\n\n const ranked = occurrences\n .map((occurrence, position) => {\n const currentOrder = (occurrenceValue(occurrence) as { order?: number } | null)?.order;\n const insertionOrder = insertionOrders.value.get(occurrenceKey(occurrence));\n const sortKey = currentOrder\n ?? (insertionOrder !== undefined ? total + insertionOrder : position + 1);\n return { occurrence, currentOrder, sortKey };\n })\n .sort((a, b) => a.sortKey - b.sortKey);\n\n ranked.forEach(({ occurrence, currentOrder }, position) => {\n const newRank = position + 1;\n if (currentOrder === newRank)\n return;\n\n formContext?.setFieldValue(`${occurrencePathOverride(occurrence)}.order` as any, newRank, false);\n });\n}\n\n// Removes `order` from every occurrence when preserveOrder flips off while mounted, so opting\n// out actually takes the persisted data out of the submitted shape. The write leaves the same\n// residual undefined-valued key clearBranch's contract accepts; removeNullValues strips it at\n// submit time. Only ever runs on an observed flip, never on mounting with the flag absent, so\n// loaded data is never touched by a flag that merely is not set.\nfunction stripOrder() {\n activeChoiceOccurrences.value.forEach((occurrence) => {\n const value = occurrenceValue(occurrence) as { order?: number } | null;\n if (value && typeof value === 'object' && 'order' in value)\n formContext?.setFieldValue(`${occurrencePathOverride(occurrence)}.order` as any, undefined, false);\n });\n}\n\n// Memoized per-occurrence remove handlers, keyed by occurrenceKey, so an unaffected occurrence\n// keeps the same handler reference across an add/remove elsewhere and doesn't needlessly re-render\n// (a plain inline arrow would hand each one a fresh reference). The handler resolves the\n// occurrence's current index by its raw key at call time, so it removes the right item even after\n// an earlier removal reindexed it.\nconst occurrenceRemoveHandlers = new Map<string, () => void>();\nfunction removeItemHandlerFor(occurrence: ChoiceOccurrence): () => void {\n const mapKey = occurrenceKey(occurrence);\n const cached = occurrenceRemoveHandlers.get(mapKey);\n if (cached)\n return cached;\n\n const rawKey = rawOccurrenceKey(occurrence);\n const handler = () => {\n const currentIndex = branchFieldArrayFor(occurrence.branchKey).fields.value.findIndex(entry => entry.key === rawKey);\n if (currentIndex >= 0) {\n removeChoiceOccurrence(occurrence.branchKey, currentIndex);\n }\n occurrenceRemoveHandlers.delete(mapKey);\n };\n occurrenceRemoveHandlers.set(mapKey, handler);\n return handler;\n}\n\n// Memoized per-branch add handlers, for the same render-stability reason as the remove handlers.\n// \"Add\" on an occurrence appends another occurrence of its own branch, so a generic -array-item\n// template behaves like a real array item. Keyed by branchKey, so the map stays bounded by the\n// branch count.\nconst branchAddHandlers = new Map<string, () => void>();\nfunction addItemHandlerFor(branchKey: string): () => void {\n let handler = branchAddHandlers.get(branchKey);\n if (!handler) {\n handler = () => addChoiceOccurrence(branchKey);\n branchAddHandlers.set(branchKey, handler);\n }\n return handler;\n}\n\n// Whether the persisted tier is running right now: the effective flag, in the repeatable\n// explicit case, with the choice not disabled.\nconst persistedTierActive = computed(() =>\n preserveOrderEffective.value && explicitChoiceSelection && maxOccurs.value > 1);\n\n// Whenever the persisted tier becomes active (mount with the flag on, a live flip-on, or the\n// choice re-enabling), normalize existing occurrences so `order` is contiguous 1..N before the\n// next add-press relies on it. immediate: true makes the mount case run synchronously during\n// setup, before the template mounts and any add-press can occur.\nwatch(persistedTierActive, (isActive) => {\n if (isActive)\n normalizeOrder();\n}, { immediate: true });\n\n// Strip `order` only when the flag itself flips off while the choice is still repeatable, not\n// when the tier merely deactivates because the choice got disabled (a maxOccursOverride of 0 is\n// often temporary, and stripping there would destroy data on a disable).\nwatch(preserveOrderEffective, (isOn, wasOn) => {\n if (!explicitChoiceSelection || maxOccurs.value <= 1)\n return;\n\n if (!isOn && wasOn)\n stripOrder();\n});\n\nif (import.meta.env.DEV) {\n // Misconfiguration warnings, once per condition per component lifetime.\n let warnedScalarBranches = false;\n let warnedOrderCollision = false;\n watch(preserveOrderRequested, (requested) => {\n if (!requested || !explicitChoiceSelection || (field.value?.maxOccurs ?? 1) <= 1)\n return;\n\n if (!allBranchesObjectShaped && !warnedScalarBranches) {\n warnedScalarBranches = true;\n const scalarBranches = (field.value?.choice ?? [])\n .filter(child => (child.children?.length ?? 0) === 0)\n .map(child => `\"${child.name}\"`)\n .join(', ');\n console.warn(`[vue-dynamic-form] preserveOrder is disabled for this whole choice: branch(es) ${scalarBranches} have no children, so their occurrences have nowhere to attach an \"order\" field. Give every branch children to enable preserveOrder.`);\n }\n\n if (allBranchesObjectShaped && !warnedOrderCollision) {\n const collidingBranches = (field.value?.choice ?? [])\n .filter(child => child.children?.some(grandChild => grandChild.name === 'order'))\n .map(child => `\"${child.name}\"`)\n .join(', ');\n if (collidingBranches) {\n warnedOrderCollision = true;\n console.warn(`[vue-dynamic-form] preserveOrder writes an \"order\" field into each occurrence, and branch(es) ${collidingBranches} declare a child with that same name; the child's value will be overwritten by the ordering. Rename the child or do not enable preserveOrder on this choice.`);\n }\n }\n }, { immediate: true });\n}\n\n// #endregion\n</script>\n\n<template>\n <component\n :is=\"template\"\n v-slot=\"slotProps\"\n :type=\"slotType\"\n :field-metadata\n :field-context\n :slot-props\n :settings\n :required\n :index\n :disabled\n :can-add-items\n :can-remove-items\n :add-item\n :remove-item\n :add-choice-occurrence=\"addChoiceOccurrence\"\n :remove-choice-occurrence=\"removeChoiceOccurrence\"\n :can-add-choice-occurrence=\"canAddChoiceOccurrence\"\n :active-choice-occurrences=\"activeChoiceOccurrences\"\n :used-choice-occurrences=\"usedChoiceOccurrences\"\n >\n <DynamicFormItem\n v-if=\"singleChild\"\n :field-metadata=\"singleChild\"\n :path-override\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"singleChildMaxOccursOverride\"\n part-of-choice-field\n\n @update:model-value=\"updateChildValue($event, 0, singleChild!.maxOccurs, true)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n />\n <template v-else-if=\"explicitChoiceSelection && maxOccurs === 1\">\n <!-- Exactly one active branch, rendered directly (no -choice-array-item wrapping). -->\n <DynamicFormItem\n v-for=\"occurrence in activeChoiceOccurrences\"\n :key=\"occurrence.branchKey\"\n :field-metadata=\"(branchByKey(occurrence.branchKey) as InternalMetadata)\"\n :path-override\n :index=\"branchIndexOf(occurrence.branchKey)\"\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"branchMaxOccursOverride(occurrence.branchKey)\"\n :is-array-override=\"childrenAreArrays\"\n part-of-choice-field\n\n @update:model-value=\"updateChildValue($event, branchIndexOf(occurrence.branchKey), branchByKey(occurrence.branchKey)!.maxOccurs)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n />\n </template>\n <template v-else-if=\"explicitChoiceSelection\">\n <!--\n One DynamicFormItem per active occurrence across every branch, through the\n *-choice-array-item slot (mirrors DynamicFormItemArray's items). Iterated over\n renderedChoiceOccurrences (the displayed order); globalIndex is this loop's index over it.\n partOfArrayField makes DynamicFormItem skip its onBeforeUnmount \"write undefined back\"\n cleanup, since removal already goes through the branch's field array (writing here too\n would hit a since-reindexed path).\n -->\n <DynamicFormItem\n v-for=\"(occurrence, globalIndex) in renderedChoiceOccurrences\"\n :key=\"occurrenceKey(occurrence)\"\n :field-metadata=\"(branchByKey(occurrence.branchKey) as InternalMetadata)\"\n :path-override=\"occurrencePathOverride(occurrence)\"\n :index=\"occurrence.index\"\n :template\n :slot-props\n :max-occurs-override=\"1\"\n is-array-override=\"single\"\n part-of-array-field\n part-of-choice-field\n :branch-key=\"occurrence.branchKey\"\n :global-index=\"globalIndex\"\n :insertion-order=\"insertionOrders.get(occurrenceKey(occurrence))\"\n :can-add-items=\"canAddChoiceOccurrence(occurrence.branchKey)\"\n :add-item=\"addItemHandlerFor(occurrence.branchKey)\"\n :can-remove-items=\"true\"\n :remove-item=\"removeItemHandlerFor(occurrence)\"\n\n @update:computed-field=\"emits('update:computedField', $event)\"\n />\n </template>\n <template v-else>\n <DynamicFormItem\n v-for=\"(child, index) in field.choice\"\n :key=\"child.name\"\n :field-metadata=\"(child as InternalMetadata)\"\n :path-override\n :index\n :template\n :slot-props\n :min-occurs-override=\"occurrences[index]?.overrideChildMinOccurrences\"\n :max-occurs-override=\"occurrences[index]?.overrideChildMaxOccurrences\"\n :is-array-override=\"childrenAreArrays\"\n part-of-choice-field\n\n @update:model-value=\"updateChildValue($event, index, child.maxOccurs)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n />\n </template>\n </component>\n</template>\n","import type { FormValidationResult, GenericObject, Path } from 'vee-validate';\nimport type { InjectionKey } from 'vue';\nimport { FormContextKey } from 'vee-validate';\nimport { getCurrentInstance, inject } from 'vue';\n\ntype FormCtx = typeof FormContextKey extends InjectionKey<infer T> ? T : never;\n\nfunction getFormContext(): FormCtx | undefined {\n // When called in the same component as useDynamicForm, inject() looks at the parent's provides\n // and won't find the context that useForm() just provided on the current instance.\n // So we check the current instance's own provides first, then fall back to inject for child-component usage.\n const instance = getCurrentInstance();\n const ownProvides = (instance as any)?.provides as Record<symbol, unknown> | undefined;\n if (ownProvides && (FormContextKey as symbol) in ownProvides)\n return ownProvides[FormContextKey as symbol] as FormCtx;\n\n return inject(FormContextKey);\n}\n\n/**\n * Provides `validateSection` for partial form validation (e.g. wizard steps).\n *\n * Must be called in the same component as `useDynamicForm()` or in a descendant.\n * When called in the same component, it reads the form context from the current instance's\n * own provides rather than via `inject`, because `inject` looks at the *parent's* provides\n * and would miss a `useForm()` call made on the current instance.\n */\nexport function useValidatePartialForm() {\n const form = getFormContext()!;\n\n /**\n * Validates all vee-validate fields whose path equals or starts with `sectionPath`.\n * Matches `sectionPath` itself, `sectionPath.child`, and `sectionPath[0]` — but not\n * unrelated paths that happen to share a prefix string.\n *\n * @param sectionPath - Dot-notated path prefix (e.g. `'address'` or `'steps[0]'`)\n * @returns A `FormValidationResult` shaped identically to vee-validate's `validate()` return value,\n * scoped to the matched fields only.\n */\n async function validateSection(sectionPath: string): Promise<FormValidationResult<GenericObject>> {\n const fieldPaths = form.getAllPathStates()\n .map(state => state.path)\n .filter(path => path === sectionPath\n || path.startsWith(`${sectionPath}.`)\n || path.startsWith(`${sectionPath}[`));\n\n const validationResults = await Promise.all(\n fieldPaths.map(async path => ({\n path,\n result: await form.validateField(path as Path<GenericObject>),\n })),\n );\n\n const results = Object.fromEntries(\n validationResults.map(({ path, result }) => [path, result]),\n ) as FormValidationResult<GenericObject>['results'];\n\n const errors = Object.fromEntries(\n validationResults\n .filter(({ result }) => !result.valid)\n .map(({ path, result }) => [path, result.errors[0] ?? '']),\n ) as FormValidationResult<GenericObject>['errors'];\n\n return {\n valid: validationResults.every(({ result }) => result.valid),\n results,\n errors,\n source: 'fields',\n };\n }\n\n return { validateSection };\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { ComputedRef } from 'vue';\nimport type { LimitedFieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata, WizardGotoStepOptions } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField } from 'vee-validate';\nimport { computed, inject, ref } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { useValidatePartialForm } from '@/core/useValidatePartialForm';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\n\n// #region Interfaces\nexport interface Emit {\n /** Bubbled up from a page's own value changes; payload is unused (a wizard has no leaf value of its own). */\n (e: 'update:modelValue', value: unknown): void\n /** Bubbled up from child `DynamicFormItem` instances; carries the updated computed field metadata. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\nconst { validateSection } = useValidatePartialForm();\n// #endregion\n\n// #region Computed state\n\nconst field = computed(() => props.fieldMetadata);\n\nconst path = computed(() => overridePath(field.value?.path ?? '', props.pathOverride));\nconst normalizedPath = computed(() => normalizePath(path.value));\n\n// Anchors a LimitedFieldContext (label/errors) at the wizard's own path, mirroring how\n// DynamicFormItemChoice anchors its own useField call at the same path its owning DynamicFormItem\n// already registered. No validation rules of its own: the wizard's requiredness is already\n// validated by the owning DynamicFormItem's own combinedValidation.\nconst { errors, errorMessage, value } = useField(normalizedPath, undefined, field.value?.fieldOptions);\nconst fieldContext: LimitedFieldContext = { label: field.value?.fieldOptions?.label, errors, errorMessage, value: computed(() => undefined) };\n\n// A non-empty choice or a maxOccurs > 1 alongside wizard is inert: pages come from children only.\n// The node explicitly opted into being a wizard, so that reading always wins; a genuine choice of\n// wizards or a repeated wizard is expressed instead by nesting wizard: true nodes inside a plain\n// choice branch or an array item's children.\nif (import.meta.env.DEV && field.value?.choice?.length) {\n console.warn(`[DynamicFormItemWizard] \"${field.value.path}\": \"choice\" is ignored on a wizard node; wizard pages come from \"children\" only.`);\n}\n// Always warned, not just in dev: rendering a single occurrence for maxOccurs > 1 silently\n// drops data for XSD-derived or generated metadata, so production needs the signal too.\nif ((field.value?.maxOccurs ?? 1) > 1) {\n console.warn(`[DynamicFormItemWizard] \"${field.value.path}\": \"maxOccurs\" is ignored on a wizard node; wizard pages come from \"children\" only.`);\n}\n\nconst pages = computed(() => field.value?.children ?? []);\nconst pageCount = computed(() => pages.value.length);\n\n// Static wizard configuration, captured once at setup (mirrors explicitChoiceSelection):\n// `wizard` is excluded from ComputedPropsFieldType, so this can never change mid-form.\nconst wizardConfig = (() => {\n const raw = props.fieldMetadata?.wizard;\n const config = typeof raw === 'object' && raw !== null ? raw : {};\n return {\n allowForwardJump: config.allowForwardJump === true,\n // Defaults on: forward movement runs validation so page errors surface. `false` opts into a\n // silent jump. Only meaningful when the move does not block (non-linear mode or a jump);\n // linear `next` always validates because it needs the result to decide whether to block.\n validateOnJump: config.validateOnJump !== false,\n };\n})();\n\nconst currentStepIndex = ref(0);\nconst isValidating = ref(false);\n\nconst isFirst = computed(() => currentStepIndex.value === 0);\n// A wizard with no pages has nothing to navigate to: treated as both first and last so no\n// \"next\" affordance is offered, rather than degenerating to isLast: false (0 === -1).\nconst isLast = computed(() =>\n pageCount.value === 0 ? true : currentStepIndex.value === pageCount.value - 1);\n\n// minOccurs/maxOccurs still govern required/disabled on the wizard node itself; maxOccurs is\n// only inert for page derivation, not for the ordinary \"disable this whole field\" meaning of 0.\nconst minOccurs = computed(() =>\n props.minOccursOverride !== undefined ? props.minOccursOverride : (field.value?.minOccurs ?? 1));\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined ? props.maxOccursOverride : (field.value?.maxOccurs ?? 1));\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// Propagate optional/disabled state to the pages, exactly like a plain parent group: an\n// untouched optional wizard must not demand its required page fields, and a disabled wizard\n// disables its pages too.\nconst _minOccursOverride = computed(() => {\n // An ancestor already relaxed the subtree: keep propagating it.\n if (props.minOccursOverride === 0)\n return 0;\n\n // The wizard itself is required: pages keep their own requirements.\n if (minOccurs.value > 0)\n return undefined;\n\n // Optional and untouched: pages stay optional. Once any value exists, page requirements apply.\n return checkTreeHasValue(value.value) ? undefined : 0;\n});\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : undefined,\n);\n\n// #endregion\n\n// #region Navigation\n\n/** The current page's vee-validate path, read from the corrected metadata tree, never re-derived. */\nfunction currentPagePath(): string | undefined {\n const page = pages.value[currentStepIndex.value];\n return page?.path ? overridePath(page.path, props.pathOverride) : undefined;\n}\n\nasync function validateCurrentPage(): Promise<boolean> {\n const sectionPath = currentPagePath();\n if (!sectionPath)\n return true;\n\n isValidating.value = true;\n try {\n const result = await validateSection(sectionPath);\n return result.valid;\n }\n finally {\n isValidating.value = false;\n }\n}\n\nasync function next() {\n if (pageCount.value === 0 || isLast.value)\n return;\n\n // Non-linear wizard: identical policy to a forward jump, so it lives in one place.\n if (wizardConfig.allowForwardJump)\n return gotoStep(currentStepIndex.value + 1);\n\n // Linear wizard: the current page must be valid before advancing. Validation is async, so\n // re-check that no other navigation landed meanwhile (e.g. a double click); a blind\n // increment could skip a page's validation or run past the last page.\n const from = currentStepIndex.value;\n if (await validateCurrentPage() && currentStepIndex.value === from)\n currentStepIndex.value = from + 1;\n}\n\nfunction prev() {\n if (pageCount.value === 0 || currentStepIndex.value === 0)\n return;\n\n currentStepIndex.value--;\n}\n\nasync function gotoStep(index: number, options?: WizardGotoStepOptions) {\n if (pageCount.value === 0)\n return;\n\n const target = Math.min(Math.max(index, 0), pageCount.value - 1);\n const from = currentStepIndex.value;\n if (target === from)\n return;\n\n // Backward jumps are always free and silent. Forward jumps require the non-linear opt-in, then\n // surface page errors (unless silenced) without blocking, mirroring next().\n if (target > from) {\n const allowForwardJump = options?.allowForwardJump ?? wizardConfig.allowForwardJump;\n if (!allowForwardJump)\n return;\n\n const validateOnJump = options?.validateOnJump ?? wizardConfig.validateOnJump;\n if (validateOnJump) {\n await validateCurrentPage();\n // Another navigation landed while validating: the first one wins.\n if (currentStepIndex.value !== from)\n return;\n }\n }\n\n currentStepIndex.value = target;\n}\n\n// #endregion\n\n// #region Methods\n\nfunction onChildComputedFieldUpdate(childField: InternalFieldMetadata<FieldMetadata>) {\n emits('update:computedField', childField);\n}\n\n// The wizard re-renders on every navigation (currentStepIndex lives here), and Vue builds a fresh\n// slot-scope object per render even when the template's <slot> bindings are unchanged. Forwarding\n// that fresh object as :slotProps would change every page child's prop identity and re-render all\n// mounted fields on each step change. This cache keeps the previous scope object alive while its\n// contents are shallow-equal, so children only re-render when a bound value actually changed.\n// Deliberately non-reactive: the slot function re-runs on exactly the renders where a new scope\n// could appear, so plain Map reads during render always see the latest comparison result.\nconst slotScopeCache = new Map<string, Record<string, unknown>>();\n\nfunction stableSlotProps(cacheKey: string, scope: object | undefined): object {\n const current = (scope ?? {}) as Record<string, unknown>;\n const previous = slotScopeCache.get(cacheKey);\n if (previous && shallowEqual(previous, current))\n return previous;\n\n slotScopeCache.set(cacheKey, current);\n return current;\n}\n\nfunction shallowEqual(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n return aKeys.length === bKeys.length && aKeys.every(key => Object.is(a[key], b[key]));\n}\n\n// #endregion\n</script>\n\n<template>\n <component\n :is=\"template\"\n :type=\"`${fieldMetadata.type}-wizard`\"\n :field-metadata\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items\n :can-remove-items\n :add-item\n :remove-item\n :current-step-index\n :pages\n :page-count\n :is-first\n :is-last\n :is-validating\n :wizard-config=\"wizardConfig\"\n :next\n :prev\n :goto-step\n >\n <template #default=\"wizardScope\">\n <template v-for=\"(page, pageIndex) in pages\" :key=\"page.path\">\n <component\n :is=\"template\"\n :type=\"`${page.type}-wizard-page`\"\n :field-metadata=\"page\"\n :field-context\n :slot-props=\"stableSlotProps('wizard', wizardScope)\"\n :settings\n :required=\"false\"\n :disabled=\"false\"\n :index=\"pageIndex\"\n :is-current=\"pageIndex === currentStepIndex\"\n :page-index\n :current-step-index\n :is-first\n :is-last\n :wizard-config=\"wizardConfig\"\n :next\n :prev\n :goto-step\n >\n <template #default=\"pageScope\">\n <DynamicFormItem\n :field-metadata=\"(page as InternalMetadata)\"\n :path-override\n :index=\"pageIndex\"\n :template\n :slot-props=\"stableSlotProps(`page:${page.path}`, pageScope)\"\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"_maxOccursOverride\"\n\n @update:model-value=\"emits('update:modelValue', $event)\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n </component>\n </template>\n </template>\n </component>\n</template>\n","import type { FieldMetadata } from '@/types/FieldMetadata';\n\n/**\n * Creates a deterministic hash of all mutable field properties (those that computedProps can change).\n * Excludes structural/immutable properties: name, path, children, choice, attributes,\n * fieldOptions, computedProps, maxOccurs, parent, and _hash itself.\n */\nexport function hashField(field: FieldMetadata): string {\n const {\n name: _name,\n path: _path,\n children: _children,\n choice: _choice,\n attributes: _attributes,\n fieldOptions: _fieldOptions,\n computedProps: _computedProps,\n maxOccurs: _maxOccurs,\n _hash: _prevHash,\n parent: _parent,\n isComplexType: _isComplexType,\n computeOnChildValueChange: _computeOnChildValueChange,\n ...mutableProps\n } = field as any;\n\n const sorted = Object.fromEntries(\n Object.entries(mutableProps).sort(([a], [b]) => a.localeCompare(b)),\n );\n return JSON.stringify(sorted);\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { GenericValidateFunction } from 'vee-validate';\nimport type { ComputedRef } from 'vue';\nimport type { FieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { ComputedPropsFieldOf, FieldMetadata, ReadOnlyFieldOf } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField, useFormContext, useSubmitCount } from 'vee-validate';\nimport { computed, inject, onBeforeUnmount, onMounted, ref, toValue, watch, watchEffect } from 'vue';\nimport DynamicFormItemArray from '@/components/DynamicFormItemArray.vue';\nimport DynamicFormItemChoice from '@/components/DynamicFormItemChoice.vue';\nimport DynamicFormItemWizard from '@/components/DynamicFormItemWizard.vue';\nimport { useIsValidationSuppressed } from '@/core/useIsValidationSuppressed';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\nimport { createValidation } from '@/utils/createValidation';\nimport { hashField } from '@/utils/hashField';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\nimport { splitToValidationFunctions } from '@/utils/splitValidationFunctions';\n\n// #region Interfaces\nexport interface Emit {\n /** Emitted by leaf input fields whenever their value changes; payload is the new field value. */\n (e: 'update:modelValue', value: unknown): void\n /** Forwarded from vee-validate's `handleBlur`; lets parent array/choice fields trigger validation on blur. */\n (e: 'blur', event?: Event | undefined, shouldValidate?: boolean | undefined): void\n /** Emitted on mount and whenever the field's computed hash changes, so the parent keeps `childFields` in sync. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\n// #endregion\n\n// #region Internal tracking\n\n// Plain variables (not reactive) to avoid triggering renders when measuring analytics.\n// eslint-disable-next-line prefer-const\nlet _analytics_renderCount = 0;\nlet _analytics_constructValidationCount = 0;\nlet _analytics_fieldChangedCount = 0;\nlet _analytics_fieldComputeCount = 0;\nlet _analytics_valueChangedCount = 0;\nlet _analytics_notifyValueUpdateCount = 0;\n\n// Detects non-idempotent writes inside computedProps that would cause an infinite recomputation\n// loop. Loops that stay inside one reactive flush are already broken by Vue's own recursive-update\n// guard; this one catches loops that self-perpetuate through async watchers (a compute whose write\n// re-triggers itself a microtask later) and therefore never let the event loop turn. The counter\n// resets on a macrotask and the limit is deliberately generous (matching Vue's recursion limit):\n// input bursts faster than a macrotask (paste, autofill, IME, automated typing) can starve the\n// reset timer, and a tight limit miscounted such legitimate once-per-update recomputes as a loop,\n// killing the field's render effect on a false positive and freezing it with stale metadata.\nconst COMPUTE_LOOP_MAX = 100;\nlet _computeLoopCount = 0;\nlet _computeLoopResetTimer: ReturnType<typeof setTimeout> | undefined;\n\nfunction assertNoComputeLoop(fieldPath: string) {\n _computeLoopCount++;\n\n if (_computeLoopResetTimer == null) {\n _computeLoopResetTimer = setTimeout(() => {\n _computeLoopCount = 0;\n _computeLoopResetTimer = undefined;\n }, 0);\n }\n if (_computeLoopCount > COMPUTE_LOOP_MAX) {\n throw new Error(\n `[DynamicFormItem] Possible infinite loop detected in computedProps for field \"${fieldPath}\". `\n + `computedProps recomputed more than ${COMPUTE_LOOP_MAX} times without the event loop turning. `\n + `Ensure value writes inside computedProps are idempotent (the same input always produces the same output).`,\n );\n }\n}\n\n// #endregion\n\n// #region Computed state\n\n// --- Path ---\n\nconst field = computed(() => {\n _analytics_fieldChangedCount++;\n return props.fieldMetadata;\n});\n\nconst path = computed(() => {\n if (!field.value?.path)\n return '';\n\n return overridePath(field.value.path, props.pathOverride);\n});\n\n// If the field has attributes, it is treated as a complex type: the user-visible value lives\n// at a nested property (e.g. `path['value']`) instead of directly at `path`.\nconst isComplexType = computed(() => field.value?.isComplexType || field.value?.attributes?.length);\n\n// The path vee-validate binds to. For complex types we append the value property key\n// using bracket notation so segment counting by '.' still works correctly.\nconst itemPath = computed(() => {\n let _path = path.value;\n if (isComplexType.value && _path) {\n const complexTypeValueProperty = settings?.value?.complexTypeValueProperty ?? 'value';\n _path = `${_path}['${complexTypeValueProperty}']`;\n }\n return _path;\n});\n\nconst normalizedPath = computed(() => normalizePath(itemPath.value));\n\nconst isArray = computed(() => {\n if (props.isArrayOverride === 'array')\n return true;\n\n if (props.isArrayOverride === 'single')\n return false;\n\n return (field.value?.maxOccurs ?? 1) > 1;\n});\n\n// --- Vee-Validate field context ---\n\n// Initialized empty; populated by the watchEffect below.\n// This indirection breaks a circular dependency:\n// combinedValidation → computedField → value → fieldContext → combinedValidation\nconst combinedValidation = ref<GenericValidateFunction[]>([]);\n\nconst fieldContext = !isArray.value\n ? useField(normalizedPath, combinedValidation, {\n ...(field.value?.fieldOptions ?? {}),\n validateOnValueUpdate: false, // validation timing is owned by this component\n }) as FieldContext\n : { value: ref(undefined) } as FieldContext;\n\nconst value = fieldContext.value;\n\n// Used only to read the form-level keepValuesOnUnmount flag for the unmount cleanup below;\n// DynamicFormItem is always a descendant of the useForm() call in useDynamicForm, so a plain\n// useFormContext() resolves it here (unlike the same-instance quirk useValidatePartialForm has\n// to guard against). keepValuesOnUnmount is deliberately left off vee-validate's public\n// FormContext type, so it is read through a loosely typed access rather than a cast to a type\n// that does not carry it.\nconst formContext = useFormContext() as { keepValuesOnUnmount?: boolean | (() => boolean) } | undefined;\n\nconst isValidationSuppressed = useIsValidationSuppressed(normalizedPath);\n\n// Lazily evaluated — only computed when accessed, safe to use on deep field trees.\nfieldContext.hasValue = computed(() => checkTreeHasValue(value.value));\n\n// Apply the global validateOnBlur setting when shouldValidate is not explicitly provided.\nconst originalHandleBlur = fieldContext.handleBlur;\nfieldContext.handleBlur = function (e?: Event | undefined, shouldValidate?: boolean | undefined) {\n shouldValidate = shouldValidate ?? settings?.value?.validateOnBlur;\n originalHandleBlur(e, shouldValidate);\n emits('blur', e, shouldValidate); // lets array fields know when a blur occurred\n};\n\n// Validation is handled in the value watcher; only pass through when explicitly requested.\nconst originalHandleChange = fieldContext.handleChange;\nfieldContext.handleChange = function (e: unknown, shouldValidate?: boolean | undefined) {\n originalHandleChange(e, shouldValidate === true);\n};\n\n// --- Field type flags ---\n\nconst isWizard = computed(() => !!field.value?.wizard);\nconst isParent = computed(() => !!field.value?.children?.length);\nconst isChoice = computed(() => !!field.value?.choice?.length);\n// An input is any leaf field — not a repeating array, not a branching choice, not a parent group,\n// and not a wizard (a wizard always has its own delegated rendering, even with no children yet).\nconst isInput = computed(() => !isArray.value && !isChoice.value && !isParent.value && !isWizard.value);\n\n// --- Reactive field and dynamic state ---\nconst initialUpdate = ref(true);\n\n/**\n * In case of an object, the useFieldValue() in vee-validate doesn't react on an update of a value of its children.\n * Therefore we keep track of an reactive value, that is updated by the children. That re-triggers reactivity\n */\nconst childValueReactivity = ref(0);\n\n/**\n * Stores the latest computedField of each direct child, keyed by path.\n * Updated when a child emits update:computedField and the hash differs from the stored one.\n * When accessed inside a computedProps function, changes to child computed fields will\n * reactively re-trigger the parent's computedField computation.\n */\nconst childFields = ref<Record<string, ReadOnlyFieldOf<FieldMetadata>>>({});\nconst childFieldsArray = computed(() => Object.values(childFields.value));\n\nconst computedField = computed(() => {\n _analytics_fieldComputeCount++;\n assertNoComputeLoop(path.value);\n\n if (field.value?.computeOnChildValueChange === true) {\n void childValueReactivity.value; // subscribe to child value changes\n }\n\n const _computedField = (field.value?.computedProps ?? []).reduce(\n (field, compute) => {\n // We allow to transform the field metadata reactively based on the current value. In case the value is not\n // called upon in any of the computedProps, it will not be part of the reactivity that triggers a re-compute.\n // The childFieldsArray ref is passed so computedProps can subscribe to children's computed field changes.\n compute(field, value, childFieldsArray);\n return field;\n },\n { ...field.value, path: path.value } as ComputedPropsFieldOf<FieldMetadata>,\n );\n\n // Always restore our calculated path plus the static choice-selection flags, then the hash —\n // computedProps may read these but must not override them. Both flags are excluded from\n // ComputedPropsFieldType, so this only defends against an `as any` cast; restoring them keeps\n // the hash (and thus the render mode) stable if one is mutated that way.\n const _internalMetadata = _computedField as InternalMetadata;\n _internalMetadata.path = path.value;\n _internalMetadata.explicitChoiceSelection = field.value?.explicitChoiceSelection;\n _internalMetadata.preserveOnSwitch = field.value?.preserveOnSwitch;\n _internalMetadata.wizard = field.value?.wizard;\n _internalMetadata._hash = hashField(_internalMetadata);\n\n return _internalMetadata;\n});\n\n// --- Occurrence limits ---\n\n// minOccurs determines how many times this field must appear at minimum.\nconst minOccurs = computed(() => {\n if (props.minOccursOverride !== undefined)\n return props.minOccursOverride;\n\n // Array items themselves control multiplicity; individual items are always optional.\n if (props.partOfArrayField)\n return 0;\n\n return computedField.value?.minOccurs ?? 1;\n});\n\n// maxOccurs determines how many times this field may appear at maximum.\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined\n ? props.maxOccursOverride\n : (computedField.value?.maxOccurs ?? 1),\n);\n\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// When this optional field has no value yet, propagate minOccurs=0 to children so their\n// required validation doesn't fire until the user starts filling in values.\nconst _minOccursOverride = computed(() => {\n // If an ancestor already set the override to 0, keep propagating it.\n if (props.minOccursOverride === 0)\n return props.minOccursOverride;\n\n // Field is required — nothing to override.\n if (minOccurs.value > 0)\n return undefined;\n\n // Field is optional but already has a value — keep children required.\n if (checkTreeHasValue(value.value))\n return undefined;\n\n // Optional field with no value: make all children optional too.\n return 0;\n});\n\n// When maxOccurs=0 (disabled), propagate the disabled state to children.\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : undefined,\n);\n\nconst _canRemoveItems = computed(() => {\n // Array items with a value can always be removed via the × button to clear them.\n if (props.partOfArrayField && checkTreeHasValue(value.value))\n return true;\n\n return props.canRemoveItems;\n});\n\n// --- Validation helpers ---\n\nconst submitCount = useSubmitCount();\nconst shouldValidateOnValueUpdate = computed(() => {\n // Only check validateOnValueUpdateAfterSubmit when it is explicitly true; otherwise leave\n // the decision to the next check (undefined means \"defer to next rule\").\n const validateOnValueUpdateAfterSubmit = settings?.value?.validateOnValueUpdateAfterSubmit === true\n ? (submitCount.value > 0 && settings?.value?.validateOnValueUpdateAfterSubmit)\n : undefined;\n\n const validateWhenInError = settings?.value?.validateWhenInError && fieldContext?.errors.value?.length > 0\n ? true\n : undefined;\n\n // Priority: field-level option → in-error state → after-submit setting → global setting\n return field.value?.fieldOptions?.validateOnValueUpdate\n ?? validateWhenInError\n ?? validateOnValueUpdateAfterSubmit\n ?? settings?.value?.validateOnValueUpdate;\n});\n\nconst showAttributes = computed(\n () => field.value?.attributes?.length && checkTreeHasValue(value.value),\n);\n\n// #endregion\n\n// #region Watchers and lifecycle events\n\n// Build the validation array reactively so it stays in sync with field metadata and settings.\n// watchEffect (rather than computed) is used here to avoid the circular dependency described\n// at the combinedValidation declaration above.\nwatchEffect(() => {\n _analytics_constructValidationCount++;\n\n const _validations: GenericValidateFunction[] = [];\n const _restriction = field.value.restriction ?? {};\n const _messages = settings?.value?.messages;\n\n if (required.value)\n _validations.push(createValidation('xsd_required', undefined, _messages?.required));\n\n if (_restriction.minLength != null)\n _validations.push(createValidation('xsd_minLength', _restriction.minLength, _messages?.minLength));\n\n if (_restriction.maxLength != null)\n _validations.push(createValidation('xsd_maxLength', _restriction.maxLength, _messages?.maxLength));\n\n if (_restriction.length != null)\n _validations.push(createValidation('xsd_length', _restriction.length, _messages?.length));\n\n if (_restriction.pattern != null)\n _validations.push(createValidation('xsd_pattern', _restriction.pattern, _messages?.pattern));\n\n if (_restriction.minInclusive != null)\n _validations.push(createValidation('xsd_minInclusive', _restriction.minInclusive, _messages?.minInclusive));\n\n if (_restriction.maxInclusive != null)\n _validations.push(createValidation('xsd_maxInclusive', _restriction.maxInclusive, _messages?.maxInclusive));\n\n if (_restriction.minExclusive != null)\n _validations.push(createValidation('xsd_minExclusive', _restriction.minExclusive, _messages?.minExclusive));\n\n if (_restriction.maxExclusive != null)\n _validations.push(createValidation('xsd_maxExclusive', _restriction.maxExclusive, _messages?.maxExclusive));\n\n if (_restriction.enumeration != null)\n _validations.push(createValidation('xsd_enumeration', _restriction.enumeration, _messages?.enumeration));\n\n if (_restriction.whiteSpace != null)\n _validations.push(createValidation('xsd_whiteSpace', _restriction.whiteSpace, _messages?.whiteSpace));\n\n if (_restriction.fractionDigits != null)\n _validations.push(createValidation('xsd_fractionDigits', _restriction.fractionDigits, _messages?.fractionDigits));\n\n if (_restriction.totalDigits != null)\n _validations.push(createValidation('xsd_totalDigits', _restriction.totalDigits, _messages?.totalDigits));\n\n if (field.value?.validation)\n _validations.push(...splitToValidationFunctions(field.value?.validation));\n\n combinedValidation.value = _validations;\n});\n\n// Normalise empty strings to undefined (or null for array items) so the field is cleanly\n// removed from the form values object rather than left as an empty string.\n// flush: 'sync' ensures the value is corrected before any other watchers or computeds read it.\nlet _transforming = false;\nwatch(value, (newValue) => {\n if (_transforming)\n return;\n\n _transforming = true;\n if (newValue === '')\n value.value = props.partOfArrayField ? null : undefined;\n _transforming = false;\n}, {\n flush: 'sync',\n});\n\n// Notify the parent and conditionally trigger validation whenever the value changes.\n// vee-validate does not provide a built-in update event, so we implement it here.\nwatch(\n value,\n (v) => {\n _analytics_valueChangedCount++;\n\n // Only leaf inputs emit; parent/array/choice fields are updated by their children.\n if (!isInput.value)\n return;\n\n // Skip notification on the initial render if there is no value yet.\n if (!initialUpdate.value || v) {\n notifyValueUpdate();\n\n // Skipped while a programmatic write that asked not to validate is flushing: a\n // resetForm/resetField (its value change would write the just-cleared errors back)\n // or a setFieldValue/setValues call with shouldValidate: false.\n if (shouldValidateOnValueUpdate.value && !isValidationSuppressed())\n fieldContext?.validate();\n }\n\n initialUpdate.value = false;\n },\n {\n immediate: true,\n },\n);\n\n// Emit the initial computedField after mounting (children mount before parents, so the parent\n// template listener is already in place). Then watch for hash changes to keep the parent in sync.\n// Deferring to onMounted avoids accessing computedField during setup, which would make it a\n// synchronous dep and break the infinite-loop guard test.\nonMounted(() => {\n emits('update:computedField', computedField.value);\n watch(() => computedField.value._hash, (newHash, oldHash) => {\n if (newHash === oldHash)\n return;\n emits('update:computedField', computedField.value);\n });\n});\n\nonBeforeUnmount(() => {\n if (_computeLoopResetTimer != null)\n clearTimeout(_computeLoopResetTimer);\n\n // Array items are cleaned up by useFieldArray's remove() — setting value to undefined here\n // would write back to form.values at the (now-removed) index, causing useFieldArray's sync\n // watcher to detect a mismatch and re-add the entry via initFields().\n if (props.partOfArrayField)\n return;\n\n // Attribute fields are conditionally mounted based on whether the owning field has a value.\n // When the owner is empty, the attribute belongs to a value that is itself gone: there is\n // nothing left to keep, so it clears regardless of keepValuesOnUnmount/keepValueOnUnmount.\n // When the owner still has a value, the attribute honours the same keep flags as any other\n // field, by skipping this explicit clear and deferring to vee-validate's own unmount handling.\n const ownerValueIsGone = props.partOfAttributeField && !props.attributeOwnerHasValue?.();\n\n if (!ownerValueIsGone) {\n const keepValue = field.value?.fieldOptions?.keepValueOnUnmount\n ?? toValue(formContext?.keepValuesOnUnmount);\n if (keepValue)\n return;\n }\n\n if (value.value !== undefined) {\n value.value = undefined;\n notifyValueUpdate();\n }\n});\n\n// #endregion\n\n// #region Methods\n\n/**\n * Called when a direct child (or a DynamicFormItemArray/Choice that wraps a child) emits update:computedField.\n * Only updates childFields when the child's hash has changed, so the parent's computedProps\n * that access childFields are only re-evaluated when something meaningful changed.\n * When childFields is updated, the parent's own computedField may re-run (if it accesses childFields),\n * and the watch above will emit update:computedField upward, notifying the entire ancestor chain.\n */\nfunction onChildComputedFieldUpdate(field: InternalFieldMetadata<FieldMetadata>) {\n if (!field.path)\n return;\n const existing = childFields.value[field.path] as InternalFieldMetadata<FieldMetadata>;\n if (existing?._hash === field._hash)\n return;\n childFields.value[field.path] = field as ReadOnlyFieldOf<FieldMetadata>;\n}\n\nfunction notifyValueUpdate() {\n _analytics_notifyValueUpdateCount++;\n childValueReactivity.value++;\n emits('update:modelValue', value.value);\n};\n\n// Array fields bypass useField and manage their own field array; when their value changes\n// we receive it here and write it directly so the parent can pick it up via its own watcher.\nfunction updateArrayValue(_value: unknown) {\n value.value = _value;\n emits('update:modelValue', value.value);\n};\n\n// #endregion\n</script>\n\n<template>\n <div v-if=\"settings?.analytics\" v-show=\"false\">\n <span :data-testid=\"`${path}-analytics-render-count`\">{{\n ++_analytics_renderCount\n }}</span>\n </div>\n <template v-if=\"isWizard\">\n <DynamicFormItemWizard\n v-bind=\"props\"\n :field-metadata=\"computedField\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-else-if=\"isChoice\">\n <DynamicFormItemChoice\n v-bind=\"props\"\n :field-metadata=\"computedField\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-else-if=\"isArray\">\n <DynamicFormItemArray\n v-bind=\"props\"\n :part-of-choice-field\n :field-metadata=\"computedField\"\n\n @update:model-value=\"updateArrayValue\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-else>\n <component\n :is=\"template\"\n :type=\"branchKey !== undefined ? `${computedField.type}-choice-array-item` : partOfArrayField ? `${computedField.type}-array-item` : computedField.type\"\n :field-metadata=\"computedField\"\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items\n :can-remove-items=\"_canRemoveItems\"\n :add-item\n :remove-item\n :branch-key=\"branchKey\"\n :global-index=\"globalIndex\"\n :insertion-order=\"insertionOrder\"\n >\n <template #default=\"slotProps\">\n <template v-if=\"isParent\">\n <DynamicFormItem\n v-for=\"(child, index) in computedField.children\"\n :key=\"child.path\"\n :field-metadata=\"(child as InternalMetadata)\"\n :path-override=\"itemPath\"\n :index\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"_maxOccursOverride\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-if=\"!isParent\">\n <component\n :is=\"template\"\n :type=\"`${computedField.type}-input`\"\n :field-metadata=\"computedField\"\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items\n :can-remove-items=\"_canRemoveItems\"\n :add-item\n :remove-item\n />\n </template>\n </template>\n <template #attributes=\"slotProps\">\n <template v-if=\"showAttributes\">\n <DynamicFormItem\n v-for=\"(attribute, index) in computedField.attributes\"\n :key=\"attribute.path\"\n :field-metadata=\"(attribute as InternalMetadata)\"\n :path-override=\"path\"\n :index\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"_maxOccursOverride\"\n :part-of-attribute-field=\"true\"\n :attribute-owner-has-value=\"() => checkTreeHasValue(value)\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n </template>\n </component>\n </template>\n</template>\n","<script lang=\"ts\" setup generic=\"Metadata extends FieldMetadata\">\nimport type { DefineComponent } from 'vue';\n\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\n\nimport { useFormContext } from 'vee-validate';\nimport { computed, provide } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { trackNonValidatingWrites } from '@/core/useIsValidationSuppressed';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\n\n// #region Interfaces\nexport interface DynamicFormProps<Metadata extends FieldMetadata> {\n /** One or more field descriptors. Pass an array for multiple top-level fields. */\n metadata: Metadata | Metadata[]\n /** A `DynamicFormTemplate`-based component that exposes the named slots used for rendering. */\n template: DefineComponent<object, object, any>\n /** Overrides for the library defaults; partial — missing keys fall back to built-in defaults. */\n settings?: DynamicFormSettings\n}\n// #endregion\n\n// #region Props and State\ndefineOptions({ name: 'DynamicForm', inheritAttrs: false });\n\nconst { settings: _settings, metadata, template } = defineProps<DynamicFormProps<Metadata>>();\n\nconst settings = computed(() => ({\n validateOnValueUpdate: true,\n validateWhenInError: true,\n ...(_settings ?? {}),\n}));\n\nprovide(dynamicFormSettingsKey, settings);\n\n// Also covers forms created with vee-validate's own useForm instead of useDynamicForm\n// (no-op when useDynamicForm already wrapped the context, or when no form is provided).\ntrackNonValidatingWrites(useFormContext());\n\nconst metadataAsArray = computed(() =>\n Array.isArray(metadata) ? metadata : [metadata],\n);\n\nconst metadataWithDefaults = computed(() =>\n metadataAsArray.value?.map((x, index) => correctMetadataAndSetDefaults(x, index)) ?? [],\n);\n\n// DefineComponent doesn't carry slot shape information, so we widen the type here\n// to make the available slots known to child components at the type level.\nconst typedTemplate = computed(\n () =>\n template as DefineComponent<\n object,\n object,\n {\n default?: ((props: object) => any) | undefined\n attributes?: ((props: object) => any) | undefined\n choice?: ((props: object) => any) | undefined\n array?: ((props: object) => any) | undefined\n }\n >,\n);\n// #endregion\n\n// #region Methods\n\n/**\n * Recursively walks the metadata tree and fills in missing defaults (name, path, type, minOccurs,\n * maxOccurs) and links each node to its parent so child components can compute fully-qualified paths.\n */\nfunction correctMetadataAndSetDefaults(\n fieldMetadata: Metadata,\n index?: number,\n parent?: InternalFieldMetadata<Metadata>,\n) {\n if (!fieldMetadata)\n return fieldMetadata;\n\n const fieldName = fieldMetadata.name ?? `field-${index}`;\n const fieldPath = fieldMetadata.path ?? [parent?.path, fieldName].filter(Boolean).join('.');\n const copy: InternalFieldMetadata<Metadata> = {\n name: fieldName,\n path: fieldPath,\n type: 'text',\n minOccurs: 1,\n maxOccurs: 1,\n\n ...fieldMetadata,\n computedProps: [...(fieldMetadata.computedProps ?? [])],\n parent,\n };\n\n copy.children = (fieldMetadata.children ?? []).map((x, index) =>\n correctMetadataAndSetDefaults(x as Metadata, index, copy),\n );\n copy.choice = (fieldMetadata.choice ?? []).map((x, index) =>\n correctMetadataAndSetDefaults(x as Metadata, index, copy),\n );\n copy.attributes = (fieldMetadata.attributes ?? []).map((x, index) =>\n correctMetadataAndSetDefaults(x as Metadata, index, copy),\n );\n\n return copy;\n}\n\n// #endregion\n</script>\n\n<template>\n <DynamicFormItem\n v-for=\"fieldMetadata in metadataWithDefaults\"\n :key=\"fieldMetadata.name\"\n :template=\"typedTemplate\"\n :field-metadata=\"(fieldMetadata as InternalFieldMetadata<FieldMetadata>)\"\n />\n</template>\n","const camelizeRE = /-\\w/g;\n/**\n * Coming from vue source code\n * @private\n */\nexport const camelize: (str: string) => string = cacheStringFunction(\n (str: string): string => {\n return str.replace(camelizeRE, c => c.slice(1).toUpperCase());\n },\n);\n\nfunction cacheStringFunction<T extends (str: string) => string>(fn: T): T {\n const cache: Record<string, string> = Object.create(null);\n return ((str: string) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n }) as T;\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"TMetadataConfiguration extends MetadataConfiguration\"\n>\nimport type { FieldContext as _FieldContext } from 'vee-validate';\nimport type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { ReadOnlyFieldType, WizardConfig, WizardGotoStepOptions } from '@/types/FieldMetadata';\nimport type { MetadataConfiguration } from '@/types/MetadataConfiguration';\nimport { computed, useAttrs } from 'vue';\nimport { camelize } from '@/utils/camelize';\n\n// #region Interfaces\n\nexport interface FieldContext<TValue = unknown> extends _FieldContext<TValue> {\n /**\n * Whether this field (or any of its descendants) has a value.\n * Lazily evaluated — only computed when accessed, so safe to use on deep field trees.\n */\n hasValue: ComputedRef<boolean>\n}\n\nexport interface DynamicFormConfigurationProps<\n TMetadataConfiguration extends MetadataConfiguration,\n> {\n /**\n * Use defineMetadata to create a strongly-typed metadata configuration.\n * This metadata configuration can be provided here to type the DynamicFormTemplate component.\n */\n metadataConfiguration: TMetadataConfiguration\n}\n\nexport interface LimitedFieldContext<TValue = unknown> {\n value: ComputedRef<TValue>\n errors: Ref<string[]>\n errorMessage: Ref<string | undefined>\n label?: MaybeRefOrGetter<string | undefined>\n}\n\n/**\n * Props passed to the template component by the library internals.\n * Defined as an interface (rather than actual props) so they don't appear in the\n * public prop signature of the user-facing DynamicFormTemplate component.\n */\nexport interface Attributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> {\n type: TMetadataConfiguration['fieldTypes'][number] | 'default' | 'default-array' | 'default-array-item' | 'default-choice' | 'default-choice-array' | 'default-choice-array-item' | 'default-wizard' | 'default-wizard-page'\n /** The metadata you configured for this field. */\n fieldMetadata: ReadOnlyFieldType<\n TMetadataConfiguration['fieldTypes'][number],\n TMetadataConfiguration['extendedProperties']\n >\n /** Whether the field is required. */\n required: boolean\n /** Whether the field is disabled (maxOccurs = 0). */\n disabled: boolean\n /** The position of this item within its parent, that can be its position in the children or choice collection or its index in an array field. */\n index: number\n /**\n * Whether a new array item can be added.\n * False when the current count has already reached maxOccurs.\n */\n canAddItems: boolean\n /**\n * Whether an array item can be removed.\n * False when the current count has already reached minOccurs.\n */\n canRemoveItems: boolean\n /** Adds a new item to the parent array field. */\n addItem: () => void\n /** Removes this item from the parent array field. */\n removeItem: () => void\n /**\n * The user defined properties that are passed between templates by adding attributes on the <slot /> elements.\n * With these properties you can set values that can be read by components \"living\" further down the tree.\n */\n slotProps: TMetadataConfiguration['slotProperties']\n /**\n * The form settings\n */\n settings: DynamicFormSettings<TMetadataConfiguration['extendedSettingsProperties']>\n}\n\nexport interface ItemAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n FieldType extends string = string,\n> extends Attributes<TMetadataConfiguration> {\n /**\n * The extended vee-validate field context from useField.\n * Includes a `hasValue` computed that is true when this field or any descendant has a value.\n */\n fieldContext: FieldContext<FieldType extends keyof TMetadataConfiguration['valueTypes']\n ? TMetadataConfiguration['valueTypes'][FieldType]\n : unknown>\n}\n\nexport interface ArrayChoiceAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> extends Attributes<TMetadataConfiguration> {\n fieldContext: LimitedFieldContext<unknown[]>\n}\n\n/** An active branch occurrence, as reported by `activeChoiceOccurrences`. */\nexport interface ChoiceOccurrence {\n /** The choice branch's `name` (e.g. 'selfServe', 'apiEndpoint'). */\n branchKey: string\n /** 0 for maxOccurs:1; the occurrence's index within its branch for maxOccurs > 1. */\n index: number\n}\n\nexport interface ChoiceAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> extends ArrayChoiceAttributes<TMetadataConfiguration> {\n /** Mark a branch active (maxOccurs:1) or add one occurrence of it (maxOccurs > 1). No-op when canAddChoiceOccurrence is false. */\n addChoiceOccurrence: (branchKey: string) => void\n /** Remove a previously added occurrence. index is required in maxOccurs > 1; ignored (optional) in maxOccurs:1 where it deselects the active branch. */\n removeChoiceOccurrence: (branchKey: string, index?: number) => void\n /** Per-branch guard: false when this branch's own maxOccurs or the choice's shared occurrence budget is exhausted, or when the choice is disabled. */\n canAddChoiceOccurrence: (branchKey: string) => boolean\n /** The currently active occurrences the template iterates for counts/selector state. */\n activeChoiceOccurrences: ChoiceOccurrence[]\n /**\n * Choice slots currently consumed, in choice-occurrence units rather than raw item count.\n * For a repeatable branch (its own `maxOccurs > 1`), every group of up to that many items\n * counts as one slot, the same unit `maxOccurs` on the choice itself is measured in, so a\n * template can show an accurate \"N of maxOccurs\" without re-deriving the batching math.\n */\n usedChoiceOccurrences: number\n}\n\n/**\n * Slot props for a single occurrence of a repeatable explicit choice (`maxOccurs > 1`), rendered\n * through the `*-choice-array-item` / `default-choice-array-item` slot. Mirrors `ItemAttributes`\n * (the same shape `*-array-item` receives) plus `branchKey`, the occurrence's branch name (drives\n * a \"kind\" badge in the template).\n */\nexport interface ChoiceArrayItemAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n FieldType extends string = string,\n> extends ItemAttributes<TMetadataConfiguration, FieldType> {\n /** The choice branch this occurrence belongs to (the child's `name`). Drives the \"kind\" badge. */\n branchKey: string\n /**\n * This occurrence's zero-based position across every branch's active occurrences, in the same\n * order `activeChoiceOccurrences` reports them (grouped by branch declaration order, then by\n * index within branch). Renumbers live when an occurrence is removed; never stored.\n */\n globalIndex: number\n /**\n * This occurrence's ephemeral, instance-local add-order position (1-based, in add-press order\n * across every branch), set only when it was added via `addChoiceOccurrence` this session.\n * `undefined` for an occurrence that already existed when the form mounted (loaded saved data).\n * Gone on remount; never stored in form values.\n */\n insertionOrder?: number\n}\n\n/**\n * Slot props for the wizard container (`<type>-wizard` / `default-wizard`). `pages` is the\n * engine's resolved page list (the corrected page metadata nodes, in page order): the single\n * source of truth for a stepper, so a template never re-derives `fieldMetadata.children` itself.\n */\nexport interface WizardAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> extends Attributes<TMetadataConfiguration> {\n fieldContext: LimitedFieldContext\n currentStepIndex: number\n pages: ReadOnlyFieldType<TMetadataConfiguration['fieldTypes'][number], TMetadataConfiguration['extendedProperties']>[]\n pageCount: number\n isFirst: boolean\n isLast: boolean\n isValidating: boolean\n /** The wizard's navigation config with defaults applied, so a stepper reflects the resolved mode (e.g. enable forward jumps when `allowForwardJump`) without re-reading `fieldMetadata.wizard` or re-deriving defaults. */\n wizardConfig: Required<WizardConfig>\n next: () => Promise<void>\n prev: () => void\n gotoStep: (index: number, options?: WizardGotoStepOptions) => Promise<void> | void\n}\n\n/**\n * Slot props for a single wizard page (`<type>-wizard-page` / `default-wizard-page`). Delivered\n * for every page, not only the current one; the template gates visibility with `isCurrent`\n * (`v-show`, never `v-if`: `v-if` deregisters the page's fields from vee-validate regardless of\n * `keepValuesOnUnmount`, and also clears their values unless that flag is set, so `v-show` stays\n * required for any page with fields).\n */\nexport interface WizardPageAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> extends Attributes<TMetadataConfiguration> {\n isCurrent: boolean\n pageIndex: number\n currentStepIndex: number\n isFirst: boolean\n isLast: boolean\n /** The wizard's navigation config with defaults applied (same object as the container slot), so a page can build its own mode-aware controls. */\n wizardConfig: Required<WizardConfig>\n next: () => Promise<void>\n prev: () => void\n gotoStep: (index: number, options?: WizardGotoStepOptions) => Promise<void> | void\n}\n\ntype Props = DynamicFormConfigurationProps<TMetadataConfiguration>;\ntype SlotProps<FieldType extends string = string> = ItemAttributes<TMetadataConfiguration, FieldType>;\ntype ArrayChoiceSlotProps = ArrayChoiceAttributes<TMetadataConfiguration>;\ntype ChoiceSlotProps = ChoiceAttributes<TMetadataConfiguration>;\ntype ChoiceArrayItemSlotProps<FieldType extends string = string> = ChoiceArrayItemAttributes<TMetadataConfiguration, FieldType>;\ntype WizardSlotProps = WizardAttributes<TMetadataConfiguration>;\ntype WizardPageSlotProps = WizardPageAttributes<TMetadataConfiguration>;\n\ntype SlotsFromMetadata = {\n // Fallback slot for field types that don't have a dedicated slot.\n default: (props: SlotProps) => any\n} & {\n // Fallback slot for input components that don't have a dedicated slot.\n 'default-input': (props: SlotProps) => any\n} & {\n // Fallback slot for components that are array's but don't have a dedicated slot.\n 'default-array': (props: ArrayChoiceSlotProps) => any\n} & {\n // Fallback slot for components that are array items but don't have a dedicated slot.\n // Also the final family fallback for repeatable-choice occurrences without any -choice-array-item slot.\n 'default-array-item': (props: SlotProps) => any\n} & {\n // Fallback slot for components that are single (maxOccurs: 1) choice fields but don't have a dedicated slot.\n // Also the final family fallback for repeatable choices without any -choice-array slot.\n 'default-choice': (props: ChoiceSlotProps) => any\n} & {\n // Fallback slot for components that are repeatable (maxOccurs > 1) choice fields but don't have a dedicated slot.\n 'default-choice-array': (props: ChoiceSlotProps) => any\n} & {\n // Fallback slot for components that are repeatable-choice occurrence items but don't have a dedicated slot.\n 'default-choice-array-item': (props: ChoiceArrayItemSlotProps) => any\n} & {\n // Fallback slot for the wizard container.\n 'default-wizard': (props: WizardSlotProps) => any\n} & {\n // Fallback slot for a single wizard page.\n 'default-wizard-page': (props: WizardPageSlotProps) => any\n} & {\n // One slot per field type defined in the metadata configuration.\n [K in TMetadataConfiguration['fieldTypes'][number]]: (props: SlotProps<K>) => any;\n} & {\n // One input slot per field type (e.g. \"text-input\") for rendering just the inner control.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-input`]: (props: SlotProps<K extends `${infer FieldType}-input` ? FieldType : never>) => any;\n} & {\n // One array slot per field type (e.g. \"text-array\") for defining how to render the type when it is an array.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-array`]: (props: ArrayChoiceSlotProps) => any;\n} & {\n // One array item slot per field type (e.g. \"text-array-item\") for defining how to render the type when it is an array item.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-array-item`]: (props: SlotProps<K extends `${infer FieldType}-input` ? FieldType : never>) => any;\n} & {\n // One choice slot per field type (e.g. \"text-choice\") for defining how to render the type when it is a single (maxOccurs: 1) choice.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-choice`]: (props: ChoiceSlotProps) => any;\n} & {\n // One choice-array slot per field type (e.g. \"text-choice-array\") for defining how to render the type when it is a repeatable (maxOccurs > 1) choice.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-choice-array`]: (props: ChoiceSlotProps) => any;\n} & {\n // One choice-array-item slot per field type (e.g. \"text-choice-array-item\") for rendering a single occurrence of a repeatable explicit choice branch.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-choice-array-item`]: (props: ChoiceArrayItemSlotProps<K extends `${infer FieldType}-choice-array-item` ? FieldType : never>) => any;\n} & {\n // One wizard container slot per field type (e.g. \"text-wizard\") for rendering the wizard's chrome.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-wizard`]: (props: WizardSlotProps) => any;\n} & {\n // One wizard page slot per field type (e.g. \"text-wizard-page\") for rendering a single page's visibility wrapper.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-wizard-page`]: (props: WizardPageSlotProps) => any;\n};\n\n// #endregion\n\n// #region State\ndefineOptions({ name: 'DynamicFormTemplate', inheritAttrs: false });\ndefineProps<Props>();\nconst slots = defineSlots<SlotsFromMetadata>();\n\n// Attributes are passed in as kebab-case HTML attributes by Vue; convert them to camelCase\n// so slot consumers receive consistent camelCase props regardless of how they were bound.\nconst rawAttrs = useAttrs();\nconst attrs = computed(() => {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(rawAttrs)) {\n result[camelize(key)] = value;\n }\n return result as unknown as SlotProps;\n});\n\ntype RegularSlotName = keyof SlotsFromMetadata;\n\n// Resolve which slot to render: prefer a dedicated per-type slot, fall back to\n// 'default-input' for input variants, and finally to 'default' for everything else.\nconst typeWithFallback = computed((): RegularSlotName => {\n const type = attrs.value.type;\n if (type && slots[type as RegularSlotName]) {\n return type as RegularSlotName;\n }\n\n if (type?.endsWith('-input')) {\n return slots['default-input'] ? 'default-input' : 'default';\n }\n // The -choice-array families must be checked before the plain -array families: a\n // \"text-choice-array\" also ends with \"-array\" (and \"text-choice-array-item\" with \"-array-item\"),\n // so the reversed order would wrongly resolve them to the array fallbacks.\n //\n // A repeatable-choice occurrence is an array item at heart (ChoiceArrayItemAttributes is a\n // superset of ItemAttributes), so past its own dedicated tiers it falls back into the\n // -array-item family: a template with a generic array-item card renders occurrences for free.\n if (type?.endsWith('-choice-array-item')) {\n if (slots['default-choice-array-item'])\n return 'default-choice-array-item';\n const arrayItemSlot = `${type.slice(0, -'-choice-array-item'.length)}-array-item` as RegularSlotName;\n if (slots[arrayItemSlot])\n return arrayItemSlot;\n return slots['default-array-item'] ? 'default-array-item' : 'default';\n }\n // A repeatable choice is still a choice (both families receive the same ChoiceAttributes), so\n // past its own dedicated tiers it falls back into the -choice family; templates written before\n // the -choice-array family existed keep rendering repeatable choices through their -choice slot.\n if (type?.endsWith('-choice-array')) {\n if (slots['default-choice-array'])\n return 'default-choice-array';\n const choiceSlot = `${type.slice(0, -'-choice-array'.length)}-choice` as RegularSlotName;\n if (slots[choiceSlot])\n return choiceSlot;\n return slots['default-choice'] ? 'default-choice' : 'default';\n }\n if (type?.endsWith('-array')) {\n return slots['default-array'] ? 'default-array' : 'default';\n }\n if (type?.endsWith('-array-item')) {\n return slots['default-array-item'] ? 'default-array-item' : 'default';\n }\n if (type?.endsWith('-choice')) {\n return slots['default-choice'] ? 'default-choice' : 'default';\n }\n // Checked before -wizard so a per-page type ending in \"-wizard-page\" resolves its own tier\n // rather than being captured by the (non-overlapping, but checked first for clarity) -wizard tier.\n if (type?.endsWith('-wizard-page')) {\n return slots['default-wizard-page'] ? 'default-wizard-page' : 'default';\n }\n if (type?.endsWith('-wizard')) {\n return slots['default-wizard'] ? 'default-wizard' : 'default';\n }\n return 'default';\n});\n\n// #endregion\n</script>\n\n<template>\n <template v-if=\"attrs.fieldMetadata\">\n <slot v-if=\"attrs.type?.endsWith('-choice-array')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as ChoiceSlotProps)\" />\n <slot v-else-if=\"attrs.type?.endsWith('-array')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as ArrayChoiceSlotProps)\" />\n <slot v-else-if=\"attrs.type?.endsWith('-choice')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as ChoiceSlotProps)\" />\n <slot v-else-if=\"attrs.type?.endsWith('-wizard-page')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as WizardPageSlotProps)\" />\n <slot v-else-if=\"attrs.type?.endsWith('-wizard')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as WizardSlotProps)\" />\n <slot v-else :name=\"typeWithFallback\" v-bind=\"attrs\" />\n </template>\n</template>\n","/**\n * Creates a typed metadata configuration for use with `DynamicFormTemplate`.\n *\n * The returned object is a pure type carrier — its runtime values are empty stubs.\n * TypeScript uses it to infer slot names, `fieldContext.value` types, extended field properties,\n * and the shape of `slotProps`. A `default` field type is always injected automatically.\n *\n * @typeParam FieldValueTypes - Map of field type names to their `fieldContext.value` types.\n * Use `never` for display-only types (headings, separators) that hold no value.\n * @typeParam ExtendedFieldProperties - Extra properties merged into every `FieldMetadata` object.\n * @typeParam SlotProperties - Shape of `slotProps` passed from parent slots to child slots.\n * @typeParam ExtendedSettingsProperties - Extra properties merged into `Settings` object.\n * @example\n * const config = defineMetadata<\n * {\n * text: string;\n * checkbox: boolean;\n * age: number;\n * address: { street: string; city: string };\n * heading: never;\n * },\n * {\n * // This will add a label and options property to each field's metadata\n * label?: string;\n * options?: Array<{ key: string; value: string }>;\n * },\n * {\n * // This will add allow you to pass hideLabel and depth through the slots\n * hideLabel?: boolean;\n * depth?: number;\n * },\n * {\n * // This will add a showOptionalOrRequired property to the settings object\n * showOptionalOrRequired?: 'optional' | 'required';\n * }\n * >();\n */\nexport function defineMetadata<\n const FieldValueTypes extends Record<string, any>,\n ExtendedFieldProperties extends object = object,\n SlotProperties extends object = object,\n ExtendedSettingsProperties extends object = object,\n>() {\n type IncludeFields = 'default';\n\n type FieldTypeMetadata\n = | keyof FieldValueTypes\n | IncludeFields;\n\n // Value types are directly from the generic parameter, default is always included and always a string\n type ValueTypeMap = FieldValueTypes & {\n default: string\n };\n\n return {\n fieldTypes: Object.keys({} as FieldValueTypes) as unknown as readonly FieldTypeMetadata[],\n extendedProperties: {} as ExtendedFieldProperties,\n slotProperties: {} as SlotProperties,\n extendedSettingsProperties: {} as ExtendedSettingsProperties,\n valueTypes: {} as ValueTypeMap,\n };\n}\n","import type {\n FlattenAndSetPathsType,\n FormContext,\n GenericObject,\n Path,\n PathValue,\n FormOptions as VeeFormOptions,\n} from 'vee-validate';\nimport type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue';\nimport {\n useFieldValue as _useFieldValue,\n useForm,\n} from 'vee-validate';\nimport { trackNonValidatingWrites } from '@/core/useIsValidationSuppressed';\nimport { useValidatePartialForm } from '@/core/useValidatePartialForm';\n\n/** Options forwarded directly to vee-validate's `useForm()`. */\nexport interface FormOptions<TValues extends GenericObject> {\n initialValues?: VeeFormOptions<TValues>['initialValues']\n initialErrors?: FlattenAndSetPathsType<TValues, string | undefined>\n initialTouched?: FlattenAndSetPathsType<TValues, boolean>\n validateOnMount?: boolean\n keepValuesOnUnmount?: MaybeRef<boolean>\n name?: string\n}\n\n/**\n * Typed wrapper around vee-validate's `useForm()`. Adds:\n * - `useFieldValue(path)` — path-aware field value accessor with full `TValues` type inference,\n * avoiding the need to manually cast `PathValue`.\n * - `validateSection(path)` — validates only the fields registered under the given path prefix,\n * useful for multi-step wizard validation.\n */\nexport function useDynamicForm<TValues extends GenericObject = GenericObject>(opts?: FormOptions<TValues>): FormContext<TValues> & {\n useFieldValue: <TPath extends Path<TValues>>(path?: MaybeRefOrGetter<TPath>) => Ref<PathValue<TValues, TPath>>\n validateSection: ReturnType<typeof useValidatePartialForm>['validateSection']\n} {\n const useFieldValue = <TPath extends Path<TValues>>(path?: MaybeRefOrGetter<TPath>) => {\n return _useFieldValue<PathValue<TValues, TPath>>(path);\n };\n\n const form = useForm<TValues>(opts);\n trackNonValidatingWrites(form);\n const { validateSection } = useValidatePartialForm();\n\n return {\n ...form,\n useFieldValue,\n validateSection,\n };\n}\n","import type { FieldMetadata } from '@/types/FieldMetadata';\n\n/**\n * Recursively walks a `FieldMetadata` tree (visiting `children` and `choice`) and applies\n * `callbackFunc` to every node, returning the transformed tree.\n *\n * The callback receives a shallow clone of each node, so mutations inside the callback do not\n * affect the original metadata. `children` and `choice` on the returned node are replaced with\n * the recursively-mapped results after the callback runs.\n */\nexport function mapEachMetadataItem<\n ExtendedFieldTypes extends string = string,\n ExtendedProperties extends object = object,\n>(\n metadata: FieldMetadata<ExtendedFieldTypes, ExtendedProperties>,\n callbackFunc: (item: FieldMetadata<ExtendedFieldTypes, ExtendedProperties>) => FieldMetadata<ExtendedFieldTypes, ExtendedProperties>,\n): FieldMetadata<ExtendedFieldTypes, ExtendedProperties> {\n if (!metadata || !callbackFunc)\n return metadata;\n\n metadata = callbackFunc?.({ ...metadata });\n metadata.children = metadata?.children?.map(x => mapEachMetadataItem(x, callbackFunc));\n metadata.choice = metadata?.choice?.map(x => mapEachMetadataItem(x, callbackFunc));\n return metadata;\n}\n"],"names":["useFieldArrayExtended","arrayPath","fields","originalFieldArray","useFieldArray","values","computed","value","useIsResetPending","path","formContext","useFormContext","toValue","suppressedForms","patchedForms","suppress","form","nextTick","trackNonValidatingWrites","context","originalSetFieldValue","field","shouldValidate","originalSetValues","useIsValidationSuppressed","isResetPending","dynamicFormSettingsKey","getSingleParam","params","paramName","isEmpty","maxLengthValidator","length","val","maxValueValidator","max","minValidator","minValueValidator","min","oneOfValidator","list","item","regexValidator","regex","checkTreeHasValue","element","resolveMessage","message","ctx","_","key","index","defineRule","failChoiceRule","min_value","max_value","one_of","mode","str","digits","decimalIndex","ruleParamNames","getFieldLabel","validationCache","createValidation","rule","param","customMessage","byParam","byMessage","validation","buildValidation","fieldName","validateOptions","normalizedCtx","result","validate","normalizePath","overridePath","overrideWithPath","parentSegments","childSegments","splitToValidationFunctions","userRules","props","__props","emits","__emit","settings","inject","_analytics_renderCount","normalizedPath","useValidateField","remove","push","update","replace","isValidationSuppressed","minOccurs","maxOccurs","disabled","required","_maxOccursOverride","_canAddItems","_canRemoveItems","combinedValidation","_validations","_messages","label","errors","errorMessage","handleBlur","useField","fieldContext","submitCount","useSubmitCount","firstValueSet","ref","shouldValidateOnValueUpdate","validateOnValueUpdateAfterSubmit","validateWhenInError","watch","v","watchEffect","_addItem","_removeItem","x","i","guardAndNotifyItemUpdate","_unref","_createElementBlock","_hoisted_1","_createElementVNode","_toDisplayString","_isRef","_hoisted_2","_openBlock","_createBlock","_resolveDynamicComponent","_withCtx","slotProps","_Fragment","_renderList","arrayIndex","DynamicFormItem","$event","_cache","deepCloneValue","clone","closestPath","explicitChoiceSelection","preserveOnSwitch","displayOrder","preserveOrderRequested","allBranchesObjectShaped","child","preserveOrderEffective","explicitlySelectedBranch","stashedBranchValues","insertionOrders","insertionCounter","branchValueRefs","useFieldValue","branchPaths","branchFieldArrays","branchPath","_minOccursOverride","childrenAreArrays","slotType","childValues","singleChild","singleChildMaxOccursOverride","occurrences","_occurrences","_maxOccurs","choiceOccurrences","choiceValuesCount","totalChoiceOccurrences","acc","othersAsChildOccurrences","totalChildOccurrences","overrideChildMaxOccurrences","valuesCount","c","activeChoiceOccurrences","active","occurrenceIndex","valueDriven","isExplicitlySelected","renderedChoiceOccurrences","sortKeyFor","occurrence","occurrenceValue","occurrenceKey","a","b","aAdded","bAdded","entry","usedChoiceOccurrences","total","fieldArray","branchMaxOccurrences","effectiveValuesCount","maxOccursTotalBreach","o","_field","updateChildValue","allBranchValues","branchValues","childIndex","maxOccurrences","skipCalculations","calculateValues","childValue","branchIndexOf","branchKey","branchMaxOccursOverride","branch","branchByKey","clearBranch","options","branchChild","existing","restoreStashedBranch","addChoiceOccurrence","canAddChoiceOccurrence","newOccurrenceIndex","activeCountBeforePush","removeChoiceOccurrence","branchIdx","fieldsLength","targetIndex","removedKey","normalizeOrder","branchCount","remainingSharedBudget","branchFieldArrayFor","rawOccurrenceKey","occurrencePathOverride","position","currentOrder","insertionOrder","sortKey","newRank","stripOrder","occurrenceRemoveHandlers","removeItemHandlerFor","mapKey","cached","rawKey","handler","currentIndex","branchAddHandlers","addItemHandlerFor","persistedTierActive","isActive","isOn","wasOn","globalIndex","getFormContext","ownProvides","getCurrentInstance","FormContextKey","useValidatePartialForm","validateSection","sectionPath","fieldPaths","state","validationResults","results","pages","pageCount","wizardConfig","raw","config","currentStepIndex","isValidating","isFirst","isLast","currentPagePath","page","validateCurrentPage","next","gotoStep","from","prev","target","onChildComputedFieldUpdate","childField","slotScopeCache","stableSlotProps","cacheKey","scope","current","previous","shallowEqual","aKeys","bKeys","wizardScope","pageIndex","pageScope","_createVNode","hashField","_name","_path","_children","_choice","_attributes","_fieldOptions","_computedProps","_prevHash","_parent","_isComplexType","_computeOnChildValueChange","mutableProps","sorted","COMPUTE_LOOP_MAX","_computeLoopCount","_computeLoopResetTimer","assertNoComputeLoop","fieldPath","isComplexType","itemPath","complexTypeValueProperty","isArray","originalHandleBlur","e","originalHandleChange","isWizard","isParent","isChoice","isInput","initialUpdate","childValueReactivity","childFields","childFieldsArray","computedField","_internalMetadata","compute","showAttributes","_restriction","_transforming","newValue","notifyValueUpdate","onMounted","newHash","oldHash","onBeforeUnmount","updateArrayValue","_value","DynamicFormItemWizard","_mergeProps","DynamicFormItemChoice","DynamicFormItemArray","_component_DynamicFormItem","attribute","provide","metadataAsArray","metadataWithDefaults","correctMetadataAndSetDefaults","typedTemplate","fieldMetadata","parent","copy","camelizeRE","camelize","cacheStringFunction","fn","cache","slots","_useSlots","rawAttrs","useAttrs","attrs","typeWithFallback","type","arrayItemSlot","choiceSlot","_renderSlot","_ctx","_normalizeProps","_guardReactiveProps","defineMetadata","useDynamicForm","opts","_useFieldValue","useForm","mapEachMetadataItem","metadata","callbackFunc"],"mappings":"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","x_google_ignoreList":[4]}