{"version":3,"file":"index.cjs","sources":["../src/types/index.ts","../node_modules/react-usestateref/dist/index.js","../node_modules/date-fns/constants.js","../node_modules/date-fns/constructFrom.js","../node_modules/date-fns/toDate.js","../node_modules/date-fns/_lib/defaultOptions.js","../node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js","../node_modules/date-fns/_lib/normalizeDates.js","../node_modules/date-fns/compareAsc.js","../node_modules/date-fns/isLastDayOfMonth.js","../node_modules/date-fns/endOfDay.js","../node_modules/date-fns/endOfMonth.js","../node_modules/date-fns/differenceInMonths.js","../node_modules/date-fns/differenceInCalendarMonths.js","../node_modules/date-fns/differenceInSeconds.js","../node_modules/date-fns/differenceInMilliseconds.js","../node_modules/date-fns/_lib/getRoundingMethod.js","../node_modules/date-fns/locale/en-US/_lib/formatDistance.js","../node_modules/date-fns/locale/_lib/buildFormatLongFn.js","../node_modules/date-fns/locale/en-US/_lib/formatLong.js","../node_modules/date-fns/locale/en-US/_lib/formatRelative.js","../node_modules/date-fns/locale/_lib/buildLocalizeFn.js","../node_modules/date-fns/locale/_lib/buildMatchFn.js","../node_modules/date-fns/locale/_lib/buildMatchPatternFn.js","../node_modules/date-fns/locale/en-US.js","../node_modules/date-fns/locale/en-US/_lib/localize.js","../node_modules/date-fns/locale/en-US/_lib/match.js","../node_modules/date-fns/formatDistanceToNow.js","../node_modules/date-fns/formatDistance.js","../node_modules/date-fns/constructNow.js","../src/hooks/useBlockList.ts","../src/helpers.ts","../src/hooks/useUsers.ts","../src/ChatContext.tsx"],"sourcesContent":["import { Chat, Dialogs, Messages } from \"connectycube/types\";\nimport { ReactNode } from \"react\";\nimport { BlockListHook } from \"../hooks/useBlockList\";\nimport { UsersHookExports } from \"../hooks/useUsers\";\n\nexport interface ChatProviderType {\n  children?: ReactNode;\n}\n\nexport interface ChatContextType extends BlockListHook, UsersHookExports {\n  isOnline: boolean;\n  connect: (credentials: Chat.ConnectionParams) => Promise<void>;\n  isConnected: boolean;\n  disconnect: () => void;\n  currentUserId?: number;\n  createChat: (userId: number, extensions?: { [key: string]: any }) => Promise<Dialogs.Dialog>;\n  createGroupChat: (\n    usersIds: number[],\n    name: string,\n    photo?: string,\n    extensions?: { [key: string]: any },\n  ) => Promise<Dialogs.Dialog>;\n  getDialogs: (filters?: Dialogs.ListParams) => Promise<Dialogs.Dialog[]>;\n  dialogs: Dialogs.Dialog[];\n  selectedDialog?: Dialogs.Dialog;\n  selectDialog: (dialog?: Dialogs.Dialog) => Promise<void>;\n  getDialogOpponentId: (dialog?: Dialogs.Dialog) => number | undefined;\n  unreadMessagesCount: { total: number; [dialogId: string]: number };\n  getMessages: (dialogId: string) => Promise<Messages.Message[]>;\n  messages: { [key: string]: Messages.Message[] };\n  markDialogAsRead: (dialog: Dialogs.Dialog) => Promise<void>;\n  addUsersToGroupChat: (usersIds: number[]) => Promise<void>;\n  removeUsersFromGroupChat: (usersIds: number[]) => Promise<void>;\n  leaveGroupChat: () => Promise<void>;\n  sendMessage: (body: string, dialog?: Dialogs.Dialog) => void;\n  sendMessageWithAttachment: (files: File[], dialog?: Dialogs.Dialog) => Promise<void>;\n  readMessage: (messageId: string, userId: number, dialogId: string) => void;\n  sendTypingStatus: (dialog?: Dialogs.Dialog, isTyping?: boolean) => void;\n  typingStatus: { [dialogId: string]: number[] };\n  lastMessageSentTimeString: (dialog: Dialogs.Dialog) => string;\n  messageSentTimeString: (message: Messages.Message) => string;\n  processOnMessage: (fn: Chat.OnMessageListener | null) => void;\n  processOnMessageError: (fn: Chat.OnMessageErrorListener | null) => void;\n}\n\nexport enum GroupChatEventType {\n  ADDED_TO_DIALOG = \"dialog/ADDED_TO_DIALOG\",\n  REMOVED_FROM_DIALOG = \"dialog/REMOVED_FROM_DIALOG\",\n  ADD_PARTICIPANTS = \"dialog/ADD_PARTICIPANTS\",\n  REMOVE_PARTICIPANTS = \"dialog/REMOVE_PARTICIPANTS\",\n  NEW_DIALOG = \"dialog/NEW_DIALOG\",\n}\n","\"use strict\";\nvar react_1 = require(\"react\");\nvar isFunction = function (setStateAction) {\n    return typeof setStateAction === \"function\";\n};\nvar useStateRef = function (initialState) {\n    var _a = react_1.useState(initialState), state = _a[0], setState = _a[1];\n    var ref = react_1.useRef(state);\n    var dispatch = react_1.useCallback(function (setStateAction) {\n        ref.current = isFunction(setStateAction) ? setStateAction(ref.current) : setStateAction;\n        setState(ref.current);\n    }, []);\n    return [state, dispatch, ref];\n};\nmodule.exports = useStateRef;\n","/**\n * @module constants\n * @summary Useful constants\n * @description\n * Collection of useful date constants.\n *\n * The constants could be imported from `date-fns/constants`:\n *\n * ```ts\n * import { maxTime, minTime } from \"./constants/date-fns/constants\";\n *\n * function isAllowedTime(time) {\n *   return time <= maxTime && time >= minTime;\n * }\n * ```\n */\n\n/**\n * @constant\n * @name daysInWeek\n * @summary Days in 1 week.\n */\nexport const daysInWeek = 7;\n\n/**\n * @constant\n * @name daysInYear\n * @summary Days in 1 year.\n *\n * @description\n * How many days in a year.\n *\n * One years equals 365.2425 days according to the formula:\n *\n * > Leap year occurs every 4 years, except for years that are divisible by 100 and not divisible by 400.\n * > 1 mean year = (365+1/4-1/100+1/400) days = 365.2425 days\n */\nexport const daysInYear = 365.2425;\n\n/**\n * @constant\n * @name maxTime\n * @summary Maximum allowed time.\n *\n * @example\n * import { maxTime } from \"./constants/date-fns/constants\";\n *\n * const isValid = 8640000000000001 <= maxTime;\n * //=> false\n *\n * new Date(8640000000000001);\n * //=> Invalid Date\n */\nexport const maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;\n\n/**\n * @constant\n * @name minTime\n * @summary Minimum allowed time.\n *\n * @example\n * import { minTime } from \"./constants/date-fns/constants\";\n *\n * const isValid = -8640000000000001 >= minTime;\n * //=> false\n *\n * new Date(-8640000000000001)\n * //=> Invalid Date\n */\nexport const minTime = -maxTime;\n\n/**\n * @constant\n * @name millisecondsInWeek\n * @summary Milliseconds in 1 week.\n */\nexport const millisecondsInWeek = 604800000;\n\n/**\n * @constant\n * @name millisecondsInDay\n * @summary Milliseconds in 1 day.\n */\nexport const millisecondsInDay = 86400000;\n\n/**\n * @constant\n * @name millisecondsInMinute\n * @summary Milliseconds in 1 minute\n */\nexport const millisecondsInMinute = 60000;\n\n/**\n * @constant\n * @name millisecondsInHour\n * @summary Milliseconds in 1 hour\n */\nexport const millisecondsInHour = 3600000;\n\n/**\n * @constant\n * @name millisecondsInSecond\n * @summary Milliseconds in 1 second\n */\nexport const millisecondsInSecond = 1000;\n\n/**\n * @constant\n * @name minutesInYear\n * @summary Minutes in 1 year.\n */\nexport const minutesInYear = 525600;\n\n/**\n * @constant\n * @name minutesInMonth\n * @summary Minutes in 1 month.\n */\nexport const minutesInMonth = 43200;\n\n/**\n * @constant\n * @name minutesInDay\n * @summary Minutes in 1 day.\n */\nexport const minutesInDay = 1440;\n\n/**\n * @constant\n * @name minutesInHour\n * @summary Minutes in 1 hour.\n */\nexport const minutesInHour = 60;\n\n/**\n * @constant\n * @name monthsInQuarter\n * @summary Months in 1 quarter.\n */\nexport const monthsInQuarter = 3;\n\n/**\n * @constant\n * @name monthsInYear\n * @summary Months in 1 year.\n */\nexport const monthsInYear = 12;\n\n/**\n * @constant\n * @name quartersInYear\n * @summary Quarters in 1 year\n */\nexport const quartersInYear = 4;\n\n/**\n * @constant\n * @name secondsInHour\n * @summary Seconds in 1 hour.\n */\nexport const secondsInHour = 3600;\n\n/**\n * @constant\n * @name secondsInMinute\n * @summary Seconds in 1 minute.\n */\nexport const secondsInMinute = 60;\n\n/**\n * @constant\n * @name secondsInDay\n * @summary Seconds in 1 day.\n */\nexport const secondsInDay = secondsInHour * 24;\n\n/**\n * @constant\n * @name secondsInWeek\n * @summary Seconds in 1 week.\n */\nexport const secondsInWeek = secondsInDay * 7;\n\n/**\n * @constant\n * @name secondsInYear\n * @summary Seconds in 1 year.\n */\nexport const secondsInYear = secondsInDay * daysInYear;\n\n/**\n * @constant\n * @name secondsInMonth\n * @summary Seconds in 1 month\n */\nexport const secondsInMonth = secondsInYear / 12;\n\n/**\n * @constant\n * @name secondsInQuarter\n * @summary Seconds in 1 quarter.\n */\nexport const secondsInQuarter = secondsInMonth * 3;\n\n/**\n * @constant\n * @name constructFromSymbol\n * @summary Symbol enabling Date extensions to inherit properties from the reference date.\n *\n * The symbol is used to enable the `constructFrom` function to construct a date\n * using a reference date and a value. It allows to transfer extra properties\n * from the reference date to the new date. It's useful for extensions like\n * [`TZDate`](https://github.com/date-fns/tz) that accept a time zone as\n * a constructor argument.\n */\nexport const constructFromSymbol = Symbol.for(\"constructDateFrom\");\n","import { constructFromSymbol } from \"./constants.js\";\n\n/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * Starting from v3.7.0, it allows to construct a date using `[Symbol.for(\"constructDateFrom\")]`\n * enabling to transfer extra properties from the reference date to the new date.\n * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)\n * that accept a time zone as a constructor argument.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from \"./constructFrom/date-fns\";\n *\n * // A function that clones a date preserving the original type\n * function cloneDate<DateType extends Date>(date: DateType): DateType {\n *   return constructFrom(\n *     date, // Use constructor from the given date\n *     date.getTime() // Use the date value to create a new date\n *   );\n * }\n */\nexport function constructFrom(date, value) {\n  if (typeof date === \"function\") return date(value);\n\n  if (date && typeof date === \"object\" && constructFromSymbol in date)\n    return date[constructFromSymbol](value);\n\n  if (date instanceof Date) return new date.constructor(value);\n\n  return new Date(value);\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","import { constructFrom } from \"./constructFrom.js\";\n\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * Starting from v3.7.0, it clones a date using `[Symbol.for(\"constructDateFrom\")]`\n * enabling to transfer extra properties from the reference date to the new date.\n * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)\n * that accept a time zone as a constructor argument.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument, context) {\n  // [TODO] Get rid of `toDate` or `constructFrom`?\n  return constructFrom(context || argument, argument);\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","let defaultOptions = {};\n\nexport function getDefaultOptions() {\n  return defaultOptions;\n}\n\nexport function setDefaultOptions(newOptions) {\n  defaultOptions = newOptions;\n}\n","import { toDate } from \"../toDate.js\";\n\n/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\nexport function getTimezoneOffsetInMilliseconds(date) {\n  const _date = toDate(date);\n  const utcDate = new Date(\n    Date.UTC(\n      _date.getFullYear(),\n      _date.getMonth(),\n      _date.getDate(),\n      _date.getHours(),\n      _date.getMinutes(),\n      _date.getSeconds(),\n      _date.getMilliseconds(),\n    ),\n  );\n  utcDate.setUTCFullYear(_date.getFullYear());\n  return +date - +utcDate;\n}\n","import { constructFrom } from \"../constructFrom.js\";\n\nexport function normalizeDates(context, ...dates) {\n  const normalize = constructFrom.bind(\n    null,\n    context || dates.find((date) => typeof date === \"object\"),\n  );\n  return dates.map(normalize);\n}\n","import { toDate } from \"./toDate.js\";\n\n/**\n * @name compareAsc\n * @category Common Helpers\n * @summary Compare the two dates and return -1, 0 or 1.\n *\n * @description\n * Compare the two dates and return 1 if the first date is after the second,\n * -1 if the first date is before the second or 0 if dates are equal.\n *\n * @param dateLeft - The first date to compare\n * @param dateRight - The second date to compare\n *\n * @returns The result of the comparison\n *\n * @example\n * // Compare 11 February 1987 and 10 July 1989:\n * const result = compareAsc(new Date(1987, 1, 11), new Date(1989, 6, 10))\n * //=> -1\n *\n * @example\n * // Sort the array of dates:\n * const result = [\n *   new Date(1995, 6, 2),\n *   new Date(1987, 1, 11),\n *   new Date(1989, 6, 10)\n * ].sort(compareAsc)\n * //=> [\n * //   Wed Feb 11 1987 00:00:00,\n * //   Mon Jul 10 1989 00:00:00,\n * //   Sun Jul 02 1995 00:00:00\n * // ]\n */\nexport function compareAsc(dateLeft, dateRight) {\n  const diff = +toDate(dateLeft) - +toDate(dateRight);\n\n  if (diff < 0) return -1;\n  else if (diff > 0) return 1;\n\n  // Return 0 if diff is 0; return NaN if diff is NaN\n  return diff;\n}\n\n// Fallback for modularized imports:\nexport default compareAsc;\n","import { endOfDay } from \"./endOfDay.js\";\nimport { endOfMonth } from \"./endOfMonth.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * @name isLastDayOfMonth\n * @category Month Helpers\n * @summary Is the given date the last day of a month?\n *\n * @description\n * Is the given date the last day of a month?\n *\n * @param date - The date to check\n * @param options - An object with options\n *\n * @returns The date is the last day of a month\n *\n * @example\n * // Is 28 February 2014 the last day of a month?\n * const result = isLastDayOfMonth(new Date(2014, 1, 28))\n * //=> true\n */\nexport function isLastDayOfMonth(date, options) {\n  const _date = toDate(date, options?.in);\n  return +endOfDay(_date, options) === +endOfMonth(_date, options);\n}\n\n// Fallback for modularized imports:\nexport default isLastDayOfMonth;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * The {@link endOfDay} function options.\n */\n\n/**\n * @name endOfDay\n * @category Day Helpers\n * @summary Return the end of a day for the given date.\n *\n * @description\n * Return the end of a day for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The end of a day\n *\n * @example\n * // The end of a day for 2 September 2014 11:55:00:\n * const result = endOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 23:59:59.999\n */\nexport function endOfDay(date, options) {\n  const _date = toDate(date, options?.in);\n  _date.setHours(23, 59, 59, 999);\n  return _date;\n}\n\n// Fallback for modularized imports:\nexport default endOfDay;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * The {@link endOfMonth} function options.\n */\n\n/**\n * @name endOfMonth\n * @category Month Helpers\n * @summary Return the end of a month for the given date.\n *\n * @description\n * Return the end of a month for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The end of a month\n *\n * @example\n * // The end of a month for 2 September 2014 11:55:00:\n * const result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 30 2014 23:59:59.999\n */\nexport function endOfMonth(date, options) {\n  const _date = toDate(date, options?.in);\n  const month = _date.getMonth();\n  _date.setFullYear(_date.getFullYear(), month + 1, 0);\n  _date.setHours(23, 59, 59, 999);\n  return _date;\n}\n\n// Fallback for modularized imports:\nexport default endOfMonth;\n","import { normalizeDates } from \"./_lib/normalizeDates.js\";\nimport { compareAsc } from \"./compareAsc.js\";\nimport { differenceInCalendarMonths } from \"./differenceInCalendarMonths.js\";\nimport { isLastDayOfMonth } from \"./isLastDayOfMonth.js\";\n\n/**\n * The {@link differenceInMonths} function options.\n */\n\n/**\n * @name differenceInMonths\n * @category Month Helpers\n * @summary Get the number of full months between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - An object with options\n *\n * @returns The number of full months\n *\n * @example\n * // How many full months are between 31 January 2014 and 1 September 2014?\n * const result = differenceInMonths(new Date(2014, 8, 1), new Date(2014, 0, 31))\n * //=> 7\n */\nexport function differenceInMonths(laterDate, earlierDate, options) {\n  const [laterDate_, workingLaterDate, earlierDate_] = normalizeDates(\n    options?.in,\n    laterDate,\n    laterDate,\n    earlierDate,\n  );\n\n  const sign = compareAsc(workingLaterDate, earlierDate_);\n  const difference = Math.abs(\n    differenceInCalendarMonths(workingLaterDate, earlierDate_),\n  );\n\n  if (difference < 1) return 0;\n\n  if (workingLaterDate.getMonth() === 1 && workingLaterDate.getDate() > 27)\n    workingLaterDate.setDate(30);\n\n  workingLaterDate.setMonth(workingLaterDate.getMonth() - sign * difference);\n\n  let isLastMonthNotFull = compareAsc(workingLaterDate, earlierDate_) === -sign;\n\n  if (\n    isLastDayOfMonth(laterDate_) &&\n    difference === 1 &&\n    compareAsc(laterDate_, earlierDate_) === 1\n  ) {\n    isLastMonthNotFull = false;\n  }\n\n  const result = sign * (difference - +isLastMonthNotFull);\n  return result === 0 ? 0 : result;\n}\n\n// Fallback for modularized imports:\nexport default differenceInMonths;\n","import { normalizeDates } from \"./_lib/normalizeDates.js\";\n\n/**\n * The {@link differenceInCalendarMonths} function options.\n */\n\n/**\n * @name differenceInCalendarMonths\n * @category Month Helpers\n * @summary Get the number of calendar months between the given dates.\n *\n * @description\n * Get the number of calendar months between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - An object with options\n *\n * @returns The number of calendar months\n *\n * @example\n * // How many calendar months are between 31 January 2014 and 1 September 2014?\n * const result = differenceInCalendarMonths(\n *   new Date(2014, 8, 1),\n *   new Date(2014, 0, 31)\n * )\n * //=> 8\n */\nexport function differenceInCalendarMonths(laterDate, earlierDate, options) {\n  const [laterDate_, earlierDate_] = normalizeDates(\n    options?.in,\n    laterDate,\n    earlierDate,\n  );\n\n  const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();\n  const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();\n\n  return yearsDiff * 12 + monthsDiff;\n}\n\n// Fallback for modularized imports:\nexport default differenceInCalendarMonths;\n","import { getRoundingMethod } from \"./_lib/getRoundingMethod.js\";\nimport { differenceInMilliseconds } from \"./differenceInMilliseconds.js\";\n\n/**\n * The {@link differenceInSeconds} function options.\n */\n\n/**\n * @name differenceInSeconds\n * @category Second Helpers\n * @summary Get the number of seconds between the given dates.\n *\n * @description\n * Get the number of seconds between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - An object with options.\n *\n * @returns The number of seconds\n *\n * @example\n * // How many seconds are between\n * // 2 July 2014 12:30:07.999 and 2 July 2014 12:30:20.000?\n * const result = differenceInSeconds(\n *   new Date(2014, 6, 2, 12, 30, 20, 0),\n *   new Date(2014, 6, 2, 12, 30, 7, 999)\n * )\n * //=> 12\n */\nexport function differenceInSeconds(laterDate, earlierDate, options) {\n  const diff = differenceInMilliseconds(laterDate, earlierDate) / 1000;\n  return getRoundingMethod(options?.roundingMethod)(diff);\n}\n\n// Fallback for modularized imports:\nexport default differenceInSeconds;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * @name differenceInMilliseconds\n * @category Millisecond Helpers\n * @summary Get the number of milliseconds between the given dates.\n *\n * @description\n * Get the number of milliseconds between the given dates.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n *\n * @returns The number of milliseconds\n *\n * @example\n * // How many milliseconds are between\n * // 2 July 2014 12:30:20.600 and 2 July 2014 12:30:21.700?\n * const result = differenceInMilliseconds(\n *   new Date(2014, 6, 2, 12, 30, 21, 700),\n *   new Date(2014, 6, 2, 12, 30, 20, 600)\n * )\n * //=> 1100\n */\nexport function differenceInMilliseconds(laterDate, earlierDate) {\n  return +toDate(laterDate) - +toDate(earlierDate);\n}\n\n// Fallback for modularized imports:\nexport default differenceInMilliseconds;\n","export function getRoundingMethod(method) {\n  return (number) => {\n    const round = method ? Math[method] : Math.trunc;\n    const result = round(number);\n    // Prevent negative zero\n    return result === 0 ? 0 : result;\n  };\n}\n","const formatDistanceLocale = {\n  lessThanXSeconds: {\n    one: \"less than a second\",\n    other: \"less than {{count}} seconds\",\n  },\n\n  xSeconds: {\n    one: \"1 second\",\n    other: \"{{count}} seconds\",\n  },\n\n  halfAMinute: \"half a minute\",\n\n  lessThanXMinutes: {\n    one: \"less than a minute\",\n    other: \"less than {{count}} minutes\",\n  },\n\n  xMinutes: {\n    one: \"1 minute\",\n    other: \"{{count}} minutes\",\n  },\n\n  aboutXHours: {\n    one: \"about 1 hour\",\n    other: \"about {{count}} hours\",\n  },\n\n  xHours: {\n    one: \"1 hour\",\n    other: \"{{count}} hours\",\n  },\n\n  xDays: {\n    one: \"1 day\",\n    other: \"{{count}} days\",\n  },\n\n  aboutXWeeks: {\n    one: \"about 1 week\",\n    other: \"about {{count}} weeks\",\n  },\n\n  xWeeks: {\n    one: \"1 week\",\n    other: \"{{count}} weeks\",\n  },\n\n  aboutXMonths: {\n    one: \"about 1 month\",\n    other: \"about {{count}} months\",\n  },\n\n  xMonths: {\n    one: \"1 month\",\n    other: \"{{count}} months\",\n  },\n\n  aboutXYears: {\n    one: \"about 1 year\",\n    other: \"about {{count}} years\",\n  },\n\n  xYears: {\n    one: \"1 year\",\n    other: \"{{count}} years\",\n  },\n\n  overXYears: {\n    one: \"over 1 year\",\n    other: \"over {{count}} years\",\n  },\n\n  almostXYears: {\n    one: \"almost 1 year\",\n    other: \"almost {{count}} years\",\n  },\n};\n\nexport const formatDistance = (token, count, options) => {\n  let result;\n\n  const tokenValue = formatDistanceLocale[token];\n  if (typeof tokenValue === \"string\") {\n    result = tokenValue;\n  } else if (count === 1) {\n    result = tokenValue.one;\n  } else {\n    result = tokenValue.other.replace(\"{{count}}\", count.toString());\n  }\n\n  if (options?.addSuffix) {\n    if (options.comparison && options.comparison > 0) {\n      return \"in \" + result;\n    } else {\n      return result + \" ago\";\n    }\n  }\n\n  return result;\n};\n","export function buildFormatLongFn(args) {\n  return (options = {}) => {\n    // TODO: Remove String()\n    const width = options.width ? String(options.width) : args.defaultWidth;\n    const format = args.formats[width] || args.formats[args.defaultWidth];\n    return format;\n  };\n}\n","import { buildFormatLongFn } from \"../../_lib/buildFormatLongFn.js\";\n\nconst dateFormats = {\n  full: \"EEEE, MMMM do, y\",\n  long: \"MMMM do, y\",\n  medium: \"MMM d, y\",\n  short: \"MM/dd/yyyy\",\n};\n\nconst timeFormats = {\n  full: \"h:mm:ss a zzzz\",\n  long: \"h:mm:ss a z\",\n  medium: \"h:mm:ss a\",\n  short: \"h:mm a\",\n};\n\nconst dateTimeFormats = {\n  full: \"{{date}} 'at' {{time}}\",\n  long: \"{{date}} 'at' {{time}}\",\n  medium: \"{{date}}, {{time}}\",\n  short: \"{{date}}, {{time}}\",\n};\n\nexport const formatLong = {\n  date: buildFormatLongFn({\n    formats: dateFormats,\n    defaultWidth: \"full\",\n  }),\n\n  time: buildFormatLongFn({\n    formats: timeFormats,\n    defaultWidth: \"full\",\n  }),\n\n  dateTime: buildFormatLongFn({\n    formats: dateTimeFormats,\n    defaultWidth: \"full\",\n  }),\n};\n","const formatRelativeLocale = {\n  lastWeek: \"'last' eeee 'at' p\",\n  yesterday: \"'yesterday at' p\",\n  today: \"'today at' p\",\n  tomorrow: \"'tomorrow at' p\",\n  nextWeek: \"eeee 'at' p\",\n  other: \"P\",\n};\n\nexport const formatRelative = (token, _date, _baseDate, _options) =>\n  formatRelativeLocale[token];\n","/**\n * The localize function argument callback which allows to convert raw value to\n * the actual type.\n *\n * @param value - The value to convert\n *\n * @returns The converted value\n */\n\n/**\n * The map of localized values for each width.\n */\n\n/**\n * The index type of the locale unit value. It types conversion of units of\n * values that don't start at 0 (i.e. quarters).\n */\n\n/**\n * Converts the unit value to the tuple of values.\n */\n\n/**\n * The tuple of localized era values. The first element represents BC,\n * the second element represents AD.\n */\n\n/**\n * The tuple of localized quarter values. The first element represents Q1.\n */\n\n/**\n * The tuple of localized day values. The first element represents Sunday.\n */\n\n/**\n * The tuple of localized month values. The first element represents January.\n */\n\nexport function buildLocalizeFn(args) {\n  return (value, options) => {\n    const context = options?.context ? String(options.context) : \"standalone\";\n\n    let valuesArray;\n    if (context === \"formatting\" && args.formattingValues) {\n      const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;\n      const width = options?.width ? String(options.width) : defaultWidth;\n\n      valuesArray =\n        args.formattingValues[width] || args.formattingValues[defaultWidth];\n    } else {\n      const defaultWidth = args.defaultWidth;\n      const width = options?.width ? String(options.width) : args.defaultWidth;\n\n      valuesArray = args.values[width] || args.values[defaultWidth];\n    }\n    const index = args.argumentCallback ? args.argumentCallback(value) : value;\n\n    // @ts-expect-error - For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it!\n    return valuesArray[index];\n  };\n}\n","export function buildMatchFn(args) {\n  return (string, options = {}) => {\n    const width = options.width;\n\n    const matchPattern =\n      (width && args.matchPatterns[width]) ||\n      args.matchPatterns[args.defaultMatchWidth];\n    const matchResult = string.match(matchPattern);\n\n    if (!matchResult) {\n      return null;\n    }\n    const matchedString = matchResult[0];\n\n    const parsePatterns =\n      (width && args.parsePatterns[width]) ||\n      args.parsePatterns[args.defaultParseWidth];\n\n    const key = Array.isArray(parsePatterns)\n      ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString))\n      : // [TODO] -- I challenge you to fix the type\n        findKey(parsePatterns, (pattern) => pattern.test(matchedString));\n\n    let value;\n\n    value = args.valueCallback ? args.valueCallback(key) : key;\n    value = options.valueCallback\n      ? // [TODO] -- I challenge you to fix the type\n        options.valueCallback(value)\n      : value;\n\n    const rest = string.slice(matchedString.length);\n\n    return { value, rest };\n  };\n}\n\nfunction findKey(object, predicate) {\n  for (const key in object) {\n    if (\n      Object.prototype.hasOwnProperty.call(object, key) &&\n      predicate(object[key])\n    ) {\n      return key;\n    }\n  }\n  return undefined;\n}\n\nfunction findIndex(array, predicate) {\n  for (let key = 0; key < array.length; key++) {\n    if (predicate(array[key])) {\n      return key;\n    }\n  }\n  return undefined;\n}\n","export function buildMatchPatternFn(args) {\n  return (string, options = {}) => {\n    const matchResult = string.match(args.matchPattern);\n    if (!matchResult) return null;\n    const matchedString = matchResult[0];\n\n    const parseResult = string.match(args.parsePattern);\n    if (!parseResult) return null;\n    let value = args.valueCallback\n      ? args.valueCallback(parseResult[0])\n      : parseResult[0];\n\n    // [TODO] I challenge you to fix the type\n    value = options.valueCallback ? options.valueCallback(value) : value;\n\n    const rest = string.slice(matchedString.length);\n\n    return { value, rest };\n  };\n}\n","import { formatDistance } from \"./en-US/_lib/formatDistance.js\";\nimport { formatLong } from \"./en-US/_lib/formatLong.js\";\nimport { formatRelative } from \"./en-US/_lib/formatRelative.js\";\nimport { localize } from \"./en-US/_lib/localize.js\";\nimport { match } from \"./en-US/_lib/match.js\";\n\n/**\n * @category Locales\n * @summary English locale (United States).\n * @language English\n * @iso-639-2 eng\n * @author Sasha Koss [@kossnocorp](https://github.com/kossnocorp)\n * @author Lesha Koss [@leshakoss](https://github.com/leshakoss)\n */\nexport const enUS = {\n  code: \"en-US\",\n  formatDistance: formatDistance,\n  formatLong: formatLong,\n  formatRelative: formatRelative,\n  localize: localize,\n  match: match,\n  options: {\n    weekStartsOn: 0 /* Sunday */,\n    firstWeekContainsDate: 1,\n  },\n};\n\n// Fallback for modularized imports:\nexport default enUS;\n","import { buildLocalizeFn } from \"../../_lib/buildLocalizeFn.js\";\n\nconst eraValues = {\n  narrow: [\"B\", \"A\"],\n  abbreviated: [\"BC\", \"AD\"],\n  wide: [\"Before Christ\", \"Anno Domini\"],\n};\n\nconst quarterValues = {\n  narrow: [\"1\", \"2\", \"3\", \"4\"],\n  abbreviated: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n  wide: [\"1st quarter\", \"2nd quarter\", \"3rd quarter\", \"4th quarter\"],\n};\n\n// Note: in English, the names of days of the week and months are capitalized.\n// If you are making a new locale based on this one, check if the same is true for the language you're working on.\n// Generally, formatted dates should look like they are in the middle of a sentence,\n// e.g. in Spanish language the weekdays and months should be in the lowercase.\nconst monthValues = {\n  narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n  abbreviated: [\n    \"Jan\",\n    \"Feb\",\n    \"Mar\",\n    \"Apr\",\n    \"May\",\n    \"Jun\",\n    \"Jul\",\n    \"Aug\",\n    \"Sep\",\n    \"Oct\",\n    \"Nov\",\n    \"Dec\",\n  ],\n\n  wide: [\n    \"January\",\n    \"February\",\n    \"March\",\n    \"April\",\n    \"May\",\n    \"June\",\n    \"July\",\n    \"August\",\n    \"September\",\n    \"October\",\n    \"November\",\n    \"December\",\n  ],\n};\n\nconst dayValues = {\n  narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n  short: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n  abbreviated: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n  wide: [\n    \"Sunday\",\n    \"Monday\",\n    \"Tuesday\",\n    \"Wednesday\",\n    \"Thursday\",\n    \"Friday\",\n    \"Saturday\",\n  ],\n};\n\nconst dayPeriodValues = {\n  narrow: {\n    am: \"a\",\n    pm: \"p\",\n    midnight: \"mi\",\n    noon: \"n\",\n    morning: \"morning\",\n    afternoon: \"afternoon\",\n    evening: \"evening\",\n    night: \"night\",\n  },\n  abbreviated: {\n    am: \"AM\",\n    pm: \"PM\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"morning\",\n    afternoon: \"afternoon\",\n    evening: \"evening\",\n    night: \"night\",\n  },\n  wide: {\n    am: \"a.m.\",\n    pm: \"p.m.\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"morning\",\n    afternoon: \"afternoon\",\n    evening: \"evening\",\n    night: \"night\",\n  },\n};\n\nconst formattingDayPeriodValues = {\n  narrow: {\n    am: \"a\",\n    pm: \"p\",\n    midnight: \"mi\",\n    noon: \"n\",\n    morning: \"in the morning\",\n    afternoon: \"in the afternoon\",\n    evening: \"in the evening\",\n    night: \"at night\",\n  },\n  abbreviated: {\n    am: \"AM\",\n    pm: \"PM\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"in the morning\",\n    afternoon: \"in the afternoon\",\n    evening: \"in the evening\",\n    night: \"at night\",\n  },\n  wide: {\n    am: \"a.m.\",\n    pm: \"p.m.\",\n    midnight: \"midnight\",\n    noon: \"noon\",\n    morning: \"in the morning\",\n    afternoon: \"in the afternoon\",\n    evening: \"in the evening\",\n    night: \"at night\",\n  },\n};\n\nconst ordinalNumber = (dirtyNumber, _options) => {\n  const number = Number(dirtyNumber);\n\n  // If ordinal numbers depend on context, for example,\n  // if they are different for different grammatical genders,\n  // use `options.unit`.\n  //\n  // `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',\n  // 'day', 'hour', 'minute', 'second'.\n\n  const rem100 = number % 100;\n  if (rem100 > 20 || rem100 < 10) {\n    switch (rem100 % 10) {\n      case 1:\n        return number + \"st\";\n      case 2:\n        return number + \"nd\";\n      case 3:\n        return number + \"rd\";\n    }\n  }\n  return number + \"th\";\n};\n\nexport const localize = {\n  ordinalNumber,\n\n  era: buildLocalizeFn({\n    values: eraValues,\n    defaultWidth: \"wide\",\n  }),\n\n  quarter: buildLocalizeFn({\n    values: quarterValues,\n    defaultWidth: \"wide\",\n    argumentCallback: (quarter) => quarter - 1,\n  }),\n\n  month: buildLocalizeFn({\n    values: monthValues,\n    defaultWidth: \"wide\",\n  }),\n\n  day: buildLocalizeFn({\n    values: dayValues,\n    defaultWidth: \"wide\",\n  }),\n\n  dayPeriod: buildLocalizeFn({\n    values: dayPeriodValues,\n    defaultWidth: \"wide\",\n    formattingValues: formattingDayPeriodValues,\n    defaultFormattingWidth: \"wide\",\n  }),\n};\n","import { buildMatchFn } from \"../../_lib/buildMatchFn.js\";\nimport { buildMatchPatternFn } from \"../../_lib/buildMatchPatternFn.js\";\n\nconst matchOrdinalNumberPattern = /^(\\d+)(th|st|nd|rd)?/i;\nconst parseOrdinalNumberPattern = /\\d+/i;\n\nconst matchEraPatterns = {\n  narrow: /^(b|a)/i,\n  abbreviated: /^(b\\.?\\s?c\\.?|b\\.?\\s?c\\.?\\s?e\\.?|a\\.?\\s?d\\.?|c\\.?\\s?e\\.?)/i,\n  wide: /^(before christ|before common era|anno domini|common era)/i,\n};\nconst parseEraPatterns = {\n  any: [/^b/i, /^(a|c)/i],\n};\n\nconst matchQuarterPatterns = {\n  narrow: /^[1234]/i,\n  abbreviated: /^q[1234]/i,\n  wide: /^[1234](th|st|nd|rd)? quarter/i,\n};\nconst parseQuarterPatterns = {\n  any: [/1/i, /2/i, /3/i, /4/i],\n};\n\nconst matchMonthPatterns = {\n  narrow: /^[jfmasond]/i,\n  abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,\n  wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i,\n};\nconst parseMonthPatterns = {\n  narrow: [\n    /^j/i,\n    /^f/i,\n    /^m/i,\n    /^a/i,\n    /^m/i,\n    /^j/i,\n    /^j/i,\n    /^a/i,\n    /^s/i,\n    /^o/i,\n    /^n/i,\n    /^d/i,\n  ],\n\n  any: [\n    /^ja/i,\n    /^f/i,\n    /^mar/i,\n    /^ap/i,\n    /^may/i,\n    /^jun/i,\n    /^jul/i,\n    /^au/i,\n    /^s/i,\n    /^o/i,\n    /^n/i,\n    /^d/i,\n  ],\n};\n\nconst matchDayPatterns = {\n  narrow: /^[smtwf]/i,\n  short: /^(su|mo|tu|we|th|fr|sa)/i,\n  abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,\n  wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i,\n};\nconst parseDayPatterns = {\n  narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],\n  any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i],\n};\n\nconst matchDayPeriodPatterns = {\n  narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,\n  any: /^([ap]\\.?\\s?m\\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i,\n};\nconst parseDayPeriodPatterns = {\n  any: {\n    am: /^a/i,\n    pm: /^p/i,\n    midnight: /^mi/i,\n    noon: /^no/i,\n    morning: /morning/i,\n    afternoon: /afternoon/i,\n    evening: /evening/i,\n    night: /night/i,\n  },\n};\n\nexport const match = {\n  ordinalNumber: buildMatchPatternFn({\n    matchPattern: matchOrdinalNumberPattern,\n    parsePattern: parseOrdinalNumberPattern,\n    valueCallback: (value) => parseInt(value, 10),\n  }),\n\n  era: buildMatchFn({\n    matchPatterns: matchEraPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseEraPatterns,\n    defaultParseWidth: \"any\",\n  }),\n\n  quarter: buildMatchFn({\n    matchPatterns: matchQuarterPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseQuarterPatterns,\n    defaultParseWidth: \"any\",\n    valueCallback: (index) => index + 1,\n  }),\n\n  month: buildMatchFn({\n    matchPatterns: matchMonthPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseMonthPatterns,\n    defaultParseWidth: \"any\",\n  }),\n\n  day: buildMatchFn({\n    matchPatterns: matchDayPatterns,\n    defaultMatchWidth: \"wide\",\n    parsePatterns: parseDayPatterns,\n    defaultParseWidth: \"any\",\n  }),\n\n  dayPeriod: buildMatchFn({\n    matchPatterns: matchDayPeriodPatterns,\n    defaultMatchWidth: \"any\",\n    parsePatterns: parseDayPeriodPatterns,\n    defaultParseWidth: \"any\",\n  }),\n};\n","import { constructNow } from \"./constructNow.js\";\n\nimport { formatDistance } from \"./formatDistance.js\";\n\n/**\n * The {@link formatDistanceToNow} function options.\n */\n\n/**\n * @name formatDistanceToNow\n * @category Common Helpers\n * @summary Return the distance between the given date and now in words.\n * @pure false\n *\n * @description\n * Return the distance between the given date and now in words.\n *\n * | Distance to now                                                   | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance to now     | Result               |\n * |---------------------|----------------------|\n * | 0 secs ... 5 secs   | less than 5 seconds  |\n * | 5 secs ... 10 secs  | less than 10 seconds |\n * | 10 secs ... 20 secs | less than 20 seconds |\n * | 20 secs ... 40 secs | half a minute        |\n * | 40 secs ... 60 secs | less than a minute   |\n * | 60 secs ... 90 secs | 1 minute             |\n *\n * @param date - The given date\n * @param options - The object with options\n *\n * @returns The distance in words\n *\n * @throws `date` must not be Invalid Date\n * @throws `options.locale` must contain `formatDistance` property\n *\n * @example\n * // If today is 1 January 2015, what is the distance to 2 July 2014?\n * const result = formatDistanceToNow(\n *   new Date(2014, 6, 2)\n * )\n * //=> '6 months'\n *\n * @example\n * // If now is 1 January 2015 00:00:00,\n * // what is the distance to 1 January 2015 00:00:15, including seconds?\n * const result = formatDistanceToNow(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   {includeSeconds: true}\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 January 2016, with a suffix?\n * const result = formatDistanceToNow(\n *   new Date(2016, 0, 1),\n *   {addSuffix: true}\n * )\n * //=> 'in about 1 year'\n *\n * @example\n * // If today is 1 January 2015,\n * // what is the distance to 1 August 2016 in Esperanto?\n * const eoLocale = require('date-fns/locale/eo')\n * const result = formatDistanceToNow(\n *   new Date(2016, 7, 1),\n *   {locale: eoLocale}\n * )\n * //=> 'pli ol 1 jaro'\n */\nexport function formatDistanceToNow(date, options) {\n  return formatDistance(date, constructNow(date), options);\n}\n\n// Fallback for modularized imports:\nexport default formatDistanceToNow;\n","import { defaultLocale } from \"./_lib/defaultLocale.js\";\nimport { getDefaultOptions } from \"./_lib/defaultOptions.js\";\nimport { getTimezoneOffsetInMilliseconds } from \"./_lib/getTimezoneOffsetInMilliseconds.js\";\nimport { normalizeDates } from \"./_lib/normalizeDates.js\";\nimport { compareAsc } from \"./compareAsc.js\";\nimport { minutesInDay, minutesInMonth } from \"./constants.js\";\nimport { differenceInMonths } from \"./differenceInMonths.js\";\nimport { differenceInSeconds } from \"./differenceInSeconds.js\";\n\n/**\n * The {@link formatDistance} function options.\n */\n\n/**\n * @name formatDistance\n * @category Common Helpers\n * @summary Return the distance between the given dates in words.\n *\n * @description\n * Return the distance between the given dates in words.\n *\n * | Distance between dates                                            | Result              |\n * |-------------------------------------------------------------------|---------------------|\n * | 0 ... 30 secs                                                     | less than a minute  |\n * | 30 secs ... 1 min 30 secs                                         | 1 minute            |\n * | 1 min 30 secs ... 44 mins 30 secs                                 | [2..44] minutes     |\n * | 44 mins ... 30 secs ... 89 mins 30 secs                           | about 1 hour        |\n * | 89 mins 30 secs ... 23 hrs 59 mins 30 secs                        | about [2..24] hours |\n * | 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs                 | 1 day               |\n * | 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs         | [2..30] days        |\n * | 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs | about 1 month       |\n * | 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs | about 2 months      |\n * | 59 days 23 hrs 59 mins 30 secs ... 1 yr                           | [2..12] months      |\n * | 1 yr ... 1 yr 3 months                                            | about 1 year        |\n * | 1 yr 3 months ... 1 yr 9 month s                                  | over 1 year         |\n * | 1 yr 9 months ... 2 yrs                                           | almost 2 years      |\n * | N yrs ... N yrs 3 months                                          | about N years       |\n * | N yrs 3 months ... N yrs 9 months                                 | over N years        |\n * | N yrs 9 months ... N+1 yrs                                        | almost N+1 years    |\n *\n * With `options.includeSeconds == true`:\n * | Distance between dates | Result               |\n * |------------------------|----------------------|\n * | 0 secs ... 5 secs      | less than 5 seconds  |\n * | 5 secs ... 10 secs     | less than 10 seconds |\n * | 10 secs ... 20 secs    | less than 20 seconds |\n * | 20 secs ... 40 secs    | half a minute        |\n * | 40 secs ... 60 secs    | less than a minute   |\n * | 60 secs ... 90 secs    | 1 minute             |\n *\n * @param laterDate - The date\n * @param earlierDate - The date to compare with\n * @param options - An object with options\n *\n * @returns The distance in words\n *\n * @throws `date` must not be Invalid Date\n * @throws `baseDate` must not be Invalid Date\n * @throws `options.locale` must contain `formatDistance` property\n *\n * @example\n * // What is the distance between 2 July 2014 and 1 January 2015?\n * const result = formatDistance(new Date(2014, 6, 2), new Date(2015, 0, 1))\n * //=> '6 months'\n *\n * @example\n * // What is the distance between 1 January 2015 00:00:15\n * // and 1 January 2015 00:00:00, including seconds?\n * const result = formatDistance(\n *   new Date(2015, 0, 1, 0, 0, 15),\n *   new Date(2015, 0, 1, 0, 0, 0),\n *   { includeSeconds: true }\n * )\n * //=> 'less than 20 seconds'\n *\n * @example\n * // What is the distance from 1 January 2016\n * // to 1 January 2015, with a suffix?\n * const result = formatDistance(new Date(2015, 0, 1), new Date(2016, 0, 1), {\n *   addSuffix: true\n * })\n * //=> 'about 1 year ago'\n *\n * @example\n * // What is the distance between 1 August 2016 and 1 January 2015 in Esperanto?\n * import { eoLocale } from 'date-fns/locale/eo'\n * const result = formatDistance(new Date(2016, 7, 1), new Date(2015, 0, 1), {\n *   locale: eoLocale\n * })\n * //=> 'pli ol 1 jaro'\n */\nexport function formatDistance(laterDate, earlierDate, options) {\n  const defaultOptions = getDefaultOptions();\n  const locale = options?.locale ?? defaultOptions.locale ?? defaultLocale;\n  const minutesInAlmostTwoDays = 2520;\n\n  const comparison = compareAsc(laterDate, earlierDate);\n\n  if (isNaN(comparison)) throw new RangeError(\"Invalid time value\");\n\n  const localizeOptions = Object.assign({}, options, {\n    addSuffix: options?.addSuffix,\n    comparison: comparison,\n  });\n\n  const [laterDate_, earlierDate_] = normalizeDates(\n    options?.in,\n    ...(comparison > 0 ? [earlierDate, laterDate] : [laterDate, earlierDate]),\n  );\n\n  const seconds = differenceInSeconds(earlierDate_, laterDate_);\n  const offsetInSeconds =\n    (getTimezoneOffsetInMilliseconds(earlierDate_) -\n      getTimezoneOffsetInMilliseconds(laterDate_)) /\n    1000;\n  const minutes = Math.round((seconds - offsetInSeconds) / 60);\n  let months;\n\n  // 0 up to 2 mins\n  if (minutes < 2) {\n    if (options?.includeSeconds) {\n      if (seconds < 5) {\n        return locale.formatDistance(\"lessThanXSeconds\", 5, localizeOptions);\n      } else if (seconds < 10) {\n        return locale.formatDistance(\"lessThanXSeconds\", 10, localizeOptions);\n      } else if (seconds < 20) {\n        return locale.formatDistance(\"lessThanXSeconds\", 20, localizeOptions);\n      } else if (seconds < 40) {\n        return locale.formatDistance(\"halfAMinute\", 0, localizeOptions);\n      } else if (seconds < 60) {\n        return locale.formatDistance(\"lessThanXMinutes\", 1, localizeOptions);\n      } else {\n        return locale.formatDistance(\"xMinutes\", 1, localizeOptions);\n      }\n    } else {\n      if (minutes === 0) {\n        return locale.formatDistance(\"lessThanXMinutes\", 1, localizeOptions);\n      } else {\n        return locale.formatDistance(\"xMinutes\", minutes, localizeOptions);\n      }\n    }\n\n    // 2 mins up to 0.75 hrs\n  } else if (minutes < 45) {\n    return locale.formatDistance(\"xMinutes\", minutes, localizeOptions);\n\n    // 0.75 hrs up to 1.5 hrs\n  } else if (minutes < 90) {\n    return locale.formatDistance(\"aboutXHours\", 1, localizeOptions);\n\n    // 1.5 hrs up to 24 hrs\n  } else if (minutes < minutesInDay) {\n    const hours = Math.round(minutes / 60);\n    return locale.formatDistance(\"aboutXHours\", hours, localizeOptions);\n\n    // 1 day up to 1.75 days\n  } else if (minutes < minutesInAlmostTwoDays) {\n    return locale.formatDistance(\"xDays\", 1, localizeOptions);\n\n    // 1.75 days up to 30 days\n  } else if (minutes < minutesInMonth) {\n    const days = Math.round(minutes / minutesInDay);\n    return locale.formatDistance(\"xDays\", days, localizeOptions);\n\n    // 1 month up to 2 months\n  } else if (minutes < minutesInMonth * 2) {\n    months = Math.round(minutes / minutesInMonth);\n    return locale.formatDistance(\"aboutXMonths\", months, localizeOptions);\n  }\n\n  months = differenceInMonths(earlierDate_, laterDate_);\n\n  // 2 months up to 12 months\n  if (months < 12) {\n    const nearestMonth = Math.round(minutes / minutesInMonth);\n    return locale.formatDistance(\"xMonths\", nearestMonth, localizeOptions);\n\n    // 1 year up to max Date\n  } else {\n    const monthsSinceStartOfYear = months % 12;\n    const years = Math.trunc(months / 12);\n\n    // N years up to 1 years 3 months\n    if (monthsSinceStartOfYear < 3) {\n      return locale.formatDistance(\"aboutXYears\", years, localizeOptions);\n\n      // N years 3 months up to N years 9 months\n    } else if (monthsSinceStartOfYear < 9) {\n      return locale.formatDistance(\"overXYears\", years, localizeOptions);\n\n      // N years 9 months up to N year 12 months\n    } else {\n      return locale.formatDistance(\"almostXYears\", years + 1, localizeOptions);\n    }\n  }\n}\n\n// Fallback for modularized imports:\nexport default formatDistance;\n","import { constructFrom } from \"./constructFrom.js\";\n\n/**\n * @name constructNow\n * @category Generic Helpers\n * @summary Constructs a new current date using the passed value constructor.\n * @pure false\n *\n * @description\n * The function constructs a new current date using the constructor from\n * the reference date. It helps to build generic functions that accept date\n * extensions and use the current date.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * @param date - The reference date to take constructor from\n *\n * @returns Current date initialized using the given date constructor\n *\n * @example\n * import { constructNow, isSameDay } from 'date-fns'\n *\n * function isToday<DateType extends Date>(\n *   date: DateArg<DateType>,\n * ): boolean {\n *   // If we were to use `new Date()` directly, the function would  behave\n *   // differently in different timezones and return false for the same date.\n *   return isSameDay(date, constructNow(date));\n * }\n */\nexport function constructNow(date) {\n  return constructFrom(date, Date.now());\n}\n\n// Fallback for modularized imports:\nexport default constructNow;\n","import ConnectyCube from \"connectycube\";\nimport { PrivacyListAction } from \"connectycube/types\";\nimport { useEffect, useState, useRef } from \"react\";\n\nexport const BLOCK_LIST_LOG_TAG = \"[useChat][useBlockList]\";\nexport const BLOCK_LIST_NAME = \"ConnectyCubeBlockList\";\n\nexport type BlockListHook = {\n  blockedUsers: number[];\n  isBlockedUser: (userId: number) => boolean;\n  unblockUser: (userId: number) => Promise<void>;\n  blockUser: (userId: number) => Promise<void>;\n};\n\nfunction useBlockList(isConnected: boolean): BlockListHook {\n  const [state, setState] = useState<Set<number>>(new Set<number>());\n  const isApplied = useRef<boolean>(false);\n\n  const isBlocked = (userId: number): boolean => state.has(userId);\n\n  const fetch = async (): Promise<void> => {\n    if (!isConnected) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[fetch]: chat is not connected`);\n      return;\n    }\n\n    const blackListNames = await ConnectyCube.chat.privacylist.getNames();\n\n    if (blackListNames.default === BLOCK_LIST_NAME) {\n      const blockList = await ConnectyCube.chat.privacylist.getList(BLOCK_LIST_NAME);\n      const newState = blockList.items.reduce((list: Set<number>, item) => {\n        if (item.action === PrivacyListAction.DENY) {\n          list.add(+item.user_id);\n        }\n        return list;\n      }, new Set<number>());\n\n      isApplied.current = true;\n\n      setState(newState);\n    }\n  };\n\n  const upsert = async (user_id: number, action: PrivacyListAction): Promise<void> => {\n    if (!isConnected) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[upsert]: ${action} user ${user_id} failed, chat is not connected`);\n      return;\n    }\n\n    const newState = new Set(state);\n\n    const blockList = {\n      name: BLOCK_LIST_NAME,\n      items: [{ user_id, action, mutualBlock: true }],\n    };\n\n    try {\n      if (action === PrivacyListAction.DENY) {\n        newState.add(user_id);\n      } else if (action === PrivacyListAction.ALLOW) {\n        newState.delete(user_id);\n      }\n\n      if (isApplied.current) {\n        await ConnectyCube.chat.privacylist.setAsDefault(null);\n        await ConnectyCube.chat.privacylist.update(blockList);\n        if (newState.size > 0) {\n          await ConnectyCube.chat.privacylist.setAsDefault(BLOCK_LIST_NAME);\n        }\n      } else {\n        await ConnectyCube.chat.privacylist.create(blockList);\n        await ConnectyCube.chat.privacylist.setAsDefault(BLOCK_LIST_NAME);\n      }\n    } catch (error) {\n      return;\n    } finally {\n      setState(newState);\n    }\n  };\n\n  const unblock = async (userId: number): Promise<void> => {\n    if (!isBlocked(userId)) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[unblock]: user ${userId} is not blocked`);\n      return;\n    }\n\n    await upsert(userId, PrivacyListAction.ALLOW);\n  };\n\n  const block = async (userId: number): Promise<void> => {\n    if (isBlocked(userId)) {\n      console.warn(`${BLOCK_LIST_LOG_TAG}[block]: user ${userId} is already blocked`);\n      return;\n    }\n\n    await upsert(userId, PrivacyListAction.DENY);\n  };\n\n  useEffect(() => {\n    if (isConnected) {\n      fetch();\n    }\n  }, [isConnected]);\n\n  return {\n    blockedUsers: Array.from(state),\n    isBlockedUser: isBlocked,\n    unblockUser: unblock,\n    blockUser: block,\n  };\n}\n\nexport default useBlockList;\n","import { DateOrTimestamp } from \"connectycube/types\";\n\nexport const parseDate = (date: DateOrTimestamp): number | undefined => {\n  let result: number | undefined;\n\n  if (typeof date === \"string\") {\n    const t = new Date(date).getTime();\n    result = isNaN(t) ? undefined : t;\n  } else if (typeof date === \"number\") {\n    result = date * 1000;\n  }\n\n  return result;\n};\n\nexport const getLastActivityText = (seconds: number): string => {\n  let status: string;\n\n  const MINUTE_IN_SEC = 60;\n  const HOUR_IN_SEC = 3600;\n  const DAY_IN_SEC = 86400;\n  const ONLINE_IN_SEC = MINUTE_IN_SEC / 2;\n\n  if (seconds <= ONLINE_IN_SEC) {\n    status = \"Online\";\n  } else if (seconds < HOUR_IN_SEC) {\n    status = `Last seen ${Math.ceil(seconds / MINUTE_IN_SEC)} minutes ago`;\n  } else if (seconds < DAY_IN_SEC) {\n    status = `Last seen ${Math.ceil(seconds / HOUR_IN_SEC)} hours ago`;\n  } else {\n    const lastLoggedInTime = new Date(Date.now() - seconds * 1000);\n    const day = lastLoggedInTime.getUTCDate();\n    const month = (lastLoggedInTime.getMonth() + 1).toString().padStart(2, \"0\");\n    const year = lastLoggedInTime.getFullYear();\n    status = `Last seen ${day}/${month}/${year}`;\n  }\n\n  return status;\n};\n","import ConnectyCube from \"connectycube\";\nimport { Chat, ChatEvent, Users } from \"connectycube/types\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport useStateRef from \"react-usestateref\";\nimport { getLastActivityText } from \"../helpers\";\n\nexport const USERS_LOG_TAG = \"[useChat][useUsers]\";\nexport const LIST_ONLINE_USERS_INTERVAL = 60000;\nexport const MAX_REQUEST_LIMIT = 100;\n\nexport type OnlineUsersLastRequestAt = number;\nexport type UsersArray = Users.User[];\nexport type UsersObject = { [userId: Users.User[\"id\"]]: Users.User };\nexport type UsersLastActivity = { [userId: number]: string };\n\nexport type UsersHookExports = {\n  users: UsersObject;\n  searchUsers: (term: string) => Promise<UsersArray>;\n  listOnlineUsers: (force?: boolean) => Promise<UsersArray>;\n  listOnlineUsersWithParams: (params: Users.ListOnlineParams) => Promise<UsersArray>;\n  onlineUsers: UsersArray;\n  getOnlineUsersCount: () => Promise<number>;\n  onlineUsersCount: number;\n  lastActivity: UsersLastActivity;\n  getLastActivity: (userId: number) => Promise<string>;\n  subscribeToUserLastActivityStatus: (userId: number) => void;\n  unsubscribeFromUserLastActivityStatus: (userId: number) => void;\n};\n\nexport type UsersHook = {\n  exports: UsersHookExports;\n  _retrieveAndStoreUsers: (usersIds: number[]) => Promise<void>;\n};\n\nfunction useUsers(currentUserId?: number): UsersHook {\n  const [users, setUsers, usersRef] = useStateRef<UsersObject>({});\n  const [onlineUsers, setOnlineUsers] = useState<UsersObject>({});\n  const [onlineUsersCount, setOnlineUsersCount] = useState<number>(0);\n  const [lastActivity, setLastActivity] = useState<UsersLastActivity>({});\n\n  const onlineUsersLastRequestAtRef = useRef<OnlineUsersLastRequestAt>(0);\n\n  const _retrieveAndStoreUsers = async (usersIds: number[]): Promise<void> => {\n    const usersToFind = usersIds.filter((userId) => !users[userId]);\n\n    if (usersToFind.length > 0) {\n      const params = { limit: MAX_REQUEST_LIMIT, id: { in: usersToFind } };\n      const { items } = await ConnectyCube.users.getV2(params);\n      const nextUsersState = items.reduce<UsersObject>(\n        (map, user) => {\n          map[user.id] = user;\n          return map;\n        },\n        { ...usersRef.current },\n      );\n\n      setUsers(nextUsersState);\n    }\n  };\n\n  const searchUsers = useCallback(\n    async (term: string): Promise<UsersArray> => {\n      const { items: usersWithFullName } = await ConnectyCube.users.getV2({\n        full_name: { start_with: term },\n        limit: MAX_REQUEST_LIMIT,\n      });\n      const { items: usersWithLogin } = await ConnectyCube.users.getV2({\n        login: { start_with: term },\n        limit: MAX_REQUEST_LIMIT,\n      });\n      const usersMap: Map<number, Users.User> = new Map();\n\n      [...usersWithFullName, ...usersWithLogin].forEach((user) => {\n        usersMap.set(user.id, user);\n      });\n\n      return Array.from(usersMap.values()).filter((user) => user.id !== currentUserId);\n    },\n    [currentUserId],\n  );\n\n  const getOnlineUsersCount = async (): Promise<number> => {\n    let nextOnlineUsersCount = onlineUsersCount;\n\n    try {\n      const { count } = await ConnectyCube.users.getOnlineCount();\n      nextOnlineUsersCount = count;\n      setOnlineUsersCount(nextOnlineUsersCount);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[getOnlineCount][Error]:`, error);\n    }\n\n    return nextOnlineUsersCount;\n  };\n\n  const _listOnline = async (): Promise<UsersObject> => {\n    const onlineUsersCount = await getOnlineUsersCount();\n    const promises = [];\n\n    let onlineUsersState: UsersObject = {};\n\n    try {\n      let limit = MAX_REQUEST_LIMIT;\n      let offset = 0;\n\n      while (offset < onlineUsersCount) {\n        promises.push(ConnectyCube.users.listOnline({ limit, offset }).then(({ users }) => users));\n        offset += limit;\n      }\n\n      const results = await Promise.all(promises);\n      const allUsers = results.flat();\n\n      onlineUsersState = allUsers.reduce<UsersObject>((map, user) => {\n        map[user.id] = user;\n        return map;\n      }, {});\n\n      setUsers({ ...usersRef.current, ...onlineUsersState });\n      setOnlineUsers(onlineUsersState);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[listOnline][Error]:`, error);\n    }\n\n    return onlineUsersState;\n  };\n\n  const listOnlineUsersWithParams = async (params: Users.ListOnlineParams): Promise<UsersArray> => {\n    let onlineUsersState: UsersObject = {};\n\n    try {\n      const { users: allUsers } = await ConnectyCube.users.listOnline(params);\n\n      onlineUsersState = allUsers.reduce<UsersObject>((map, user) => {\n        map[user.id] = user;\n        return map;\n      }, {});\n\n      setUsers({ ...usersRef.current, ...onlineUsersState });\n      setOnlineUsers(onlineUsersState);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[listOnlineWithParams][Error]:`, error);\n    }\n\n    return Object.values(onlineUsersState);\n  };\n\n  const listOnlineUsers = async (force: boolean = false): Promise<UsersArray> => {\n    const lastRequestedAt = onlineUsersLastRequestAtRef.current;\n    const currentTimestamp = Date.now();\n    const shouldRequest = currentTimestamp - lastRequestedAt > LIST_ONLINE_USERS_INTERVAL;\n\n    let onlineUsersState = onlineUsers;\n\n    if (shouldRequest || force) {\n      onlineUsersState = await _listOnline();\n      onlineUsersLastRequestAtRef.current = Date.now();\n    }\n\n    return Object.values(onlineUsersState);\n  };\n\n  const getLastActivity = async (userId: number): Promise<string> => {\n    let status = \"Last seen recently\";\n\n    try {\n      const { seconds } = await ConnectyCube.chat.getLastUserActivity(userId);\n      status = getLastActivityText(seconds);\n    } catch (error) {\n      console.error(`${USERS_LOG_TAG}[getLastActivity][Error]:`, error);\n    } finally {\n      setLastActivity((prevLastActivity) => ({ ...prevLastActivity, [userId]: status }));\n      return status;\n    }\n  };\n\n  const subscribeToUserLastActivityStatus = (userId: number): void => {\n    ConnectyCube.chat.subscribeToUserLastActivityStatus(userId);\n  };\n\n  const unsubscribeFromUserLastActivityStatus = (userId: number): void => {\n    ConnectyCube.chat.unsubscribeFromUserLastActivityStatus(userId);\n  };\n\n  useEffect(() => {\n    const processUserLastActivityChange = (\n      userId: Chat.LastActivity[\"userId\"],\n      seconds: Chat.LastActivity[\"seconds\"],\n    ) => {\n      if (typeof userId === \"number\" && seconds >= 0) {\n        const status = getLastActivityText(seconds);\n        setLastActivity((prevLastActivity) => ({ ...prevLastActivity, [userId]: status }));\n      }\n    };\n\n    ConnectyCube.chat.addListener(ChatEvent.USER_LAST_ACTIVITY, processUserLastActivityChange);\n\n    return () => {\n      ConnectyCube.chat.removeListener(ChatEvent.USER_LAST_ACTIVITY);\n    };\n  }, []);\n\n  return {\n    _retrieveAndStoreUsers,\n    exports: {\n      users,\n      searchUsers,\n      listOnlineUsers,\n      listOnlineUsersWithParams,\n      onlineUsers: Object.values(onlineUsers),\n      getOnlineUsersCount,\n      onlineUsersCount,\n      lastActivity,\n      getLastActivity,\n      subscribeToUserLastActivityStatus,\n      unsubscribeFromUserLastActivityStatus,\n    },\n  };\n}\n\nexport default useUsers;\n","import { createContext, useCallback, useContext, useEffect, useRef, useState } from \"react\";\nimport { ChatContextType, ChatProviderType, GroupChatEventType } from \"./types\";\nimport { Chat, ChatEvent, ChatType, Dialogs, DialogType, Messages } from \"connectycube/types\";\n\nimport ConnectyCube from \"connectycube\";\nimport useStateRef from \"react-usestateref\";\nimport { formatDistanceToNow } from \"date-fns\";\nimport { useBlockList, useUsers } from \"./hooks\";\nimport { parseDate } from \"./helpers\";\n\nconst ChatContext = createContext<ChatContextType | undefined>(undefined);\nChatContext.displayName = \"ChatContext\";\n\nexport const useChat = (): ChatContextType => {\n  const context = useContext(ChatContext);\n\n  if (!context) {\n    throw new Error(\"useChat must be within ChatProvider\");\n  }\n\n  return context;\n};\n\nexport const ChatProvider = ({ children }: ChatProviderType): React.ReactElement => {\n  // state\n  const [isOnline, setIsOnline] = useState<boolean>(navigator.onLine);\n  const [isConnected, setIsConnected] = useState(false);\n  const [unreadMessagesCount, setUnreadMessagesCount] = useState<ChatContextType[\"unreadMessagesCount\"]>({ total: 0 });\n  const [messages, setMessages] = useState<{ [dialogId: string]: Messages.Message[] }>({});\n  const [typingStatus, setTypingStatus] = useState<{ [dialogId: string]: number[] }>({});\n  const [activatedDialogs, setActivatedDialogs] = useState<{ [dialogId: string]: boolean }>({});\n  // refs\n  const typingTimers = useRef<{ [dialogId: string]: { [userId: number | string]: NodeJS.Timeout } }>({});\n  const onMessageRef = useRef<Chat.OnMessageListener | null>(null);\n  const onMessageErrorRef = useRef<Chat.OnMessageErrorListener | null>(null);\n  const privateDialogsIdsRef = useRef<{ [userId: number | string]: string }>({});\n  // state refs\n  const [dialogs, setDialogs, dialogsRef] = useStateRef<Dialogs.Dialog[]>([]);\n  const [currentUserId, setCurrentUserId, currentUserIdRef] = useStateRef<number | undefined>();\n  const [selectedDialog, setSelectedDialog, selectedDialogRef] = useStateRef<Dialogs.Dialog | undefined>();\n  // internal hooks\n  const chatBlockList = useBlockList(isConnected);\n  const chatUsers = useUsers(currentUserId);\n  const { _retrieveAndStoreUsers } = chatUsers;\n\n  const connect = async (credentials: Chat.ConnectionParams) => {\n    try {\n      const _isConnected = await ConnectyCube.chat.connect(credentials);\n      if (_isConnected) {\n        setIsConnected(_isConnected);\n        setCurrentUserId(credentials.userId);\n      }\n    } catch (error) {\n      console.error(`Failed to connect due to ${error}`);\n    }\n  };\n\n  const disconnect = () => {\n    if (ConnectyCube.chat.isConnected) {\n      ConnectyCube.chat.disconnect();\n      setCurrentUserId(undefined);\n      setIsConnected(false);\n    }\n  };\n\n  const createChat = async (userId: number, extensions?: { [key: string]: any }): Promise<Dialogs.Dialog> => {\n    const params = {\n      type: DialogType.PRIVATE,\n      occupants_ids: [userId],\n      extensions,\n    };\n    const dialog = await ConnectyCube.chat.dialog.create(params);\n\n    setDialogs((prevDialogs) => [dialog, ...prevDialogs.filter((d) => d._id !== dialog._id)]);\n\n    privateDialogsIdsRef.current[userId] = dialog._id;\n\n    _notifyUsers(GroupChatEventType.NEW_DIALOG, dialog._id, userId);\n    _retrieveAndStoreUsers([userId, currentUserId as number]);\n\n    return dialog;\n  };\n\n  const createGroupChat = async (\n    usersIds: number[],\n    name: string,\n    photo?: string,\n    extensions?: { [key: string]: any },\n  ): Promise<Dialogs.Dialog> => {\n    const params = {\n      type: DialogType.GROUP,\n      name,\n      photo,\n      occupants_ids: usersIds,\n      extensions,\n    };\n\n    const dialog = await ConnectyCube.chat.dialog.create(params);\n\n    setDialogs((prevDialogs) => [dialog, ...prevDialogs.filter((d) => d._id !== dialog._id)]);\n\n    usersIds.forEach((userId) => {\n      _notifyUsers(GroupChatEventType.NEW_DIALOG, dialog._id, userId);\n    });\n    _retrieveAndStoreUsers([...usersIds, currentUserId as number]);\n\n    return dialog;\n  };\n\n  const getDialogs = async (filters?: Dialogs.ListParams): Promise<Dialogs.Dialog[]> => {\n    // fetch chats\n    const { items: fetchedDialogs } = await ConnectyCube.chat.dialog.list(filters);\n\n    // store dialogs\n    setDialogs((prevDialogs) => {\n      const allDialogs = [...prevDialogs, ...fetchedDialogs];\n\n      // Create a map keyed by dialog._id to eliminate duplicates\n      const uniqueDialogsMap = new Map<string, Dialogs.Dialog>();\n      allDialogs.forEach((dialog) => uniqueDialogsMap.set(dialog._id, dialog));\n\n      // Convert the map values to an array and sort by the most recent message date\n      const sortedDialogs = Array.from(uniqueDialogsMap.values()).sort((a, b) => {\n        const dateA = parseDate(a.last_message_date_sent) || parseDate(a.created_at) || 0;\n        const dateB = parseDate(b.last_message_date_sent) || parseDate(b.created_at) || 0;\n        return dateB - dateA; // Sort in descending order (most recent first)\n      });\n\n      return sortedDialogs;\n    });\n\n    // store users\n    const usersIds = Array.from(new Set(fetchedDialogs.flatMap((dialog) => dialog.occupants_ids)));\n    _retrieveAndStoreUsers(usersIds);\n\n    return fetchedDialogs;\n  };\n\n  const getMessages = async (dialogId: string): Promise<Messages.Message[]> => {\n    const params = {\n      chat_dialog_id: dialogId,\n      sort_desc: \"date_sent\",\n      limit: 100,\n      skip: 0,\n    };\n    try {\n      const result = await ConnectyCube.chat.message.list(params);\n      // store messages\n      const retrievedMessages = result.items\n        .sort((a: Messages.Message, b: Messages.Message) => {\n          return a._id.toString().localeCompare(b._id.toString()); // revers sort\n        })\n        .map((msg) => {\n          const attachments = msg.attachments?.map((attachment) => ({\n            ...attachment,\n            url: ConnectyCube.storage.privateUrl(attachment.uid),\n          }));\n          return { ...msg, attachments };\n        });\n      setMessages((prevMessages) => ({ ...prevMessages, [dialogId]: retrievedMessages }));\n      return retrievedMessages;\n    } catch (error: any) {\n      if (error.code === 404) {\n        // dialog not found\n        setMessages((prevMessages) => ({ ...prevMessages, [dialogId]: [] }));\n        return [];\n      }\n      throw error;\n    }\n  };\n\n  const selectDialog = async (dialog?: Dialogs.Dialog): Promise<void> => {\n    setSelectedDialog(dialog);\n    if (!dialog) {\n      return;\n    }\n\n    // retrieve messages if chat is not activated yet\n    if (!activatedDialogs[dialog._id]) {\n      await getMessages(dialog._id);\n      setActivatedDialogs({ ...activatedDialogs, [dialog._id]: true });\n    }\n\n    if (dialog.unread_messages_count > 0) {\n      await markDialogAsRead(dialog).catch((_error) => {});\n    }\n  };\n\n  const getDialogOpponentId = (dialog?: Dialogs.Dialog): number | undefined => {\n    dialog ??= selectedDialog;\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    if (dialog.type !== DialogType.PRIVATE) {\n      return undefined;\n    }\n    const opponentId = dialog.occupants_ids.filter((oId) => {\n      return oId !== currentUserId;\n    })[0];\n\n    privateDialogsIdsRef.current[opponentId] = dialog._id;\n\n    return opponentId;\n  };\n\n  const _updateUnreadMessagesCount = () => {\n    const count: ChatContextType[\"unreadMessagesCount\"] = { total: 0 };\n\n    dialogs.forEach(({ _id, unread_messages_count = 0 }: Dialogs.Dialog) => {\n      if (_id !== selectedDialog?._id) {\n        count[_id] = unread_messages_count;\n        count.total += unread_messages_count;\n      }\n    });\n\n    setUnreadMessagesCount(count);\n  };\n\n  const markDialogAsRead = async (dialog: Dialogs.Dialog): Promise<void> => {\n    // mark all messages as read\n    const params = {\n      read: 1,\n      chat_dialog_id: dialog._id,\n    };\n    await ConnectyCube.chat.message.update(\"\", params);\n\n    setDialogs((prevDialogs) =>\n      prevDialogs.map((d) => (d._id === dialog._id ? { ...d, unread_messages_count: 0 } : d)),\n    );\n  };\n\n  const addUsersToGroupChat = async (usersIds: number[]): Promise<void> => {\n    if (!selectedDialog) {\n      throw new Error(\"No dialog selected\");\n    }\n\n    // add users to group chat\n    const dialogId = selectedDialog._id;\n    const toUpdateParams = { push_all: { occupants_ids: usersIds } };\n    await ConnectyCube.chat.dialog.update(dialogId, toUpdateParams);\n\n    // notify existing participants with system message\n    selectedDialog.occupants_ids\n      .filter((userId) => userId !== currentUserId)\n      .forEach((userId) => {\n        _notifyUsers(GroupChatEventType.ADD_PARTICIPANTS, dialogId, userId, {\n          addedParticipantsIds: usersIds.join(),\n        });\n      });\n\n    usersIds.forEach((userId) => {\n      _notifyUsers(GroupChatEventType.ADDED_TO_DIALOG, dialogId, userId);\n    });\n\n    // update store\n    _retrieveAndStoreUsers(usersIds);\n\n    const updatedDialog = {\n      ...selectedDialog,\n      occupants_ids: Array.from(new Set([...selectedDialog.occupants_ids, ...usersIds])),\n    };\n\n    setDialogs((prevDialogs) => prevDialogs.map((d) => (d._id === dialogId ? updatedDialog : d)));\n    setSelectedDialog(updatedDialog);\n  };\n\n  const removeUsersFromGroupChat = async (usersIds: number[]): Promise<void> => {\n    if (!selectedDialog) {\n      throw new Error(\"No dialog selected\");\n    }\n\n    // remove users from group chat\n    const dialogId = selectedDialog._id;\n    const toUpdateParams = { pull_all: { occupants_ids: usersIds } };\n    await ConnectyCube.chat.dialog.update(dialogId, toUpdateParams);\n\n    // notify users that they are removed from the dialog\n    usersIds.forEach((userId) => {\n      _notifyUsers(GroupChatEventType.REMOVED_FROM_DIALOG, dialogId, userId);\n    });\n\n    selectedDialog.occupants_ids\n      .filter((userId) => {\n        return !usersIds.includes(userId) && userId !== currentUserId;\n      })\n      .forEach((userId) => {\n        _notifyUsers(GroupChatEventType.REMOVE_PARTICIPANTS, dialogId, userId, {\n          removedParticipantsIds: usersIds.join(),\n        });\n      });\n\n    // update store\n    const updatedDialog = {\n      ...selectedDialog,\n      occupants_ids: selectedDialog.occupants_ids.filter((userId) => !usersIds.includes(userId)),\n    };\n\n    setDialogs((prevDialogs) => prevDialogs.map((d) => (d._id === dialogId ? updatedDialog : d)));\n    setSelectedDialog(updatedDialog);\n  };\n\n  const leaveGroupChat = async (): Promise<void> => {\n    if (!selectedDialog) {\n      throw new Error(\"No dialog selected\");\n    }\n\n    await ConnectyCube.chat.dialog.delete(selectedDialog._id);\n\n    // notify participants with system message\n    selectedDialog.occupants_ids\n      .filter((userId) => userId !== currentUserId)\n      .forEach((userId) => {\n        _notifyUsers(GroupChatEventType.REMOVED_FROM_DIALOG, selectedDialog._id, userId);\n      });\n\n    setDialogs(dialogs.filter((dialog) => dialog._id !== selectedDialog._id));\n    setSelectedDialog(undefined);\n  };\n\n  const sendMessage = (body: string, dialog?: Dialogs.Dialog) => {\n    dialog ??= selectedDialog;\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    const opponentId = getDialogOpponentId(dialog);\n    const messageId = _sendMessage(body, null, dialog, opponentId);\n\n    // add message to store\n    _addMessageToStore(messageId, body, dialog._id, currentUserId as number, opponentId);\n  };\n\n  const sendMessageWithAttachment = async (files: File[], dialog?: Dialogs.Dialog): Promise<void> => {\n    dialog ??= selectedDialog;\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n\n    const opponentId = getDialogOpponentId(dialog);\n    const tempId = Date.now() + \"\";\n    const attachments = files.map((file, index) => ({\n      uid: `local-${tempId}-${index}`, // just for temporary\n      type: file.type,\n      url: URL.createObjectURL(file),\n    }));\n\n    // add message to store\n    _addMessageToStore(tempId, \"Attachment\", dialog._id, currentUserId as number, opponentId, attachments, true);\n\n    // upload files to cloud\n    const uploadFilesPromises = files.map((file) => {\n      const fileParams = {\n        file: file,\n        name: file.name,\n        type: file.type,\n        size: file.size,\n        public: false,\n      };\n      return ConnectyCube.storage.createAndUpload(fileParams);\n    });\n\n    const uploadedFilesResults = await Promise.all(uploadFilesPromises);\n    const uploadedAttachments = uploadedFilesResults.map(({ uid, content_type }) => ({\n      uid,\n      type: content_type ?? \"\",\n      url: ConnectyCube.storage.privateUrl(uid),\n    }));\n\n    // send\n    const messageId = _sendMessage(\"Attachment\", uploadedAttachments, dialog, opponentId);\n\n    // update message in store\n    setMessages((prevMessages) => ({\n      ...prevMessages,\n      [dialog._id]: prevMessages[dialog._id].map((msg) =>\n        msg._id === tempId ? { ...msg, _id: messageId, attachments, isLoading: false } : msg,\n      ),\n    }));\n  };\n\n  const _sendMessage = (\n    body: string,\n    attachments: Messages.Attachment[] | null,\n    dialog: Dialogs.Dialog,\n    opponentId?: number,\n  ): string => {\n    // send message\n    const messageParams: Chat.MessageParams = {\n      type: dialog.type === DialogType.PRIVATE ? ChatType.CHAT : ChatType.GROUPCHAT,\n      body,\n      extension: {\n        save_to_history: 1,\n        dialog_id: dialog._id,\n      },\n    };\n    if (attachments) {\n      messageParams.extension.attachments = attachments;\n    }\n    const messageId = ConnectyCube.chat.send(\n      dialog.type === DialogType.PRIVATE ? (opponentId as number) : dialog._id,\n      messageParams,\n    );\n\n    return messageId;\n  };\n\n  const _addMessageToStore = (\n    messageId: string,\n    body: string,\n    dialogId: string,\n    senderId: number,\n    recipientId?: number,\n    attachments?: Messages.Attachment[],\n    isLoading?: boolean,\n  ) => {\n    const ts = Math.round(new Date().getTime() / 1000);\n\n    setDialogs((prevDialogs) =>\n      prevDialogs\n        .map((dialog) =>\n          dialog._id === dialogId\n            ? {\n                ...dialog,\n                last_message: body,\n                last_message_user_id: senderId,\n                last_message_date_sent: ts,\n              }\n            : dialog,\n        )\n        .sort((a, b) => {\n          const dateA = parseDate(a.last_message_date_sent) || (parseDate(a.created_at) as number);\n          const dateB = parseDate(b.last_message_date_sent) || (parseDate(b.created_at) as number);\n          return dateB - dateA;\n        }),\n    );\n\n    setMessages((prevMessages) => ({\n      ...prevMessages,\n      [dialogId]: [\n        ...(prevMessages[dialogId] || []),\n        {\n          _id: messageId,\n          created_at: ts,\n          updated_at: ts,\n          chat_dialog_id: dialogId,\n          message: body,\n          sender_id: senderId,\n          recipient_id: recipientId as any,\n          date_sent: ts,\n          read: 0,\n          read_ids: [senderId],\n          delivered_ids: [senderId],\n          views_count: 0,\n          attachments: attachments ? attachments : [],\n          reactions: {} as any,\n          isLoading,\n        },\n      ],\n    }));\n  };\n\n  const readMessage = (messageId: string, userId: number, dialogId: string) => {\n    ConnectyCube.chat.sendReadStatus({\n      messageId,\n      userId,\n      dialogId,\n    });\n\n    setMessages((prevMessages) => ({\n      ...prevMessages,\n      [dialogId]: prevMessages[dialogId].map((message) =>\n        message._id === messageId ? { ...message, read: 1 } : message,\n      ),\n    }));\n\n    setDialogs((prevDialogs) =>\n      prevDialogs.map((dialog) =>\n        dialog._id === dialogId\n          ? {\n              ...dialog,\n              unread_messages_count: Math.max(0, dialog.unread_messages_count - 1),\n            }\n          : dialog,\n      ),\n    );\n  };\n\n  const _notifyUsers = (command: string, dialogId: string, userId: number, params: any = {}) => {\n    const msg = {\n      body: command,\n      extension: {\n        dialogId,\n        ...params,\n      },\n    };\n\n    ConnectyCube.chat.sendSystemMessage(userId, msg);\n  };\n\n  const sendTypingStatus = (dialog?: Dialogs.Dialog) => {\n    dialog ??= selectedDialog;\n    if (!dialog) {\n      throw \"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.\";\n    }\n    ConnectyCube.chat.sendIsTypingStatus(\n      dialog.type === DialogType.PRIVATE ? (getDialogOpponentId(dialog) as number) : dialog._id,\n    );\n  };\n\n  const _updateTypingStatus = (dialogId: string, userId: number, isTyping: boolean) => {\n    setTypingStatus((prevTypingStatus) => {\n      const prevUsersIds = prevTypingStatus[dialogId];\n      const nextUsersIds = prevUsersIds ? new Set<number>(prevUsersIds) : new Set<number>();\n\n      if (isTyping) {\n        nextUsersIds.add(userId);\n      } else {\n        nextUsersIds.delete(userId);\n      }\n\n      return { ...prevTypingStatus, [dialogId]: [...nextUsersIds] };\n    });\n  };\n\n  const _clearTypingStatus = (dialogId: string, userId: number) => {\n    _updateTypingStatus(dialogId, userId, false);\n    clearTimeout(typingTimers.current[dialogId][userId]);\n    delete typingTimers.current[dialogId][userId];\n  };\n\n  const _getPrivateDialogIdByUserId = (userId: number): string | undefined => {\n    let dialogId: string | undefined = privateDialogsIdsRef.current[userId];\n\n    if (!dialogId) {\n      const dialog = dialogsRef.current.find(\n        (dialog) => dialog.type === DialogType.PRIVATE && getDialogOpponentId(dialog) === userId,\n      );\n\n      if (dialog) {\n        dialogId = dialog._id;\n        privateDialogsIdsRef.current[userId] = dialogId;\n      }\n    }\n\n    return dialogId;\n  };\n\n  const lastMessageSentTimeString = (dialog: Dialogs.Dialog): string => {\n    return formatDistanceToNow(\n      dialog.last_message_date_sent ? (dialog.last_message_date_sent as number) * 1000 : (dialog.created_at as string),\n      {\n        addSuffix: true,\n      },\n    );\n  };\n\n  const messageSentTimeString = (message: Messages.Message): string => {\n    return formatDistanceToNow((message.date_sent as number) * 1000, {\n      addSuffix: true,\n    });\n  };\n\n  const processOnMessage = (callbackFn: Chat.OnMessageListener | null) => {\n    onMessageRef.current = callbackFn;\n  };\n\n  const processOnMessageError = (callbackFn: Chat.OnMessageErrorListener | null) => {\n    onMessageErrorRef.current = callbackFn;\n  };\n\n  // Internet listeners\n  useEffect(() => {\n    const abortController1 = new AbortController();\n    const abortController2 = new AbortController();\n\n    window.addEventListener(\n      \"online\",\n      () => {\n        setIsOnline(true);\n      },\n      {\n        signal: abortController1.signal,\n      },\n    );\n    window.addEventListener(\n      \"offline\",\n      () => {\n        setIsOnline(false);\n        setActivatedDialogs({});\n      },\n      {\n        signal: abortController2.signal,\n      },\n    );\n\n    return () => {\n      abortController1.abort();\n      abortController2.abort();\n    };\n  }, []);\n\n  const _processDisconnect = () => {\n    setActivatedDialogs({});\n  };\n\n  const _processReconnect = () => {\n    console.log(\"[useChat] Reconnected\");\n  };\n\n  const _processMessage = (userId: number, message: Chat.Message) => {\n    // TODO: handle multi-device\n    if (userId === currentUserIdRef.current) {\n      return;\n    }\n\n    const currentDialog = selectedDialogRef.current;\n    const dialogId = message.dialog_id as string;\n    const messageId = message.id;\n    const body = message.body || \"\";\n    const opponentId = message.type === ChatType.CHAT ? (currentUserIdRef.current as number) : undefined;\n\n    const attachments =\n      message.extension.attachments?.length > 0\n        ? message.extension.attachments.map((attachment: Messages.Attachment) => ({\n            ...attachment,\n            url: ConnectyCube.storage.privateUrl(attachment.uid),\n          }))\n        : undefined;\n\n    // add message to store\n    _addMessageToStore(messageId, body, dialogId, userId, opponentId, attachments);\n    // clear typing status\n    _clearTypingStatus(dialogId, userId);\n\n    // updates chats store\n    setDialogs((prevDialogs) =>\n      prevDialogs.map((dialog) =>\n        dialog._id === dialogId\n          ? {\n              ...dialog,\n              unread_messages_count:\n                !currentDialog || currentDialog._id !== message.dialog_id\n                  ? (dialog.unread_messages_count || 0) + 1\n                  : dialog.unread_messages_count,\n              last_message: message.body,\n              last_message_date_sent: parseInt(message.extension.date_sent),\n            }\n          : dialog,\n      ),\n    );\n\n    if (onMessageRef.current) {\n      onMessageRef.current(userId, message);\n    }\n  };\n\n  const _processErrorMessage = (messageId: string, error: { code: number; info: string }) => {\n    if (onMessageErrorRef.current) {\n      onMessageErrorRef.current(messageId, error);\n    }\n  };\n\n  const _processSystemMessage = async (message: Chat.SystemMessage) => {\n    const dialogId = message.extension.dialogId;\n    const senderId = message.userId;\n\n    // TODO: handle multi-device\n    if (senderId === currentUserIdRef.current) {\n      return;\n    }\n\n    switch (message.body) {\n      // when someone created a new chat with you or added to chat\n      case GroupChatEventType.NEW_DIALOG:\n      case GroupChatEventType.ADDED_TO_DIALOG: {\n        const result = await ConnectyCube.chat.dialog.list({\n          _id: dialogId,\n        });\n        const dialog = result.items[0];\n\n        _retrieveAndStoreUsers(dialog.occupants_ids);\n\n        setDialogs((prevDialogs) => [dialog, ...prevDialogs.filter((d) => d._id !== dialog._id)]);\n\n        break;\n      }\n      // when someone added new participants to the chat\n      case GroupChatEventType.ADD_PARTICIPANTS: {\n        const usersIds = message.extension.addedParticipantsIds.split(\",\").map(Number) as number[];\n        _retrieveAndStoreUsers(usersIds);\n\n        setDialogs((prevDialogs) =>\n          prevDialogs.map((d) => {\n            if (d._id === dialogId) {\n              d.occupants_ids = Array.from(new Set([...d.occupants_ids, ...usersIds]));\n            }\n            return d;\n          }),\n        );\n        break;\n      }\n      // when someone removed participants from chat\n      case GroupChatEventType.REMOVE_PARTICIPANTS: {\n        const usersIds = message.extension.removedParticipantsIds.split(\",\").map(Number);\n\n        setDialogs((prevDialogs) =>\n          prevDialogs.map((d) => {\n            if (d._id === dialogId) {\n              d.occupants_ids = d.occupants_ids.filter((id) => !usersIds.includes(id));\n            }\n            return d;\n          }),\n        );\n        break;\n      }\n      // when other user left the chat\n      case GroupChatEventType.REMOVED_FROM_DIALOG: {\n        setDialogs((prevDialogs) =>\n          prevDialogs.map((d) => {\n            if (d._id === dialogId && d.type !== DialogType.PRIVATE) {\n              d.occupants_ids = d.occupants_ids.filter((id) => id !== senderId);\n            }\n            return d;\n          }),\n        );\n        break;\n      }\n    }\n  };\n\n  const _processReadMessageStatus = (messageId: string, dialogId: string, userId: number) => {\n    // TODO: handle multi-device\n    if (userId === currentUserIdRef.current) {\n      return;\n    }\n\n    setMessages((prevMessages) => {\n      (prevMessages[dialogId] || []).forEach((message) => {\n        if (message._id === messageId && message.read === 0) {\n          message.read = 1;\n          message.read_ids?.push(userId);\n        }\n      });\n      return prevMessages;\n    });\n  };\n\n  const _processTypingMessageStatus = (isTyping: boolean, userId: number, dialogId: string | null) => {\n    const _dialogId = dialogId || _getPrivateDialogIdByUserId(userId);\n\n    // TODO: handle multi-device\n    if (!_dialogId || !userId || userId === currentUserIdRef.current) {\n      return;\n    }\n\n    _updateTypingStatus(_dialogId, userId, isTyping);\n\n    if (!typingTimers.current[_dialogId]) {\n      typingTimers.current[_dialogId] = {};\n    }\n\n    if (isTyping) {\n      // clear previous and run new timer\n      if (typingTimers.current[_dialogId]?.[userId]) {\n        clearTimeout(typingTimers.current[_dialogId][userId]);\n        delete typingTimers.current[_dialogId][userId];\n      }\n      typingTimers.current[_dialogId][userId] = setTimeout(() => {\n        _clearTypingStatus(_dialogId, userId);\n      }, 6000);\n    } else {\n      _clearTypingStatus(_dialogId, userId);\n    }\n  };\n\n  // Chat callbacks\n  useEffect(() => {\n    ConnectyCube.chat.addListener(ChatEvent.DISCONNECTED, _processDisconnect);\n    ConnectyCube.chat.addListener(ChatEvent.RECONNECTED, _processReconnect);\n    ConnectyCube.chat.addListener(ChatEvent.MESSAGE, _processMessage);\n    ConnectyCube.chat.addListener(ChatEvent.ERROR_MESSAGE, _processErrorMessage);\n    ConnectyCube.chat.addListener(ChatEvent.SYSTEM_MESSAGE, _processSystemMessage);\n    ConnectyCube.chat.addListener(ChatEvent.READ_MESSAGE, _processReadMessageStatus);\n    ConnectyCube.chat.addListener(ChatEvent.TYPING_MESSAGE, _processTypingMessageStatus);\n\n    return () => {\n      ConnectyCube.chat.removeAllListeners();\n    };\n  }, []);\n\n  useEffect(() => {\n    _updateUnreadMessagesCount();\n  }, [dialogs]);\n\n  return (\n    <ChatContext.Provider\n      value={{\n        isOnline,\n        connect,\n        isConnected,\n        disconnect,\n        currentUserId,\n        selectDialog,\n        selectedDialog,\n        getDialogOpponentId,\n        unreadMessagesCount,\n        getMessages,\n        messages,\n        sendMessage,\n        dialogs,\n        getDialogs,\n        createChat,\n        createGroupChat,\n        sendTypingStatus,\n        typingStatus,\n        sendMessageWithAttachment,\n        markDialogAsRead,\n        removeUsersFromGroupChat,\n        addUsersToGroupChat,\n        leaveGroupChat,\n        readMessage,\n        lastMessageSentTimeString,\n        messageSentTimeString,\n        processOnMessage,\n        processOnMessageError,\n        ...chatBlockList,\n        ...chatUsers.exports,\n      }}\n    >\n      {children}\n    </ChatContext.Provider>\n  );\n};\n"],"names":["GroupChatEventType","react_1","require$$0","dist","initialState","_a","useState","state","setState","ref","useRef","useCallback","setStateAction","current","isFunction","minutesInMonth","constructFromSymbol","Symbol","for","constructFrom","date","value","Date","constructor","toDate","argument","context","defaultOptions","getDefaultOptions","getTimezoneOffsetInMilliseconds","_date","utcDate","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","setUTCFullYear","normalizeDates","dates","normalize","bind","find","map","compareAsc","dateLeft","dateRight","diff","isLastDayOfMonth","options","setHours","endOfDay","month","setFullYear","endOfMonth","differenceInMonths","laterDate","earlierDate","laterDate_","workingLaterDate","earlierDate_","in","sign","difference","Math","abs","differenceInCalendarMonths","setDate","setMonth","isLastMonthNotFull","result","differenceInSeconds","differenceInMilliseconds","method","roundingMethod","number","trunc","formatDistanceLocale","lessThanXSeconds","one","other","xSeconds","halfAMinute","lessThanXMinutes","xMinutes","aboutXHours","xHours","xDays","aboutXWeeks","xWeeks","aboutXMonths","xMonths","aboutXYears","xYears","overXYears","almostXYears","buildFormatLongFn","args","width","String","defaultWidth","formats","formatLong","full","long","medium","short","time","dateTime","formatRelativeLocale","lastWeek","yesterday","today","tomorrow","nextWeek","buildLocalizeFn","valuesArray","formattingValues","defaultFormattingWidth","values","argumentCallback","buildMatchFn","string","matchPattern","matchPatterns","defaultMatchWidth","matchResult","match","matchedString","parsePatterns","defaultParseWidth","key","Array","isArray","array","predicate","length","findIndex","pattern","test","object","Object","prototype","hasOwnProperty","call","findKey","valueCallback","rest","slice","enUS","code","formatDistance","token","count","tokenValue","replace","toString","addSuffix","comparison","formatRelative","_baseDate","_options","localize","ordinalNumber","dirtyNumber","Number","rem100","era","narrow","abbreviated","wide","quarter","day","dayPeriod","am","pm","midnight","noon","morning","afternoon","evening","night","parsePattern","parseInt","parseResult","any","index","weekStartsOn","firstWeekContainsDate","formatDistanceToNow","locale","defaultLocale","isNaN","RangeError","localizeOptions","assign","seconds","offsetInSeconds","minutes","round","months","includeSeconds","hours","days","nearestMonth","monthsSinceStartOfYear","years","now","constructNow","BLOCK_LIST_LOG_TAG","BLOCK_LIST_NAME","useBlockList","isConnected","Set","isApplied","isBlocked","userId","has","upsert","async","user_id","action","console","warn","newState","blockList","name","items","mutualBlock","PrivacyListAction","DENY","add","ALLOW","delete","ConnectyCube","chat","privacylist","setAsDefault","update","size","create","error","useEffect","getNames","default","getList","reduce","list","item","fetch","blockedUsers","from","isBlockedUser","unblockUser","blockUser","parseDate","t","getTime","undefined","getLastActivityText","status","MINUTE_IN_SEC","ceil","lastLoggedInTime","getUTCDate","padStart","USERS_LOG_TAG","MAX_REQUEST_LIMIT","useUsers","currentUserId","users","setUsers","usersRef","useStateRef","onlineUsers","setOnlineUsers","onlineUsersCount","setOnlineUsersCount","lastActivity","setLastActivity","onlineUsersLastRequestAtRef","searchUsers","term","usersWithFullName","getV2","full_name","start_with","limit","usersWithLogin","login","usersMap","Map","forEach","user","set","id","filter","getOnlineUsersCount","nextOnlineUsersCount","getOnlineCount","addListener","ChatEvent","USER_LAST_ACTIVITY","prevLastActivity","removeListener","_retrieveAndStoreUsers","usersIds","usersToFind","params","nextUsersState","exports","listOnlineUsers","force","lastRequestedAt","currentTimestamp","onlineUsersState","promises","offset","push","listOnline","then","Promise","all","flat","_listOnline","listOnlineUsersWithParams","allUsers","getLastActivity","getLastUserActivity","subscribeToUserLastActivityStatus","unsubscribeFromUserLastActivityStatus","ChatContext","createContext","displayName","children","isOnline","setIsOnline","navigator","onLine","setIsConnected","unreadMessagesCount","setUnreadMessagesCount","total","messages","setMessages","typingStatus","setTypingStatus","activatedDialogs","setActivatedDialogs","typingTimers","onMessageRef","onMessageErrorRef","privateDialogsIdsRef","dialogs","setDialogs","dialogsRef","setCurrentUserId","currentUserIdRef","selectedDialog","setSelectedDialog","selectedDialogRef","chatBlockList","chatUsers","getMessages","dialogId","chat_dialog_id","sort_desc","skip","retrievedMessages","message","sort","a","b","_id","localeCompare","msg","attachments","attachment","url","storage","privateUrl","uid","prevMessages","getDialogOpponentId","dialog","type","DialogType","PRIVATE","opponentId","occupants_ids","oId","markDialogAsRead","read","prevDialogs","d","unread_messages_count","_sendMessage","body","messageParams","ChatType","CHAT","GROUPCHAT","extension","save_to_history","dialog_id","send","_addMessageToStore","messageId","senderId","recipientId","isLoading","ts","last_message","last_message_user_id","last_message_date_sent","dateA","created_at","updated_at","sender_id","recipient_id","date_sent","read_ids","delivered_ids","views_count","reactions","_notifyUsers","command","sendSystemMessage","_updateTypingStatus","isTyping","prevTypingStatus","prevUsersIds","nextUsersIds","_clearTypingStatus","clearTimeout","abortController1","AbortController","abortController2","window","addEventListener","signal","abort","_processDisconnect","_processReconnect","log","_processMessage","currentDialog","_processErrorMessage","_processSystemMessage","NEW_DIALOG","ADDED_TO_DIALOG","ADD_PARTICIPANTS","addedParticipantsIds","split","REMOVE_PARTICIPANTS","removedParticipantsIds","includes","REMOVED_FROM_DIALOG","_processReadMessageStatus","_processTypingMessageStatus","_dialogId","_getPrivateDialogIdByUserId","setTimeout","DISCONNECTED","RECONNECTED","MESSAGE","ERROR_MESSAGE","SYSTEM_MESSAGE","READ_MESSAGE","TYPING_MESSAGE","removeAllListeners","_updateUnreadMessagesCount","_jsx","Provider","connect","credentials","_isConnected","disconnect","selectDialog","catch","_error","sendMessage","getDialogs","filters","fetchedDialogs","allDialogs","uniqueDialogsMap","flatMap","createChat","extensions","createGroupChat","photo","GROUP","sendTypingStatus","sendIsTypingStatus","sendMessageWithAttachment","files","tempId","file","URL","createObjectURL","uploadFilesPromises","fileParams","public","createAndUpload","uploadedAttachments","content_type","removeUsersFromGroupChat","Error","toUpdateParams","pull_all","join","updatedDialog","addUsersToGroupChat","push_all","leaveGroupChat","readMessage","sendReadStatus","max","lastMessageSentTimeString","messageSentTimeString","processOnMessage","callbackFn","processOnMessageError","useContext"],"mappings":"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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]}