import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _extends from "@babel/runtime/helpers/esm/extends";
import { getMonthsInYear } from '../../utils/date-utils';
export var getDateSectionConfigFromFormatToken = function getDateSectionConfigFromFormatToken(utils, formatToken) {
  var config = utils.formatTokenMap[formatToken];
  if (config == null) {
    throw new Error(["MUI: The token \"".concat(formatToken, "\" is not supported by the Date and Time Pickers."), 'Please try using another token or open an issue on https://github.com/mui/mui-x/issues/new/choose if you think it should be supported.'].join('\n'));
  }
  if (typeof config === 'string') {
    return {
      type: config,
      contentType: config === 'meridiem' ? 'letter' : 'digit',
      maxLength: undefined
    };
  }
  return {
    type: config.sectionType,
    contentType: config.contentType,
    maxLength: config.maxLength
  };
};
var getDeltaFromKeyCode = function getDeltaFromKeyCode(keyCode) {
  switch (keyCode) {
    case 'ArrowUp':
      return 1;
    case 'ArrowDown':
      return -1;
    case 'PageUp':
      return 5;
    case 'PageDown':
      return -5;
    default:
      return 0;
  }
};
export var getDaysInWeekStr = function getDaysInWeekStr(utils, timezone, format) {
  var elements = [];
  var now = utils.dateWithTimezone(undefined, timezone);
  var startDate = utils.startOfWeek(now);
  var endDate = utils.endOfWeek(now);
  var current = startDate;
  while (utils.isBefore(current, endDate)) {
    elements.push(current);
    current = utils.addDays(current, 1);
  }
  return elements.map(function (weekDay) {
    return utils.formatByString(weekDay, format);
  });
};
export var getLetterEditingOptions = function getLetterEditingOptions(utils, timezone, sectionType, format) {
  switch (sectionType) {
    case 'month':
      {
        return getMonthsInYear(utils, utils.dateWithTimezone(undefined, timezone)).map(function (month) {
          return utils.formatByString(month, format);
        });
      }
    case 'weekDay':
      {
        return getDaysInWeekStr(utils, timezone, format);
      }
    case 'meridiem':
      {
        var now = utils.dateWithTimezone(undefined, timezone);
        return [utils.startOfDay(now), utils.endOfDay(now)].map(function (date) {
          return utils.formatByString(date, format);
        });
      }
    default:
      {
        return [];
      }
  }
};
export var cleanLeadingZeros = function cleanLeadingZeros(utils, valueStr, size) {
  var cleanValueStr = valueStr;

  // Remove the leading zeros
  cleanValueStr = Number(cleanValueStr).toString();

  // Add enough leading zeros to fill the section
  while (cleanValueStr.length < size) {
    cleanValueStr = "0".concat(cleanValueStr);
  }
  return cleanValueStr;
};
export var cleanDigitSectionValue = function cleanDigitSectionValue(utils, timezone, value, sectionBoundaries, section) {
  if (process.env.NODE_ENV !== 'production') {
    if (section.type !== 'day' && section.contentType === 'digit-with-letter') {
      throw new Error(["MUI: The token \"".concat(section.format, "\" is a digit format with letter in it.'\n             This type of format is only supported for 'day' sections")].join('\n'));
    }
  }
  if (section.type === 'day' && section.contentType === 'digit-with-letter') {
    var date = utils.setDate(sectionBoundaries.longestMonth, value);
    return utils.formatByString(date, section.format);
  }

  // queryValue without leading `0` (`01` => `1`)
  var valueStr = value.toString();
  if (section.hasLeadingZerosInInput) {
    return cleanLeadingZeros(utils, valueStr, section.maxLength);
  }
  return valueStr;
};
export var adjustSectionValue = function adjustSectionValue(utils, timezone, section, keyCode, sectionsValueBoundaries, activeDate, stepsAttributes) {
  var delta = getDeltaFromKeyCode(keyCode);
  var isStart = keyCode === 'Home';
  var isEnd = keyCode === 'End';
  var shouldSetAbsolute = section.value === '' || isStart || isEnd;
  var adjustDigitSection = function adjustDigitSection() {
    var sectionBoundaries = sectionsValueBoundaries[section.type]({
      currentDate: activeDate,
      format: section.format,
      contentType: section.contentType
    });
    var getCleanValue = function getCleanValue(value) {
      return cleanDigitSectionValue(utils, timezone, value, sectionBoundaries, section);
    };
    var step = section.type === 'minutes' && stepsAttributes != null && stepsAttributes.minutesStep ? stepsAttributes.minutesStep : 1;
    var currentSectionValue = parseInt(section.value, 10);
    var newSectionValueNumber = currentSectionValue + delta * step;
    if (shouldSetAbsolute) {
      if (section.type === 'year' && !isEnd && !isStart) {
        return utils.formatByString(utils.dateWithTimezone(undefined, timezone), section.format);
      }
      if (delta > 0 || isStart) {
        newSectionValueNumber = sectionBoundaries.minimum;
      } else {
        newSectionValueNumber = sectionBoundaries.maximum;
      }
    }
    if (newSectionValueNumber % step !== 0) {
      if (delta < 0 || isStart) {
        newSectionValueNumber += step - (step + newSectionValueNumber) % step; // for JS -3 % 5 = -3 (should be 2)
      }

      if (delta > 0 || isEnd) {
        newSectionValueNumber -= newSectionValueNumber % step;
      }
    }
    if (newSectionValueNumber > sectionBoundaries.maximum) {
      return getCleanValue(sectionBoundaries.minimum + (newSectionValueNumber - sectionBoundaries.maximum - 1) % (sectionBoundaries.maximum - sectionBoundaries.minimum + 1));
    }
    if (newSectionValueNumber < sectionBoundaries.minimum) {
      return getCleanValue(sectionBoundaries.maximum - (sectionBoundaries.minimum - newSectionValueNumber - 1) % (sectionBoundaries.maximum - sectionBoundaries.minimum + 1));
    }
    return getCleanValue(newSectionValueNumber);
  };
  var adjustLetterSection = function adjustLetterSection() {
    var options = getLetterEditingOptions(utils, timezone, section.type, section.format);
    if (options.length === 0) {
      return section.value;
    }
    if (shouldSetAbsolute) {
      if (delta > 0 || isStart) {
        return options[0];
      }
      return options[options.length - 1];
    }
    var currentOptionIndex = options.indexOf(section.value);
    var newOptionIndex = (currentOptionIndex + options.length + delta) % options.length;
    return options[newOptionIndex];
  };
  if (section.contentType === 'digit' || section.contentType === 'digit-with-letter') {
    return adjustDigitSection();
  }
  return adjustLetterSection();
};
export var getSectionVisibleValue = function getSectionVisibleValue(section, target) {
  var value = section.value || section.placeholder;
  var hasLeadingZeros = target === 'non-input' ? section.hasLeadingZerosInFormat : section.hasLeadingZerosInInput;
  if (target === 'non-input' && section.hasLeadingZerosInInput && !section.hasLeadingZerosInFormat) {
    value = Number(value).toString();
  }

  // In the input, we add an empty character at the end of each section without leading zeros.
  // This makes sure that `onChange` will always be fired.
  // Otherwise, when your input value equals `1/dd/yyyy` (format `M/DD/YYYY` on DayJs),
  // If you press `1`, on the first section, the new value is also `1/dd/yyyy`,
  // So the browser will not fire the input `onChange`.
  var shouldAddInvisibleSpace = ['input-rtl', 'input-ltr'].includes(target) && section.contentType === 'digit' && !hasLeadingZeros && value.length === 1;
  if (shouldAddInvisibleSpace) {
    value = "".concat(value, "\u200E");
  }
  if (target === 'input-rtl') {
    value = "\u2068".concat(value, "\u2069");
  }
  return value;
};
export var cleanString = function cleanString(dirtyString) {
  return dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
};
export var addPositionPropertiesToSections = function addPositionPropertiesToSections(sections, isRTL) {
  var position = 0;
  var positionInInput = isRTL ? 1 : 0;
  var newSections = [];
  for (var i = 0; i < sections.length; i += 1) {
    var section = sections[i];
    var renderedValue = getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr');
    var sectionStr = "".concat(section.startSeparator).concat(renderedValue).concat(section.endSeparator);
    var sectionLength = cleanString(sectionStr).length;
    var sectionLengthInInput = sectionStr.length;

    // The ...InInput values consider the unicode characters but do include them in their indexes
    var cleanedValue = cleanString(renderedValue);
    var startInInput = positionInInput + renderedValue.indexOf(cleanedValue[0]) + section.startSeparator.length;
    var endInInput = startInInput + cleanedValue.length;
    newSections.push(_extends({}, section, {
      start: position,
      end: position + sectionLength,
      startInInput: startInInput,
      endInInput: endInInput
    }));
    position += sectionLength;
    // Move position to the end of string associated to the current section
    positionInInput += sectionLengthInInput;
  }
  return newSections;
};
var getSectionPlaceholder = function getSectionPlaceholder(utils, timezone, localeText, sectionConfig, currentTokenValue) {
  switch (sectionConfig.type) {
    case 'year':
      {
        return localeText.fieldYearPlaceholder({
          digitAmount: utils.formatByString(utils.dateWithTimezone(undefined, timezone), currentTokenValue).length
        });
      }
    case 'month':
      {
        return localeText.fieldMonthPlaceholder({
          contentType: sectionConfig.contentType
        });
      }
    case 'day':
      {
        return localeText.fieldDayPlaceholder();
      }
    case 'weekDay':
      {
        return localeText.fieldWeekDayPlaceholder({
          contentType: sectionConfig.contentType
        });
      }
    case 'hours':
      {
        return localeText.fieldHoursPlaceholder();
      }
    case 'minutes':
      {
        return localeText.fieldMinutesPlaceholder();
      }
    case 'seconds':
      {
        return localeText.fieldSecondsPlaceholder();
      }
    case 'meridiem':
      {
        return localeText.fieldMeridiemPlaceholder();
      }
    default:
      {
        return currentTokenValue;
      }
  }
};
export var changeSectionValueFormat = function changeSectionValueFormat(utils, valueStr, currentFormat, newFormat) {
  if (process.env.NODE_ENV !== 'production') {
    if (getDateSectionConfigFromFormatToken(utils, currentFormat).type === 'weekDay') {
      throw new Error("changeSectionValueFormat doesn't support week day formats");
    }
  }
  return utils.formatByString(utils.parse(valueStr, currentFormat), newFormat);
};
var isFourDigitYearFormat = function isFourDigitYearFormat(utils, timezone, format) {
  return utils.formatByString(utils.dateWithTimezone(undefined, timezone), format).length === 4;
};
export var doesSectionFormatHaveLeadingZeros = function doesSectionFormatHaveLeadingZeros(utils, timezone, contentType, sectionType, format) {
  if (contentType !== 'digit') {
    return false;
  }
  var now = utils.dateWithTimezone(undefined, timezone);
  switch (sectionType) {
    // We can't use `changeSectionValueFormat`, because  `utils.parse('1', 'YYYY')` returns `1971` instead of `1`.
    case 'year':
      {
        if (isFourDigitYearFormat(utils, timezone, format)) {
          var formatted0001 = utils.formatByString(utils.setYear(now, 1), format);
          return formatted0001 === '0001';
        }
        var formatted2001 = utils.formatByString(utils.setYear(now, 2001), format);
        return formatted2001 === '01';
      }
    case 'month':
      {
        return utils.formatByString(utils.startOfYear(now), format).length > 1;
      }
    case 'day':
      {
        return utils.formatByString(utils.startOfMonth(now), format).length > 1;
      }
    case 'weekDay':
      {
        return utils.formatByString(utils.startOfWeek(now), format).length > 1;
      }
    case 'hours':
      {
        return utils.formatByString(utils.setHours(now, 1), format).length > 1;
      }
    case 'minutes':
      {
        return utils.formatByString(utils.setMinutes(now, 1), format).length > 1;
      }
    case 'seconds':
      {
        return utils.formatByString(utils.setMinutes(now, 1), format).length > 1;
      }
    default:
      {
        throw new Error('Invalid section type');
      }
  }
};
var getEscapedPartsFromFormat = function getEscapedPartsFromFormat(utils, format) {
  var escapedParts = [];
  var _utils$escapedCharact = utils.escapedCharacters,
    startChar = _utils$escapedCharact.start,
    endChar = _utils$escapedCharact.end;
  var regExp = new RegExp("(\\".concat(startChar, "[^\\").concat(endChar, "]*\\").concat(endChar, ")+"), 'g');
  var match = null;
  // eslint-disable-next-line no-cond-assign
  while (match = regExp.exec(format)) {
    escapedParts.push({
      start: match.index,
      end: regExp.lastIndex - 1
    });
  }
  return escapedParts;
};
export var splitFormatIntoSections = function splitFormatIntoSections(utils, timezone, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL) {
  var startSeparator = '';
  var sections = [];
  var now = utils.date();
  var commitToken = function commitToken(token) {
    if (token === '') {
      return null;
    }
    var sectionConfig = getDateSectionConfigFromFormatToken(utils, token);
    var hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, timezone, sectionConfig.contentType, sectionConfig.type, token);
    var hasLeadingZerosInInput = shouldRespectLeadingZeros ? hasLeadingZerosInFormat : sectionConfig.contentType === 'digit';
    var isValidDate = date != null && utils.isValid(date);
    var sectionValue = isValidDate ? utils.formatByString(date, token) : '';
    var maxLength = null;
    if (hasLeadingZerosInInput) {
      if (hasLeadingZerosInFormat) {
        maxLength = sectionValue === '' ? utils.formatByString(now, token).length : sectionValue.length;
      } else {
        if (sectionConfig.maxLength == null) {
          throw new Error("MUI: The token ".concat(token, " should have a 'maxDigitNumber' property on it's adapter"));
        }
        maxLength = sectionConfig.maxLength;
        if (isValidDate) {
          sectionValue = cleanLeadingZeros(utils, sectionValue, maxLength);
        }
      }
    }
    sections.push(_extends({}, sectionConfig, {
      format: token,
      maxLength: maxLength,
      value: sectionValue,
      placeholder: getSectionPlaceholder(utils, timezone, localeText, sectionConfig, token),
      hasLeadingZeros: hasLeadingZerosInFormat,
      hasLeadingZerosInFormat: hasLeadingZerosInFormat,
      hasLeadingZerosInInput: hasLeadingZerosInInput,
      startSeparator: sections.length === 0 ? startSeparator : '',
      endSeparator: '',
      modified: false
    }));
    return null;
  };

  // Expand the provided format
  var formatExpansionOverflow = 10;
  var prevFormat = format;
  var nextFormat = utils.expandFormat(format);
  while (nextFormat !== prevFormat) {
    prevFormat = nextFormat;
    nextFormat = utils.expandFormat(prevFormat);
    formatExpansionOverflow -= 1;
    if (formatExpansionOverflow < 0) {
      throw new Error('MUI: The format expansion seems to be  enter in an infinite loop. Please open an issue with the format passed to the picker component');
    }
  }
  var expandedFormat = nextFormat;

  // Get start/end indexes of escaped sections
  var escapedParts = getEscapedPartsFromFormat(utils, expandedFormat);

  // This RegExp test if the beginning of a string correspond to a supported token
  var isTokenStartRegExp = new RegExp("^(".concat(Object.keys(utils.formatTokenMap).join('|'), ")"));
  var currentTokenValue = '';
  var _loop = function _loop(i) {
    var escapedPartOfCurrentChar = escapedParts.find(function (escapeIndex) {
      return escapeIndex.start <= i && escapeIndex.end >= i;
    });
    var char = expandedFormat[i];
    var isEscapedChar = escapedPartOfCurrentChar != null;
    var potentialToken = "".concat(currentTokenValue).concat(expandedFormat.slice(i));
    if (!isEscapedChar && char.match(/([A-Za-z]+)/) && isTokenStartRegExp.test(potentialToken)) {
      currentTokenValue += char;
    } else {
      // If we are on the opening or closing character of an escaped part of the format,
      // Then we ignore this character.
      var isEscapeBoundary = isEscapedChar && (escapedPartOfCurrentChar == null ? void 0 : escapedPartOfCurrentChar.start) === i || (escapedPartOfCurrentChar == null ? void 0 : escapedPartOfCurrentChar.end) === i;
      if (!isEscapeBoundary) {
        commitToken(currentTokenValue);
        currentTokenValue = '';
        if (sections.length === 0) {
          startSeparator += char;
        } else {
          sections[sections.length - 1].endSeparator += char;
        }
      }
    }
  };
  for (var i = 0; i < expandedFormat.length; i += 1) {
    _loop(i);
  }
  commitToken(currentTokenValue);
  return sections.map(function (section) {
    var cleanSeparator = function cleanSeparator(separator) {
      var cleanedSeparator = separator;
      if (isRTL && cleanedSeparator !== null && cleanedSeparator.includes(' ')) {
        cleanedSeparator = "\u2069".concat(cleanedSeparator, "\u2066");
      }
      if (formatDensity === 'spacious' && ['/', '.', '-'].includes(cleanedSeparator)) {
        cleanedSeparator = " ".concat(cleanedSeparator, " ");
      }
      return cleanedSeparator;
    };
    section.startSeparator = cleanSeparator(section.startSeparator);
    section.endSeparator = cleanSeparator(section.endSeparator);
    return section;
  });
};

