(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";

const Repeater = (window.Swal && typeof window.Swal.mixin === 'function')
  ? window.Swal.mixin({
      customClass: {
        container: 'wpcfto-settings',
        confirmButton: 'button'
      }
    })
  : {
      // Fallback that mimics Swal.fire returning a Promise
      fire: (opts) => Promise.resolve({
        isConfirmed: window.confirm((opts && (opts.text || opts.html || opts.title)) || 'Are you sure?')
      })
    };

Vue.component('wpcfto_repeater', {
    mixins: (window.validationMixin ? [window.validationMixin] : []),
    props: ['fields', 'field_label', 'field_name', 'field_id', 'field_value'],
    data: function data() {
      return {
        repeater: [],
        repeater_values: {}
      };
    },
    template: `
      <div class="wpcfto_generic_field wpcfto_generic_field_repeater wpcfto-repeater unflex_fields">
        <wpcfto_fields_aside_before
          :fields="fields"
          :field_label="field_label"
          :required="fields && fields.required === true"
        />
        <div class="wpcfto-field-content">
          <!-- Required proxy: forces validation when repeater is empty -->
          <input
            v-if="fields && fields.required === true"
            class="wpcfto-required-proxy"
            type="text"
            :name="field_id + '__required__'"
            :value="(repeater && repeater.length ? 'ok' : '')"
            :required="!repeater || repeater.length === 0"
            :disabled="repeater && repeater.length > 0"
            tabindex="-1" readonly
            style="position:absolute; left:-9999px; top:auto; width:1px; height:1px; opacity:0; pointer-events:none;"
          />
          <!-- Hidden data carrier to persist repeater rows via standard form submit -->
          <input
            type="hidden"
            :name="field_name"
            :value="jsonValue"
          />
          <div v-for="(area, area_key) in repeater" class="wpcfto-repeater-single" :class="'wpcfto-repeater_' + field_name + '_' + area_key">
            <div class="wpcfto_group_title" @click="toggleArea(area)" v-html="getGroupTitle(area, area_key)"></div>
            <div class="repeater_inner" :class="{ closed: area.closed_tab }">
              <div class="wpcfto-repeater-field" v-for="(field, field_name_inner) in fields.fields">
                <component
                    :is="'wpcfto_' + field.type"
                    :fields="field"
                    :field_id="field.field_id + '_' + area_key + '_' + field_name_inner"
                    :field_name="field_name + '_' + area_key + '_' + field_name_inner"
                    :field_label="field.label"
                    :field_value="getFieldValue(area_key, field, field_name_inner)"
                    :field_data="field"
                    :field_native_name="field_name"
                    :field_native_name_inner="field_name_inner"
                    @wpcfto-get-value="$set(repeater[area_key], field_name_inner, $event)"
                    :ref="'field_' + area_key + '_' + field_name_inner"
                ></component>
              </div>
            </div>
            <span class="wpcfto-repeater-single-delete" @click="removeArea(area_key)">
              <i class="fa fa-trash-alt"></i>Delete
            </span>
          </div>
          <div v-if="repeater && repeater.length > 0" class="separator"></div>
          <div class="addArea" @click="validateAndAddArea">
            <i class="fa fa-plus-circle"></i>
            <span v-html="'Add ' + field_label"></span>
          </div>
        </div>
        <wpcfto_fields_aside_after :fields="fields"></wpcfto_fields_aside_after>
      </div>
    `,
    mounted: function mounted() {
        var _this = this;
        if (typeof _this.field_value === 'string' && WpcftoIsJsonString(_this.field_value)) {
          _this.field_value = JSON.parse(_this.field_value);
        }
        if (typeof _this.field_value !== 'undefined' && typeof _this.field_value !== 'string') {
          _this.$set(_this, 'repeater_values', _this.field_value);
          _this.repeater_values.forEach(function(item, index) {
            var repeaterItem = { closed_tab: true };
            for (var field_name in item) {
              repeaterItem[field_name] = item[field_name];
            }
            _this.repeater.push(repeaterItem);
          });
          // *** Ensure ALL rows are closed after initialization ***
          _this.repeater.forEach(function(item) {
            item.closed_tab = true;
          });
        }
        // Normalize rows to include only declared fields (copy defaults if missing)
        if (this.fields && this.fields.fields) {
          this.repeater = this.repeater.map((row) => {
            const normalized = { closed_tab: true };
            Object.keys(this.fields.fields).forEach((fname) => {
              if (typeof row[fname] !== 'undefined') {
                normalized[fname] = row[fname];
              } else {
                const def = this.fields.fields[fname] && this.fields.fields[fname].value;
                if (typeof def !== 'undefined') normalized[fname] = def;
              }
            });
            return normalized;
          });
        }
        // Initial validation state
        if (typeof this.validateField === 'function') this.validateField();
        if (this.fields && this.fields.required === true) {
          // Block Save when repeater is required but empty (length check only)
          const handler = (e) => {
              // Only enforce when this component is in DOM
              if (!this.$el || !document.body.contains(this.$el)) return;
              const emptyRequired = !this.repeater || this.repeater.length === 0;
              if (emptyRequired) {
                  e.preventDefault();
                  e.stopPropagation();
                  this.focusSelf();
              }
          };
          try {
              const btns = document.querySelectorAll('.wpcfto_save_settings, .wpcfto_save_metabox');
              btns.forEach(btn => btn.addEventListener('click', handler, true));
              this.__wpcftoSaveHandler = handler;
          } catch(e) {}
          // Also prevent <form> submission if invalid (works for both settings + metabox)
          try {
              const form = this.$el.closest('form');
              if (form) {
                  const onSubmit = (e) => {
                      const emptyRequired = !this.repeater || this.repeater.length === 0;
                      if (emptyRequired) {
                          e.preventDefault();
                          e.stopPropagation();
                          this.focusSelf();
                      }
                  };
                  form.addEventListener('submit', onSubmit, true);
                  this.__wpcftoFormSubmitHandler = onSubmit;
              }
          } catch(e) {}
        }
        if (typeof this.validateField === 'function') this.validateField();
    },
    beforeDestroy: function () {
        if (this.__wpcftoSaveHandler) {
          try {
            const btns = document.querySelectorAll('.wpcfto_save_settings, .wpcfto_save_metabox');
            btns.forEach(btn => btn.removeEventListener('click', this.__wpcftoSaveHandler, true));
          } catch(e) {}
          this.__wpcftoSaveHandler = null;
        }
        if (this.__wpcftoFormSubmitHandler) {
          try {
            const form = this.$el && this.$el.closest ? this.$el.closest('form') : null;
            if (form) form.removeEventListener('submit', this.__wpcftoFormSubmitHandler, true);
          } catch(e) {}
          this.__wpcftoFormSubmitHandler = null;
        }
    },
    methods: {
        focusSelf() {
            try {
                const rect = this.$el.getBoundingClientRect();
                const top = window.pageYOffset + rect.top - 60;
                window.scrollTo({ top, behavior: 'smooth' });
            } catch(e) {}
            try { this.$el.classList.add('wpcfto-invalid'); } catch(e) {}
        },
        // scrollIntoViewIfNeeded() {
        //   try {
        //     const top = window.pageYOffset + this.$el.getBoundingClientRect().top - 60;
        //     window.scrollTo({ top, behavior: 'smooth' });
        //   } catch(e) {}
        // },
        formatLabelPath(parts) {
          return parts.filter(Boolean).map(function (s) {
              return String(s).trim();
          }).filter(Boolean).join(' → ');
        },
        validateField() {
          // If this repeater is not required, always treat as valid and clean any invalid markers
          if (!(this.fields && this.fields.required === true)) {
            try { this.$el.classList.remove('wpcfto-invalid'); } catch(e){}
            try { this.$el.removeAttribute('aria-invalid'); } catch(e){}
            try {
              const fid = this.field_id || (this.fields && this.fields.field_id);
              if (fid) this.$root.$emit('field-validation', { fieldId: fid, isValid: true });
            } catch(e) {}
            return true;
          }
          // Repeater-level required: valid iff it has at least one row
          let isValid = true;
          if (this.fields && this.fields.required === true) {
            const len = (this.repeater && Array.isArray(this.repeater)) ? this.repeater.length : 0;
            isValid = len > 0;
          }

          if (!isValid) {
            try { this.$el.classList.add('wpcfto-invalid'); } catch(e){}
            try { this.$el.setAttribute('aria-invalid','true'); } catch(e){}
            // Notify global validator (validationMixin listener)
            try {
              const fid = this.field_id || (this.fields && this.fields.field_id);
              if (fid) this.$root.$emit('field-validation', { fieldId: fid, isValid: false });
            } catch(e) {}
            return false;
          }

          // valid state
          try { this.$el.classList.remove('wpcfto-invalid'); } catch(e){}
          try { this.$el.removeAttribute('aria-invalid'); } catch(e){}
          try {
            const fid = this.field_id || (this.fields && this.fields.field_id);
            if (fid) this.$root.$emit('field-validation', { fieldId: fid, isValid: true });
          } catch(e) {}
          return true;
        },
        // This method validates all visible required fields in all rows before adding a new row
        validateAndAddArea: function() {
            const fieldsInRepeater = this._props.fields.fields;            
            let group_title = null;
            Object.values(fieldsInRepeater).forEach(field => {
              if ('is_group_title' in field) {
                if (field.is_group_title !== false) {
                  group_title = field.label;
                }
              }
            });
            var invalidFields = [];
            // Loop through all repeater rows and all fields
            this.repeater.forEach((area, area_key) => {
            for (const field_name_inner in this.fields.fields) {
                const field = this.fields.fields[field_name_inner];
                // Find the child component via $refs
                const refName = 'field_' + area_key + '_' + field_name_inner;
                const child = this.$refs[refName];
                // $refs[refName] can be an array if used inside v-for, so get the first element
                const childComponent = Array.isArray(child) ? child[0] : child;
                // If the child component exists and has validateField method, call it
                if (childComponent && typeof childComponent.validateField === 'function') {
                // Only validate visible required fields
                if (childComponent.isVisible && childComponent.fields && childComponent.fields.required) {
                    if (!childComponent.validateField()) {
                    invalidFields.push({
                        repeater_label: this._props.field_label,
                        group_title: group_title,
                        label: childComponent.fields.label || field_name_inner,
                        area: area_key + 1
                    });
                    // Optionally, you can add a visual error class here
                    // childComponent.$el.classList.add('invalid-field');
                    }
                }
                }
            }
            });
            if (invalidFields.length > 0) {
              // Compose error message
              var msg = 'Please fill all required fields before adding a new item:\n\n';
              const firstInvalidItem = invalidFields[0];
              msg += 'Check item #'+firstInvalidItem.area+': <b>'+this.formatLabelPath([firstInvalidItem.group_title, firstInvalidItem.label])+'</b>';
              // Use SweetAlert2 if available, otherwise alert()
              if (typeof window.Swal === 'function') {
                  Repeater.fire({
                      icon: 'warning',
                      title: 'Required fields missing',
                      html: msg.replace(/\n/g, '<br>'),
                      width: 'fit-content',
                      customClass: {
                          confirmButton: 'btn text-bg-primary'
                      },
                  });
              } else {
                  alert(msg);
              }
              return;
            }
            // If all required fields are valid, add a new row
            this.addArea();
        },
        addArea: function addArea() {
            // Close all rows before adding new
            this.repeater.forEach(item => { item.closed_tab = true; });
            this.repeater.push({ closed_tab: false }); // new row is open
            var el = 'wpcfto-repeater_' + this.field_name + '_' + (this.repeater.length - 1);
            Vue.nextTick(function () {
                if (typeof jQuery !== 'undefined') {
                    var $ = jQuery;
                    $([document.documentElement, document.body]).animate({
                    scrollTop: $("." + el).offset().top - 40
                    }, 400);
                }
            });
            this.validateField();
            if (typeof jQuery !== 'undefined') {
              jQuery(document).trigger('repeater-item-added', [this._props]);
            }
        },
        toggleArea: function toggleArea(area) {
            // Close all other rows
            this.repeater.forEach(item => {
              if (item !== area) {
                this.$set(item, 'closed_tab', true);
              }
            });
            
            // Toggle clicked row's closed_tab state
            const isCurrentlyClosed = area.closed_tab === true || typeof area.closed_tab === 'undefined';
            this.$set(area, 'closed_tab', !isCurrentlyClosed);
        },
        removeArea: function removeArea(areaIndex) {
            // if (confirm('Do your really want to delete this field?')) {
            //     this.repeater.splice(areaIndex, 1);
            // }
            Repeater.fire({
                icon: 'question',
                html: 'Do your really want to delete this item?',
                showCancelButton: true,
                reverseButtons: true
            }).then((result) => {
                if (result.isConfirmed) {
                    this.repeater.splice(areaIndex, 1);
                    // jQuery action hook trigger example:
                    if (typeof jQuery !== 'undefined') {
                      jQuery(document).trigger('repeater-item-removed', [this._props, areaIndex]);
                    }
                }
            });
        },
        getFieldValue: function getFieldValue(key, field, field_name) {
            if (this.repeater[key] && typeof this.repeater[key][field_name] !== 'undefined') {
                return this.repeater[key][field_name];
            }
            if (typeof this.repeater_values !== 'undefined' &&
                typeof this.repeater_values[key] !== 'undefined' &&
                typeof this.repeater_values[key][field_name] !== 'undefined') {
                    return this.repeater_values[key][field_name];
                }
            return field.value;
        },
        getGroupTitle(area, area_key) {
            let groupTitleFieldName = null;
            let groupTitleField = null;
            for (const [fname, field] of Object.entries(this.fields.fields)) {
            if (field.is_group_title) {
                groupTitleFieldName = fname;
                groupTitleField = field;
                break;
            }
            }
            if (groupTitleFieldName) {
            let value = area[groupTitleFieldName];
            if (typeof value === 'undefined' && this.repeater_values && this.repeater_values[area_key]) {
                value = this.repeater_values[area_key][groupTitleFieldName];
            }
            if (typeof value === 'undefined' || value === '') {
                value = groupTitleField.label || this.field_label;
            } else {
                if (groupTitleField.options && groupTitleField.options[value]) {
                value = groupTitleField.options[value];
                }
            }
            return value;
            }
            return this.field_label + ' #' + (area_key + 1);
        },
        validateAllRows() {
            let invalidFields = [];
        
            this.repeater.forEach((area, area_key) => {
              for (const field_name_inner in this.fields.fields) {
                const field = this.fields.fields[field_name_inner];
                // Find child component by ref
                const refName = 'field_' + area_key + '_' + field_name_inner;
                const child = this.$refs[refName];
                const childComponent = Array.isArray(child) ? child[0] : child;
        
                if (childComponent && typeof childComponent.validateField === 'function') {
                  if (childComponent.isVisible && field.required) {
                    if (!childComponent.validateField()) {
                      invalidFields.push({
                        label: field.label || field_name_inner,
                        row: area_key + 1
                      });
                      // Optionally add visual error here
                    }
                  }
                }
              }
            });
        
            if (invalidFields.length > 0) {
              let msg = 'Please fill all required fields before saving:\n\n';
              msg += invalidFields.map(f => `Row #${f.row}: ${f.label}`).join('\n');
        
              if (typeof window.Swal === 'function') {
                Swal.fire({
                  icon: 'warning',
                  title: 'Required fields missing',
                  html: msg.replace(/\n/g, '<br>')
                });
              } else {
                alert(msg);
              }
              return false;
            }
        
            return true;
        },
        saveChanges() {
            // Block if repeater required but empty OR if any child invalid
            const selfValid = this.validateField();
            // const rowsValid = this.validateAllRows();
            if (!selfValid) { return; }
            // Proceed with save logic here...
        }
    },
    watch: {
        repeater: {
            deep: true,
            handler: function handler(repeater) {
              // Build a clean payload with only declared inner fields
              const payload = (Array.isArray(repeater) ? repeater : []).map((row) => {
                const out = {};
                if (this.fields && this.fields.fields) {
                  Object.keys(this.fields.fields).forEach((fname) => {
                    if (typeof row[fname] !== 'undefined') out[fname] = row[fname];
                  });
                }
                return out;
              });
              this.$emit('wpcfto-get-value', payload);
              this.validateField();
            }
        }
    },
    computed: {
      jsonValue() {
        const list = Array.isArray(this.repeater) ? this.repeater : [];
        const fieldsDef = (this.fields && this.fields.fields) ? this.fields.fields : null;
        const payload = list.map((row) => {
          const out = {};
          if (fieldsDef) {
            Object.keys(fieldsDef).forEach((fname) => {
              if (typeof row[fname] !== 'undefined') out[fname] = row[fname];
              else {
                const def = fieldsDef[fname] && fieldsDef[fname].value;
                if (typeof def !== 'undefined') out[fname] = def;
              }
            });
          }
          return out;
        });
        try { return JSON.stringify(payload); } catch(e) { return '[]'; }
      }
    }
  });
  
//# sourceMappingURL=data:application/json;charset=utf-8;base64, 
},{}]},{},[1])