{"version":3,"file":"form-item.mjs","sources":["../../../../../src/components/ivue-form/form-item.vue"],"sourcesContent":["<template>\r\n  <div :class=\"wrapperClasses\" ref=\"formItem\">\r\n    <!-- 标签 -->\r\n    <form-label-wrap\r\n      :is-auto-width=\"labelStyle.width === 'auto'\"\r\n      :update-all=\"formContext?.labelWidth === 'auto'\"\r\n    >\r\n      <component\r\n        :class=\"`${prefixCls}--label`\"\r\n        :is=\"labelFor ? 'label' : 'div'\"\r\n        :id=\"labelId\"\r\n        :for=\"labelFor\"\r\n        :style=\"labelStyle\"\r\n        v-if=\"showLabel\"\r\n      >\r\n        <slot name=\"label\" :label=\"currentLabel\">{{ currentLabel }}</slot>\r\n      </component>\r\n    </form-label-wrap>\r\n    <!-- 内容 -->\r\n    <div :class=\"`${prefixCls}--content`\" :style=\"contentStyle\">\r\n      <slot></slot>\r\n      <!-- 错误提示 -->\r\n      <transition :name=\"`${prefixCls}-zoom-in-top`\">\r\n        <slot name=\"error\" :error=\"validateMessage\" v-if=\"shouldShowError\">\r\n          <div :class=\"validateClasses\">{{ validateMessage }}</div>\r\n        </slot>\r\n      </transition>\r\n      <!-- 成功 -->\r\n      <transition :name=\"`${prefixCls}-zoom-in-top`\">\r\n        <slot name=\"success\" v-if=\"shouldShowSuccess && validateSuccessMessage\">\r\n          <div :class=\"validateClasses\">{{ validateSuccessMessage }}</div>\r\n        </slot>\r\n      </transition>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n  computed,\r\n  defineComponent,\r\n  ref,\r\n  provide,\r\n  reactive,\r\n  toRefs,\r\n  inject,\r\n  onMounted,\r\n  onBeforeUnmount,\r\n  nextTick,\r\n  watch,\r\n} from 'vue';\r\nimport { isString } from '@vue/shared';\r\nimport AsyncValidator from 'async-validator';\r\nimport { refDebounced } from '@vueuse/core';\r\nimport { clone } from 'lodash-unified';\r\n\r\nimport FormLabelWrap from './form-label-wrap';\r\nimport IvueIcon from '../ivue-icon/index.vue';\r\n\r\nimport { useId } from '../../hooks';\r\nimport { addUnit } from '../../utils/dom/style';\r\nimport { isFunction } from '../../utils/helpers';\r\nimport { ensureArray } from '../../utils/arrays';\r\nimport { getProp } from '../../utils/objects';\r\n\r\n// type\r\nimport type { CSSProperties } from 'vue';\r\nimport type { RuleItem } from 'async-validator';\r\nimport { FormContextKey, FormValidateFailure } from './types/form';\r\nimport {\r\n  Props,\r\n  FormItemContextKey,\r\n  FormItemContext,\r\n  FormItemRule,\r\n  Arrayable,\r\n  FormItemValidateState,\r\n} from './types/form-item';\r\n\r\nconst prefixCls = 'ivue-form-item';\r\n\r\nexport default defineComponent({\r\n  name: prefixCls,\r\n  props: {\r\n    /**\r\n     * 标签文本\r\n     *\r\n     * @type {String}\r\n     */\r\n    label: {\r\n      type: String,\r\n    },\r\n    /**\r\n     * 属性规定 label 与哪个表单元素绑定\r\n     *\r\n     * @type {String}\r\n     */\r\n    for: {\r\n      type: String,\r\n    },\r\n    /**\r\n     * 标签宽度\r\n     *\r\n     * @type {String | Number}\r\n     */\r\n    labelWidth: {\r\n      type: [String, Number],\r\n      default: '',\r\n    },\r\n    /**\r\n     * model 的键名\r\n     *\r\n     * @type {String | String[]}\r\n     */\r\n    prop: {\r\n      type: [String, Array],\r\n    },\r\n    /**\r\n     * 是否为必填项，如不设置，则会根据校验规则确认\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    required: {\r\n      type: Boolean,\r\n    },\r\n    /**\r\n     * 表单验证规则\r\n     *\r\n     * @type {Object | Array}\r\n     */\r\n    rules: {\r\n      type: [Object, Array],\r\n    },\r\n    /**\r\n     * 是否显示校验错误信息\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    showMessage: {\r\n      type: Boolean,\r\n      default: true,\r\n    },\r\n    /**\r\n     * 验证成功提示状态\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    showSuccessStatus: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 验证成功提示信息\r\n     *\r\n     * @type {String}\r\n     */\r\n    validateSuccessMessage: {\r\n      type: String,\r\n      default: '',\r\n    },\r\n    /**\r\n     * 表单域验证错误时的提示信息\r\n     *\r\n     * @type {String}\r\n     */\r\n    error: {\r\n      type: String,\r\n    },\r\n  },\r\n  setup(props: Props, { slots }) {\r\n    // form inject\r\n    const formContext = inject(FormContextKey, undefined);\r\n    // 父级item\r\n    const parentFormItemContext = inject(FormItemContextKey, undefined);\r\n\r\n    // 是否是嵌套的item\r\n    const isNested = !!parentFormItemContext;\r\n\r\n    // label id\r\n    const labelId = useId().value;\r\n\r\n    // ref\r\n\r\n    // 输入框id\r\n    const inputIds = ref<string[]>([]);\r\n    // 验证状态\r\n    const validateState = ref('');\r\n    // 验证状态节流\r\n    const validateStateDebounced = refDebounced(validateState, 100);\r\n\r\n    // 是否重置验证\r\n    const isResettingField = ref<boolean>(false);\r\n    // 验证提示\r\n    const validateMessage = ref<string>('');\r\n    // item dom\r\n    const formItem = ref<HTMLDivElement>();\r\n    // 内敛值\r\n    const initialValue = ref(undefined);\r\n\r\n    // computed\r\n\r\n    // class\r\n    const wrapperClasses = computed(() => {\r\n      return [\r\n        prefixCls,\r\n        {\r\n          // 错误提示\r\n          ['is-error']: validateState.value === 'error',\r\n          // 成功提示\r\n          ['is-success']: shouldShowSuccess.value,\r\n          // 必填\r\n          ['is-required']: isRequired.value || props.required,\r\n          // 是否隐藏必填字段标签旁边的红色星号\r\n          ['is-no-asterisk']: formContext.hideRequiredAsterisk,\r\n        },\r\n        // 星号的位置\r\n        formContext.requireAsteriskPosition === 'right'\r\n          ? 'asterisk-right'\r\n          : 'asterisk-left',\r\n      ];\r\n    });\r\n\r\n    // 提示样式\r\n    const validateClasses = computed(() => {\r\n      return {\r\n        [`${prefixCls}--error`]: shouldShowError.value,\r\n        [`${prefixCls}--success`]: shouldShowSuccess.value,\r\n      };\r\n    });\r\n\r\n    // 结果反馈图标\r\n    const iconClasses = computed(() => {\r\n      return [\r\n        `${prefixCls}--icon`,\r\n        {\r\n          [`${prefixCls}--icon__${validateState.value}`]: validateState.value,\r\n        },\r\n      ];\r\n    });\r\n\r\n    // 属性规定 label 与哪个表单元素绑定\r\n    const labelFor = computed(() => {\r\n      return props.for || inputIds.value.length === 1\r\n        ? inputIds.value[0]\r\n        : undefined;\r\n    });\r\n\r\n    // 当前标签文本\r\n    const currentLabel = computed(\r\n      () => `${props.label || ''}${formContext?.labelSuffix || ''}`\r\n    );\r\n\r\n    // 标签样式\r\n    const labelStyle = computed<CSSProperties>(() => {\r\n      let obj = {};\r\n\r\n      if (formContext?.labelPosition === 'top') {\r\n        return obj;\r\n      }\r\n\r\n      // 添加单位\r\n      const labelWidth = addUnit(\r\n        props.labelWidth || formContext?.labelWidth || ''\r\n      );\r\n\r\n      if (labelWidth) {\r\n        obj = {\r\n          width: labelWidth,\r\n        };\r\n      }\r\n\r\n      return obj;\r\n    });\r\n\r\n    // 是否显示标签\r\n    const showLabel = computed<boolean>(() => {\r\n      return !!(props.label || slots.label);\r\n    });\r\n\r\n    // 内容样式\r\n    const contentStyle = computed<CSSProperties>(() => {\r\n      let obj = {};\r\n\r\n      if (formContext?.labelPosition === 'top') {\r\n        return obj;\r\n      }\r\n\r\n      // 是嵌套的item\r\n      if (!props.label && !props.labelWidth && isNested) {\r\n        return obj;\r\n      }\r\n\r\n      // 添加单位\r\n      const labelWidth = addUnit(\r\n        props.labelWidth || formContext?.labelWidth || ''\r\n      );\r\n\r\n      if (!props.label && !slots.label) {\r\n        obj = {\r\n          marginLeft: labelWidth,\r\n        };\r\n      }\r\n\r\n      return obj;\r\n    });\r\n\r\n    // 格式化验证\r\n    const normalizedRules = computed(() => {\r\n      const { required } = props;\r\n\r\n      const rules: FormItemRule[] = [];\r\n\r\n      // 当前item有设置表单验证规则\r\n      if (props.rules) {\r\n        rules.push(...ensureArray(props.rules));\r\n      }\r\n\r\n      // 获取form的验证规则\r\n      const formRules = formContext?.rules;\r\n\r\n      // 有验证规则 && 有 model 的键名\r\n      if (formRules && props.prop) {\r\n        // 获取当前item对应的规则\r\n        const currentRules = getProp<Arrayable<FormItemRule> | undefined>(\r\n          formRules,\r\n          props.prop\r\n        ).value;\r\n\r\n        // 有当前item对应的规则\r\n        if (currentRules) {\r\n          rules.push(...ensureArray(currentRules));\r\n        }\r\n      }\r\n\r\n      // 是否为必填项\r\n      if (required) {\r\n        // 必填的验证\r\n        const requiredRules = rules\r\n          .map((rule, index) => [rule, index] as const)\r\n          .filter(([rule]) => Object.keys(rule).includes('required'));\r\n\r\n        // 有必填项\r\n        if (requiredRules.length > 0) {\r\n          for (const [rule, index] of requiredRules) {\r\n            // 必填项\r\n            if (rule.required === required) {\r\n              continue;\r\n            }\r\n\r\n            rules[index] = {\r\n              ...rule,\r\n              required,\r\n            };\r\n          }\r\n        }\r\n        // 没有必填项\r\n        else {\r\n          rules.push({\r\n            required,\r\n          });\r\n        }\r\n      }\r\n\r\n      return rules;\r\n    });\r\n\r\n    // 是否需要验证\r\n    const validateEnabled = computed(() => normalizedRules.value.length > 0);\r\n\r\n    // model的键名转换为 string\r\n    const propString = computed(() => {\r\n      if (!props.prop) {\r\n        return '';\r\n      }\r\n\r\n      return isString(props.prop) ? props.prop : props.prop.join('.');\r\n    });\r\n\r\n    // 获取该item的 model 值\r\n    const fieldValue = computed(() => {\r\n      // 表单数据对象\r\n      const model = formContext?.model;\r\n\r\n      if (!model || !props.prop) {\r\n        return;\r\n      }\r\n\r\n      return getProp(model, props.prop).value;\r\n    });\r\n\r\n    // 显示错误提示\r\n    const shouldShowError = computed(() => {\r\n      return (\r\n        // 验证状态节流\r\n        validateStateDebounced.value === 'error' &&\r\n        // 是否显示校验错误信息\r\n        props.showMessage &&\r\n        // 是否显示校验错误信息\r\n        (formContext?.showMessage ?? true)\r\n      );\r\n    });\r\n\r\n    // 显示成功提示\r\n    const shouldShowSuccess = computed(() => {\r\n      return (\r\n        // 验证状态节流\r\n        validateStateDebounced.value === 'success' &&\r\n        // 没有错误信息\r\n        !shouldShowError.value &&\r\n        // item验证成功提示状态\r\n        (props.showSuccessStatus || formContext?.showSuccessStatus)\r\n      );\r\n    });\r\n\r\n    // 是必填\r\n    const isRequired = computed(() => {\r\n      return normalizedRules.value.some((rule) => rule.required);\r\n    });\r\n\r\n    // 有标签\r\n    const hasLabel = computed(() => {\r\n      return !!(props.label || slots.label);\r\n    });\r\n\r\n    // methods\r\n\r\n    // 添加输入框id\r\n    const addInputId = (id: string) => {\r\n      if (!inputIds.value.includes(id)) {\r\n        inputIds.value.push(id);\r\n      }\r\n    };\r\n\r\n    // 删除输入框id\r\n    const removeInputId = (id: string) => {\r\n      inputIds.value = inputIds.value.filter((listId) => listId !== id);\r\n    };\r\n\r\n    // 验证字段\r\n    const validate: FormItemContext['validate'] = async (\r\n      // 触发方式\r\n      trigger,\r\n      // 回调函数\r\n      callback\r\n    ) => {\r\n      // 如果重置则跳过验证\r\n      if (isResettingField.value || !props.prop) {\r\n        return false;\r\n      }\r\n\r\n      // 是否有回调函数\r\n      const hasCallback = isFunction(callback);\r\n\r\n      // 不需要验证\r\n      if (!validateEnabled.value) {\r\n        callback?.(false);\r\n\r\n        return false;\r\n      }\r\n\r\n      // 获取过滤规则\r\n      const rules = getFilteredRule(trigger);\r\n      if (rules.length === 0) {\r\n        callback?.(true);\r\n        return true;\r\n      }\r\n\r\n      // 验证中\r\n      setValidationState('validating');\r\n\r\n      // 验证规则\r\n      return useValidate(rules)\r\n        .then(() => {\r\n          callback?.(true);\r\n\r\n          return true as const;\r\n        })\r\n        .catch((err: FormValidateFailure) => {\r\n          const { fields } = err;\r\n\r\n          callback?.(false, fields);\r\n\r\n          // 有回调函数\r\n          return hasCallback ? false : Promise.reject(fields);\r\n        });\r\n    };\r\n\r\n    // 设置验证状态\r\n    const setValidationState = (state: FormItemValidateState) => {\r\n      validateState.value = state;\r\n    };\r\n\r\n    // 设置验证状态为成功\r\n    const setValidationSucceeded = () => {\r\n      setValidationState('success');\r\n\r\n      // 任一表单项被校验后触发\r\n      formContext?.emit('on-validate', props.prop!, true, '');\r\n    };\r\n\r\n    // 设置验证状态为失败\r\n    const setValidationFailed = (error: FormValidateFailure) => {\r\n      const { errors, fields } = error;\r\n\r\n      if (!errors || !fields) {\r\n        // eslint-disable-next-line no-console\r\n        console.error(error);\r\n      }\r\n\r\n      // 设置验证状态为失败\r\n      setValidationState('error');\r\n\r\n      // 验证提示\r\n      validateMessage.value = errors\r\n        ? errors?.[0]?.message ?? `${props.prop} is required`\r\n        : '';\r\n\r\n      // 任一表单项被校验后触发\r\n      formContext?.emit(\r\n        'on-validate',\r\n        props.prop!,\r\n        false,\r\n        validateMessage.value\r\n      );\r\n    };\r\n\r\n    // 验证规则\r\n    const useValidate = async (rules: RuleItem[]): Promise<true> => {\r\n      // model的键名\r\n      const modelName = propString.value;\r\n\r\n      // 验证规则\r\n      const validator = new AsyncValidator({\r\n        [modelName]: rules,\r\n      });\r\n\r\n      return validator\r\n        .validate(\r\n          // 要验证的对象\r\n          {\r\n            [modelName]: fieldValue.value,\r\n          },\r\n          {\r\n            // 当指定字段的第一条校验规则产生错误时调用，\r\n            // 不再处理同字段的校验规则。\r\n            // true表示所有字段\r\n            firstFields: true,\r\n          }\r\n        )\r\n        .then(() => {\r\n          // 设置验证状态为成功\r\n          setValidationSucceeded();\r\n\r\n          return true as const;\r\n        })\r\n        .catch((err: FormValidateFailure) => {\r\n          // 设置验证状态为失败\r\n          setValidationFailed(err as FormValidateFailure);\r\n\r\n          return Promise.reject(err);\r\n        });\r\n    };\r\n\r\n    // 获取过滤规则\r\n    const getFilteredRule = (trigger: string) => {\r\n      const rules = normalizedRules.value;\r\n\r\n      return (\r\n        rules\r\n          .filter((rule) => {\r\n            // 验证逻辑的触发方式\r\n            if (!rule.trigger || !trigger) {\r\n              return true;\r\n            }\r\n\r\n            // 验证逻辑的触发方式\r\n            if (Array.isArray(rule.trigger)) {\r\n              return rule.trigger.includes(trigger);\r\n            } else {\r\n              return rule.trigger === trigger;\r\n            }\r\n          })\r\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n          .map(({ trigger, ...rule }): RuleItem => rule)\r\n      );\r\n    };\r\n\r\n    // 对该表单项进行重置\r\n    const resetField: FormItemContext['resetField'] = async () => {\r\n      const model = formContext?.model;\r\n\r\n      if (!model || !props.prop) {\r\n        return;\r\n      }\r\n\r\n      // 获取当前item对应的规则\r\n      const computedValue = getProp(model, props.prop);\r\n\r\n      // 防止验证被触发\r\n      isResettingField.value = true;\r\n\r\n      // 重置的时候重新赋值给props\r\n      computedValue.value = clone(initialValue.value);\r\n\r\n      // nextTick\r\n      await nextTick();\r\n\r\n      // 清除验证\r\n      clearValidate();\r\n\r\n      // 是否重置验证\r\n      isResettingField.value = false;\r\n    };\r\n\r\n    // 清除验证\r\n    const clearValidate: FormItemContext['clearValidate'] = () => {\r\n      // 清除验证\r\n      setValidationState('');\r\n\r\n      // 验证提示\r\n      validateMessage.value = '';\r\n\r\n      // 是否重置验证\r\n      isResettingField.value = false;\r\n    };\r\n\r\n    // provide\r\n    const context: FormItemContext = reactive({\r\n      ...toRefs(props),\r\n      $el: formItem,\r\n      inputIds,\r\n      addInputId,\r\n      removeInputId,\r\n      validate,\r\n      resetField,\r\n      clearValidate,\r\n      hasLabel,\r\n    });\r\n\r\n    // provide\r\n    provide(FormItemContextKey, context);\r\n\r\n    // onMounted\r\n    onMounted(() => {\r\n      if (props.prop) {\r\n        // 添加验证字段\r\n        formContext?.addField(context);\r\n        // 保存当前 item 的值\r\n        initialValue.value = clone(fieldValue.value);\r\n      }\r\n    });\r\n\r\n    // onBeforeUnmount\r\n    onBeforeUnmount(() => {\r\n      formContext?.removeField(context);\r\n    });\r\n\r\n    // watch\r\n\r\n    // 监听表单域验证错误时的提示信息\r\n    watch(\r\n      () => props.error,\r\n      (value) => {\r\n        // 验证提示\r\n        validateMessage.value = value || '';\r\n\r\n        // 设置验证状态\r\n        setValidationState(value ? 'error' : '');\r\n      },\r\n      {\r\n        immediate: true,\r\n      }\r\n    );\r\n\r\n    return {\r\n      prefixCls,\r\n\r\n      // inject\r\n      formContext,\r\n\r\n      // dom\r\n      formItem,\r\n\r\n      // data\r\n      validateMessage,\r\n      validateState,\r\n      labelId,\r\n\r\n      // computed\r\n      wrapperClasses,\r\n      validateClasses,\r\n      iconClasses,\r\n      labelStyle,\r\n      contentStyle,\r\n      currentLabel,\r\n      labelFor,\r\n      showLabel,\r\n      shouldShowError,\r\n      shouldShowSuccess,\r\n      hasLabel,\r\n\r\n      // methods\r\n      addInputId,\r\n      removeInputId,\r\n      resetField,\r\n      clearValidate,\r\n      validate,\r\n    };\r\n  },\r\n  components: {\r\n    FormLabelWrap,\r\n    IvueIcon,\r\n  },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_createCommentVNode","_createVNode","_withCtx","_resolveDynamicComponent","_normalizeStyle","_createElementVNode","_renderSlot","_Transition"],"mappings":";;;;;;qCACEA,iBAiCM,iBAAA,CAAA,CAAA;EAjC2B,OAAAC,SAAA,EAAU,EAAAC,kBAAA,CAAA,KAAA,EAAA;AAAA,IAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,IACzC,GAAA,EAAA,UAAA;AAAA,GACA,EAAA;AAAA,IACkBC,mBAAA,gBAAA,CAAA;AAAA,IAAAC,YACf,0BAAyB,EAAA;AAAA,MAAA,eAAA,EAAA,IAAA,CAAA,UAAA,CAAA,KAAA,KAAA,MAAA;AAAA,MAWd,YAAA,EAAA,CAAA,CAAA,EAAA,GAAA,IAAA,CAAA,WAAA,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,UAAA,MAAA,MAAA;AAAA,KAAA,EAAA;AAAA,MATZ,OAAA,EAAAC,QAAA,MAAA;AAAA,QAAA,IAAA,CAAA,SAAA,IAAAL,SAAA,gBACaM,wBAAS,IAAA,CAAA,QAAA,GAAA,OAAA,GAAA,KAAA,CAAA,EAAA;AAAA,UAEnB,GAAI,EAAA,CAAA;AAAA,UACJ,KAAK,EAAAJ,cAAA,CAAQ,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,OAAA,CAAA,CAAA;AAAA,UACb,IAAK,IAAA,CAAA,OAAA;AAAA,UAAA,KAAA,IAAA,CAAA,QAAA;AAAA,UAG4D,KAAA,EAAAK,cAAA,CAAA,IAAA,CAAA,UAAA,CAAA;AAAA,SAAA,EAAA;AAAA;;;;;;;;MAGtE,CAAA,EAAA,CAAA;AAAA,KAeM,EAAA,CAAA,EAAA,CAAA,eAAA,EAAA,YAAA,CAAA,CAAA;AAAA,IAdKJ,mBAAA,gBAAA,CAAA;AAAA,IAAAK,mBAAiC,KAAE,EAAA;AAAA,MAAA,KAAA,EAAAN,cAAA,CAAA,CAAA,EAAA,IAAA,CAAA,SAAA,CAAA,SAAA,CAAA,CAAA;AAAA,MAC5C,KAAA,EAAaK,cAAA,CAAA,IAAA,CAAA,YAAA,CAAA;AAAA,KACb,EAAA;AAAA,MACAE,UAAA,CAIa,IAAA,CAAA,MAAA,EAAA,SAAA,CAAA;AAAA,MAAAN,mBAJS,4BAAS,CAAA;AAAA,MAAAC,YAAAM,UAAA,EAAA;AAAA;;iBAC7BL,QAEO,MAAA;AAAA,UAAA,IAAA,CAAA,eAAA,GAAAI,UAFoB,CAAA,IAAA,CAAe,QAAA,OAAA,EAAA;AAAA,YAEnC,GAAA,EAAA,CAAA;AAAA,YADL,OAAA,IAAA,CAAA,eAAA;AAAA,aAAW,MAAA;AAAA,YAAsBD,mBAAA,KAAA,EAAA;AAAA,cAAA,KAAA,EAAAN,cAAA,CAAA,IAAA,CAAA,eAAA,CAAA;AAAA;;;QAGrC,CAAA,EAAA,CAAA;AAAA,OAKa,EAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CAAA;AAAA,MAAAC,mBAJS,gBAAS,CAAA;AAAA,MAAAC,YAAAM,UAAA,EAAA;AAAA;;iBAC7BL,QAEO,MAAA;AAAA,UADL,IAAA,CAAA,iBAAA,IAAgE,IAArD,CAAA,sBAAA,GAAAI,UAAA,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAE,EAAe,GAAA,EAAA,CAAA,EAAA,EAAA,MAAA;AAAA,YAAKD,mBAAA,KAAA,EAAA;AAAA,cAAA,KAAA,EAAAN,cAAA,CAAA,IAAA,CAAA,eAAA,CAAA;AAAA;;;;;;;;;;;;"}