var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/utils/index.ts
var utils_exports = {};
__export(utils_exports, {
  ArrayUtil: () => ArrayUtil,
  BagFunctionUtil: () => BagFunctionUtil,
  EaseFunctions: () => EaseFunctions,
  LocalStorageService: () => LocalStorageService,
  LoopingArrayCalculator: () => LoopingArrayCalculator,
  MultiSearchWithMapping: () => MultiSearchWithMapping,
  MultiSubjectSearchWithMapping: () => MultiSubjectSearchWithMapping,
  SessionStorageService: () => SessionStorageService,
  SimpleSearch: () => SimpleSearch,
  SimpleSearchWithMapping: () => SimpleSearchWithMapping,
  addDuration: () => addDuration,
  builder: () => builder,
  changeDuration: () => changeDuration,
  clamp: () => clamp,
  closestMatch: () => closestMatch,
  createLoopingList: () => createLoopingList,
  createLoopingListWithIndex: () => createLoopingListWithIndex,
  equalDate: () => equalDate,
  equalSizeGroups: () => equalSizeGroups,
  formatDate: () => formatDate,
  formatDateTime: () => formatDateTime,
  getBetweenDuration: () => getBetweenDuration,
  getDaysInMonth: () => getDaysInMonth,
  getNeighbours: () => getNeighbours,
  getWeeksForCalenderMonth: () => getWeeksForCalenderMonth,
  isInTimeSpan: () => isInTimeSpan,
  match: () => match,
  monthsList: () => monthsList,
  noop: () => noop,
  range: () => range,
  resolveSetState: () => resolveSetState,
  subtractDuration: () => subtractDuration,
  validateEmail: () => validateEmail,
  weekDayList: () => weekDayList,
  writeToClipboard: () => writeToClipboard
});
module.exports = __toCommonJS(utils_exports);

// src/utils/array.ts
var equalSizeGroups = (array, groupSize) => {
  if (groupSize <= 0) {
    console.warn(`group size should be greater than 0: groupSize = ${groupSize}`);
    return [[...array]];
  }
  const groups = [];
  for (let i = 0; i < array.length; i += groupSize) {
    groups.push(array.slice(i, Math.min(i + groupSize, array.length)));
  }
  return groups;
};
var defaultRangeOptions = {
  allowEmptyRange: false,
  stepSize: 1,
  exclusiveStart: false,
  exclusiveEnd: true
};
var range = (endOrRange, options) => {
  const { allowEmptyRange, stepSize, exclusiveStart, exclusiveEnd } = { ...defaultRangeOptions, ...options };
  let start = 0;
  let end;
  if (typeof endOrRange === "number") {
    end = endOrRange;
  } else {
    start = endOrRange[0];
    end = endOrRange[1];
  }
  if (!exclusiveEnd) {
    end -= 1;
  }
  if (exclusiveStart) {
    start += 1;
  }
  if (end - 1 < start) {
    if (!allowEmptyRange) {
      console.warn(`range: end (${end}) < start (${start}) should be allowed explicitly, set options.allowEmptyRange to true`);
    }
    return [];
  }
  return Array.from({ length: end - start }, (_, index) => index * stepSize + start);
};
var closestMatch = (list, firstCloser) => {
  return list.reduce((item1, item2) => {
    return firstCloser(item1, item2) ? item1 : item2;
  });
};
var getNeighbours = (list, item, neighbourDistance = 2) => {
  const index = list.indexOf(item);
  const totalItems = neighbourDistance * 2 + 1;
  if (list.length < totalItems) {
    console.warn("List is to short");
    return list;
  }
  if (index === -1) {
    console.error("item not found in list");
    return list.splice(0, totalItems);
  }
  let start = index - neighbourDistance;
  if (start < 0) {
    start += list.length;
  }
  const end = (index + neighbourDistance + 1) % list.length;
  const result = [];
  let ignoreOnce = list.length === totalItems;
  for (let i = start; i !== end || ignoreOnce; i = (i + 1) % list.length) {
    result.push(list[i]);
    if (end === i && ignoreOnce) {
      ignoreOnce = false;
    }
  }
  return result;
};
var createLoopingListWithIndex = (list, startIndex = 0, length = 0, forwards = true) => {
  if (length < 0) {
    console.warn(`createLoopingList: length must be >= 0, given ${length}`);
  } else if (length === 0) {
    length = list.length;
  }
  const returnList = [];
  if (forwards) {
    for (let i = startIndex; returnList.length < length; i = (i + 1) % list.length) {
      returnList.push([i, list[i]]);
    }
  } else {
    for (let i = startIndex; returnList.length < length; i = i === 0 ? i = list.length - 1 : i - 1) {
      returnList.push([i, list[i]]);
    }
  }
  return returnList;
};
var createLoopingList = (list, startIndex = 0, length = 0, forwards = true) => {
  return createLoopingListWithIndex(list, startIndex, length, forwards).map(([_, item]) => item);
};
var moveItems = (list, move = 0) => {
  const result = [];
  let start = move;
  if (start < 0) {
    start = list.length - move;
  }
  start = start % list.length;
  for (let i = 0; i < list.length; i++) {
    result[i] = list[(i + start) % list.length];
  }
  return result;
};
function resolveSingleOrArray(value) {
  if (Array.isArray(value)) {
    return value;
  } else if (value) {
    return [value];
  }
  return [];
}
var ArrayUtil = {
  unique: (list) => {
    const seen = /* @__PURE__ */ new Set();
    return list.filter((item) => {
      if (seen.has(item)) {
        return false;
      }
      seen.add(item);
      return true;
    });
  },
  difference: (list, removeList) => {
    const remove = new Set(removeList);
    return list.filter((item) => !remove.has(item));
  },
  moveItems,
  resolveSingleOrArray
};

