{"version":3,"file":"index-iGClY3ec.cjs","sources":["../src/utils/light/index.ts","../src/HassConnect/createDateFormatters.ts","../src/HassConnect/callApi.ts","../src/HassConnect/HassContext.tsx","../src/hooks/useHass/index.ts","../src/hooks/useLocale/index.ts","../src/utils/computeDomainTitle.ts","../src/utils/entity.ts","../src/utils/entity_registry.ts","../src/utils/computeAttributeDisplay.ts","../src/utils/computeStateDisplay.ts","../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.development.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/index.js","../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","../../../node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js","../../../node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js","../../../node_modules/@emotion/react/jsx-runtime/dist/emotion-react-jsx-runtime.browser.esm.js","../../../node_modules/zustand/esm/vanilla/shallow.mjs","../../../node_modules/zustand/esm/react/shallow.mjs","../src/HassConnect/Provider.tsx","../src/hooks/useConfig/index.ts","../src/utils/subscribe/devices.ts","../src/HassConnect/FetchLocale/index.tsx","../src/HassConnect/index.tsx"],"sourcesContent":["import { type HassEntityWithService, type LightColorMode, type LightColor, temperature2rgb } from \"@core\";\nimport { LIGHT_COLOR_MODES } from \"../../types/autogenerated-types-by-domain\";\n\nconst modesSupportingColor: LightColorMode[] = [\n  LIGHT_COLOR_MODES.HS,\n  LIGHT_COLOR_MODES.XY,\n  LIGHT_COLOR_MODES.RGB,\n  LIGHT_COLOR_MODES.RGBW,\n  LIGHT_COLOR_MODES.RGBWW,\n];\n\nconst modesSupportingBrightness: LightColorMode[] = [\n  ...modesSupportingColor,\n  LIGHT_COLOR_MODES.COLOR_TEMP,\n  LIGHT_COLOR_MODES.BRIGHTNESS,\n  LIGHT_COLOR_MODES.WHITE,\n];\n\nexport const lightSupportsColorMode = (entity: HassEntityWithService<\"light\">, mode: LightColorMode) =>\n  entity.attributes.supported_color_modes?.includes(mode) || false;\n\nexport const lightIsInColorMode = (entity: HassEntityWithService<\"light\">) =>\n  (entity.attributes.color_mode && modesSupportingColor.includes(entity.attributes.color_mode)) || false;\n\nexport const lightSupportsColor = (entity: HassEntityWithService<\"light\">) =>\n  entity.attributes.supported_color_modes?.some((mode) => modesSupportingColor.includes(mode)) || false;\n\nexport const lightSupportsBrightness = (entity: HassEntityWithService<\"light\">) =>\n  entity.attributes.supported_color_modes?.some((mode) => modesSupportingBrightness.includes(mode)) || false;\n\nexport const lightSupportsFavoriteColors = (entity: HassEntityWithService<\"light\">) =>\n  lightSupportsColor(entity) || lightSupportsColorMode(entity, LIGHT_COLOR_MODES.COLOR_TEMP);\n\nexport const getLightCurrentModeRgbColor = (entity: HassEntityWithService<\"light\">): number[] | undefined =>\n  entity.attributes.color_mode === LIGHT_COLOR_MODES.RGBWW\n    ? entity.attributes.rgbww_color\n    : entity.attributes.color_mode === LIGHT_COLOR_MODES.RGBW\n      ? entity.attributes.rgbw_color\n      : entity.attributes.rgb_color;\n\nconst COLOR_TEMP_COUNT = 4;\nconst DEFAULT_COLORED_COLORS = [\n  { rgb_color: [127, 172, 255] }, // blue #7FACFF\n  { rgb_color: [215, 150, 255] }, // purple #D796FF\n  { rgb_color: [255, 158, 243] }, // pink #FF9EF3\n  { rgb_color: [255, 110, 84] }, // red #FF6E54\n] as LightColor[];\n\nexport const computeDefaultFavoriteColors = (stateObj: HassEntityWithService<\"light\">): LightColor[] => {\n  const colors: LightColor[] = [];\n\n  const supportsColorTemp = lightSupportsColorMode(stateObj, LIGHT_COLOR_MODES.COLOR_TEMP);\n\n  const supportsColor = lightSupportsColor(stateObj);\n\n  if (supportsColorTemp) {\n    const min = stateObj.attributes.min_color_temp_kelvin!;\n    const max = stateObj.attributes.max_color_temp_kelvin!;\n    const step = (max - min) / (COLOR_TEMP_COUNT - 1);\n\n    for (let i = 0; i < COLOR_TEMP_COUNT; i++) {\n      colors.push({\n        color_temp_kelvin: Math.round(min + step * i),\n      });\n    }\n  } else if (supportsColor) {\n    const min = 2000;\n    const max = 6500;\n    const step = (max - min) / (COLOR_TEMP_COUNT - 1);\n\n    for (let i = 0; i < COLOR_TEMP_COUNT; i++) {\n      colors.push({\n        rgb_color: temperature2rgb(Math.round(min + step * i)),\n      });\n    }\n  }\n\n  if (supportsColor) {\n    colors.push(...DEFAULT_COLORED_COLORS);\n  }\n\n  return colors;\n};\n","import { useInternalStore } from \"./HassContext\";\nimport {\n  formatDate,\n  formatTime,\n  formatDateTime,\n  formatDateTimeWithSeconds,\n  formatShortDateTime,\n  formatShortDateTimeWithYear,\n  formatShortDateTimeWithConditionalYear,\n  formatDateTimeWithBrowserDefaults,\n  formatDateTimeNumeric,\n  formatDateWeekdayDay,\n  formatDateShort,\n  formatDateVeryShort,\n  formatDateMonthYear,\n  formatDateMonth,\n  formatDateYear,\n  formatDateWeekday,\n  formatDateWeekdayShort,\n  formatDateNumeric,\n  formatTimeWithoutAmPm,\n  formatAmPmSuffix,\n  formatHour,\n  formatMinute,\n  formatSeconds,\n} from \"@core\";\n\n/**\n * A collection of all supported date/time formatting helpers exposed via the Hass formatter API.\n * Each method accepts either a Date object or an ISO/string parseable by the Date constructor.\n * All helpers automatically read `locale` and `config` from the internal store on every call so\n * they stay reactive to user preference changes without needing recreation.\n * If required data (locale or config) is not yet available, they fall back to a browser default\n * formatter (`formatDateTimeWithBrowserDefaults`).\n */\nexport interface DateFormatters {\n  /** Long date (e.g. \"August 9, 2025\") */\n  formatDate(date: Date | string): string;\n  /** Time respecting 12/24 preference (e.g. \"8:23 AM\" or \"08:23\") */\n  formatTime(date: Date | string): string;\n  /** Time without AM/PM regardless of user preference is set to 12 or 24 hours */\n  formatTimeWithoutAmPm(date: Date | string): string;\n  /** Hour numeric only respecting 12/24 preference (no suffix, e.g. \"5\" or \"17\") */\n  formatHour(date: Date | string): string;\n  /** Localized AM/PM (day period) suffix irrespective of user 24h preference */\n  formatAmPmSuffix(date: Date | string): string;\n  /** Minute numeric only (e.g. \"07\") */\n  formatMinute(date: Date | string): string;\n  /** Seconds numeric only (e.g. \"09\") */\n  formatSeconds(date: Date | string): string;\n  /** Long date & time without seconds (e.g. \"August 9, 2025, 8:23 AM\") */\n  formatDateTime(date: Date | string): string;\n  /** Long date & time with seconds (e.g. \"August 9, 2025, 8:23:15 AM\") */\n  formatDateTimeWithSeconds(date: Date | string): string;\n  /** Short date & time without year if current year (e.g. \"Aug 9, 8:23 AM\") */\n  formatShortDateTime(date: Date | string): string;\n  /** Short date & time with year (e.g. \"Aug 9, 2025, 8:23 AM\") */\n  formatShortDateTimeWithYear(date: Date | string): string;\n  /** Short date & time with conditional year (omits year if current) */\n  formatShortDateTimeWithConditionalYear(date: Date | string): string;\n  /** Browser default date & time fallback (locale/config independent) */\n  formatDateTimeWithBrowserDefaults(date: Date | string): string;\n  /** Numeric date & time (e.g. \"9/8/2025, 8:23 AM\") honoring locale ordering */\n  formatDateTimeNumeric(date: Date | string): string;\n  /** Weekday + Month + Day (e.g. \"Tuesday, August 10\") */\n  formatDateWeekdayDay(date: Date | string): string;\n  /** Short date (e.g. \"Aug 10, 2025\") */\n  formatDateShort(date: Date | string): string;\n  /** Very short date (e.g. \"Aug 10\") */\n  formatDateVeryShort(date: Date | string): string;\n  /** Month + Year (e.g. \"August 2025\") */\n  formatDateMonthYear(date: Date | string): string;\n  /** Month name (e.g. \"August\") */\n  formatDateMonth(date: Date | string): string;\n  /** Year (e.g. \"2025\") */\n  formatDateYear(date: Date | string): string;\n  /** Weekday long (e.g. \"Monday\") */\n  formatDateWeekday(date: Date | string): string;\n  /** Weekday short (e.g. \"Mon\") */\n  formatDateWeekdayShort(date: Date | string): string;\n  /** Numeric date honoring user ordering preference (e.g. DMY -> 10/08/2025) */\n  formatDateNumeric(date: Date | string): string;\n}\n\n/**\n * Safely coerce an incoming value to a Date instance. If construction fails, still pass the\n * resulting Date (which will be invalid) to downstream formatters which will then fall back.\n */\nfunction toDate(date: Date | string): Date {\n  return typeof date === \"string\" ? new Date(date) : date;\n}\n\n/**\n * Create the suite of date formatting helpers bound to the current internal store state.\n * They query `useInternalStore().getState()` at call time so preference updates are reflected\n * immediately without needing to recreate the formatter object.\n */\nexport function createDateFormatters(): DateFormatters {\n  const fallback = (d: Date) => formatDateTimeWithBrowserDefaults(d);\n  const getCtx = () => useInternalStore.getState();\n\n  /** Long date (e.g. \"August 9, 2025\") */\n  const formatDateWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDate(d, config, locale);\n  };\n  /** Time respecting 12/24 preference */\n  const formatTimeWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatTime(d, config, locale);\n  };\n  /** Time without AM/PM */\n  const formatTimeWithoutAmPmWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) {\n      // simple 24h fallback\n      return `${d.getHours().toString().padStart(2, \"0\")}:${d.getMinutes().toString().padStart(2, \"0\")}`;\n    }\n    return formatTimeWithoutAmPm(d, config, locale);\n  };\n  /** Hour only respecting 12/24 preference */\n  const formatHourWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) {\n      // Fallback: 24h hour without suffix\n      return d.getHours().toString().padStart(2, \"0\");\n    }\n    return formatHour(d, config, locale);\n  };\n  /** AM/PM suffix only */\n  const formatAmPmSuffixWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return d.getHours() >= 12 ? \"PM\" : \"AM\";\n    return formatAmPmSuffix(d, locale, config);\n  };\n  /** Minute only */\n  const formatMinuteWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return d.getMinutes().toString().padStart(2, \"0\");\n    return formatMinute(d, config, locale);\n  };\n  /** Seconds only */\n  const formatSecondsWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return d.getSeconds().toString().padStart(2, \"0\");\n    return formatSeconds(d, config, locale);\n  };\n  /** Long date & time without seconds */\n  const formatDateTimeWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateTime(d, config, locale);\n  };\n  /** Long date & time with seconds */\n  const formatDateTimeWithSecondsWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateTimeWithSeconds(d, locale, config);\n  };\n  /** Short date & time without year if current year */\n  const formatShortDateTimeWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatShortDateTime(d, locale, config);\n  };\n  /** Short date & time with year */\n  const formatShortDateTimeWithYearWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatShortDateTimeWithYear(d, locale, config);\n  };\n  /** Short date & time with conditional year */\n  const formatShortDateTimeWithConditionalYearWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatShortDateTimeWithConditionalYear(d, locale, config);\n  };\n  /** Browser default date & time fallback */\n  const formatDateTimeWithBrowserDefaultsWrapper = (value: Date | string) => {\n    return formatDateTimeWithBrowserDefaults(toDate(value));\n  };\n  /** Numeric date & time honoring locale ordering */\n  const formatDateTimeNumericWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateTimeNumeric(d, locale, config);\n  };\n  /** Weekday + Month + Day */\n  const formatDateWeekdayDayWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateWeekdayDay(d, locale, config);\n  };\n  /** Short date */\n  const formatDateShortWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateShort(d, locale, config);\n  };\n  /** Very short date */\n  const formatDateVeryShortWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateVeryShort(d, locale, config);\n  };\n  /** Month + Year */\n  const formatDateMonthYearWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateMonthYear(d, locale, config);\n  };\n  /** Month name */\n  const formatDateMonthWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateMonth(d, locale, config);\n  };\n  /** Year */\n  const formatDateYearWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateYear(d, locale, config);\n  };\n  /** Weekday long */\n  const formatDateWeekdayWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateWeekday(d, locale, config);\n  };\n  /** Weekday short */\n  const formatDateWeekdayShortWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateWeekdayShort(d, locale, config);\n  };\n  /** Numeric date honoring user ordering preference */\n  const formatDateNumericWrapper = (value: Date | string) => {\n    const d = toDate(value);\n    const { locale, config } = getCtx();\n    if (!locale || !config) return fallback(d);\n    return formatDateNumeric(d, locale, config);\n  };\n\n  return {\n    formatDate: formatDateWrapper,\n    formatTime: formatTimeWrapper,\n    formatTimeWithoutAmPm: formatTimeWithoutAmPmWrapper,\n    formatHour: formatHourWrapper,\n    formatAmPmSuffix: formatAmPmSuffixWrapper,\n    formatMinute: formatMinuteWrapper,\n    formatSeconds: formatSecondsWrapper,\n    formatDateTime: formatDateTimeWrapper,\n    formatDateTimeWithSeconds: formatDateTimeWithSecondsWrapper,\n    formatShortDateTime: formatShortDateTimeWrapper,\n    formatShortDateTimeWithYear: formatShortDateTimeWithYearWrapper,\n    formatShortDateTimeWithConditionalYear: formatShortDateTimeWithConditionalYearWrapper,\n    formatDateTimeWithBrowserDefaults: formatDateTimeWithBrowserDefaultsWrapper,\n    formatDateTimeNumeric: formatDateTimeNumericWrapper,\n    formatDateWeekdayDay: formatDateWeekdayDayWrapper,\n    formatDateShort: formatDateShortWrapper,\n    formatDateVeryShort: formatDateVeryShortWrapper,\n    formatDateMonthYear: formatDateMonthYearWrapper,\n    formatDateMonth: formatDateMonthWrapper,\n    formatDateYear: formatDateYearWrapper,\n    formatDateWeekday: formatDateWeekdayWrapper,\n    formatDateWeekdayShort: formatDateWeekdayShortWrapper,\n    formatDateNumeric: formatDateNumericWrapper,\n  };\n}\n","import { useInternalStore } from \"./HassContext\";\n\nexport async function callApi<T>(\n  endpoint: string,\n  options?: RequestInit,\n): Promise<\n  | {\n      data: T;\n      status: \"success\";\n    }\n  | {\n      data: string;\n      status: \"error\";\n    }\n> {\n  try {\n    const { connection, hassUrl } = useInternalStore.getState();\n    const response = await fetch(`${hassUrl}/api${endpoint}`, {\n      method: \"GET\",\n      ...(options ?? {}),\n      headers: {\n        Authorization: \"Bearer \" + connection?.options.auth?.accessToken,\n        \"Content-type\": \"application/json;charset=UTF-8\",\n        ...(options?.headers ?? {}),\n      },\n    });\n    if (response.status === 200) {\n      const data = await response.json();\n      return {\n        status: \"success\",\n        data,\n      };\n    }\n    return {\n      status: \"error\",\n      data: response.statusText,\n    };\n  } catch (e) {\n    console.error(\"API Error:\", e);\n    return {\n      status: \"error\",\n      data: `API Request failed for endpoint \"${endpoint}\", follow instructions here: https://shannonhochkins.github.io/ha-component-kit/?path=/docs/core-hooks-usehass-hass-callapi--docs.`,\n    };\n  }\n}\n","// types\nimport type { Connection, HassEntities, HassEntity, HassConfig, HassServices, Auth } from \"home-assistant-js-websocket\";\nimport { type CSSInterpolation } from \"@emotion/serialize\";\nimport { ServiceData, SnakeOrCamelDomains, DomainService, Target, LocaleKeys, ServiceResponse } from \"@typings\";\nimport { create } from \"zustand\";\nimport { type ConnectionStatus } from \"./handleSuspendResume\";\nimport {\n  AreaRegistryEntry,\n  AuthUser,\n  computeAttributeValueDisplay,\n  computeStateDisplay,\n  DeviceRegistryEntry,\n  EntityRegistryDisplayEntry,\n  FloorRegistryEntry,\n  FrontendLocaleData,\n  resolveTimeZone,\n  shouldUseAmPm,\n} from \"@core\";\nimport { createDateFormatters, DateFormatters } from \"./createDateFormatters\";\nimport { isArray, snakeCase } from \"lodash\";\nimport { callService as _callService } from \"home-assistant-js-websocket\";\nimport { callApi } from \"./callApi\";\nimport { CurrentUser } from \"@utils/subscribe/user\";\nexport interface CallServiceArgs<T extends SnakeOrCamelDomains, M extends DomainService<T>, R extends boolean> {\n  domain: T;\n  service: M;\n  serviceData?: ServiceData<T, M>;\n  target?: Target;\n  returnResponse?: R;\n}\n\nexport interface Route {\n  hash: string;\n  name: string;\n  icon: string;\n  active: boolean;\n}\n\nexport interface SensorNumericDeviceClasses {\n  numeric_device_classes: string[];\n}\n\nexport type SupportedComponentOverrides =\n  | \"buttonCard\"\n  | \"modal\"\n  | \"areaCard\"\n  | \"calendarCard\"\n  | \"climateCard\"\n  | \"cameraCard\"\n  | \"entitiesCard\"\n  | \"fabCard\"\n  | \"cardBase\"\n  | \"garbageCollectionCard\"\n  | \"mediaPlayerCard\"\n  | \"pictureCard\"\n  | \"sensorCard\"\n  | \"timeCard\"\n  | \"triggerCard\"\n  | \"weatherCard\"\n  | \"menu\"\n  | \"personCard\"\n  | \"familyCard\"\n  | \"vacuumCard\"\n  | \"alarmCard\";\nexport interface InternalStore {\n  sensorNumericDeviceClasses: string[];\n  setSensorNumericDeviceClasses: (classes: string[]) => void;\n  /** home assistant instance locale data */\n  locale: FrontendLocaleData | null;\n  setLocale: (locale: FrontendLocaleData | null) => void;\n  /** the device registry from home assistant */\n  devices: Record<string, DeviceRegistryEntry>;\n  setDevices: (devices: Record<string, DeviceRegistryEntry>) => void;\n  /** the entity registry display from home assistant */\n  entitiesRegistryDisplay: Record<string, EntityRegistryDisplayEntry>;\n  setEntitiesRegistryDisplay: (entities: Record<string, EntityRegistryDisplayEntry>) => void;\n  /** the area registry from home assistant */\n  areas: Record<string, AreaRegistryEntry>;\n  setAreas: (areas: Record<string, AreaRegistryEntry>) => void;\n  /** the floor registry from home assistant */\n  floors: Record<string, FloorRegistryEntry>;\n  setFloors: (floors: Record<string, FloorRegistryEntry>) => void;\n  /** The entities in the home assistant instance */\n  entities: HassEntities;\n  setEntities: (entities: HassEntities) => void;\n  /** the home assistant services data */\n  services: HassServices;\n  setServices: (services: HassServices) => void;\n  /** the connection status of your home assistant instance */\n  connectionStatus: ConnectionStatus;\n  setConnectionStatus: (status: ConnectionStatus) => void;\n  /** The connection object from home-assistant-js-websocket */\n  connection: Connection | null;\n  setConnection: (connection: Connection | null) => void;\n  /** any errors caught during core authentication */\n  error: null | string;\n  setError: (error: string | null) => void;\n  /** if there was an issue connecting to HA */\n  cannotConnect: boolean;\n  setCannotConnect: (cannotConnect: boolean) => void;\n  /** This is an internal value, no need to use this */\n  ready: boolean;\n  setReady: (ready: boolean) => void;\n  /** the current hash in the url */\n  hash: string;\n  /** set the current hash */\n  setHash: (hash: string) => void;\n  /** returns available routes */\n  routes: Route[];\n  setRoutes: (routes: Route[]) => void;\n  /** the home assistant authentication object */\n  auth: Auth | null;\n  setAuth: (auth: Auth | null) => void;\n  /** the current authenticated user */\n  user: CurrentUser | null;\n  setUser: (user: CurrentUser | null) => void;\n  /** all users in the home assistant instance */\n  users: AuthUser[];\n  setUsers: (users: AuthUser[]) => void;\n  /** the home assistant configuration */\n  config: HassConfig | null;\n  setConfig: (config: HassConfig | null) => void;\n  /** the hassUrl provided to the HassConnect component */\n  hassUrl: string | null;\n  /** set the hassUrl */\n  setHassUrl: (hassUrl: string | null) => void;\n  /** a way to provide or overwrite default styles for any particular component */\n  setGlobalComponentStyles: (styles: Partial<Record<SupportedComponentOverrides, CSSInterpolation>>) => void;\n  globalComponentStyles: Partial<Record<SupportedComponentOverrides, CSSInterpolation>>;\n  portalRoot?: HTMLElement;\n  setPortalRoot: (portalRoot: HTMLElement) => void;\n  locales: Record<LocaleKeys, string> | null;\n  setLocales: (locales: Record<LocaleKeys, string>) => void;\n  // used by some features to change which window context to use\n  setWindowContext: (windowContext: Window) => void;\n  windowContext: Window;\n  /** internal - callbacks that will fire when the connection disconnects with home assistant */\n  disconnectCallbacks: (() => void)[];\n  /** use this to trigger certain functionality when the web socket connection disconnects */\n  onDisconnect?: (cb: () => void) => void;\n  /** internal function which will trigger when the connection disconnects */\n  triggerOnDisconnect: () => void;\n  /** convenience helpers to format specific entity attributes, values, dates etc */\n  formatter: {\n    /** will format the state value automatically based on the entity provided */\n    stateValue: (entity: HassEntity) => string;\n    /** will format the attribute value automatically based on the entity and attribute provided */\n    attributeValue: (entity: HassEntity, attribute: string) => string;\n  } & DateFormatters;\n  helpers: {\n    /** logout of HA */\n    logout: () => void;\n    /** function to call a service through web sockets */\n    callService: {\n      <ResponseType extends object, T extends SnakeOrCamelDomains, M extends DomainService<T>>(\n        args: CallServiceArgs<T, M, true>,\n      ): Promise<ServiceResponse<ResponseType>>;\n\n      /** Overload for when `returnResponse` is false */\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      <_ResponseType extends object, T extends SnakeOrCamelDomains, M extends DomainService<T>>(args: CallServiceArgs<T, M, false>): void;\n\n      /** Overload for when `returnResponse` is omitted (defaults to false) */\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      <_ResponseType extends object, T extends SnakeOrCamelDomains, M extends DomainService<T>>(\n        args: Omit<CallServiceArgs<T, M, false>, \"returnResponse\">,\n      ): void;\n    };\n    /** add a new route to the provider */\n    addRoute: (route: Omit<Route, \"active\">) => void;\n    /** retrieve a route by name */\n    getRoute: (hash: string) => Route | null;\n    /** will retrieve all HassEntities from the context */\n    getAllEntities: () => HassEntities;\n    /** join a path to the hassUrl */\n    joinHassUrl: (path: string) => string;\n    /** call the home assistant api */\n    callApi: <T>(\n      endpoint: string,\n      options?: RequestInit,\n    ) => Promise<\n      | {\n          data: T;\n          status: \"success\";\n        }\n      | {\n          data: string;\n          status: \"error\";\n        }\n    >;\n    /** date time related helper functions */\n    dateTime: {\n      /** determine if the current locale/timezone should use am/pm time format */\n      shouldUseAmPm: () => boolean;\n      /** resolve the correct timezone to use based on locale and config */\n      getTimeZone: () => string;\n    };\n  };\n}\n\n// ignore some keys that we don't actually care about when comparing entities\nconst shallowEqual = (entity: HassEntity, other: HassEntity): boolean => {\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  const { last_changed, last_updated, context, ...restEntity } = entity;\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  const { last_changed: c1, last_updated: c2, context: c3, ...restOther } = other;\n\n  return JSON.stringify(restEntity) === JSON.stringify(restOther);\n};\n\n// Store dedicated to provider-level connection/session bookkeeping (authentication state and active websocket subscriptions)\nexport interface HassProviderStore {\n  /** whether we've successfully initiated an auth/connect attempt for current hassUrl */\n  authenticated: boolean;\n  /** set authenticated flag */\n  setAuthenticated: (value: boolean) => void;\n  /** active unsubscribe functions keyed by a descriptive name */\n  subscriptions: Record<string, UnsubscribeFunc>;\n  /** register (or replace) a subscription; will auto-unsubscribe previous key before storing */\n  addSubscription: (key: string, fn: UnsubscribeFunc | null | undefined) => void;\n  /** remove a subscription by key and call its unsubscribe */\n  removeSubscription: (key: string) => void;\n  /** unsubscribe every tracked subscription and clear map */\n  unsubscribeAll: () => void;\n  /** resets the information on the internal store */\n  reset: () => void;\n}\n\n// We import the type from home-assistant-js-websocket here to avoid circular imports elsewhere\nimport type { UnsubscribeFunc } from \"home-assistant-js-websocket\";\nimport { clearTokens } from \"./token-storage\";\n\nexport const useInternalStore = create<InternalStore>((set, get) => ({\n  sensorNumericDeviceClasses: [],\n  setSensorNumericDeviceClasses: (classes: string[]) => set({ sensorNumericDeviceClasses: classes }),\n  locale: null,\n  setLocale: (locale) => set({ locale }),\n  routes: [],\n  setRoutes: (routes) => set(() => ({ routes })),\n  entities: {},\n  devices: {},\n  setDevices: (devices) => set(() => ({ devices })),\n  entitiesRegistryDisplay: {},\n  setEntitiesRegistryDisplay: (entities) => set(() => ({ entitiesRegistryDisplay: entities })),\n  areas: {},\n  setAreas: (areas) => set(() => ({ areas })),\n  floors: {},\n  services: {},\n  setServices: (services: HassServices) => set(() => ({ services })),\n  setFloors: (floors) => set(() => ({ floors })),\n  setHassUrl: (hassUrl) => set({ hassUrl }),\n  hassUrl: null,\n  hash: \"\",\n  locales: null,\n  setLocales: (locales) => set({ locales }),\n  setHash: (hash) => set({ hash }),\n  setPortalRoot: (portalRoot) => set({ portalRoot }),\n  windowContext: window,\n  setWindowContext: (windowContext) => set({ windowContext }),\n  setEntities: (newEntities) =>\n    set((state) => {\n      let changed = false;\n      const next = { ...state.entities };\n      for (const [id, newEnt] of Object.entries(newEntities)) {\n        const oldEnt = state.entities[id];\n\n        // ---- fast path: first time we ever see this ID ----\n        if (!oldEnt) {\n          next[id] = newEnt;\n          changed = true;\n          continue;\n        }\n\n        if (!shallowEqual(oldEnt, newEnt)) {\n          next[id] = newEnt; // replace only if meaningful props differ\n          changed = true;\n        }\n      }\n      return changed ? { entities: next, lastUpdated: Date.now(), ready: true } : state;\n    }),\n  connectionStatus: \"pending\",\n  setConnectionStatus: (status) => set({ connectionStatus: status }),\n  connection: null,\n  setConnection: (connection) => set({ connection }),\n  cannotConnect: false,\n  setCannotConnect: (cannotConnect) => set({ cannotConnect }),\n  ready: false,\n  setReady: (ready) => set({ ready }),\n  auth: null,\n  setAuth: (auth) => set({ auth }),\n  config: null,\n  setConfig: (config) => set({ config }),\n  user: null,\n  setUser: (user) => set({ user }),\n  users: [],\n  setUsers: (users) => set({ users }),\n  error: null,\n  setError: (error) => set({ error }),\n  globalComponentStyles: {},\n  setGlobalComponentStyles: (styles) => set(() => ({ globalComponentStyles: styles })),\n  disconnectCallbacks: [],\n  onDisconnect: (cb) => set((state) => ({ disconnectCallbacks: [...state.disconnectCallbacks, cb] })),\n  triggerOnDisconnect: () =>\n    set((state) => {\n      state.disconnectCallbacks.forEach((cb) => cb());\n      return { disconnectCallbacks: [] };\n    }),\n  helpers: {\n    logout() {\n      const { reset } = useHassProviderStore.getState();\n      const { setError } = get();\n      try {\n        reset();\n        clearTokens();\n        if (location) location.reload();\n      } catch (err: unknown) {\n        console.error(\"Error:\", err);\n        setError(\"Unable to log out!\");\n      }\n    },\n    callService: (<ResponseType extends object, T extends SnakeOrCamelDomains, M extends DomainService<T>>(\n      rawArgs: CallServiceArgs<T, M, boolean>,\n    ): Promise<ServiceResponse<ResponseType>> | void => {\n      const { domain, service, serviceData, target: _target, returnResponse } = rawArgs;\n      const { connection, ready } = get();\n      const target = typeof _target === \"string\" || isArray(_target) ? { entity_id: _target } : _target;\n\n      // basic guards\n      if (!connection || !ready) {\n        if (returnResponse) {\n          return Promise.reject(new Error(\"callService: connection not established or not ready\"));\n        }\n        return; // fire & forget path does nothing when not ready\n      }\n\n      try {\n        const result = _callService(connection, snakeCase(domain), snakeCase(service), serviceData ?? {}, target, returnResponse);\n        return returnResponse ? (result as Promise<ServiceResponse<ResponseType>>) : undefined; // fire & forget\n      } catch (e) {\n        console.error(\"Error calling service:\", e);\n        return returnResponse ? Promise.reject(e) : undefined;\n      }\n    }) as InternalStore[\"helpers\"][\"callService\"],\n    addRoute(route) {\n      const { routes, setRoutes } = get();\n      const exists = routes.find((r) => r.hash === route.hash);\n      if (!exists) {\n        const hashWithoutPound = typeof window !== \"undefined\" ? window.location.hash.replace(\"#\", \"\") : \"\";\n        const active = hashWithoutPound !== \"\" && hashWithoutPound === route.hash;\n        setRoutes([...routes, { ...route, active } satisfies Route]);\n      }\n    },\n    getRoute(hash) {\n      const { routes } = get();\n      return routes.find((r) => r.hash === hash) || null;\n    },\n    getAllEntities() {\n      return get().entities;\n    },\n    joinHassUrl(path: string) {\n      const { connection } = get();\n      return connection ? new URL(path, connection.options.auth?.data.hassUrl).toString() : \"\";\n    },\n    callApi: callApi,\n    dateTime: {\n      shouldUseAmPm: () => {\n        const { locale } = get();\n        if (locale) {\n          return shouldUseAmPm(locale);\n        }\n        return true;\n      },\n      getTimeZone() {\n        const { locale, config } = get();\n        if (!config || !locale) {\n          return \"UTC\";\n        }\n        return resolveTimeZone(locale.time_zone, config.time_zone);\n      },\n    },\n  },\n  formatter: {\n    stateValue: (entity: HassEntity) => {\n      const { config, entitiesRegistryDisplay, locale, sensorNumericDeviceClasses } = get();\n      if (!config || !locale) {\n        return \"\";\n      }\n      return computeStateDisplay(entity, config, entitiesRegistryDisplay, locale, sensorNumericDeviceClasses, entity.state);\n    },\n    attributeValue: (entity: HassEntity, attribute: string) => {\n      const { config, entitiesRegistryDisplay, locale } = get();\n      if (!config || !locale) {\n        return \"\";\n      }\n      return computeAttributeValueDisplay(entity, locale, config, entitiesRegistryDisplay, attribute);\n    },\n    ...createDateFormatters(),\n  },\n}));\n\nexport const useHassProviderStore = create<HassProviderStore>((set, get) => ({\n  authenticated: false,\n  setAuthenticated: (value) => set({ authenticated: value }),\n  subscriptions: {},\n  addSubscription: (key, fn) => {\n    if (!fn) return;\n    const subs = get().subscriptions;\n    // if an existing subscription with this key exists, attempt cleanup first\n    if (subs[key]) {\n      try {\n        subs[key]();\n      } catch (e) {\n        if (process.env.NODE_ENV !== \"production\") {\n          console.warn(`Failed to unsubscribe previous subscription for key '${key}'`, e);\n        }\n      }\n    }\n    set({ subscriptions: { ...subs, [key]: fn } });\n  },\n  removeSubscription: (key) => {\n    const subs = get().subscriptions;\n    if (!subs[key]) return;\n    try {\n      subs[key]!();\n    } catch (e) {\n      if (process.env.NODE_ENV !== \"production\") {\n        console.warn(`Failed to unsubscribe subscription for key '${key}'`, e);\n      }\n    }\n    const next = { ...subs };\n    delete next[key];\n    set({ subscriptions: next });\n  },\n  unsubscribeAll: () => {\n    const subs = get().subscriptions;\n    for (const key of Object.keys(subs)) {\n      try {\n        subs[key]!();\n      } catch (e) {\n        if (process.env.NODE_ENV !== \"production\") {\n          console.warn(`Failed during mass unsubscribe for key '${key}'`, e);\n        }\n      }\n    }\n    set({ subscriptions: {} });\n  },\n\n  reset() {\n    const { unsubscribeAll, setAuthenticated } = get();\n    const {\n      setAuth,\n      setUser,\n      setCannotConnect,\n      setConfig,\n      setConnection,\n      setEntities,\n      setError,\n      setReady,\n      setRoutes,\n      setConnectionStatus,\n    } = useInternalStore.getState();\n    // when the hassUrl changes, reset some properties and re-authenticate\n    setAuth(null);\n    setRoutes([]);\n    setReady(false);\n    setConnection(null);\n    setEntities({});\n    setConfig(null);\n    setError(null);\n    setCannotConnect(false);\n    setUser(null);\n    setConnectionStatus(\"pending\");\n    setAuthenticated(false);\n    unsubscribeAll();\n  },\n}));\n","import { useInternalStore, type InternalStore } from \"../../HassConnect/HassContext\";\nimport type { StoreApi, UseBoundStore } from \"zustand\";\n\nexport const DATA_KEYS = [\n  \"routes\",\n  \"setRoutes\",\n  \"entities\",\n  \"hassUrl\",\n  \"hash\",\n  \"setHash\",\n  \"locales\",\n  \"portalRoot\",\n  \"windowContext\",\n  \"setWindowContext\",\n  \"connectionStatus\",\n  \"connection\",\n  \"ready\",\n  \"auth\",\n  \"config\",\n  \"user\",\n  \"users\",\n  \"globalComponentStyles\",\n  \"setGlobalComponentStyles\",\n  \"entitiesRegistryDisplay\",\n  \"services\",\n  \"areas\",\n  \"devices\",\n  \"floors\",\n  \"services\",\n  \"formatter\",\n  \"helpers\",\n  \"locale\",\n  \"sensorNumericDeviceClasses\",\n] satisfies (keyof InternalStore)[];\n\ntype KeysToPick = (typeof DATA_KEYS)[number];\n\n/* @deprecated Use `HassStore` instead */\nexport type Store = Pick<InternalStore, KeysToPick>;\n/** The data structure of the public store */\nexport type HassStore = Pick<InternalStore, KeysToPick>;\n/** The return value of the `useHass` hook */\nexport type UseHassHook = UseBoundStore<StoreApi<Store>>;\n/** @deprecated Use `UseHassHook` instead */\nexport type UseStoreHook = UseBoundStore<StoreApi<Store>>;\n\n// things we want to expose for the user\n// this is a type only difference, it still contains everything but the goal here is to please typescript users.\n\n/** @deprecated Use `useHass` instead */\nexport const useStore = useInternalStore as UseStoreHook;\nexport const useHass = useInternalStore as UseHassHook;\n","import { useState, useEffect } from \"react\";\nimport { LocaleKeys } from \"./locales/types\";\nimport locales from \"./locales\";\nimport { useHass } from \"../useHass\";\n\nconst LOCALES: Record<string, string> = {};\n\nexport function updateLocales(translations: Record<string, string>): void {\n  Object.assign(LOCALES, translations);\n}\n\ninterface Options {\n  /** if the string isn't found as some languages might not have specific values translated, it will use this value. */\n  fallback?: string;\n  /** value to search & replace */\n  search?: string;\n  /** value to search & replace */\n  replace?: string;\n}\n\nexport function localize(key: LocaleKeys, options?: Options): string {\n  const { search, replace, fallback } = options ?? {};\n  if (!LOCALES[key]) {\n    if (fallback) {\n      return fallback;\n    }\n    // as a generic fallback, we just return the keyname\n    return key;\n  }\n  if (typeof search === \"string\" && typeof replace === \"string\") {\n    return LOCALES[key].replace(`${search}`, replace).trim();\n  }\n  return LOCALES[key];\n}\n\nexport function useLocales(): Record<LocaleKeys, string> {\n  return LOCALES;\n}\n\nexport const useLocale = (key: LocaleKeys, options?: Options) => {\n  const { fallback = localize(\"unknown\") } = options ?? {};\n  const [value, setValue] = useState<string>(fallback);\n  const config = useHass((state) => state.config);\n  const localeData = useHass((state) => state.locale);\n\n  useEffect(() => {\n    const fetchAndSetLocale = async () => {\n      const locale = config?.language;\n      const localeDataHelper = locales.find((l) => l.code === localeData?.language || l.code === locale);\n      if (localeDataHelper) {\n        const data = await localeDataHelper.fetch();\n        setValue(data[key] ?? fallback);\n      }\n    };\n\n    fetchAndSetLocale();\n  }, [key, fallback, localeData, config]);\n\n  return value;\n};\n","import { EntityName, LocaleKeys } from \"@typings\";\nimport { computeDomain } from \"./computeDomain\";\nimport { lowerCase, startCase } from \"lodash\";\nimport { localize } from \"../hooks/useLocale\";\n\n/**\n * @description - Compute a localized title for a given entity domain, with special handling for certain domains and device classes.\n * @param entityId - The entity ID to compute the domain title for.\n * @param deviceClass - A device class if needed to compute outlet vs switch titles.\n * @returns\n */\nexport const computeDomainTitle = <E extends EntityName | \"unknown\">(entityId: E, deviceClass?: string): string => {\n  const domain = computeDomain(entityId);\n  // add in switches for different domains\n  switch (domain) {\n    case \"plant\":\n      return localize(\"plant_status\");\n    case \"switch\": {\n      if (deviceClass && deviceClass === \"outlet\") {\n        return localize(\"outlet\");\n      }\n      return localize(\"switch\");\n    }\n    case \"alarm_control_panel\":\n      return localize(\"alarm_panel\");\n    case \"lawn_mower\":\n      return localize(\"lawn_mower_commands\");\n    case \"datetime\":\n      return localize(\"date_time\");\n    case \"alert\":\n      return localize(\"alert_classes\");\n    case \"water_heater\":\n      return `${localize(\"water\")} ${localize(\"heat\")}`;\n    case \"logbook\":\n      return localize(\"activity\");\n    case \"homeassistant\":\n      return localize(\"home_assistant\");\n    // exact matches\n    case \"weather\":\n    case \"sun\":\n    case \"binary_sensor\":\n    case \"timer\":\n    case \"counter\":\n    case \"automation\":\n    case \"input_select\":\n    case \"device_tracker\":\n    case \"media_player\":\n    case \"input_number\":\n      return localize(domain);\n    case \"stt\":\n    case \"google\":\n    case \"reolink\":\n    case \"notify\":\n    case \"zha\":\n    case \"vacuum\":\n      return startCase(lowerCase(domain));\n    case \"frontend\":\n    case \"conversation\":\n    case \"hassio\":\n    case \"command_line\":\n    case \"onvif\":\n    case \"rest_command\":\n    case \"system_log\":\n    case \"media_extractor\":\n    case \"file\":\n    case \"persistent_notification\":\n    case \"cloud\":\n    case \"profiler\":\n    case \"recorder\":\n    case \"logger\":\n    case \"tts\":\n    case \"backup\":\n    case \"shelly\":\n    case \"matter\":\n    case \"climate\":\n    case \"fordpass\":\n      return localize(`${domain}.title`);\n    default: {\n      const localized = localize(domain, {\n        // just try to process with the title suffix\n        fallback: localize(`${domain}.title` as LocaleKeys, {\n          fallback: domain,\n        }),\n      });\n      if (localized === domain) {\n        return startCase(lowerCase(domain));\n      }\n      return localized;\n    }\n  }\n};\n","import {\n  isUnavailableState,\n  UNAVAILABLE,\n  OFF,\n  computeDomain,\n  EntityName,\n  DeviceRegistryEntry,\n  AreaRegistryEntry,\n  FloorRegistryEntry,\n  localize,\n  stripPrefixFromEntityName,\n  fallbackDeviceName,\n} from \"../\";\nimport { HassEntities, HassEntity } from \"home-assistant-js-websocket\";\nimport { EntityRegistryDisplayEntry, EntityRegistryEntry, ExtEntityRegistryEntry } from \"./entity_registry\";\n\nexport type EntityNameItem =\n  | {\n      type: \"entity\" | \"device\" | \"area\" | \"floor\";\n    }\n  | {\n      type: \"text\";\n      text: string;\n    };\n\nexport const DEFAULT_ENTITY_NAME = [{ type: \"device\" }, { type: \"entity\" }] satisfies EntityNameItem[];\n\nconst DEFAULT_SEPARATOR = \" \";\n\nexport interface EntityContext {\n  entity: EntityRegistryDisplayEntry | null;\n  device: DeviceRegistryEntry | null;\n  area: AreaRegistryEntry | null;\n  floor: FloorRegistryEntry | null;\n}\n\nexport interface EntityNameOptions {\n  separator?: string;\n}\n\n// we just hardcode the light domain here so types work\n/**\n * Determine whether a given entity state should be considered \"active\" for UI color/state purposes.\n *\n * Domain specific rules override a generic interpretation of activity. For many domains \"off\" or\n * an unavailable state implies inactive; however certain domains (e.g. alert, group, plant) have\n * custom semantics. This largely mirrors Home Assistant frontend logic for dynamic badge coloring.\n *\n * @param entity The Home Assistant entity state object.\n * @returns true if the entity is deemed active; false otherwise.\n */\nexport function stateActive(entity: HassEntity): boolean {\n  const domain = computeDomain(entity.entity_id as EntityName);\n  const compareState = entity.state;\n\n  if ([\"button\", \"event\", \"input_button\", \"scene\"].includes(domain)) {\n    return compareState !== UNAVAILABLE;\n  }\n\n  if (isUnavailableState(compareState)) {\n    return false;\n  }\n\n  // The \"off\" check is relevant for most domains, but there are exceptions\n  // such as \"alert\" where \"off\" is still a somewhat active state and\n  // therefore gets a custom color and \"idle\" is instead the state that\n  // matches what most other domains consider inactive.\n  if (compareState === OFF && domain !== \"alert\") {\n    return false;\n  }\n\n  // Custom cases\n  switch (domain) {\n    case \"alarm_control_panel\":\n      return compareState !== \"disarmed\";\n    case \"alert\":\n      // \"on\" and \"off\" are active, as \"off\" just means alert was acknowledged but is still active\n      return compareState !== \"idle\";\n    case \"cover\":\n      return compareState !== \"closed\";\n    case \"device_tracker\":\n    case \"person\":\n      return compareState !== \"not_home\";\n    case \"lawn_mower\":\n      return [\"mowing\", \"error\"].includes(compareState);\n    case \"lock\":\n      return compareState !== \"locked\";\n    case \"media_player\":\n      return compareState !== \"standby\";\n    case \"vacuum\":\n      return ![\"idle\", \"docked\", \"paused\"].includes(compareState);\n    case \"plant\":\n      return compareState === \"problem\";\n    case \"group\":\n      return [\"on\", \"home\", \"open\", \"locked\", \"problem\"].includes(compareState);\n    case \"timer\":\n      return compareState === \"active\";\n    case \"camera\":\n      return compareState === \"streaming\";\n  }\n\n  return true;\n}\n\n/** Compute the object ID of a state. */\n/**\n * Compute the object id portion of an entity id (text after the domain prefix).\n *\n * Example: `light.kitchen_ceiling` -> `kitchen_ceiling`.\n *\n * @param entityId Full entity id including domain.\n * @returns Object id portion (substring after first dot).\n */\nexport const computeObjectId = (entityId: string): string => entityId.substr(entityId.indexOf(\".\") + 1);\n\n/**\n * Derive a human readable state name from entity attributes.\n * Falls back to object id with underscores replaced if no friendly_name is present or undefined.\n *\n * @param entityId Full entity id.\n * @param attributes Entity attributes bag.\n * @returns Friendly name or formatted object id; empty string if friendly_name explicitly blank.\n */\nexport const computeStateNameFromEntityAttributes = (entityId: string, attributes: HassEntity[\"attributes\"]): string =>\n  attributes?.friendly_name === undefined ? computeObjectId(entityId).replace(/_/g, \" \") : attributes.friendly_name || \"\";\n\n/**\n * Convenience wrapper to compute display name directly from a HassEntity state object.\n *\n * @param stateObj HassEntity state object.\n * @returns Human readable name.\n */\nexport const computeStateName = (stateObj: HassEntity): string =>\n  computeStateNameFromEntityAttributes(stateObj.entity_id, stateObj.attributes);\n\n/**\n * Resolve contextual registry objects (entity, device, area, floor) for a given live state object.\n * Safely handles missing registry entries by returning nulls.\n *\n * @param stateObj Live HassEntity state object.\n * @param entities Display registry entries keyed by entity_id.\n * @param devices Device registry entries keyed by device_id.\n * @param areas Area registry entries keyed by area_id.\n * @param floors Floor registry entries keyed by floor_id.\n * @returns An EntityContext containing resolved registry references or null placeholders.\n */\nexport const getEntityContext = (\n  stateObj: HassEntity,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n): EntityContext => {\n  const entry = entities[stateObj.entity_id] as EntityRegistryDisplayEntry | undefined;\n\n  if (!entry) {\n    return {\n      entity: null,\n      device: null,\n      area: null,\n      floor: null,\n    };\n  }\n  return getEntityEntryContext(entry, entities, devices, areas, floors);\n};\n\n/**\n * Resolve contextual registry objects given a registry entry (entity/device/area/floor relationships).\n *\n * It prefers the entity's explicit area assignment falling back to its device's area, then derives floor\n * from the area if present.\n *\n * @param entry Any supported registry entry shape (display/regular/extended).\n * @param entities Display registry lookup keyed by entity_id.\n * @param devices Device registry lookup keyed by device_id.\n * @param areas Area registry lookup keyed by area_id.\n * @param floors Floor registry lookup keyed by floor_id.\n * @returns EntityContext object.\n */\nexport const getEntityEntryContext = (\n  entry: EntityRegistryDisplayEntry | EntityRegistryEntry | ExtEntityRegistryEntry,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n): EntityContext => {\n  const entity = entities[entry.entity_id];\n  const deviceId = entry?.device_id;\n  const device = deviceId ? devices[deviceId] : undefined;\n  const areaId = entry?.area_id || device?.area_id;\n  const area = areaId ? areas[areaId] : undefined;\n  const floorId = area?.floor_id;\n  const floor = floorId ? floors[floorId] : undefined;\n\n  return {\n    entity: entity,\n    device: device || null,\n    area: area || null,\n    floor: floor || null,\n  };\n};\n\n/**\n * Compute a device name for presentation, falling back to synthesized name when absent.\n * Uses `computeDeviceName`, then optional fallback naming heuristics (`fallbackDeviceName`), then a localized\n * \"unnamed_device\" token.\n *\n * @param device Device registry entry.\n * @param hassEntities Full HA entity state map for fallback heuristics.\n * @param entities Optional collection used when computing a fallback name.\n * @returns Display/device name string.\n */\nexport const computeDeviceNameDisplay = (\n  device: DeviceRegistryEntry,\n  hassEntities: HassEntities,\n  entities?: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[],\n) => computeDeviceName(device) || (entities && fallbackDeviceName(hassEntities, entities)) || localize(\"unnamed_device\");\n\n/**\n * Extract the explicit or user overridden device name (trimmed).\n *\n * @param device Device registry entry.\n * @returns Name string or undefined if not set.\n */\nexport const computeDeviceName = (device: DeviceRegistryEntry): string | undefined => (device.name_by_user || device.name)?.trim();\n\n/**\n * Compute the uncluttered entity name relative to its device.\n * Falls back to friendly state name if not found in entity registry.\n *\n * @param stateObj Live entity state.\n * @param entities Registry display entries.\n * @param devices Device registry entries.\n * @returns Derived entity name or undefined.\n */\nexport const computeEntityName = (\n  stateObj: HassEntity,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n): string | undefined => {\n  const entry = entities[stateObj.entity_id] as EntityRegistryDisplayEntry | undefined;\n\n  if (!entry) {\n    // Fall back to state name if not in the entity registry (friendly name)\n    return computeStateName(stateObj);\n  }\n  return computeEntityEntryName(entry, devices);\n};\n\n/**\n * Compute the entity's relative name based on registry entry and device. Removes redundant device prefix,\n * supports fallback to state name when provided.\n *\n * @param entry Registry entry shape.\n * @param devices Device registry lookup.\n * @param fallbackStateObj Optional state object to derive name when registry name absent.\n * @returns Relative entity name or undefined if redundant with device name.\n */\nexport const computeEntityEntryName = (\n  entry: EntityRegistryDisplayEntry | EntityRegistryEntry,\n  devices: Record<string, DeviceRegistryEntry>,\n  fallbackStateObj?: HassEntity,\n): string | undefined => {\n  const name = entry.name || (\"original_name\" in entry && entry.original_name != null ? String(entry.original_name) : undefined);\n\n  const device = entry.device_id ? devices[entry.device_id] : undefined;\n\n  if (!device) {\n    if (name) {\n      return name;\n    }\n    if (fallbackStateObj) {\n      return computeStateName(fallbackStateObj);\n    }\n    return undefined;\n  }\n\n  const deviceName = computeDeviceName(device);\n\n  // If the device name is the same as the entity name, consider empty entity name\n  if (deviceName === name) {\n    return undefined;\n  }\n\n  // Remove the device name from the entity name if it starts with it\n  if (deviceName && name) {\n    return stripPrefixFromEntityName(name, deviceName) || name;\n  }\n\n  return name;\n};\n\n/**\n * Retrieve a trimmed floor name.\n * @param floor Floor registry entry.\n * @returns Trimmed name string.\n */\nexport const computeFloorName = (floor: FloorRegistryEntry): string => floor.name?.trim();\n\n/**\n * Retrieve a trimmed area name.\n * @param area Area registry entry.\n * @returns Trimmed name or undefined.\n */\nexport const computeAreaName = (area: AreaRegistryEntry): string | undefined => area.name?.trim();\n\n/**\n * Build an ordered list of entity related names based on a descriptor array.\n * Supports types: entity, device, area, floor, and static text.\n *\n * @param stateObj Live entity state.\n * @param name Descriptor array (or items) defining which names to include.\n * @param entities Registry entries lookup.\n * @param devices Device registry lookup.\n * @param areas Area registry lookup.\n * @param floors Floor registry lookup.\n * @returns Array of names (string or undefined) preserving descriptor order.\n */\nexport const computeEntityNameList = (\n  stateObj: HassEntity,\n  name: EntityNameItem[],\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n): (string | undefined)[] => {\n  const { device, area, floor } = getEntityContext(stateObj, entities, devices, areas, floors);\n\n  const names = name.map((item) => {\n    switch (item.type) {\n      case \"entity\":\n        return computeEntityName(stateObj, entities, devices);\n      case \"device\":\n        return device ? computeDeviceName(device) : undefined;\n      case \"area\":\n        return area ? computeAreaName(area) : undefined;\n      case \"floor\":\n        return floor ? computeFloorName(floor) : undefined;\n      case \"text\":\n        return item.text;\n      default:\n        return \"\";\n    }\n  });\n\n  return names;\n};\n\n/**\n * Determine if the entity name is effectively the device name (redundant) and thus should use the device name\n * directly in displays.\n *\n * @param stateObj Live entity state.\n * @param entities Registry display entries.\n * @param devices Device registry entries.\n * @returns true if entity name should be replaced by device name; false otherwise.\n */\nexport const entityUseDeviceName = (\n  stateObj: HassEntity,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n): boolean => !computeEntityName(stateObj, entities, devices);\n\n/**\n * Produce a final display name string for an entity combining multiple name parts.\n * Applies replacement of entity descriptor with device descriptor when entity name is redundant; supports\n * separators and pure text-only sequences.\n *\n * @param stateObj Live entity state.\n * @param name Single or array of name descriptors (defaults to device + entity).\n * @param entities Registry display entries.\n * @param devices Device registry entries.\n * @param areas Area registry entries.\n * @param floors Floor registry entries.\n * @param options Optional separator override.\n * @returns Concatenated display name string.\n */\nexport const computeEntityNameDisplay = (\n  stateObj: HassEntity,\n  name: EntityNameItem | EntityNameItem[] | undefined,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n  options?: EntityNameOptions,\n) => {\n  let items = Array.isArray(name) ? name : name ? [name] : DEFAULT_ENTITY_NAME;\n\n  const separator = options?.separator ?? DEFAULT_SEPARATOR;\n\n  // If all items are text, just join them\n  if (items.every((n) => n.type === \"text\")) {\n    return items.map((item) => item.text).join(separator);\n  }\n\n  const useDeviceName = entityUseDeviceName(stateObj, entities, devices);\n\n  // If entity uses device name, and device is not already included, replace it with device name\n  if (useDeviceName) {\n    const hasDevice = items.some((n) => n.type === \"device\");\n    if (!hasDevice) {\n      items = items.map((n) => (n.type === \"entity\" ? { type: \"device\" } : n));\n    }\n  }\n\n  const names = computeEntityNameList(stateObj, items, entities, devices, areas, floors);\n\n  // If after processing there is only one name, return that\n  if (names.length === 1) {\n    return names[0] || \"\";\n  }\n\n  return names.filter((n) => n).join(separator);\n};\n","import { createCollection, type Connection, type HassEntities, type HassEntity } from \"home-assistant-js-websocket\";\nimport { LightColor } from \"../types/autogenerated-types-by-domain\";\nimport { computeDomain } from \"./computeDomain\";\nimport { EntityName } from \"@typings\";\nimport { computeEntityNameList, computeStateName } from \"./entity\";\nimport { AreaRegistryEntry, DeviceRegistryEntry, FloorRegistryEntry } from \"../hooks\";\nimport { caseInsensitiveStringCompare } from \"./string\";\nimport { Store } from \"home-assistant-js-websocket/dist/store.js\";\nimport { debounce } from \"lodash\";\nimport { computeDomainTitle } from \"./computeDomainTitle\";\n\ntype EntityCategory = \"config\" | \"diagnostic\";\n\nexport interface RegistryEntry {\n  created_at: number;\n  modified_at: number;\n}\n\nexport interface EntityRegistryDisplayEntry {\n  entity_id: string;\n  name?: string;\n  icon?: string;\n  device_id?: string;\n  area_id?: string;\n  labels: string[];\n  hidden?: boolean;\n  entity_category?: EntityCategory;\n  translation_key?: string;\n  platform?: string;\n  display_precision?: number;\n  has_entity_name?: boolean;\n}\n\nexport interface EntityRegistryDisplayEntryResponse {\n  entities: {\n    ei: string;\n    di?: string;\n    ai?: string;\n    lb: string[];\n    ec?: number;\n    en?: string;\n    ic?: string;\n    pl?: string;\n    tk?: string;\n    hb?: boolean;\n    dp?: number;\n    hn?: boolean;\n  }[];\n  entity_categories: Record<number, EntityCategory>;\n}\n\nexport interface EntityRegistryEntry extends RegistryEntry {\n  id: string;\n  entity_id: string;\n  name: string | null;\n  icon: string | null;\n  platform: string;\n  config_entry_id: string | null;\n  config_subentry_id: string | null;\n  device_id: string | null;\n  area_id: string | null;\n  labels: string[];\n  disabled_by: \"user\" | \"device\" | \"integration\" | \"config_entry\" | null;\n  hidden_by: Exclude<EntityRegistryEntry[\"disabled_by\"], \"config_entry\">;\n  entity_category: EntityCategory | null;\n  has_entity_name: boolean;\n  original_name?: string;\n  unique_id: string;\n  translation_key?: string;\n  options: EntityRegistryOptions | null;\n  categories: Record<string, string>;\n}\n\nexport interface ExtEntityRegistryEntry extends EntityRegistryEntry {\n  capabilities: Record<string, unknown>;\n  original_icon?: string;\n  device_class?: string;\n  original_device_class?: string;\n  aliases: string[];\n}\n\nexport interface UpdateEntityRegistryEntryResult {\n  entity_entry: ExtEntityRegistryEntry;\n  reload_delay?: number;\n  require_restart?: boolean;\n}\n\nexport interface SensorEntityOptions {\n  display_precision?: number | null;\n  suggested_display_precision?: number | null;\n  unit_of_measurement?: string | null;\n}\n\nexport interface LightEntityOptions {\n  favorite_colors?: LightColor[];\n}\n\nexport interface NumberEntityOptions {\n  unit_of_measurement?: string | null;\n}\n\nexport interface LockEntityOptions {\n  default_code?: string | null;\n}\n\nexport interface AlarmControlPanelEntityOptions {\n  default_code?: string | null;\n}\n\nexport interface WeatherEntityOptions {\n  precipitation_unit?: string | null;\n  pressure_unit?: string | null;\n  temperature_unit?: string | null;\n  visibility_unit?: string | null;\n  wind_speed_unit?: string | null;\n}\n\nexport interface SwitchAsXEntityOptions {\n  entity_id: string;\n  invert: boolean;\n}\n\nexport interface EntityRegistryOptions {\n  number?: NumberEntityOptions;\n  sensor?: SensorEntityOptions;\n  alarm_control_panel?: AlarmControlPanelEntityOptions;\n  lock?: LockEntityOptions;\n  weather?: WeatherEntityOptions;\n  light?: LightEntityOptions;\n  switch_as_x?: SwitchAsXEntityOptions;\n  conversation?: Record<string, unknown>;\n  \"cloud.alexa\"?: Record<string, unknown>;\n  \"cloud.google_assistant\"?: Record<string, unknown>;\n}\n\nexport interface EntityRegistryEntryUpdateParams {\n  name?: string | null;\n  icon?: string | null;\n  device_class?: string | null;\n  area_id?: string | null;\n  disabled_by?: string | null;\n  hidden_by: string | null;\n  new_entity_id?: string;\n  options_domain?: string;\n  options?:\n    | SensorEntityOptions\n    | NumberEntityOptions\n    | LockEntityOptions\n    | AlarmControlPanelEntityOptions\n    | WeatherEntityOptions\n    | LightEntityOptions;\n  aliases?: string[];\n  labels?: string[];\n  categories?: Record<string, string | null>;\n}\n\nconst batteryPriorities = [\"sensor\", \"binary_sensor\"];\n/**\n * Find the most relevant battery entity from a list of registry display entries.\n *\n * Prioritization order is defined in `batteryPriorities` (sensor > binary_sensor).\n * A matching entity must have `attributes.device_class === \"battery\"` and its domain\n * must appear in the priorities list. The first item after sorting by domain priority is returned.\n *\n * @template T extends object containing an `entity_id` field.\n * @param hassEntities Full Home Assistant entity state map.\n * @param entities Candidate list (typically registry entries or simplified objects with entity_id).\n * @returns The highest priority battery entity or `undefined` if none match.\n */\nexport const findBatteryEntity = <T extends { entity_id: string }>(hassEntities: HassEntities, entities: T[]): T | undefined => {\n  const batteryEntities = entities\n    .filter(\n      (entity) =>\n        hassEntities[entity.entity_id] &&\n        hassEntities[entity.entity_id].attributes.device_class === \"battery\" &&\n        batteryPriorities.includes(computeDomain(entity.entity_id as EntityName)),\n    )\n    .sort(\n      (a, b) =>\n        batteryPriorities.indexOf(computeDomain(a.entity_id as EntityName)) -\n        batteryPriorities.indexOf(computeDomain(b.entity_id as EntityName)),\n    );\n  if (batteryEntities.length > 0) {\n    return batteryEntities[0];\n  }\n\n  return undefined;\n};\n\n/**\n * Locate a battery charging entity (device_class === \"battery_charging\") in the provided list.\n * Returns the first match; no domain prioritization is applied.\n *\n * @template T extends object containing an `entity_id` field.\n * @param hassEntities Full HA entity state map.\n * @param entities Candidate list.\n * @returns A matching charging entity or `undefined` if not found.\n */\nexport const findBatteryChargingEntity = <T extends { entity_id: string }>(hassEntities: HassEntities, entities: T[]): T | undefined =>\n  entities.find(\n    (entity) => hassEntities[entity.entity_id] && hassEntities[entity.entity_id].attributes.device_class === \"battery_charging\",\n  );\n\n/**\n * Compute a human readable name for an entity registry entry.\n *\n * Resolution order:\n * 1. Explicit `entry.name`\n * 2. Derived friendly state name (via `computeStateName`)\n * 3. Original name (`entry.original_name`) or fallback to `entry.entity_id`.\n *\n * @param hassEntities Full HA entity state map.\n * @param entry The registry entry we want to name.\n * @returns Resolved name or `null` if not determinable.\n */\nexport const computeEntityRegistryName = (hassEntities: HassEntities, entry: EntityRegistryEntry): string | null => {\n  if (entry.name) {\n    return entry.name;\n  }\n  const state = hassEntities[entry.entity_id];\n  if (state) {\n    return computeStateName(state);\n  }\n  return entry.original_name ? entry.original_name : entry.entity_id;\n};\n\n/**\n * Fetch a single extended entity registry entry from Home Assistant.\n *\n * This issues a WebSocket command (`config/entity_registry/get`) via `sendMessagePromise`.\n *\n * @param connection Active HA websocket connection.\n * @param entityId Target entity_id to retrieve extended registry info for.\n * @returns Promise resolving to the extended registry entry.\n */\nexport const getExtendedEntityRegistryEntry = (connection: Connection, entityId: string): Promise<ExtEntityRegistryEntry> =>\n  connection.sendMessagePromise<ExtEntityRegistryEntry>({\n    type: \"config/entity_registry/get\",\n    entity_id: entityId,\n  });\n\n/**\n * Fetch multiple extended entity registry entries in a single request.\n *\n * Issues `config/entity_registry/get_entries` with an array of ids.\n *\n * @param connection Active HA websocket connection.\n * @param entityIds Array of entity_ids to fetch.\n * @returns Promise resolving to a keyed record (entity_id -> extended entry).\n */\nexport const getExtendedEntityRegistryEntries = (\n  connection: Connection,\n  entityIds: string[],\n): Promise<Record<string, ExtEntityRegistryEntry>> =>\n  connection.sendMessagePromise<Record<string, ExtEntityRegistryEntry>>({\n    type: \"config/entity_registry/get_entries\",\n    entity_ids: entityIds,\n  });\n\n/**\n * Update an existing entity registry entry.\n *\n * Issues `config/entity_registry/update` with partial update fields.\n * Supports renaming, area assignment, icon/device_class changes, and options updates.\n *\n * @param connection HA websocket connection.\n * @param entityId Target entity_id.\n * @param updates Partial set of fields to update.\n * @returns Promise resolving to the update result (may include restart or reload hints).\n */\nexport const updateEntityRegistryEntry = (\n  connection: Connection,\n  entityId: string,\n  updates: Partial<EntityRegistryEntryUpdateParams>,\n): Promise<UpdateEntityRegistryEntryResult> =>\n  connection.sendMessagePromise<UpdateEntityRegistryEntryResult>({\n    type: \"config/entity_registry/update\",\n    entity_id: entityId,\n    ...updates,\n  });\n\n/**\n * Remove an entity from the registry (may not remove underlying integration/device).\n *\n * Issues `config/entity_registry/remove`.\n *\n * @param connection HA websocket connection.\n * @param entityId The entity_id to remove.\n * @returns Promise resolving when removal is acknowledged.\n */\nexport const removeEntityRegistryEntry = (connection: Connection, entityId: string): Promise<void> =>\n  connection.sendMessagePromise<void>({\n    type: \"config/entity_registry/remove\",\n    entity_id: entityId,\n  });\n\n/**\n * Retrieve compact display-friendly registry entries.\n *\n * Issues `config/entity_registry/list_for_display`, returning a structure optimized\n * for UI listing (with short keys and separate category mapping).\n *\n * @param connection HA websocket connection.\n * @returns Promise resolving to display entry response payload.\n */\nexport const fetchEntityRegistryDisplay = (connection: Connection) =>\n  connection.sendMessagePromise<EntityRegistryDisplayEntryResponse>({\n    type: \"config/entity_registry/list_for_display\",\n  });\n\nconst subscribeEntityRegistryDisplayUpdates = (conn: Connection, store: Store<EntityRegistryDisplayEntryResponse>) =>\n  conn.subscribeEvents(\n    debounce(() => fetchEntityRegistryDisplay(conn).then((entities) => store.setState(entities, true)), 500, {\n      leading: true,\n      trailing: true,\n    }),\n    \"entity_registry_updated\",\n  );\n\nexport const subscribeEntityRegistryDisplay = (conn: Connection, onChange: (entities: EntityRegistryDisplayEntryResponse) => void) =>\n  createCollection<EntityRegistryDisplayEntryResponse>(\n    \"_entityRegistryDisplay\",\n    fetchEntityRegistryDisplay,\n    subscribeEntityRegistryDisplayUpdates,\n    conn,\n    onChange,\n  );\n\n/**\n * Sort registry entries by their explicit name (locale-aware case-insensitive).\n *\n * @param entries Registry entries array (mutated in place by Array.sort).\n * @param language Locale/language code for comparison rules.\n * @returns The same array reference sorted.\n */\nexport const sortEntityRegistryByName = (entries: EntityRegistryEntry[], language: string) =>\n  entries.sort((entry1, entry2) => caseInsensitiveStringCompare(entry1.name || \"\", entry2.name || \"\", language));\n\n/**\n * Build a lookup map keyed by `entity_id` for quick access.\n *\n * @param entries Array of registry entries.\n * @returns Record mapping entity_id -> entry.\n */\nexport const entityRegistryByEntityId = (entries: EntityRegistryEntry[]) => {\n  const entities: Record<string, EntityRegistryEntry> = {};\n  for (const entity of entries) {\n    entities[entity.entity_id] = entity;\n  }\n  return entities;\n};\n\n/**\n * Build a lookup map keyed by internal registry `id`.\n *\n * @param entries Array of registry entries.\n * @returns Record mapping registry id -> entry.\n */\nexport const entityRegistryById = (entries: EntityRegistryEntry[]) => {\n  const entities: Record<string, EntityRegistryEntry> = {};\n  for (const entity of entries) {\n    entities[entity.id] = entity;\n  }\n  return entities;\n};\n\n/**\n * Produce a mapping from entity_id to integration platform name.\n * Ignores entries lacking a platform.\n *\n * @param entities Registry entries.\n * @returns Record entity_id -> platform string.\n */\nexport const getEntityPlatformLookup = (entities: EntityRegistryEntry[]): Record<string, string> => {\n  const entityLookup: Record<string, string> = {};\n  for (const confEnt of entities) {\n    if (!confEnt.platform) {\n      continue;\n    }\n    entityLookup[confEnt.entity_id] = confEnt.platform;\n  }\n  return entityLookup;\n};\n\n/**\n * Ask Home Assistant for automatically suggested entity_ids for given IDs.\n *\n * Issues `config/entity_registry/get_automatic_entity_ids`.\n *\n * @param connection HA websocket connection.\n * @param entity_ids List of entity IDs to query.\n * @returns Promise resolving to a mapping of original id -> suggested new id (or null).\n */\nexport const getAutomaticEntityIds = (connection: Connection, entity_ids: string[]) =>\n  connection.sendMessagePromise<Record<string, string | null>>({\n    type: \"config/entity_registry/get_automatic_entity_ids\",\n    entity_ids,\n  });\n\nexport interface EntityListInfoCommon {\n  id: string;\n  primary: string;\n  secondary?: string;\n  search_labels?: string[];\n  sorting_label?: string;\n  icon_path?: string;\n  icon?: string;\n}\n\nexport interface EntityListInfo extends EntityListInfoCommon {\n  domain_name?: string;\n  stateObj?: HassEntity;\n}\n\n/**\n * Build a filtered & decorated list of entity metadata for UI consumption.\n *\n * Applies domain/entity include & exclude filters, device class filtering, unit filtering,\n * custom predicate filtering, and search label composition. Produces a stable list of\n * `EntityListInfo` objects with primary/secondary labels.\n *\n * @param hassEntities Raw HA entities state map.\n * @param entities Display registry entry map (entity_id -> display entry) used for name resolution.\n * @param devices Device registry map (device_id -> device entry) for hierarchical naming.\n * @param areas Area registry map (area_id -> area entry) for hierarchical naming.\n * @param floors Floor registry map (floor_id -> floor entry) for hierarchical naming.\n * @param includeDomains Domains to explicitly include (optional).\n * @param excludeDomains Domains to explicitly exclude (optional).\n * @param entityFilter Additional predicate applied to each HassEntity (optional).\n * @param includeDeviceClasses Device classes to include (optional).\n * @param includeUnitOfMeasurement Units of measurement to include (optional).\n * @param includeEntities Explicit entity_ids to include (optional).\n * @param excludeEntities Explicit entity_ids to exclude (optional).\n * @param value A selected value whose entity should always be retained in filtering (optional).\n * @param idPrefix Prefix applied to generated `id` field (defaults to '').\n * @returns Filtered, mapped array of `EntityListInfo` objects.\n */\nexport const getEntities = (\n  hassEntities: HassEntities,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  devices: Record<string, DeviceRegistryEntry>,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n  includeDomains?: string[],\n  excludeDomains?: string[],\n  entityFilter?: (entityId: HassEntity) => boolean,\n  includeDeviceClasses?: string[],\n  includeUnitOfMeasurement?: string[],\n  includeEntities?: string[],\n  excludeEntities?: string[],\n  value?: string,\n  idPrefix = \"\",\n): EntityListInfo[] => {\n  let items: EntityListInfo[] = [];\n\n  let entityIds = Object.keys(hassEntities);\n\n  if (includeEntities) {\n    entityIds = entityIds.filter((entityId) => includeEntities.includes(entityId));\n  }\n\n  if (excludeEntities) {\n    entityIds = entityIds.filter((entityId) => !excludeEntities.includes(entityId));\n  }\n\n  if (includeDomains) {\n    entityIds = entityIds.filter((eid) => includeDomains.includes(computeDomain(eid as EntityName)));\n  }\n\n  if (excludeDomains) {\n    entityIds = entityIds.filter((eid) => !excludeDomains.includes(computeDomain(eid as EntityName)));\n  }\n\n  items = entityIds.map<EntityListInfo>((entityId) => {\n    const stateObj = hassEntities[entityId];\n\n    const friendlyName = computeStateName(stateObj); // Keep this for search\n    const [entityName, deviceName, areaName] = computeEntityNameList(\n      stateObj,\n      [{ type: \"entity\" }, { type: \"device\" }, { type: \"area\" }],\n      entities,\n      devices,\n      areas,\n      floors,\n    );\n    const domain = computeDomain(entityId as EntityName);\n    const domainTitle = computeDomainTitle(domain as EntityName, stateObj.attributes.device_class);\n\n    const primary = entityName || deviceName || entityId;\n    const secondary = [areaName, entityName ? deviceName : undefined].filter(Boolean).join(\" ▸ \");\n\n    return {\n      id: `${idPrefix}${entityId}`,\n      primary: primary,\n      secondary: secondary,\n      domain_name: domainTitle,\n      sorting_label: [deviceName, entityName].filter(Boolean).join(\"_\"),\n      search_labels: [entityName, deviceName, areaName, domainTitle, friendlyName, entityId].filter(Boolean) as string[],\n      stateObj: stateObj,\n    };\n  });\n\n  if (includeDeviceClasses) {\n    items = items.filter(\n      (item) =>\n        // We always want to include the entity of the current value\n        item.id === value ||\n        (item.stateObj?.attributes.device_class && includeDeviceClasses.includes(item.stateObj.attributes.device_class)),\n    );\n  }\n\n  if (includeUnitOfMeasurement) {\n    items = items.filter(\n      (item) =>\n        // We always want to include the entity of the current value\n        item.id === value ||\n        (item.stateObj?.attributes.unit_of_measurement && includeUnitOfMeasurement.includes(item.stateObj.attributes.unit_of_measurement)),\n    );\n  }\n\n  if (entityFilter) {\n    items = items.filter(\n      (item) =>\n        // We always want to include the entity of the current value\n        item.id === value || (item.stateObj && entityFilter!(item.stateObj)),\n    );\n  }\n\n  return items;\n};\n","import { EntityName, EntityRegistryDisplayEntry, FrontendLocaleData, WeatherEntity, computeDomain, localize } from \"../\";\nimport { HassConfig, HassEntity } from \"home-assistant-js-websocket\";\nimport { formatNumber } from \"./number\";\nimport { formatDuration, isDate, isTimestamp, checkValidDate, formatDateTimeWithSeconds, formatDate } from \"./date\";\nimport { blankBeforeUnit } from \"./blankBeforeUnit\";\n\nexport const TEMPERATURE_ATTRIBUTES = new Set([\n  \"temperature\",\n  \"current_temperature\",\n  \"target_temperature\",\n  \"target_temp_temp\",\n  \"target_temp_high\",\n  \"target_temp_low\",\n  \"target_temp_step\",\n  \"min_temp\",\n  \"max_temp\",\n]);\n\ntype Formatter = (value: number) => string;\n\nexport const DOMAIN_ATTRIBUTES_FORMATTERS: Record<string, Record<string, Formatter>> = {\n  light: {\n    brightness: (value) => Math.round((value / 255) * 100).toString(),\n  },\n  media_player: {\n    volume_level: (value) => Math.round(value * 100).toString(),\n    media_duration: (value) => formatDuration(value.toString(), \"s\"),\n  },\n};\n\nexport const DOMAIN_ATTRIBUTES_UNITS = {\n  climate: {\n    humidity: \"%\",\n    current_humidity: \"%\",\n    target_humidity_low: \"%\",\n    target_humidity_high: \"%\",\n    target_humidity_step: \"%\",\n    min_humidity: \"%\",\n    max_humidity: \"%\",\n  },\n  cover: {\n    current_position: \"%\",\n    current_tilt_position: \"%\",\n  },\n  fan: {\n    percentage: \"%\",\n  },\n  humidifier: {\n    humidity: \"%\",\n    current_humidity: \"%\",\n    min_humidity: \"%\",\n    max_humidity: \"%\",\n  },\n  light: {\n    color_temp: \"mired\",\n    max_mireds: \"mired\",\n    min_mireds: \"mired\",\n    color_temp_kelvin: \"K\",\n    min_color_temp_kelvin: \"K\",\n    max_color_temp_kelvin: \"K\",\n    brightness: \"%\",\n  },\n  sun: {\n    azimuth: \"°\",\n    elevation: \"°\",\n  },\n  vacuum: {\n    battery_level: \"%\",\n  },\n  valve: {\n    current_position: \"%\",\n  },\n  sensor: {\n    battery_level: \"%\",\n  },\n  media_player: {\n    volume_level: \"%\",\n  },\n} as const satisfies Record<string, Record<string, string>>;\n\nexport const getWeatherUnit = (config: HassConfig, stateObj: WeatherEntity, measure: string): string => {\n  const lengthUnit = config.unit_system.length || \"\";\n  switch (measure) {\n    case \"visibility\":\n      return stateObj.attributes.visibility_unit || lengthUnit;\n    case \"precipitation\":\n      return stateObj.attributes.precipitation_unit || (lengthUnit === \"km\" ? \"mm\" : \"in\");\n    case \"pressure\":\n      return stateObj.attributes.pressure_unit || (lengthUnit === \"km\" ? \"hPa\" : \"inHg\");\n    case \"temperature\":\n    case \"templow\":\n      return stateObj.attributes.temperature_unit || config.unit_system.temperature;\n    case \"wind_speed\":\n      return stateObj.attributes.wind_speed_unit || `${lengthUnit}/h`;\n    case \"humidity\":\n    case \"precipitation_probability\":\n      return \"%\";\n    default: {\n      const unitSystem = config.unit_system;\n      if (measure in unitSystem) {\n        return unitSystem[measure as keyof HassConfig[\"unit_system\"]];\n      }\n      return \"\";\n    }\n  }\n};\n/**\n * Compute a human‑friendly display string for a SPECIFIC ATTRIBUTE of an entity.\n *\n * Differences vs `computeStateDisplayFromEntityAttributes`:\n * - Operates on a single attribute key/value (not the primary entity state) and can be called recursively for arrays.\n * - Applies attribute/domain specific conversions (e.g. light.brightness 0‑255 → 0‑100 %, media_player.volume_level → %).\n * - Inserts appropriate units using domain maps (`DOMAIN_ATTRIBUTES_UNITS`), weather‑aware unit resolution & temperature unit system.\n * - Handles duration/device_class conversions for domain attributes (e.g. media_duration seconds → HH:MM:SS).\n * - Localizes spacing before units via `blankBeforeUnit` for languages needing a non‑breaking space or locale‑specific separator.\n * - Formats numeric values with `formatNumber`, respects precision & currency for monetary representations.\n * - Detects date / timestamp strings and formats them (timestamp → date + time with seconds; date only → long date).\n * - Serializes nested objects to JSON and flattens arrays to a comma‑separated list, formatting each item individually.\n * - Returns localized \"unknown\" when value is nullish.\n *\n * Example Usage:\n * ```ts\n * // Light brightness attribute (128 → \"50 %\")\n * computeAttributeValueDisplay(lightEntity, locale, config, entities, 'brightness', 128);\n *\n * // Weather temperature attribute\n * computeAttributeValueDisplay(weatherEntity, locale, config, entities, 'temperature', 23);\n * // => \"23 °C\" (unit depends on config.unit_system.temperature)\n *\n * // Timestamp string attribute\n * computeAttributeValueDisplay(entity, locale, config, entities, 'last_seen', '2025-11-12T08:30:00Z');\n * // => localized date & time with seconds\n *\n * // Date string attribute (no time)\n * computeAttributeValueDisplay(entity, locale, config, entities, 'date_only', '2025-11-12');\n * // => \"Nov 12, 2025\" (example)\n *\n * // Array of simple values\n * computeAttributeValueDisplay(entity, locale, config, entities, 'supported_modes', ['auto','cool','heat']);\n * // => \"auto, cool, heat\"\n *\n * // Object value\n * computeAttributeValueDisplay(entity, locale, config, entities, 'options', { a: 1, b: 2 });\n * // => '{\"a\":1,\"b\":2}'\n * ```\n */\nexport const computeAttributeValueDisplay = (\n  entity: HassEntity,\n  locale: FrontendLocaleData,\n  config: HassConfig,\n  entities: Record<string, EntityRegistryDisplayEntry>,\n  attribute: string,\n  value?: unknown,\n): string => {\n  const attributeValue = value !== undefined ? value : entity.attributes[attribute];\n\n  // Null value, the state is unknown\n  if (attributeValue === null || attributeValue === undefined) {\n    return localize(\"unknown\");\n  }\n\n  // Number value, return formatted number\n  if (typeof attributeValue === \"number\") {\n    const domain = computeDomain(entity.entity_id as EntityName);\n\n    const formatter = DOMAIN_ATTRIBUTES_FORMATTERS[domain]?.[attribute];\n\n    const formattedValue = formatter ? formatter(attributeValue) : formatNumber(attributeValue);\n\n    const key = domain as keyof typeof DOMAIN_ATTRIBUTES_UNITS;\n    let unit = DOMAIN_ATTRIBUTES_UNITS[key]?.[attribute as keyof (typeof DOMAIN_ATTRIBUTES_UNITS)[typeof key]] as string | undefined;\n\n    if (domain === \"weather\") {\n      unit = getWeatherUnit(config, entity as WeatherEntity, attribute);\n    } else if (TEMPERATURE_ATTRIBUTES.has(attribute)) {\n      unit = config.unit_system.temperature;\n    }\n\n    if (unit) {\n      return `${formattedValue}${blankBeforeUnit(unit, locale)}${unit}`;\n    }\n\n    return formattedValue;\n  }\n\n  // Special handling in case this is a string with an known format\n  if (typeof attributeValue === \"string\") {\n    // Date handling\n    if (isDate(attributeValue, true)) {\n      // Timestamp handling\n      if (isTimestamp(attributeValue)) {\n        const date = new Date(attributeValue);\n        if (checkValidDate(date)) {\n          return formatDateTimeWithSeconds(date, locale, config);\n        }\n      }\n\n      // Value was not a timestamp, so only do date formatting\n      const date = new Date(attributeValue);\n      if (checkValidDate(date)) {\n        return formatDate(date, config, locale);\n      }\n    }\n  }\n\n  // Values are objects, render object\n  if (\n    (Array.isArray(attributeValue) && attributeValue.some((val) => val instanceof Object)) ||\n    (!Array.isArray(attributeValue) && attributeValue instanceof Object)\n  ) {\n    return JSON.stringify(attributeValue);\n  }\n  // If this is an array, try to determine the display value for each item\n  if (Array.isArray(attributeValue)) {\n    return attributeValue.map((item) => computeAttributeValueDisplay(entity, locale, config, entities, attribute, item)).join(\", \");\n  }\n\n  return localize(attributeValue);\n};\n","import {\n  localize,\n  computeDomain,\n  UNAVAILABLE,\n  UNKNOWN,\n  EntityName,\n  LocaleKeys,\n  EntityRegistryDisplayEntry,\n  FrontendLocaleData,\n} from \"@core\";\nimport { HassEntity, HassConfig, HassEntityAttributeBase } from \"home-assistant-js-websocket\";\n\nimport { formatNumber, getNumberFormatOptions, isNumericFromAttributes } from \"./number\";\nimport { UNIT_TO_MILLISECOND_CONVERT, formatDuration, formatDateTime, formatDate, formatTime } from \"./date\";\n\nexport const computeStateDisplay = (\n  entity: HassEntity,\n  config: HassConfig,\n  entities: Record<string, EntityRegistryDisplayEntry> | undefined,\n  locale: FrontendLocaleData | null,\n  sensorNumericDeviceClasses: string[],\n  state?: string,\n): string => {\n  const _entity = entities?.[entity.entity_id] as EntityRegistryDisplayEntry | undefined;\n  return computeStateDisplayFromEntityAttributes(\n    locale,\n    sensorNumericDeviceClasses,\n    config,\n    _entity,\n    entity.entity_id,\n    entity.attributes,\n    state !== undefined ? state : entity.state,\n  );\n};\n\n/**\n * Compute a human‑friendly display string for an entity's PRIMARY `state` value (not a specific attribute).\n *\n * Differences vs `computeAttributeValueDisplay`:\n * - Operates on the entity `state` only; does not traverse or recursively format nested structures.\n * - Applies domain/device_class heuristics (numeric, monetary, duration, timestamp/date handling).\n * - For numeric states uses `formatNumber` and appends raw unit_of_measurement if present.\n * - Handles special date/time domains by parsing the raw state string (e.g. \"2025-11-12 08:30:00\").\n * - Handles timestamp-like states (device_class: `timestamp` or specific domains) by converting ISO strings.\n * - Returns a localized placeholder for `unknown` or `unavailable`.\n * - Does NOT apply attribute-specific transforms like brightness %, weather units, temperature unit selection—those are handled by `computeAttributeValueDisplay` when formatting attributes individually.\n *\n * NOTE: This signature intentionally does not take a `locale` argument directly (unlike the attribute formatter)\n * because it historically relied on Home Assistant's internal formatting helpers where needed; date/time helpers\n * invoked here already localize based on global config/locale state upstream.\n *\n * Example Usage:\n * ```ts\n * // Numeric temperature sensor\n * computeStateDisplayFromEntityAttributes(conn, config, entry, 'sensor.living_room_temp', { unit_of_measurement: '°C', state_class: 'measurement' } as any, '21.56');\n * // => \"21.56°C\"\n *\n * // Duration sensor (device_class: duration, seconds)\n * computeStateDisplayFromEntityAttributes(conn, config, entry, 'sensor.timer', { device_class: 'duration', unit_of_measurement: 's' } as any, '3600');\n * // => \"1:00:00\"\n *\n * // input_datetime entity with date + time\n * computeStateDisplayFromEntityAttributes(conn, config, entry, 'input_datetime.event', {}, '2025-11-12 08:30:00');\n * // => \"Nov 12, 2025, 8:30 AM\" (example – actual formatting depends on locale)\n *\n * // Timestamp sensor\n * computeStateDisplayFromEntityAttributes(conn, config, entry, 'sensor.last_update', { device_class: 'timestamp' } as any, '2025-11-12T07:45:00.000Z');\n * // => Localized date/time string\n * ```\n */\nexport const computeStateDisplayFromEntityAttributes = (\n  locale: FrontendLocaleData | null,\n  sensorNumericDeviceClasses: string[],\n  config: HassConfig,\n  entity: EntityRegistryDisplayEntry | undefined,\n  entityId: string,\n  attributes: HassEntityAttributeBase,\n  state: string,\n): string => {\n  if (state === UNKNOWN || state === UNAVAILABLE) {\n    return localize(state);\n  }\n\n  const domain = computeDomain(entityId as EntityName);\n  const is_number_domain = domain === \"counter\" || domain === \"number\" || domain === \"input_number\";\n\n  // Entities with a `unit_of_measurement` or `state_class` are numeric values and should use `formatNumber`\n  if (isNumericFromAttributes(attributes, domain === \"sensor\" ? sensorNumericDeviceClasses : []) || is_number_domain) {\n    const key = attributes.unit_of_measurement as keyof typeof UNIT_TO_MILLISECOND_CONVERT;\n    // state is duration\n    if (\n      attributes.device_class === \"duration\" &&\n      attributes.unit_of_measurement &&\n      UNIT_TO_MILLISECOND_CONVERT[key] &&\n      entity?.display_precision === undefined\n    ) {\n      try {\n        return formatDuration(state, key);\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      } catch (_err) {\n        // fallback to default\n      }\n    }\n    if (attributes.device_class === \"monetary\") {\n      try {\n        return formatNumber(state, {\n          style: \"currency\",\n          currency: attributes.unit_of_measurement,\n          minimumFractionDigits: 2,\n          // Override monetary options with number format\n          ...getNumberFormatOptions({ state, attributes } as HassEntity, entity),\n        });\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n      } catch (_err) {\n        // fallback to default\n      }\n    }\n\n    const value = formatNumber(state, getNumberFormatOptions({ state, attributes } as HassEntity, entity));\n\n    const unit = attributes.unit_of_measurement;\n\n    if (unit) {\n      return `${value}${unit}`;\n    }\n\n    return value;\n  }\n\n  if ([\"date\", \"input_datetime\", \"time\"].includes(domain)) {\n    // If trying to display an explicit state, need to parse the explicit state to `Date` then format.\n    // Attributes aren't available, we have to use `state`.\n\n    // These are timezone agnostic, so we should NOT use the system timezone here.\n    try {\n      const components = state.split(\" \");\n      if (components.length === 2) {\n        // Date and time.\n        if (locale) return formatDateTime(new Date(components.join(\"T\")), config, locale);\n        return new Date(components.join(\"T\")).toLocaleString();\n      }\n      if (components.length === 1) {\n        if (state.includes(\"-\")) {\n          // Date only.\n          if (locale) return formatDate(new Date(`${state}T00:00`), config, locale);\n          return new Date(`${state}T00:00`).toLocaleDateString();\n        }\n        if (state.includes(\":\")) {\n          // Time only.\n          const now = new Date();\n          if (locale) return formatTime(new Date(`${now.toISOString().split(\"T\")[0]}T${state}`), config, locale);\n          return new Date(`${now.toISOString().split(\"T\")[0]}T${state}`).toLocaleTimeString();\n        }\n      }\n      return state;\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    } catch (_e) {\n      // Formatting methods may throw error if date parsing doesn't go well,\n      // just return the state string in that case.\n      return state;\n    }\n  }\n\n  // state is a timestamp\n  if (\n    [\n      \"ai_task\",\n      \"button\",\n      \"conversation\",\n      \"event\",\n      \"image\",\n      \"input_button\",\n      \"notify\",\n      \"scene\",\n      \"stt\",\n      \"tag\",\n      \"tts\",\n      \"wake_word\",\n      \"datetime\",\n    ].includes(domain) ||\n    (domain === \"sensor\" && attributes.device_class === \"timestamp\")\n  ) {\n    try {\n      if (locale) return formatDateTime(new Date(state), config, locale);\n      return new Date(state).toLocaleString();\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    } catch (_err) {\n      return state;\n    }\n  }\n\n  // state is a timestamp\n  if (\n    [\"button\", \"conversation\", \"event\", \"image\", \"input_button\", \"notify\", \"scene\", \"stt\", \"tag\", \"tts\", \"wake_word\"].includes(domain) ||\n    (domain === \"sensor\" && attributes.device_class === \"timestamp\")\n  ) {\n    try {\n      if (locale) return formatDateTime(new Date(state), config, locale);\n      return new Date(state).toLocaleString();\n      // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    } catch (_err) {\n      return state;\n    }\n  }\n\n  return localize(state as LocaleKeys);\n};\n","/** @license React v16.13.1\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var b=\"function\"===typeof Symbol&&Symbol.for,c=b?Symbol.for(\"react.element\"):60103,d=b?Symbol.for(\"react.portal\"):60106,e=b?Symbol.for(\"react.fragment\"):60107,f=b?Symbol.for(\"react.strict_mode\"):60108,g=b?Symbol.for(\"react.profiler\"):60114,h=b?Symbol.for(\"react.provider\"):60109,k=b?Symbol.for(\"react.context\"):60110,l=b?Symbol.for(\"react.async_mode\"):60111,m=b?Symbol.for(\"react.concurrent_mode\"):60111,n=b?Symbol.for(\"react.forward_ref\"):60112,p=b?Symbol.for(\"react.suspense\"):60113,q=b?\nSymbol.for(\"react.suspense_list\"):60120,r=b?Symbol.for(\"react.memo\"):60115,t=b?Symbol.for(\"react.lazy\"):60116,v=b?Symbol.for(\"react.block\"):60121,w=b?Symbol.for(\"react.fundamental\"):60117,x=b?Symbol.for(\"react.responder\"):60118,y=b?Symbol.for(\"react.scope\"):60119;\nfunction z(a){if(\"object\"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}exports.AsyncMode=l;exports.ConcurrentMode=m;exports.ContextConsumer=k;exports.ContextProvider=h;exports.Element=c;exports.ForwardRef=n;exports.Fragment=e;exports.Lazy=t;exports.Memo=r;exports.Portal=d;\nexports.Profiler=g;exports.StrictMode=f;exports.Suspense=p;exports.isAsyncMode=function(a){return A(a)||z(a)===l};exports.isConcurrentMode=A;exports.isContextConsumer=function(a){return z(a)===k};exports.isContextProvider=function(a){return z(a)===h};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===c};exports.isForwardRef=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};exports.isLazy=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};exports.isPortal=function(a){return z(a)===d};exports.isProfiler=function(a){return z(a)===g};exports.isStrictMode=function(a){return z(a)===f};exports.isSuspense=function(a){return z(a)===p};\nexports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||\"object\"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};exports.typeOf=z;\n","/** @license React v16.13.1\n * react-is.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n  (function() {\n'use strict';\n\n// The Symbol used to tag the ReactElement-like types. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar hasSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;\nvar REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;\nvar REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;\nvar REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;\nvar REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;\nvar REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;\nvar REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary\n// (unstable) APIs that have been removed. Can we remove the symbols?\n\nvar REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf;\nvar REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;\nvar REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;\nvar REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;\nvar REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;\nvar REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;\nvar REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;\nvar REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;\nvar REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;\nvar REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;\nvar REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;\n\nfunction isValidElementType(type) {\n  return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.\n  type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);\n}\n\nfunction typeOf(object) {\n  if (typeof object === 'object' && object !== null) {\n    var $$typeof = object.$$typeof;\n\n    switch ($$typeof) {\n      case REACT_ELEMENT_TYPE:\n        var type = object.type;\n\n        switch (type) {\n          case REACT_ASYNC_MODE_TYPE:\n          case REACT_CONCURRENT_MODE_TYPE:\n          case REACT_FRAGMENT_TYPE:\n          case REACT_PROFILER_TYPE:\n          case REACT_STRICT_MODE_TYPE:\n          case REACT_SUSPENSE_TYPE:\n            return type;\n\n          default:\n            var $$typeofType = type && type.$$typeof;\n\n            switch ($$typeofType) {\n              case REACT_CONTEXT_TYPE:\n              case REACT_FORWARD_REF_TYPE:\n              case REACT_LAZY_TYPE:\n              case REACT_MEMO_TYPE:\n              case REACT_PROVIDER_TYPE:\n                return $$typeofType;\n\n              default:\n                return $$typeof;\n            }\n\n        }\n\n      case REACT_PORTAL_TYPE:\n        return $$typeof;\n    }\n  }\n\n  return undefined;\n} // AsyncMode is deprecated along with isAsyncMode\n\nvar AsyncMode = REACT_ASYNC_MODE_TYPE;\nvar ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;\nvar ContextConsumer = REACT_CONTEXT_TYPE;\nvar ContextProvider = REACT_PROVIDER_TYPE;\nvar Element = REACT_ELEMENT_TYPE;\nvar ForwardRef = REACT_FORWARD_REF_TYPE;\nvar Fragment = REACT_FRAGMENT_TYPE;\nvar Lazy = REACT_LAZY_TYPE;\nvar Memo = REACT_MEMO_TYPE;\nvar Portal = REACT_PORTAL_TYPE;\nvar Profiler = REACT_PROFILER_TYPE;\nvar StrictMode = REACT_STRICT_MODE_TYPE;\nvar Suspense = REACT_SUSPENSE_TYPE;\nvar hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated\n\nfunction isAsyncMode(object) {\n  {\n    if (!hasWarnedAboutDeprecatedIsAsyncMode) {\n      hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint\n\n      console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.');\n    }\n  }\n\n  return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;\n}\nfunction isConcurrentMode(object) {\n  return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;\n}\nfunction isContextConsumer(object) {\n  return typeOf(object) === REACT_CONTEXT_TYPE;\n}\nfunction isContextProvider(object) {\n  return typeOf(object) === REACT_PROVIDER_TYPE;\n}\nfunction isElement(object) {\n  return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n}\nfunction isForwardRef(object) {\n  return typeOf(object) === REACT_FORWARD_REF_TYPE;\n}\nfunction isFragment(object) {\n  return typeOf(object) === REACT_FRAGMENT_TYPE;\n}\nfunction isLazy(object) {\n  return typeOf(object) === REACT_LAZY_TYPE;\n}\nfunction isMemo(object) {\n  return typeOf(object) === REACT_MEMO_TYPE;\n}\nfunction isPortal(object) {\n  return typeOf(object) === REACT_PORTAL_TYPE;\n}\nfunction isProfiler(object) {\n  return typeOf(object) === REACT_PROFILER_TYPE;\n}\nfunction isStrictMode(object) {\n  return typeOf(object) === REACT_STRICT_MODE_TYPE;\n}\nfunction isSuspense(object) {\n  return typeOf(object) === REACT_SUSPENSE_TYPE;\n}\n\nexports.AsyncMode = AsyncMode;\nexports.ConcurrentMode = ConcurrentMode;\nexports.ContextConsumer = ContextConsumer;\nexports.ContextProvider = ContextProvider;\nexports.Element = Element;\nexports.ForwardRef = ForwardRef;\nexports.Fragment = Fragment;\nexports.Lazy = Lazy;\nexports.Memo = Memo;\nexports.Portal = Portal;\nexports.Profiler = Profiler;\nexports.StrictMode = StrictMode;\nexports.Suspense = Suspense;\nexports.isAsyncMode = isAsyncMode;\nexports.isConcurrentMode = isConcurrentMode;\nexports.isContextConsumer = isContextConsumer;\nexports.isContextProvider = isContextProvider;\nexports.isElement = isElement;\nexports.isForwardRef = isForwardRef;\nexports.isFragment = isFragment;\nexports.isLazy = isLazy;\nexports.isMemo = isMemo;\nexports.isPortal = isPortal;\nexports.isProfiler = isProfiler;\nexports.isStrictMode = isStrictMode;\nexports.isSuspense = isSuspense;\nexports.isValidElementType = isValidElementType;\nexports.typeOf = typeOf;\n  })();\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n  module.exports = require('./cjs/react-is.production.min.js');\n} else {\n  module.exports = require('./cjs/react-is.development.js');\n}\n","'use strict';\n\nvar reactIs = require('react-is');\n\n/**\n * Copyright 2015, Yahoo! Inc.\n * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nvar REACT_STATICS = {\n  childContextTypes: true,\n  contextType: true,\n  contextTypes: true,\n  defaultProps: true,\n  displayName: true,\n  getDefaultProps: true,\n  getDerivedStateFromError: true,\n  getDerivedStateFromProps: true,\n  mixins: true,\n  propTypes: true,\n  type: true\n};\nvar KNOWN_STATICS = {\n  name: true,\n  length: true,\n  prototype: true,\n  caller: true,\n  callee: true,\n  arguments: true,\n  arity: true\n};\nvar FORWARD_REF_STATICS = {\n  '$$typeof': true,\n  render: true,\n  defaultProps: true,\n  displayName: true,\n  propTypes: true\n};\nvar MEMO_STATICS = {\n  '$$typeof': true,\n  compare: true,\n  defaultProps: true,\n  displayName: true,\n  propTypes: true,\n  type: true\n};\nvar TYPE_STATICS = {};\nTYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;\nTYPE_STATICS[reactIs.Memo] = MEMO_STATICS;\n\nfunction getStatics(component) {\n  // React v16.11 and below\n  if (reactIs.isMemo(component)) {\n    return MEMO_STATICS;\n  } // React v16.12 and above\n\n\n  return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;\n}\n\nvar defineProperty = Object.defineProperty;\nvar getOwnPropertyNames = Object.getOwnPropertyNames;\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar getPrototypeOf = Object.getPrototypeOf;\nvar objectPrototype = Object.prototype;\nfunction hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {\n  if (typeof sourceComponent !== 'string') {\n    // don't hoist over string (html) components\n    if (objectPrototype) {\n      var inheritedComponent = getPrototypeOf(sourceComponent);\n\n      if (inheritedComponent && inheritedComponent !== objectPrototype) {\n        hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);\n      }\n    }\n\n    var keys = getOwnPropertyNames(sourceComponent);\n\n    if (getOwnPropertySymbols) {\n      keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n    }\n\n    var targetStatics = getStatics(targetComponent);\n    var sourceStatics = getStatics(sourceComponent);\n\n    for (var i = 0; i < keys.length; ++i) {\n      var key = keys[i];\n\n      if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {\n        var descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n        try {\n          // Avoid failures from read-only properties\n          defineProperty(targetComponent, key, descriptor);\n        } catch (e) {}\n      }\n    }\n  }\n\n  return targetComponent;\n}\n\nmodule.exports = hoistNonReactStatics;\n","import * as React from 'react';\n\nvar syncFallback = function syncFallback(create) {\n  return create();\n};\n\nvar useInsertionEffect = React['useInsertion' + 'Effect'] ? React['useInsertion' + 'Effect'] : false;\nvar useInsertionEffectAlwaysWithSyncFallback = useInsertionEffect || syncFallback;\nvar useInsertionEffectWithLayoutFallback = useInsertionEffect || React.useLayoutEffect;\n\nexport { useInsertionEffectAlwaysWithSyncFallback, useInsertionEffectWithLayoutFallback };\n","import * as React from 'react';\nimport { useContext, forwardRef } from 'react';\nimport createCache from '@emotion/cache';\nimport _extends from '@babel/runtime/helpers/esm/extends';\nimport weakMemoize from '@emotion/weak-memoize';\nimport hoistNonReactStatics from '../_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js';\nimport { getRegisteredStyles, registerStyles, insertStyles } from '@emotion/utils';\nimport { serializeStyles } from '@emotion/serialize';\nimport { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks';\n\nvar isDevelopment = false;\n\nvar EmotionCacheContext = /* #__PURE__ */React.createContext( // we're doing this to avoid preconstruct's dead code elimination in this one case\n// because this module is primarily intended for the browser and node\n// but it's also required in react native and similar environments sometimes\n// and we could have a special build just for that\n// but this is much easier and the native packages\n// might use a different theme context in the future anyway\ntypeof HTMLElement !== 'undefined' ? /* #__PURE__ */createCache({\n  key: 'css'\n}) : null);\n\nvar CacheProvider = EmotionCacheContext.Provider;\nvar __unsafe_useEmotionCache = function useEmotionCache() {\n  return useContext(EmotionCacheContext);\n};\n\nvar withEmotionCache = function withEmotionCache(func) {\n  return /*#__PURE__*/forwardRef(function (props, ref) {\n    // the cache will never be null in the browser\n    var cache = useContext(EmotionCacheContext);\n    return func(props, cache, ref);\n  });\n};\n\nvar ThemeContext = /* #__PURE__ */React.createContext({});\n\nvar useTheme = function useTheme() {\n  return React.useContext(ThemeContext);\n};\n\nvar getTheme = function getTheme(outerTheme, theme) {\n  if (typeof theme === 'function') {\n    var mergedTheme = theme(outerTheme);\n\n    return mergedTheme;\n  }\n\n  return _extends({}, outerTheme, theme);\n};\n\nvar createCacheWithTheme = /* #__PURE__ */weakMemoize(function (outerTheme) {\n  return weakMemoize(function (theme) {\n    return getTheme(outerTheme, theme);\n  });\n});\nvar ThemeProvider = function ThemeProvider(props) {\n  var theme = React.useContext(ThemeContext);\n\n  if (props.theme !== theme) {\n    theme = createCacheWithTheme(theme)(props.theme);\n  }\n\n  return /*#__PURE__*/React.createElement(ThemeContext.Provider, {\n    value: theme\n  }, props.children);\n};\nfunction withTheme(Component) {\n  var componentName = Component.displayName || Component.name || 'Component';\n  var WithTheme = /*#__PURE__*/React.forwardRef(function render(props, ref) {\n    var theme = React.useContext(ThemeContext);\n    return /*#__PURE__*/React.createElement(Component, _extends({\n      theme: theme,\n      ref: ref\n    }, props));\n  });\n  WithTheme.displayName = \"WithTheme(\" + componentName + \")\";\n  return hoistNonReactStatics(WithTheme, Component);\n}\n\nvar hasOwn = {}.hasOwnProperty;\n\nvar typePropName = '__EMOTION_TYPE_PLEASE_DO_NOT_USE__';\nvar createEmotionProps = function createEmotionProps(type, props) {\n\n  var newProps = {};\n\n  for (var _key in props) {\n    if (hasOwn.call(props, _key)) {\n      newProps[_key] = props[_key];\n    }\n  }\n\n  newProps[typePropName] = type; // Runtime labeling is an opt-in feature because:\n\n  return newProps;\n};\n\nvar Insertion = function Insertion(_ref) {\n  var cache = _ref.cache,\n      serialized = _ref.serialized,\n      isStringTag = _ref.isStringTag;\n  registerStyles(cache, serialized, isStringTag);\n  useInsertionEffectAlwaysWithSyncFallback(function () {\n    return insertStyles(cache, serialized, isStringTag);\n  });\n\n  return null;\n};\n\nvar Emotion = /* #__PURE__ */withEmotionCache(function (props, cache, ref) {\n  var cssProp = props.css; // so that using `css` from `emotion` and passing the result to the css prop works\n  // not passing the registered cache to serializeStyles because it would\n  // make certain babel optimisations not possible\n\n  if (typeof cssProp === 'string' && cache.registered[cssProp] !== undefined) {\n    cssProp = cache.registered[cssProp];\n  }\n\n  var WrappedComponent = props[typePropName];\n  var registeredStyles = [cssProp];\n  var className = '';\n\n  if (typeof props.className === 'string') {\n    className = getRegisteredStyles(cache.registered, registeredStyles, props.className);\n  } else if (props.className != null) {\n    className = props.className + \" \";\n  }\n\n  var serialized = serializeStyles(registeredStyles, undefined, React.useContext(ThemeContext));\n\n  className += cache.key + \"-\" + serialized.name;\n  var newProps = {};\n\n  for (var _key2 in props) {\n    if (hasOwn.call(props, _key2) && _key2 !== 'css' && _key2 !== typePropName && (!isDevelopment )) {\n      newProps[_key2] = props[_key2];\n    }\n  }\n\n  newProps.className = className;\n\n  if (ref) {\n    newProps.ref = ref;\n  }\n\n  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Insertion, {\n    cache: cache,\n    serialized: serialized,\n    isStringTag: typeof WrappedComponent === 'string'\n  }), /*#__PURE__*/React.createElement(WrappedComponent, newProps));\n});\n\nvar Emotion$1 = Emotion;\n\nexport { CacheProvider as C, Emotion$1 as E, ThemeContext as T, __unsafe_useEmotionCache as _, ThemeProvider as a, withTheme as b, createEmotionProps as c, hasOwn as h, isDevelopment as i, useTheme as u, withEmotionCache as w };\n","import * as ReactJSXRuntime from 'react/jsx-runtime';\nimport { h as hasOwn, E as Emotion, c as createEmotionProps } from '../../dist/emotion-element-f0de968e.browser.esm.js';\nimport 'react';\nimport '@emotion/cache';\nimport '@babel/runtime/helpers/extends';\nimport '@emotion/weak-memoize';\nimport '../../_isolated-hnrs/dist/emotion-react-_isolated-hnrs.browser.esm.js';\nimport 'hoist-non-react-statics';\nimport '@emotion/utils';\nimport '@emotion/serialize';\nimport '@emotion/use-insertion-effect-with-fallbacks';\n\nvar Fragment = ReactJSXRuntime.Fragment;\nvar jsx = function jsx(type, props, key) {\n  if (!hasOwn.call(props, 'css')) {\n    return ReactJSXRuntime.jsx(type, props, key);\n  }\n\n  return ReactJSXRuntime.jsx(Emotion, createEmotionProps(type, props), key);\n};\nvar jsxs = function jsxs(type, props, key) {\n  if (!hasOwn.call(props, 'css')) {\n    return ReactJSXRuntime.jsxs(type, props, key);\n  }\n\n  return ReactJSXRuntime.jsxs(Emotion, createEmotionProps(type, props), key);\n};\n\nexport { Fragment, jsx, jsxs };\n","const isIterable = (obj) => Symbol.iterator in obj;\nconst hasIterableEntries = (value) => (\n  // HACK: avoid checking entries type\n  \"entries\" in value\n);\nconst compareEntries = (valueA, valueB) => {\n  const mapA = valueA instanceof Map ? valueA : new Map(valueA.entries());\n  const mapB = valueB instanceof Map ? valueB : new Map(valueB.entries());\n  if (mapA.size !== mapB.size) {\n    return false;\n  }\n  for (const [key, value] of mapA) {\n    if (!mapB.has(key) || !Object.is(value, mapB.get(key))) {\n      return false;\n    }\n  }\n  return true;\n};\nconst compareIterables = (valueA, valueB) => {\n  const iteratorA = valueA[Symbol.iterator]();\n  const iteratorB = valueB[Symbol.iterator]();\n  let nextA = iteratorA.next();\n  let nextB = iteratorB.next();\n  while (!nextA.done && !nextB.done) {\n    if (!Object.is(nextA.value, nextB.value)) {\n      return false;\n    }\n    nextA = iteratorA.next();\n    nextB = iteratorB.next();\n  }\n  return !!nextA.done && !!nextB.done;\n};\nfunction shallow(valueA, valueB) {\n  if (Object.is(valueA, valueB)) {\n    return true;\n  }\n  if (typeof valueA !== \"object\" || valueA === null || typeof valueB !== \"object\" || valueB === null) {\n    return false;\n  }\n  if (Object.getPrototypeOf(valueA) !== Object.getPrototypeOf(valueB)) {\n    return false;\n  }\n  if (isIterable(valueA) && isIterable(valueB)) {\n    if (hasIterableEntries(valueA) && hasIterableEntries(valueB)) {\n      return compareEntries(valueA, valueB);\n    }\n    return compareIterables(valueA, valueB);\n  }\n  return compareEntries(\n    { entries: () => Object.entries(valueA) },\n    { entries: () => Object.entries(valueB) }\n  );\n}\n\nexport { shallow };\n","import React from 'react';\nimport { shallow } from 'zustand/vanilla/shallow';\n\nfunction useShallow(selector) {\n  const prev = React.useRef(void 0);\n  return (state) => {\n    const next = selector(state);\n    return shallow(prev.current, next) ? prev.current : prev.current = next;\n  };\n}\n\nexport { useShallow };\n","import { useEffect, useCallback } from \"react\";\nimport { subscribeEntities, subscribeConfig, subscribeServices } from \"home-assistant-js-websocket\";\nimport { Locales } from \"@typings\";\nimport { loadTokens } from \"./token-storage\";\nimport { InternalStore, useInternalStore, useHassProviderStore } from \"./HassContext\";\nimport { useHass } from \"../hooks/useHass\";\nimport { useShallow } from \"zustand/shallow\";\nimport { handleSuspendResume, type HandleSuspendResumeOptions } from \"./handleSuspendResume\";\nimport { handleError, tryConnection } from \"./tryConnection\";\nimport {\n  subscribeAreaRegistry,\n  subscribeEntityRegistryDisplay,\n  subscribeDeviceRegistry,\n  subscribeFloorRegistry,\n  subscribeFrontendUserData,\n  getUserLocaleLanguage,\n  type SensorNumericDeviceClasses,\n} from \"@core\";\nimport { subscribeUser, subscribeUsers } from \"@utils/subscribe/user\";\n\nexport interface HassProviderProps {\n  /** components to render once authenticated, this accepts a child function which will pass if it is ready or not */\n  children: (ready: boolean) => React.ReactNode;\n  /** the home assistant url */\n  hassUrl: string;\n  /** if you provide a hassToken you will bypass the login screen altogether - @see https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token */\n  hassToken?: string;\n  /** the language of the UI to use, this will also control the values used within the `localize` function or `useLocale` / `useLocales` hooks, by default this is retrieved from your home assistant instance. */\n  locale?: Locales;\n  /** location to render portals @default document.body */\n  portalRoot?: HTMLElement;\n  /** Will tell the various features like breakpoints, modals and resize events which window to match media on, if serving within an iframe it'll potentially be running in the wrong window */\n  windowContext?: Window;\n  /** A method to render any error states with a react wrapper of your choosing, useful if you want to change styles */\n  renderError?: (children: React.ReactNode) => React.ReactNode;\n  /** options to provide to the handleResume functionality for the HA web socket connection */\n  handleResumeOptions?: HandleSuspendResumeOptions;\n}\n\n// Track if a connection attempt for the current hassUrl has already started in this page lifecycle.\n// Using a ref avoids any need for timers and is Strict Mode safe.\nconst attemptedUrls = new Set<string>();\n\nexport function HassProvider({\n  children,\n  hassUrl,\n  hassToken,\n  portalRoot,\n  windowContext,\n  renderError = (children) => children,\n  handleResumeOptions,\n}: HassProviderProps) {\n  // provider-level state & subscription helpers from dedicated store\n  const addSubscription = useHassProviderStore((s) => s.addSubscription);\n  const setAuthenticated = useHassProviderStore((s) => s.setAuthenticated);\n  const {\n    hash: _hash,\n    ready,\n    error,\n    cannotConnect,\n    setError,\n  } = useInternalStore(\n    useShallow((s) => ({\n      hash: s.hash,\n      routes: s.routes,\n      ready: s.ready, // ready is set internally in the store when we have entities (setEntities does this)\n      error: s.error,\n      cannotConnect: s.cannotConnect,\n      auth: s.auth,\n      setError: s.setError,\n    })),\n  );\n\n  useEffect(() => {\n    const { setPortalRoot } = useInternalStore.getState();\n    if (portalRoot) setPortalRoot(portalRoot);\n  }, [portalRoot]);\n\n  useEffect(() => {\n    const { setWindowContext } = useInternalStore.getState();\n    if (windowContext) setWindowContext(windowContext);\n  }, [windowContext]);\n\n  const handleConnect = useCallback(async () => {\n    const {\n      setError,\n      setUser,\n      setCannotConnect,\n      setAuth,\n      setConnection,\n      setEntities,\n      setConfig,\n      setConnectionStatus,\n      setAreas,\n      setDevices,\n      setFloors,\n      setEntitiesRegistryDisplay,\n      setServices,\n      setUsers,\n      setLocale,\n      setSensorNumericDeviceClasses,\n    } = useInternalStore.getState();\n\n    // this will trigger on first mount\n    const response = await tryConnection(hassUrl, hassToken);\n    if (response.type === \"error\") {\n      setAuthenticated(false);\n      setError(response.error);\n    } else if (response.type === \"failed\") {\n      setAuthenticated(false);\n      setCannotConnect(true);\n    } else if (response.type === \"success\") {\n      const { connection, auth } = response;\n      // store a reference to the authentication object\n      setAuth(auth);\n      // store the connection to pass to the provider\n      setConnection(connection);\n      addSubscription(\n        \"entities\",\n        subscribeEntities(connection, ($entities) => {\n          setEntities($entities);\n        }),\n      );\n      addSubscription(\n        \"entity_registry_display\",\n        subscribeEntityRegistryDisplay(connection, (entityReg) => {\n          const entitiesRegistryDisplay: InternalStore[\"entitiesRegistryDisplay\"] = {};\n          for (const entity of entityReg.entities) {\n            entitiesRegistryDisplay[entity.ei] = {\n              entity_id: entity.ei,\n              device_id: entity.di,\n              area_id: entity.ai,\n              labels: entity.lb,\n              translation_key: entity.tk,\n              platform: entity.pl,\n              entity_category: entity.ec !== undefined ? entityReg.entity_categories[entity.ec] : undefined,\n              has_entity_name: entity.hn,\n              name: entity.en,\n              icon: entity.ic,\n              hidden: entity.hb,\n              display_precision: entity.dp,\n            };\n          }\n          setEntitiesRegistryDisplay(entitiesRegistryDisplay);\n        }),\n      );\n      addSubscription(\n        \"areas\",\n        subscribeAreaRegistry(connection, (areaReg) => {\n          const areas: InternalStore[\"areas\"] = {};\n          for (const area of areaReg) {\n            areas[area.area_id] = area;\n          }\n          setAreas(areas);\n        }),\n      );\n      addSubscription(\n        \"devices\",\n        subscribeDeviceRegistry(connection, (deviceReg) => {\n          const devices: InternalStore[\"devices\"] = {};\n          for (const device of deviceReg) {\n            devices[device.id] = device;\n          }\n          setDevices(devices);\n        }),\n      );\n      addSubscription(\n        \"floors\",\n        subscribeFloorRegistry(connection, (floorReg) => {\n          const floors: InternalStore[\"floors\"] = {};\n          for (const floor of floorReg) {\n            floors[floor.floor_id] = floor;\n          }\n          setFloors(floors);\n        }),\n      );\n      addSubscription(\n        \"config\",\n        subscribeConfig(connection, (newConfig) => {\n          setConfig(newConfig);\n        }),\n      );\n\n      addSubscription(\n        \"current_user\",\n        subscribeUser(connection, (user) => {\n          setUser(user);\n        }),\n      );\n\n      addSubscription(\n        \"services\",\n        subscribeServices(connection, (services) => {\n          setServices(services);\n        }),\n      );\n\n      addSubscription(\n        \"users\",\n        subscribeUsers(connection, (users) => {\n          setUsers(users);\n        }),\n      );\n\n      addSubscription(\n        \"language\",\n        await subscribeFrontendUserData(connection, \"language\", (data) => {\n          if (data.value) {\n            const language = getUserLocaleLanguage(data.value);\n            setLocale({\n              ...data.value,\n              language,\n            });\n          } else {\n            setLocale(data.value);\n          }\n        }),\n      );\n\n      connection\n        .sendMessagePromise<SensorNumericDeviceClasses>({\n          type: \"sensor/numeric_device_classes\",\n        })\n        .then((sensorNumericDeviceClasses) => {\n          // once we have the device classes, we are ready\n          setSensorNumericDeviceClasses(sensorNumericDeviceClasses.numeric_device_classes);\n        });\n\n      const { onStatusChange, ...rest } = handleResumeOptions || {};\n      // return the cleanup function\n      const resumeCleanup = handleSuspendResume(connection, {\n        suspendWhenHidden: true,\n        hiddenDelayMs: 300_000, // 5 minutes\n        debug: false,\n        onStatusChange: (status) => {\n          setConnectionStatus(status);\n          onStatusChange?.(status);\n        },\n        ...rest,\n      });\n      addSubscription(\"resume\", resumeCleanup);\n    }\n  }, [hassUrl, hassToken, handleResumeOptions, addSubscription, setAuthenticated]);\n\n  useEffect(() => {\n    const { setHassUrl } = useInternalStore.getState();\n    setHassUrl(hassUrl);\n  }, [hassUrl]);\n\n  useEffect(() => {\n    const { setHash } = useInternalStore.getState();\n    if (location.hash === \"\") return;\n    if (location.hash.replace(\"#\", \"\") === _hash) return;\n    setHash(location.hash);\n  }, [_hash]);\n\n  useEffect(() => {\n    if (typeof window !== \"undefined\") window.addEventListener(\"hashchange\", onHashChange);\n    return () => {\n      if (typeof window !== \"undefined\") window.removeEventListener(\"hashchange\", onHashChange);\n    };\n  }, []);\n\n  // Standard unmount cleanup; Strict Mode double-invocation will call this twice but second time state already cleared.\n  useEffect(() => () => useHassProviderStore.getState().reset(), []);\n\n  // then wrap the whole connect routine so it’s stable too\n  const connectOnce = useCallback(async () => {\n    if (attemptedUrls.has(hassUrl)) return;\n    attemptedUrls.add(hassUrl);\n    try {\n      if (useHassProviderStore.getState().authenticated && useInternalStore.getState().hassUrl !== hassUrl) {\n        useHassProviderStore.getState().reset();\n      }\n      setAuthenticated(true);\n      handleResumeOptions?.onStatusChange?.(\"pending\");\n      await handleConnect();\n    } catch (e) {\n      const message = handleError(e);\n      setError(`Unable to connect to Home Assistant, please check the URL: \"${message}\"`);\n    }\n  }, [handleConnect, setError, handleResumeOptions, hassUrl, setAuthenticated]);\n\n  // run it once after mount\n  useEffect(() => {\n    connectOnce();\n  }, [connectOnce]);\n\n  if (cannotConnect) {\n    return renderError(\n      <p>\n        Unable to connect to {loadTokens(hassUrl)?.hassUrl}, refresh the page and try again, or{\" \"}\n        <a onClick={useHass.getState().helpers.logout}>Logout</a>.\n      </p>,\n    );\n  }\n  return error === null ? children(ready) : renderError(error);\n}\n\nfunction onHashChange() {\n  const { routes, setRoutes, setHash } = useInternalStore.getState();\n  setRoutes(\n    routes.map((route) => {\n      if (route.hash === location.hash.replace(\"#\", \"\")) {\n        return {\n          ...route,\n          active: true,\n        };\n      }\n      return {\n        ...route,\n        active: false,\n      };\n    }),\n  );\n  setHash(location.hash);\n}\n","import { useMemo } from \"react\";\nimport { useHass } from \"@core\";\n\nexport function useConfig() {\n  const config = useHass((state) => state.config);\n\n  // Memoize the config to prevent unnecessary re-renders\n  return useMemo(() => config, [config]);\n}\n","/**\n * Device & entity registry helpers and subscription utilities.\n *\n * This module wraps Home Assistant websocket commands for the device registry and\n * provides a set of lookup builders and higher-level selection/filtering utilities\n * consumed by UI components (e.g. device pickers, area views). It also normalizes\n * naming so that fallbacks (like deriving a device label from one of its entities)\n * are consistently applied.\n *\n * Key exports:\n * - Subscription: `subscribeDeviceRegistry` (debounced event driven updates)\n * - Mutations: `updateDeviceRegistryEntry`, `removeConfigEntryFromDevice`\n * - Lookups: `getDeviceEntityLookup`, `getDeviceEntityDisplayLookup`, `getDeviceIntegrationLookup`\n * - Context resolution: `getDeviceContext`\n * - Filtering & listing: `getDevices` (rich multi-criteria filtering)\n */\nimport {\n  AreaRegistryEntry,\n  caseInsensitiveStringCompare,\n  computeAreaName,\n  computeDeviceNameDisplay,\n  computeDomain,\n  computeStateName,\n  EntityListInfoCommon,\n  EntityName,\n  EntityRegistryDisplayEntry,\n  EntityRegistryEntry,\n  FloorRegistryEntry,\n  LocaleKeys,\n  localize,\n  RegistryEntry,\n} from \"@core\";\nimport { Connection, createCollection, HassEntities, HassEntity } from \"home-assistant-js-websocket\";\nimport { Store } from \"home-assistant-js-websocket/dist/store.js\";\nimport { debounce } from \"lodash\";\nimport { EntitySources } from \"./entity_sources\";\n\n/**\n * Home Assistant device registry entry (extended shape).\n * Mirrors HA's `config/device_registry/list` response with selected fields.\n */\nexport interface DeviceRegistryEntry extends RegistryEntry {\n  id: string;\n  config_entries: string[];\n  config_entries_subentries: Record<string, (string | null)[]>;\n  connections: [string, string][];\n  identifiers: [string, string][];\n  manufacturer: string | null;\n  model: string | null;\n  model_id: string | null;\n  name: string | null;\n  labels: string[];\n  sw_version: string | null;\n  hw_version: string | null;\n  serial_number: string | null;\n  via_device_id: string | null;\n  area_id: string | null;\n  name_by_user: string | null;\n  entry_type: \"service\" | null;\n  disabled_by: \"user\" | \"integration\" | \"config_entry\" | null;\n  configuration_url: string | null;\n  primary_config_entry: string | null;\n}\n\n/**\n * Retrieve the full device registry list from Home Assistant.\n * @param conn Active websocket connection.\n * @returns Promise resolving to the array of device registry entries.\n */\nconst fetchDeviceRegistry = (conn: Connection) => conn.sendMessagePromise<DeviceRegistryEntry[]>({ type: \"config/device_registry/list\" });\n\n/**\n * Internal helper to subscribe to device registry update events.\n * Debounces fetches to avoid hammering the websocket when bursts of updates occur.\n * @param conn Active HA connection.\n * @param store Local collection store receiving updated state.\n */\nconst subscribeDeviceRegistryUpdates = (conn: Connection, store: Store<DeviceRegistryEntry[]>) =>\n  conn.subscribeEvents(\n    debounce(() => fetchDeviceRegistry(conn).then((devices) => store.setState(devices, true)), 500, { leading: true, trailing: true }),\n    \"device_registry_updated\",\n  );\n\n/**\n * Public subscription wrapper providing createCollection semantics.\n * @param conn Active HA connection.\n * @param onChange Callback invoked with the latest device list anytime it changes.\n * @returns Unsubscribe function to stop listening.\n */\nexport const subscribeDeviceRegistry = (conn: Connection, onChange: (devices: DeviceRegistryEntry[]) => void) =>\n  createCollection<DeviceRegistryEntry[]>(\"_dr\", fetchDeviceRegistry, subscribeDeviceRegistryUpdates, conn, onChange);\n\nexport type DeviceEntityDisplayLookup = Record<string, EntityRegistryDisplayEntry[]>;\n\nexport type DeviceEntityLookup = Record<string, EntityRegistryEntry[]>;\n\nexport interface DeviceRegistryEntryMutableParams {\n  area_id?: string | null;\n  name_by_user?: string | null;\n  disabled_by?: string | null;\n  labels?: string[];\n}\n\n/**\n * Attempt to derive a readable device name from one of its entities' state names.\n * Used when the device has no explicit name.\n * @param hassEntities Current states map.\n * @param entities Entities associated with the device (or raw entity_id strings).\n * @returns First non-empty computed state name or undefined.\n */\nexport const fallbackDeviceName = (\n  hassEntities: HassEntities,\n  entities: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[],\n) => {\n  for (const entity of entities || []) {\n    const entityId = typeof entity === \"string\" ? entity : entity.entity_id;\n    const stateObj = hassEntities[entityId];\n    if (stateObj) {\n      return computeStateName(stateObj);\n    }\n  }\n  return undefined;\n};\n\n/**\n * Filter devices by a specific area id.\n * @param devices All devices.\n * @param areaId Target area id.\n */\nexport const devicesInArea = (devices: DeviceRegistryEntry[], areaId: string) => devices.filter((device) => device.area_id === areaId);\n\n/**\n * Update mutable fields on a device registry entry.\n * @param connection HA connection.\n * @param deviceId Target device id.\n * @param updates Partial of mutable params.\n * @returns Updated device entry.\n */\nexport const updateDeviceRegistryEntry = (connection: Connection, deviceId: string, updates: Partial<DeviceRegistryEntryMutableParams>) =>\n  connection.sendMessagePromise<DeviceRegistryEntry>({ type: \"config/device_registry/update\", device_id: deviceId, ...updates });\n\n/**\n * Detach a config entry from a device (e.g. removing an integration association).\n * @param connection HA connection.\n * @param deviceId Device id.\n * @param configEntryId Config entry id to remove.\n * @returns Updated device entry.\n */\nexport const removeConfigEntryFromDevice = (connection: Connection, deviceId: string, configEntryId: string) =>\n  connection.sendMessagePromise<DeviceRegistryEntry>({\n    type: \"config/device_registry/remove_config_entry\",\n    device_id: deviceId,\n    config_entry_id: configEntryId,\n  });\n\n/**\n * Sort devices in-place by their name using locale-aware case-insensitive comparison.\n * @param entries Mutable array of device entries.\n * @param language BCP-47 locale tag.\n */\nexport const sortDeviceRegistryByName = (entries: DeviceRegistryEntry[], language: string) =>\n  entries.sort((entry1, entry2) => caseInsensitiveStringCompare(entry1.name || \"\", entry2.name || \"\", language));\n\n/**\n * Build a lookup mapping device_id => entities (raw registry entries).\n * @param entities All entity registry entries.\n */\nexport const getDeviceEntityLookup = (entities: EntityRegistryEntry[]): DeviceEntityLookup => {\n  const deviceEntityLookup: DeviceEntityLookup = {};\n  for (const entity of entities) {\n    if (!entity.device_id) {\n      continue;\n    }\n    if (!(entity.device_id in deviceEntityLookup)) {\n      deviceEntityLookup[entity.device_id] = [];\n    }\n    deviceEntityLookup[entity.device_id].push(entity);\n  }\n  return deviceEntityLookup;\n};\n\n/**\n * Build a lookup mapping device_id => display entities (enriched entries).\n * @param entities Enriched entity display entries.\n */\nexport const getDeviceEntityDisplayLookup = (entities: EntityRegistryDisplayEntry[]): DeviceEntityDisplayLookup => {\n  const deviceEntityLookup: DeviceEntityDisplayLookup = {};\n  for (const entity of entities) {\n    if (!entity.device_id) {\n      continue;\n    }\n    if (!(entity.device_id in deviceEntityLookup)) {\n      deviceEntityLookup[entity.device_id] = [];\n    }\n    deviceEntityLookup[entity.device_id].push(entity);\n  }\n  return deviceEntityLookup;\n};\n\nexport interface ConfigEntry {\n  entry_id: string;\n  domain: string;\n  title: string;\n  source: string;\n  state: \"loaded\" | \"setup_error\" | \"migration_error\" | \"setup_retry\" | \"not_loaded\" | \"failed_unload\" | \"setup_in_progress\";\n  supports_options: boolean;\n  supports_remove_device: boolean;\n  supports_unload: boolean;\n  supports_reconfigure: boolean;\n  supported_subentry_types: Record<string, { supports_reconfigure: boolean }>;\n  num_subentries: number;\n  pref_disable_new_entities: boolean;\n  pref_disable_polling: boolean;\n  disabled_by: \"user\" | null;\n  reason: string | null;\n  error_reason_translation_key: string | null;\n  error_reason_translation_placeholders: Record<string, string> | null;\n}\n\n/**\n * Derive a mapping of device_id => set of integration domains.\n * Sources:\n * - Primary: entitySources (entity_id -> domain) for entities bound to the device.\n * - Fallback: config entry domains for devices that have no entities.\n * @param entitySources Source map from `entity/source`.\n * @param entities Entity entries (display or raw) to inspect for device linkage.\n * @param devices Optional list of devices (for fallback when no entities).\n * @param configEntries Optional config entry list for domain fallback.\n */\nexport const getDeviceIntegrationLookup = (\n  entitySources: EntitySources,\n  entities: EntityRegistryDisplayEntry[] | EntityRegistryEntry[],\n  devices?: DeviceRegistryEntry[],\n  configEntries?: ConfigEntry[],\n): Record<string, Set<string>> => {\n  const deviceIntegrations: Record<string, Set<string>> = {};\n\n  for (const entity of entities) {\n    const source = entitySources[entity.entity_id];\n    if (!source?.domain || entity.device_id === null) {\n      continue;\n    }\n\n    deviceIntegrations[entity.device_id!] = deviceIntegrations[entity.device_id!] || new Set<string>();\n    deviceIntegrations[entity.device_id!].add(source.domain);\n  }\n  // Lookup devices that have no entities\n  if (devices && configEntries) {\n    for (const device of devices) {\n      for (const config_entry_id of device.config_entries) {\n        const entry = configEntries.find((e) => e.entry_id === config_entry_id);\n        if (entry?.domain) {\n          deviceIntegrations[device.id] = deviceIntegrations[device.id] || new Set<string>();\n          deviceIntegrations[device.id].add(entry.domain);\n        }\n      }\n    }\n  }\n  return deviceIntegrations;\n};\n\n/**\n * Combined context for a device including resolved area and floor.\n */\ninterface DeviceContext {\n  device: DeviceRegistryEntry;\n  area: AreaRegistryEntry | null;\n  floor: FloorRegistryEntry | null;\n}\n\n/**\n * Resolve the area and floor objects for a given device.\n * @param device Device entry.\n * @param areas Lookup of areas by id.\n * @param floors Lookup of floors by id.\n */\nexport const getDeviceContext = (\n  device: DeviceRegistryEntry,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n): DeviceContext => {\n  const areaId = device.area_id;\n  const area = areaId ? areas[areaId] : undefined;\n  const floorId = area?.floor_id;\n  const floor = floorId ? floors[floorId] : undefined;\n\n  return {\n    device: device,\n    area: area || null,\n    floor: floor || null,\n  };\n};\n\n/**\n * UI-friendly projection of a device suitable for list/search components.\n */\nexport interface DeviceListItem extends EntityListInfoCommon {\n  domain?: string;\n  domain_name?: string;\n}\n\n/**\n * Build a filtered, decorated list of devices for display/search.\n *\n * Filtering criteria (applied in sequence):\n * - Disabled devices excluded (unless matching `value` id)\n * - includeDomains: keep devices having at least one entity in one of the domains.\n * - excludeDomains: drop devices having any entity in excluded domains.\n * - excludeDevices: explicit id exclusion list.\n * - includeDeviceClasses: keep devices with entities whose state attributes.device_class matches.\n * - entityFilter: arbitrary predicate on entity state objects (logical OR across entities).\n * - deviceFilter: arbitrary predicate on the device (OR forcing inclusion if matches current `value`).\n *\n * Naming logic:\n * - Primary label derived via `computeDeviceNameDisplay` (uses explicit name or entity fallbacks).\n * - Secondary label uses area name when available.\n * - Domain & localized domain name derived from primary config entry (if present).\n *\n * @param hassEntities States map for entity-level filtering/device naming.\n * @param areas Area lookup.\n * @param floors Floor lookup.\n * @param entitiesI Entity display entry lookup keyed by entity_id.\n * @param devicesI Device registry lookup keyed by id.\n * @param configEntryLookup Config entries keyed by entry_id.\n * @param includeDomains Domains that must appear in device's entities to include the device.\n * @param excludeDomains Domains that, if present, exclude the device.\n * @param includeDeviceClasses Device classes that must appear among entities.\n * @param deviceFilter Optional predicate on device entry.\n * @param entityFilter Optional predicate on entity state.\n * @param excludeDevices Explicit list of device ids to omit.\n * @param value Current selected device id (always retained even if disabled or filtered out).\n * @param idPrefix Optional prefix applied to output item ids.\n * @returns Array of `DeviceListItem` ready for rendering/search.\n */\nexport const getDevices = (\n  hassEntities: HassEntities,\n  areas: Record<string, AreaRegistryEntry>,\n  floors: Record<string, FloorRegistryEntry>,\n  entitiesI: Record<string, EntityRegistryDisplayEntry>,\n  devicesI: Record<string, DeviceRegistryEntry>,\n  configEntryLookup: Record<string, ConfigEntry>,\n  includeDomains?: string[],\n  excludeDomains?: string[],\n  includeDeviceClasses?: string[],\n  deviceFilter?: (device: DeviceRegistryEntry) => boolean,\n  entityFilter?: (entity: HassEntity) => boolean,\n  excludeDevices?: string[],\n  value?: string,\n  idPrefix = \"\",\n): DeviceListItem[] => {\n  const devices = Object.values(devicesI);\n  const entities = Object.values(entitiesI);\n\n  let deviceEntityLookup: DeviceEntityDisplayLookup = {};\n\n  if (includeDomains || excludeDomains || includeDeviceClasses || entityFilter) {\n    deviceEntityLookup = getDeviceEntityDisplayLookup(entities);\n  }\n\n  let inputDevices = devices.filter((device) => device.id === value || !device.disabled_by);\n\n  if (includeDomains) {\n    inputDevices = inputDevices.filter((device) => {\n      const devEntities = deviceEntityLookup[device.id];\n      if (!devEntities || !devEntities.length) {\n        return false;\n      }\n      return deviceEntityLookup[device.id].some((entity) => includeDomains.includes(computeDomain(entity.entity_id as EntityName)));\n    });\n  }\n\n  if (excludeDomains) {\n    inputDevices = inputDevices.filter((device) => {\n      const devEntities = deviceEntityLookup[device.id];\n      if (!devEntities || !devEntities.length) {\n        return true;\n      }\n      return entities.every((entity) => !excludeDomains.includes(computeDomain(entity.entity_id as EntityName)));\n    });\n  }\n\n  if (excludeDevices) {\n    inputDevices = inputDevices.filter((device) => !excludeDevices!.includes(device.id));\n  }\n\n  if (includeDeviceClasses) {\n    inputDevices = inputDevices.filter((device) => {\n      const devEntities = deviceEntityLookup[device.id];\n      if (!devEntities || !devEntities.length) {\n        return false;\n      }\n      return deviceEntityLookup[device.id].some((entity) => {\n        const stateObj = hassEntities[entity.entity_id];\n        if (!stateObj) {\n          return false;\n        }\n        return stateObj.attributes.device_class && includeDeviceClasses.includes(stateObj.attributes.device_class);\n      });\n    });\n  }\n\n  if (entityFilter) {\n    inputDevices = inputDevices.filter((device) => {\n      const devEntities = deviceEntityLookup[device.id];\n      if (!devEntities || !devEntities.length) {\n        return false;\n      }\n      return devEntities.some((entity) => {\n        const stateObj = hassEntities[entity.entity_id];\n        if (!stateObj) {\n          return false;\n        }\n        return entityFilter(stateObj);\n      });\n    });\n  }\n\n  if (deviceFilter) {\n    inputDevices = inputDevices.filter(\n      (device) =>\n        // We always want to include the device of the current value\n        device.id === value || deviceFilter!(device),\n    );\n  }\n\n  const outputDevices = inputDevices.map<DeviceListItem>((device) => {\n    const deviceName = computeDeviceNameDisplay(device, hassEntities, deviceEntityLookup[device.id]);\n\n    const { area } = getDeviceContext(device, areas, floors);\n\n    const areaName = area ? computeAreaName(area) : undefined;\n\n    const configEntry = device.primary_config_entry ? configEntryLookup?.[device.primary_config_entry] : undefined;\n\n    const domain = configEntry?.domain;\n    const domainName = domain\n      ? localize(`${domain}.title` as LocaleKeys, {\n          fallback: domain,\n        })\n      : undefined;\n\n    return {\n      id: `${idPrefix}${device.id}`,\n      label: \"\",\n      primary: deviceName || localize(\"unnamed_device\"),\n      secondary: areaName,\n      domain: configEntry?.domain,\n      domain_name: domainName,\n      search_labels: [deviceName, areaName, domain, domainName].filter(Boolean) as string[],\n      sorting_label: deviceName || \"zzz\",\n    };\n  });\n\n  return outputDevices;\n};\n","import { useConfig } from \"@hooks\";\nimport { Locales } from \"@typings\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { updateLocales } from \"../../hooks/useLocale\";\nimport locales from \"../../hooks/useLocale/locales\";\nimport { useInternalStore } from \"../HassContext\";\n\ninterface FetchLocaleProps {\n  locale?: Locales;\n  children?: React.ReactNode;\n}\nexport function FetchLocale({ locale, children }: FetchLocaleProps) {\n  const config = useConfig();\n  const [fetched, setFetched] = useState(false);\n  const fetchPending = useRef(false);\n  const previousLocale = useRef<Locales | null>(null);\n  const setError = useInternalStore((store) => store.setError);\n  const setLocales = useInternalStore((store) => store.setLocales);\n\n  useEffect(() => {\n    const _locale = locale ?? config?.language;\n    if (!_locale) {\n      // may just be waiting for the users config to resolve\n      return;\n    }\n    const match = locales.find(({ code }) => code === (locale ?? config?.language));\n    if (previousLocale.current !== match?.code) {\n      setFetched(false);\n      fetchPending.current = false;\n      setError(null);\n    }\n\n    if (!match) {\n      fetchPending.current = false;\n      setError(\n        `Locale \"${locale ?? config?.language}\" not found, available options are \"${locales.map(({ code }) => `${code}`).join(\", \")}\"`,\n      );\n    } else {\n      if (fetchPending.current) return;\n      fetchPending.current = true;\n      previousLocale.current = match.code;\n      match\n        .fetch()\n        .then((response) => {\n          fetchPending.current = false;\n          setFetched(true);\n          updateLocales(response);\n          setLocales(response);\n        })\n        .catch((e) => {\n          fetchPending.current = false;\n          setFetched(true);\n          setError(`Error retrieving translations from Home Assistant: ${e?.message ?? e}`);\n        });\n    }\n  }, [config, fetched, setLocales, setError, locale]);\n\n  return fetched ? children : null;\n}\n","import { memo, useMemo, type ReactNode } from \"react\";\nimport { useRef } from \"react\";\nimport { HassProvider } from \"./Provider\";\nimport type { HassProviderProps } from \"./Provider\";\nimport styled from \"@emotion/styled\";\nimport { keyframes } from \"@emotion/react\";\nimport { FetchLocale } from \"./FetchLocale\";\n\nexport type HassConnectProps = {\n  /** Any react node to render when authenticated */\n  children: ReactNode;\n  /** The url to your home assistant instance, can be local, nabucasa or any hosted url with home-assistant.  */\n  hassUrl: string;\n  /** if you provide a hassToken you will bypass the login screen altogether - @see https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token */\n  hassToken?: string;\n  /** Any react node to render when not authenticated or loading */\n  loading?: ReactNode;\n  /** called once the entity subscription is successful, and only once */\n  onReady?: () => void;\n  /** options for the provider */\n  options?: Omit<HassProviderProps, \"children\" | \"hassUrl\" | \"hassToken\">;\n  /** props to pass to the wrapper element, useful if you want to add additional styling or behavior */\n  wrapperProps?: React.ComponentPropsWithoutRef<\"div\">;\n};\n\nconst blip = keyframes`\n  0% {stroke-width:0; opacity:0;}\n  50% {stroke-width:5; opacity:1;}\n  100% {stroke-width:0; opacity:0;}\n`;\n\nfunction LoaderBase({ className }: { className?: string }) {\n  return (\n    <div className={className}>\n      <svg>\n        <path d=\"m 12.5,20 15,0 0,0 -15,0 z\" />\n        <path d=\"m 32.5,20 15,0 0,0 -15,0 z\" />\n        <path d=\"m 52.5,20 15,0 0,0 -15,0 z\" />\n        <path d=\"m 72.5,20 15,0 0,0 -15,0 z\" />\n      </svg>\n    </div>\n  );\n}\n\nconst Loader = styled(LoaderBase)`\n  position: fixed;\n  inset: 0;\n  background-color: #1a1a1a;\n  svg {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    width: 6.25em;\n    height: 3.125em;\n    margin: -1.562em 0 0 -3.125em;\n    path {\n      fill: none;\n      stroke: #f0c039;\n      opacity: 0;\n    }\n    path:nth-of-type(1) {\n      animation: ${blip} 1s ease-in-out 0s infinite alternate;\n    }\n    path:nth-of-type(2) {\n      animation: ${blip} 1s ease-in-out 0.1s infinite alternate;\n    }\n    path:nth-of-type(3) {\n      animation: ${blip} 1s ease-in-out 0.2s infinite alternate;\n    }\n    path:nth-of-type(4) {\n      animation: ${blip} 1s ease-in-out 0.3s infinite alternate;\n    }\n  }\n`;\n\nconst Wrapper = styled.div`\n  width: 100%;\n  height: 100%;\n`;\n\n/** This component will show the Home Assistant login form you're used to seeing normally when logging into HA, once logged in you shouldn't see this again unless you clear device storage, once authenticated it will render the child components of HassConnect and provide access to the api. */\nexport const HassConnect = memo(function HassConnect({\n  children,\n  hassUrl,\n  hassToken,\n  loading = <Loader />,\n  onReady,\n  options = {},\n  wrapperProps,\n}: HassConnectProps): ReactNode {\n  const onReadyCalled = useRef(false);\n\n  const sanitizedUrl = useMemo(() => {\n    try {\n      // htftp://lofcalhost:1234/ => origin of \"null\" so we need to account for malformed urls\n      // @see https://github.com/shannonhochkins/ha-component-kit/issues/146#issuecomment-2138352567\n      return new URL(hassUrl).origin;\n    } catch (e) {\n      console.log(\"Error:\", e);\n      return null;\n    }\n  }, [hassUrl]);\n\n  if (!sanitizedUrl || sanitizedUrl === \"null\" || sanitizedUrl === null) {\n    return <>{`Provide the hassUrl prop with a valid url to your home assistant instance.`}</>;\n  }\n\n  return (\n    <HassProvider hassUrl={sanitizedUrl} hassToken={hassToken} {...options}>\n      {(ready) => (\n        <>\n          {ready ? (\n            <Wrapper {...wrapperProps}>\n              <FetchLocale locale={options.locale}>\n                {onReady &&\n                  !onReadyCalled.current &&\n                  ((() => {\n                    onReady();\n                    onReadyCalled.current = true;\n                  })(),\n                  null)}\n                {children}\n              </FetchLocale>\n            </Wrapper>\n          ) : (\n            <Wrapper {...wrapperProps}>{loading}</Wrapper>\n          )}\n        </>\n      )}\n    </HassProvider>\n  );\n});\n"],"names":["modesSupportingColor","LIGHT_COLOR_MODES","modesSupportingBrightness","lightSupportsColorMode","entity","mode","lightIsInColorMode","lightSupportsColor","lightSupportsBrightness","lightSupportsFavoriteColors","getLightCurrentModeRgbColor","COLOR_TEMP_COUNT","DEFAULT_COLORED_COLORS","computeDefaultFavoriteColors","stateObj","colors","supportsColorTemp","supportsColor","min","step","i","temperature2rgb","toDate","date","createDateFormatters","fallback","d","formatDateTimeWithBrowserDefaults","getCtx","useInternalStore","value","locale","config","formatDate","formatTime","formatTimeWithoutAmPm","formatHour","formatAmPmSuffix","formatMinute","formatSeconds","formatDateTime","formatDateTimeWithSeconds","formatShortDateTime","formatShortDateTimeWithYear","formatShortDateTimeWithConditionalYear","formatDateTimeNumeric","formatDateWeekdayDay","formatDateShort","formatDateVeryShort","formatDateMonthYear","formatDateMonth","formatDateYear","formatDateWeekday","formatDateWeekdayShort","formatDateNumeric","callApi","endpoint","options","connection","hassUrl","response","e","shallowEqual","other","last_changed","last_updated","context","restEntity","c1","c2","c3","restOther","create","set","get","classes","routes","devices","entities","areas","services","floors","locales","hash","portalRoot","windowContext","newEntities","state","changed","next","id","newEnt","oldEnt","status","cannotConnect","ready","auth","user","users","error","styles","cb","reset","useHassProviderStore","setError","clearTokens","err","rawArgs","domain","service","serviceData","_target","returnResponse","target","isArray","result","_callService","snakeCase","route","setRoutes","r","hashWithoutPound","active","path","shouldUseAmPm","resolveTimeZone","entitiesRegistryDisplay","sensorNumericDeviceClasses","computeStateDisplay","attribute","computeAttributeValueDisplay","key","fn","subs","unsubscribeAll","setAuthenticated","setAuth","setUser","setCannotConnect","setConfig","setConnection","setEntities","setReady","setConnectionStatus","DATA_KEYS","useStore","useHass","LOCALES","updateLocales","translations","localize","search","replace","useLocales","useLocale","setValue","useState","localeData","useEffect","localeDataHelper","l","data","computeDomainTitle","entityId","deviceClass","computeDomain","startCase","lowerCase","localized","DEFAULT_ENTITY_NAME","DEFAULT_SEPARATOR","stateActive","compareState","UNAVAILABLE","isUnavailableState","OFF","computeObjectId","computeStateNameFromEntityAttributes","attributes","computeStateName","getEntityContext","entry","getEntityEntryContext","deviceId","device","areaId","area","floorId","floor","computeDeviceNameDisplay","hassEntities","computeDeviceName","fallbackDeviceName","computeEntityName","computeEntityEntryName","fallbackStateObj","name","deviceName","stripPrefixFromEntityName","computeFloorName","computeAreaName","computeEntityNameList","item","entityUseDeviceName","computeEntityNameDisplay","items","separator","n","names","batteryPriorities","findBatteryEntity","batteryEntities","a","b","findBatteryChargingEntity","computeEntityRegistryName","getExtendedEntityRegistryEntry","getExtendedEntityRegistryEntries","entityIds","updateEntityRegistryEntry","updates","removeEntityRegistryEntry","fetchEntityRegistryDisplay","subscribeEntityRegistryDisplayUpdates","conn","store","debounce","subscribeEntityRegistryDisplay","onChange","createCollection","sortEntityRegistryByName","entries","language","entry1","entry2","caseInsensitiveStringCompare","entityRegistryByEntityId","entityRegistryById","getEntityPlatformLookup","entityLookup","confEnt","getAutomaticEntityIds","entity_ids","getEntities","includeDomains","excludeDomains","entityFilter","includeDeviceClasses","includeUnitOfMeasurement","includeEntities","excludeEntities","idPrefix","eid","friendlyName","entityName","areaName","domainTitle","primary","secondary","TEMPERATURE_ATTRIBUTES","DOMAIN_ATTRIBUTES_FORMATTERS","formatDuration","DOMAIN_ATTRIBUTES_UNITS","getWeatherUnit","measure","lengthUnit","unitSystem","attributeValue","formatter","formattedValue","formatNumber","unit","blankBeforeUnit","isDate","isTimestamp","checkValidDate","val","_entity","computeStateDisplayFromEntityAttributes","UNKNOWN","is_number_domain","isNumericFromAttributes","UNIT_TO_MILLISECOND_CONVERT","getNumberFormatOptions","components","now","c","f","g","h","k","m","p","q","t","v","w","x","y","z","u","A","reactIs_production_min","hasSymbol","REACT_ELEMENT_TYPE","REACT_PORTAL_TYPE","REACT_FRAGMENT_TYPE","REACT_STRICT_MODE_TYPE","REACT_PROFILER_TYPE","REACT_PROVIDER_TYPE","REACT_CONTEXT_TYPE","REACT_ASYNC_MODE_TYPE","REACT_CONCURRENT_MODE_TYPE","REACT_FORWARD_REF_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_MEMO_TYPE","REACT_LAZY_TYPE","REACT_BLOCK_TYPE","REACT_FUNDAMENTAL_TYPE","REACT_RESPONDER_TYPE","REACT_SCOPE_TYPE","isValidElementType","type","typeOf","object","$$typeof","$$typeofType","AsyncMode","ConcurrentMode","ContextConsumer","ContextProvider","Element","ForwardRef","Fragment","Lazy","Memo","Portal","Profiler","StrictMode","Suspense","hasWarnedAboutDeprecatedIsAsyncMode","isAsyncMode","isConcurrentMode","isContextConsumer","isContextProvider","isElement","isForwardRef","isFragment","isLazy","isMemo","isPortal","isProfiler","isStrictMode","isSuspense","reactIs_development","reactIsModule","require$$0","require$$1","reactIs","REACT_STATICS","KNOWN_STATICS","FORWARD_REF_STATICS","MEMO_STATICS","TYPE_STATICS","getStatics","component","defineProperty","getOwnPropertyNames","getOwnPropertySymbols","getOwnPropertyDescriptor","getPrototypeOf","objectPrototype","hoistNonReactStatics","targetComponent","sourceComponent","blacklist","inheritedComponent","keys","targetStatics","sourceStatics","descriptor","hoistNonReactStatics_cjs","syncFallback","useInsertionEffect","React","useInsertionEffectAlwaysWithSyncFallback","EmotionCacheContext","createCache","withEmotionCache","func","forwardRef","props","ref","cache","useContext","ThemeContext","hasOwn","typePropName","createEmotionProps","newProps","_key","Insertion","_ref","serialized","isStringTag","registerStyles","insertStyles","Emotion","cssProp","WrappedComponent","registeredStyles","className","getRegisteredStyles","serializeStyles","_key2","Emotion$1","ReactJSXRuntime","jsx","jsxs","isIterable","obj","hasIterableEntries","compareEntries","valueA","valueB","mapA","mapB","compareIterables","iteratorA","iteratorB","nextA","nextB","shallow","useShallow","selector","prev","attemptedUrls","HassProvider","children","hassToken","renderError","handleResumeOptions","addSubscription","s","_hash","setPortalRoot","setWindowContext","handleConnect","useCallback","setAreas","setDevices","setFloors","setEntitiesRegistryDisplay","setServices","setUsers","setLocale","setSensorNumericDeviceClasses","tryConnection","subscribeEntities","$entities","entityReg","subscribeAreaRegistry","areaReg","subscribeDeviceRegistry","deviceReg","subscribeFloorRegistry","floorReg","subscribeConfig","newConfig","subscribeUser","subscribeServices","subscribeUsers","subscribeFrontendUserData","getUserLocaleLanguage","onStatusChange","rest","resumeCleanup","handleSuspendResume","setHassUrl","setHash","onHashChange","connectOnce","message","handleError","loadTokens","useConfig","useMemo","fetchDeviceRegistry","subscribeDeviceRegistryUpdates","devicesInArea","updateDeviceRegistryEntry","removeConfigEntryFromDevice","configEntryId","sortDeviceRegistryByName","getDeviceEntityLookup","deviceEntityLookup","getDeviceEntityDisplayLookup","getDeviceIntegrationLookup","entitySources","configEntries","deviceIntegrations","source","config_entry_id","getDeviceContext","getDevices","entitiesI","devicesI","configEntryLookup","deviceFilter","excludeDevices","inputDevices","devEntities","configEntry","domainName","FetchLocale","fetched","setFetched","fetchPending","useRef","previousLocale","setLocales","match","code","blip","keyframes","LoaderBase","Loader","styled","Wrapper","HassConnect","memo","loading","onReady","wrapperProps","onReadyCalled","sanitizedUrl"],"mappings":"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","x_google_ignoreList":[11,12,13,14,15,16,17,18,19]}