/**
 * Some date libraries like `dayjs` don't support parsing from date with escaped characters.
 * To make sure that the parsing works, we are building a format and a date without any separator.
 */
export var getDateFromDateSections = function getDateFromDateSections(utils, sections) {
  // If we have both a day and a weekDay section,
  // Then we skip the weekDay in the parsing because libraries like dayjs can't parse complicated formats containing a weekDay.
  // dayjs(dayjs().format('dddd MMMM D YYYY'), 'dddd MMMM D YYYY')) // returns `Invalid Date` even if the format is valid.
  var shouldSkipWeekDays = sections.some(function (section) {
    return section.type === 'day';
  });
  var sectionFormats = [];
  var sectionValues = [];
  for (var i = 0; i < sections.length; i += 1) {
    var section = sections[i];
    var shouldSkip = shouldSkipWeekDays && section.type === 'weekDay';
    if (!shouldSkip) {
      sectionFormats.push(section.format);
      sectionValues.push(getSectionVisibleValue(section, 'non-input'));
    }
  }
  var formatWithoutSeparator = sectionFormats.join(' ');
  var dateWithoutSeparatorStr = sectionValues.join(' ');
  return utils.parse(dateWithoutSeparatorStr, formatWithoutSeparator);
};
export var createDateStrForInputFromSections = function createDateStrForInputFromSections(sections, isRTL) {
  var formattedSections = sections.map(function (section) {
    var dateValue = getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr');
    return "".concat(section.startSeparator).concat(dateValue).concat(section.endSeparator);
  });
  var dateStr = formattedSections.join('');
  if (!isRTL) {
    return dateStr;
  }

  // \u2066: start left-to-right isolation
  // \u2067: start right-to-left isolation
  // \u2068: start first strong character isolation
  // \u2069: pop isolation
  // wrap into an isolated group such that separators can split the string in smaller ones by adding \u2069\u2068
  return "\u2066".concat(dateStr, "\u2069");
};
export var getSectionsBoundaries = function getSectionsBoundaries(utils, timezone) {
  var today = utils.dateWithTimezone(undefined, timezone);
  var endOfYear = utils.endOfYear(today);
  var endOfDay = utils.endOfDay(today);
  var _getMonthsInYear$redu = getMonthsInYear(utils, today).reduce(function (acc, month) {
      var daysInMonth = utils.getDaysInMonth(month);
      if (daysInMonth > acc.maxDaysInMonth) {
        return {
          maxDaysInMonth: daysInMonth,
          longestMonth: month
        };
      }
      return acc;
    }, {
      maxDaysInMonth: 0,
      longestMonth: null
    }),
    maxDaysInMonth = _getMonthsInYear$redu.maxDaysInMonth,
    longestMonth = _getMonthsInYear$redu.longestMonth;
  return {
    year: function year(_ref) {
      var format = _ref.format;
      return {
        minimum: 0,
        maximum: isFourDigitYearFormat(utils, timezone, format) ? 9999 : 99
      };
    },
    month: function month() {
      return {
        minimum: 1,
        // Assumption: All years have the same amount of months
        maximum: utils.getMonth(endOfYear) + 1
      };
    },
    day: function day(_ref2) {
      var currentDate = _ref2.currentDate;
      return {
        minimum: 1,
        maximum: currentDate != null && utils.isValid(currentDate) ? utils.getDaysInMonth(currentDate) : maxDaysInMonth,
        longestMonth: longestMonth
      };
    },
    weekDay: function weekDay(_ref3) {
      var format = _ref3.format,
        contentType = _ref3.contentType;
      if (contentType === 'digit') {
        var daysInWeek = getDaysInWeekStr(utils, timezone, format).map(Number);
        return {
          minimum: Math.min.apply(Math, _toConsumableArray(daysInWeek)),
          maximum: Math.max.apply(Math, _toConsumableArray(daysInWeek))
        };
      }
      return {
        minimum: 1,
        maximum: 7
      };
    },
    hours: function hours(_ref4) {
      var format = _ref4.format;
      var lastHourInDay = utils.getHours(endOfDay);
      var hasMeridiem = utils.formatByString(utils.endOfDay(today), format) !== lastHourInDay.toString();
      if (hasMeridiem) {
        return {
          minimum: 1,
          maximum: Number(utils.formatByString(utils.startOfDay(today), format))
        };
      }
      return {
        minimum: 0,
        maximum: lastHourInDay
      };
    },
    minutes: function minutes() {
      return {
        minimum: 0,
        // Assumption: All years have the same amount of minutes
        maximum: utils.getMinutes(endOfDay)
      };
    },
    seconds: function seconds() {
      return {
        minimum: 0,
        // Assumption: All years have the same amount of seconds
        maximum: utils.getSeconds(endOfDay)
      };
    },
    meridiem: function meridiem() {
      return {
        minimum: 0,
        maximum: 0
      };
    }
  };
};
var warnedOnceInvalidSection = false;
export var validateSections = function validateSections(sections, valueType) {
  if (process.env.NODE_ENV !== 'production') {
    if (!warnedOnceInvalidSection) {
      var supportedSections = [];
      if (['date', 'date-time'].includes(valueType)) {
        supportedSections.push('weekDay', 'day', 'month', 'year');
      }
      if (['time', 'date-time'].includes(valueType)) {
        supportedSections.push('hours', 'minutes', 'seconds', 'meridiem');
      }
      var invalidSection = sections.find(function (section) {
        return !supportedSections.includes(section.type);
      });
      if (invalidSection) {
        console.warn("MUI: The field component you are using is not compatible with the \"".concat(invalidSection.type, " date section."), "The supported date sections are [\"".concat(supportedSections.join('", "'), "\"]`."));
        warnedOnceInvalidSection = true;
      }
    }
  }
};
var transferDateSectionValue = function transferDateSectionValue(utils, timezone, section, dateToTransferFrom, dateToTransferTo) {
  switch (section.type) {
    case 'year':
      {
        return utils.setYear(dateToTransferTo, utils.getYear(dateToTransferFrom));
      }
    case 'month':
      {
        return utils.setMonth(dateToTransferTo, utils.getMonth(dateToTransferFrom));
      }
    case 'weekDay':
      {
        var formattedDaysInWeek = getDaysInWeekStr(utils, timezone, section.format);
        var dayInWeekStrOfActiveDate = utils.formatByString(dateToTransferFrom, section.format);
        var dayInWeekOfActiveDate = formattedDaysInWeek.indexOf(dayInWeekStrOfActiveDate);
        var dayInWeekOfNewSectionValue = formattedDaysInWeek.indexOf(section.value);
        var diff = dayInWeekOfNewSectionValue - dayInWeekOfActiveDate;
        return utils.addDays(dateToTransferFrom, diff);
      }
    case 'day':
      {
        return utils.setDate(dateToTransferTo, utils.getDate(dateToTransferFrom));
      }
    case 'meridiem':
      {
        var isAM = utils.getHours(dateToTransferFrom) < 12;
        var mergedDateHours = utils.getHours(dateToTransferTo);
        if (isAM && mergedDateHours >= 12) {
          return utils.addHours(dateToTransferTo, -12);
        }
        if (!isAM && mergedDateHours < 12) {
          return utils.addHours(dateToTransferTo, 12);
        }
        return dateToTransferTo;
      }
    case 'hours':
      {
        return utils.setHours(dateToTransferTo, utils.getHours(dateToTransferFrom));
      }
    case 'minutes':
      {
        return utils.setMinutes(dateToTransferTo, utils.getMinutes(dateToTransferFrom));
      }
    case 'seconds':
      {
        return utils.setSeconds(dateToTransferTo, utils.getSeconds(dateToTransferFrom));
      }
    default:
      {
        return dateToTransferTo;
      }
  }
};
var reliableSectionModificationOrder = {
  year: 1,
  month: 2,
  day: 3,
  weekDay: 4,
  hours: 5,
  minutes: 6,
  seconds: 7,
  meridiem: 8
};
export var mergeDateIntoReferenceDate = function mergeDateIntoReferenceDate(utils, timezone, dateToTransferFrom, sections, referenceDate, shouldLimitToEditedSections) {
  return (
    // cloning sections before sort to avoid mutating it
    _toConsumableArray(sections).sort(function (a, b) {
      return reliableSectionModificationOrder[a.type] - reliableSectionModificationOrder[b.type];
    }).reduce(function (mergedDate, section) {
      if (!shouldLimitToEditedSections || section.modified) {
        return transferDateSectionValue(utils, timezone, section, dateToTransferFrom, mergedDate);
      }
      return mergedDate;
    }, referenceDate)
  );
};
export var isAndroid = function isAndroid() {
  return navigator.userAgent.toLowerCase().indexOf('android') > -1;
};
export var getSectionOrder = function getSectionOrder(sections, isRTL) {
  var neighbors = {};
  if (!isRTL) {
    sections.forEach(function (_, index) {
      var leftIndex = index === 0 ? null : index - 1;
      var rightIndex = index === sections.length - 1 ? null : index + 1;
      neighbors[index] = {
        leftIndex: leftIndex,
        rightIndex: rightIndex
      };
    });
    return {
      neighbors: neighbors,
      startIndex: 0,
      endIndex: sections.length - 1
    };
  }
  var rtl2ltr = {};
  var ltr2rtl = {};
  var groupedSectionsStart = 0;
  var groupedSectionsEnd = 0;
  var RTLIndex = sections.length - 1;
  while (RTLIndex >= 0) {
    groupedSectionsEnd = sections.findIndex(
    // eslint-disable-next-line @typescript-eslint/no-loop-func
    function (section, index) {
      var _section$endSeparator;
      return index >= groupedSectionsStart && ((_section$endSeparator = section.endSeparator) == null ? void 0 : _section$endSeparator.includes(' ')) &&
      // Special case where the spaces were not there in the initial input
      section.endSeparator !== ' / ';
    });
    if (groupedSectionsEnd === -1) {
      groupedSectionsEnd = sections.length - 1;
    }
    for (var i = groupedSectionsEnd; i >= groupedSectionsStart; i -= 1) {
      ltr2rtl[i] = RTLIndex;
      rtl2ltr[RTLIndex] = i;
      RTLIndex -= 1;
    }
    groupedSectionsStart = groupedSectionsEnd + 1;
  }
  sections.forEach(function (_, index) {
    var rtlIndex = ltr2rtl[index];
    var leftIndex = rtlIndex === 0 ? null : rtl2ltr[rtlIndex - 1];
    var rightIndex = rtlIndex === sections.length - 1 ? null : rtl2ltr[rtlIndex + 1];
    neighbors[index] = {
      leftIndex: leftIndex,
      rightIndex: rightIndex
    };
  });
  return {
    neighbors: neighbors,
    startIndex: rtl2ltr[0],
    endIndex: rtl2ltr[sections.length - 1]
  };
};