// src/utils/bagFunctions.ts
var resolve = (children, bag) => {
  if (typeof children === "function") {
    return children(bag);
  }
  return children ?? void 0;
};
var BagFunctionUtil = {
  resolve
};

// src/utils/builder.ts
var builder = (value, update) => {
  update(value);
  return value;
};

// src/utils/date.ts
var monthsList = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"];
var weekDayList = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
var formatDate = (date) => {
  const year = date.getFullYear().toString().padStart(4, "0");
  const month = (date.getMonth() + 1).toString().padStart(2, "0");
  const day = date.getDate().toString().padStart(2, "0");
  return `${year}-${month}-${day}`;
};
var formatDateTime = (date) => {
  const dateString = formatDate(date);
  const hours = date.getHours().toString().padStart(2, "0");
  const minutes = date.getMinutes().toString().padStart(2, "0");
  return `${dateString}T${hours}:${minutes}`;
};
var getDaysInMonth = (year, month) => {
  const lastDayOfMonth = new Date(year, month + 1, 0);
  return lastDayOfMonth.getDate();
};
var changeDuration = (date, duration, isAdding) => {
  const {
    years = 0,
    months = 0,
    days = 0,
    hours = 0,
    minutes = 0,
    seconds = 0,
    milliseconds = 0
  } = duration;
  if (years < 0) {
    console.error(`Range error years must be greater than 0: received ${years}`);
    return new Date(date);
  }
  if (months < 0 || months > 11) {
    console.error(`Range error month must be 0 <= month <= 11: received ${months}`);
    return new Date(date);
  }
  if (days < 0) {
    console.error(`Range error days must be greater than 0: received ${days}`);
    return new Date(date);
  }
  if (hours < 0 || hours > 23) {
    console.error(`Range error hours must be 0 <= hours <= 23: received ${hours}`);
    return new Date(date);
  }
  if (minutes < 0 || minutes > 59) {
    console.error(`Range error minutes must be 0 <= minutes <= 59: received ${minutes}`);
    return new Date(date);
  }
  if (seconds < 0 || seconds > 59) {
    console.error(`Range error seconds must be 0 <= seconds <= 59: received ${seconds}`);
    return new Date(date);
  }
  if (milliseconds < 0) {
    console.error(`Range error seconds must be greater than 0: received ${milliseconds}`);
    return new Date(date);
  }
  const multiplier = isAdding ? 1 : -1;
  const newDate = new Date(date);
  newDate.setFullYear(newDate.getFullYear() + multiplier * years);
  newDate.setMonth(newDate.getMonth() + multiplier * months);
  newDate.setDate(newDate.getDate() + multiplier * days);
  newDate.setHours(newDate.getHours() + multiplier * hours);
  newDate.setMinutes(newDate.getMinutes() + multiplier * minutes);
  newDate.setSeconds(newDate.getSeconds() + multiplier * seconds);
  newDate.setMilliseconds(newDate.getMilliseconds() + multiplier * milliseconds);
  return newDate;
};
var addDuration = (date, duration) => {
  return changeDuration(date, duration, true);
};
var subtractDuration = (date, duration) => {
  return changeDuration(date, duration, false);
};
var getBetweenDuration = (startDate, endDate) => {
  const durationInMilliseconds = endDate.getTime() - startDate.getTime();
  const millisecondsInSecond = 1e3;
  const millisecondsInMinute = 60 * millisecondsInSecond;
  const millisecondsInHour = 60 * millisecondsInMinute;
  const millisecondsInDay = 24 * millisecondsInHour;
  const millisecondsInMonth = 30 * millisecondsInDay;
  const years = Math.floor(durationInMilliseconds / (365.25 * millisecondsInDay));
  const months = Math.floor(durationInMilliseconds / millisecondsInMonth);
  const days = Math.floor(durationInMilliseconds / millisecondsInDay);
  const hours = Math.floor(durationInMilliseconds % millisecondsInDay / millisecondsInHour);
  const seconds = Math.floor(durationInMilliseconds % millisecondsInHour / millisecondsInSecond);
  const milliseconds = durationInMilliseconds % millisecondsInSecond;
  return {
    years,
    months,
    days,
    hours,
    seconds,
    milliseconds
  };
};
var isInTimeSpan = (value, startDate, endDate) => {
  if (startDate && endDate) {
    console.assert(startDate <= endDate);
    return startDate <= value && value <= endDate;
  } else if (startDate) {
    return startDate <= value;
  } else if (endDate) {
    return endDate >= value;
  } else {
    return true;
  }
};
var equalDate = (date1, date2) => {
  return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate();
};
var getWeeksForCalenderMonth = (date, weekStart, weeks = 6) => {
  const month = date.getMonth();
  const year = date.getFullYear();
  const dayList = [];
  let currentDate = new Date(year, month, 1);
  const weekStartIndex = weekDayList.indexOf(weekStart);
  while (currentDate.getDay() !== weekStartIndex) {
    currentDate = subtractDuration(currentDate, { days: 1 });
  }
  while (dayList.length < 7 * weeks) {
    const date2 = new Date(currentDate);
    date2.setHours(date2.getHours(), date2.getMinutes());
    dayList.push(date2);
    currentDate = addDuration(currentDate, { days: 1 });
  }
  return equalSizeGroups(dayList, 7);
};

// src/utils/math.ts
var clamp = (value, range2 = [0, 1]) => {
  const [min, max] = range2;
  return Math.min(Math.max(value, min), max);
};

// src/utils/easeFunctions.ts
var EaseFunctions = class _EaseFunctions {
  static cubicBezierGeneric(x1, y1, x2, y2) {
    const cx = 3 * x1;
    const bx = 3 * (x2 - x1) - cx;
    const ax = 1 - cx - bx;
    const cy = 3 * y1;
    const by = 3 * (y2 - y1) - cy;
    const ay = 1 - cy - by;
    const x = (t) => ((ax * t + bx) * t + cx) * t;
    const y = (t) => ((ay * t + by) * t + cy) * t;
    return {
      x,
      y
    };
  }
  static cubicBezier(x1, y1, x2, y2) {
    const { y } = _EaseFunctions.cubicBezierGeneric(x1, y1, x2, y2);
    return (t) => {
      t = clamp(t);
      return y(t);
    };
  }
  static easeInEaseOut(t) {
    return _EaseFunctions.cubicBezier(0.65, 0, 0.35, 1)(t);
  }
};

// src/utils/emailValidation.ts
var validateEmail = (email) => {
  return /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(email);
};

// src/utils/loopingArray.ts
var LoopingArrayCalculator = class _LoopingArrayCalculator {
  constructor(length, isLooping = true, allowedOverScroll = 0.1) {
    if (allowedOverScroll < 0 || length < 1) {
      throw new Error("Invalid parameters: allowedOverScroll >= 0 and length >= 1 must be true");
    }
    this.length = length;
    this.isLooping = isLooping;
    this.allowedOverScroll = allowedOverScroll;
  }
  getCorrectedPosition(position) {
    if (!this.isLooping) {
      return Math.max(-this.allowedOverScroll, Math.min(this.allowedOverScroll + this.length - 1, position));
    }
    if (position >= this.length) {
      return position % this.length;
    }
    if (position < 0) {
      return this.length - Math.abs(position) % this.length;
    }
    return position;
  }
  static withoutOffset(position) {
    return position + _LoopingArrayCalculator.getOffset(position);
  }
  static getOffset(position) {
    return Math.round(position) - position;
  }
  /**
   * @return absolute distance forwards or Infinity when the target cannot be reached (only possible when not isLooping)
   */
  getDistanceDirectional(position, target, direction) {
    if (!this.isLooping && (position < -this.allowedOverScroll || position > this.allowedOverScroll + this.length - 1)) {
      throw new Error("Invalid parameters: position is out of bounds.");
    }
    const isForwardInvalid = direction === 1 && position > target;
    const isBackwardInvalid = direction === -1 && target < position;
    if (!this.isLooping && (isForwardInvalid || isBackwardInvalid)) {
      return Infinity;
    }
    if (direction === -1) {
      return this.getDistanceDirectional(target, position, 1);
    }
    position = this.getCorrectedPosition(position);
    target = this.getCorrectedPosition(target);
    let distance = (target - position) * direction;
    if (distance < 0) {
      distance = this.length - Math.abs(position) % this.length + target;
    }
    return distance;
  }
  getDistanceForward(position, target) {
    return this.getDistanceDirectional(position, target, 1);
  }
  getDistanceBackward(position, target) {
    return this.getDistanceDirectional(position, target, -1);
  }
  getDistance(position, target) {
    const forwardDistance = this.getDistanceForward(position, target);
    const backwardDistance = this.getDistanceBackward(position, target);
    return Math.min(forwardDistance, backwardDistance);
  }
  getBestDirection(position, target) {
    const forwardDistance = this.getDistanceForward(position, target);
    const backwardDistance = this.getDistanceBackward(position, target);
    return forwardDistance < backwardDistance ? 1 : -1;
  }
};

// src/utils/match.ts
var match = (key, values) => {
  return values[key];
};

// src/utils/noop.ts
var noop = () => void 0;

// src/utils/resolveSetState.ts
function resolveSetState(action, prev) {
  return typeof action === "function" ? action(prev) : action;
}

// src/utils/simpleSearch.ts
var MultiSubjectSearchWithMapping = (search, objects, mapping) => {
  return objects.filter((object) => {
    const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
    if (!mappedSearchKeywords) {
      return true;
    }
    return search.every((searchValue) => !!mappedSearchKeywords.find((value) => !!value && value.includes(searchValue.toLowerCase().trim())));
  });
};
var MultiSearchWithMapping = (search, objects, mapping) => {
  return objects.filter((object) => {
    const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
    if (!mappedSearchKeywords) {
      return true;
    }
    return !!mappedSearchKeywords.find((value) => value.includes(search.toLowerCase().trim()));
  });
};
var SimpleSearchWithMapping = (search, objects, mapping) => {
  return MultiSearchWithMapping(search, objects, (value) => [mapping(value)]);
};
var SimpleSearch = (search, objects) => {
  return SimpleSearchWithMapping(search, objects, (value) => value);
};

// src/utils/storage.ts
var StorageService = class {
  // this seems to be a bug in eslint as 'paramter-properties' is a special syntax of typescript
  constructor(storage) {
    this.storage = storage;
  }
  get(key) {
    const value = this.storage.getItem(key);
    if (value === null) {
      return null;
    }
    return JSON.parse(value);
  }
  set(key, value) {
    this.storage.setItem(key, JSON.stringify(value));
  }
  delete(key) {
    this.storage.removeItem(key);
  }
  deleteAll() {
    this.storage.clear();
  }
};
var LocalStorageService = class extends StorageService {
  constructor() {
    super(window.localStorage);
  }
};
var SessionStorageService = class extends StorageService {
  constructor() {
    super(window.sessionStorage);
  }
};

// src/utils/writeToClipboard.ts
var writeToClipboard = (text) => {
  return navigator.clipboard.writeText(text);
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ArrayUtil,
  BagFunctionUtil,
  EaseFunctions,
  LocalStorageService,
  LoopingArrayCalculator,
  MultiSearchWithMapping,
  MultiSubjectSearchWithMapping,
  SessionStorageService,
  SimpleSearch,
  SimpleSearchWithMapping,
  addDuration,
  builder,
  changeDuration,
  clamp,
  closestMatch,
  createLoopingList,
  createLoopingListWithIndex,
  equalDate,
  equalSizeGroups,
  formatDate,
  formatDateTime,
  getBetweenDuration,
  getDaysInMonth,
  getNeighbours,
  getWeeksForCalenderMonth,
  isInTimeSpan,
  match,
  monthsList,
  noop,
  range,
  resolveSetState,
  subtractDuration,
  validateEmail,
  weekDayList,
  writeToClipboard
});
//# sourceMappingURL=index.cjs.map