{"version":3,"file":"index-BbkMZwLg.cjs","sources":["../src/hooks/useHass/index.ts","../src/hooks/useLocale/index.ts","../../../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","../src/HassConnect/Provider.tsx","../src/HassConnect/index.tsx"],"sourcesContent":["import { useContext } from \"react\";\nimport { isEmpty } from \"lodash\";\nimport { HassContext } from \"@core\";\nimport type { HassContextProps } from \"@core\";\n\nexport function useHass(): HassContextProps {\n  const context = useContext(HassContext);\n  if (context === undefined || isEmpty(context)) {\n    throw new Error(\"useHass must be used within a HassProvider, have you wrapped your application in <HassConnect hassUrl={HASS_URL} />?\");\n  }\n  return context;\n}\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 { getConfig } = useHass();\n\n  useEffect(() => {\n    const fetchAndSetLocale = async () => {\n      const locale = (await getConfig())?.language;\n      const localeData = locales.find((l) => l.code === locale);\n      if (localeData) {\n        const data = await localeData.fetch();\n        setValue(data[key] ?? fallback);\n      }\n    };\n\n    fetchAndSetLocale();\n  }, [key, fallback, getConfig]);\n\n  return value;\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","import { useEffect, useCallback, useRef } from \"react\";\n// types\nimport type { Connection, HassConfig, getAuthOptions as AuthOptions, Auth, UnsubscribeFunc } from \"home-assistant-js-websocket\";\n// methods\nimport {\n  getAuth,\n  createLongLivedTokenAuth,\n  createConnection,\n  subscribeEntities,\n  callService as _callService,\n  getStates as _getStates,\n  getServices as _getServices,\n  getConfig as _getConfig,\n  getUser as _getUser,\n  ERR_HASS_HOST_REQUIRED,\n  ERR_CONNECTION_LOST,\n  ERR_CANNOT_CONNECT,\n  ERR_INVALID_AUTH,\n  ERR_INVALID_HTTPS_TO_HTTP,\n  subscribeConfig,\n} from \"home-assistant-js-websocket\";\nimport { isArray, snakeCase } from \"lodash\";\nimport { SnakeOrCamelDomains, DomainService, Locales, CallServiceArgs, Route, ServiceResponse } from \"@typings\";\nimport { saveTokens, loadTokens, clearTokens } from \"./token-storage\";\nimport { useDebouncedCallback } from \"use-debounce\";\nimport locales from \"../hooks/useLocale/locales\";\nimport { updateLocales } from \"../hooks/useLocale\";\nimport { HassContext, type HassContextProps, useStore } from \"./HassContext\";\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  /** update the window reference that's used internally on some features, for example useBreakpoint will use the current window if not specified, and if running within an iframe this may not be expected behavior */\n  windowContext?: Window;\n}\n\nfunction handleError(err: number | string | Error | unknown, hassToken?: string): string {\n  const getMessage = () => {\n    switch (err) {\n      case ERR_INVALID_AUTH:\n        return `ERR_INVALID_AUTH: Invalid authentication. ${hassToken ? 'Check your \"Long-Lived Access Token\".' : \"\"}`;\n      case ERR_CANNOT_CONNECT:\n        return \"ERR_CANNOT_CONNECT: Unable to connect\";\n      case ERR_CONNECTION_LOST:\n        return \"ERR_CONNECTION_LOST: Lost connection to home assistant.\";\n      case ERR_HASS_HOST_REQUIRED:\n        return \"ERR_HASS_HOST_REQUIRED: Please enter a Home Assistant URL.\";\n      case ERR_INVALID_HTTPS_TO_HTTP:\n        return 'ERR_INVALID_HTTPS_TO_HTTP: Cannot connect to Home Assistant instances over \"http://\".';\n      default:\n        return null;\n    }\n  };\n  const message = getMessage();\n  if (message !== null) return message;\n  return (\n    (\n      err as {\n        error: string;\n      }\n    )?.error ||\n    (err as Error)?.message ||\n    `Unknown Error (${err})`\n  );\n}\ntype ConnectionResponse =\n  | {\n      type: \"success\";\n      connection: Connection;\n      auth: Auth;\n    }\n  | {\n      type: \"error\";\n      error: string;\n    }\n  | {\n      type: \"failed\";\n      cannotConnect: true;\n    };\n\ntype ConnectionType = \"auth-callback\" | \"user-request\" | \"saved-tokens\" | \"inherited-auth\" | \"provided-token\";\n\nfunction getInheritedConnection(): typeof window.hassConnection | undefined {\n  try {\n    return window.top?.hassConnection;\n  } catch (e) {\n    console.error(\"Error getting inherited connection\", e);\n    return undefined;\n  }\n}\n\nfunction determineConnectionType(hassUrl: string, hassToken?: string): ConnectionType {\n  const isAuthCallback = location && location.search.includes(\"auth_callback=1\");\n  const hasHassConnection = !!getInheritedConnection();\n  const providedToken = !!hassToken;\n  // when we have a hass connection, we don't need to validate the tokens\n  // so removing the tokens if values are different and we have a connection are not needed.\n  const savedTokens = !!loadTokens(hassUrl, false);\n\n  switch (true) {\n    case isAuthCallback:\n      return \"auth-callback\";\n    case hasHassConnection:\n      return \"inherited-auth\";\n    case providedToken:\n      return \"provided-token\";\n    case savedTokens:\n      return \"saved-tokens\";\n    default:\n      return \"user-request\";\n  }\n}\n\nconst tryConnection = async (hassUrl: string, hassToken?: string): Promise<ConnectionResponse> => {\n  const connectionType = determineConnectionType(hassUrl, hassToken);\n\n  if (connectionType === \"inherited-auth\") {\n    try {\n      // if we've hit this connect type, the connection will be available\n      const { auth, conn } = (await getInheritedConnection()) as { conn: Connection; auth: Auth };\n      return {\n        type: \"success\",\n        connection: conn,\n        auth: auth,\n      };\n    } catch (e) {\n      const message = handleError(e, hassToken);\n      return {\n        type: \"error\",\n        error: message,\n      };\n    }\n  }\n  if (connectionType === \"provided-token\" && hassToken) {\n    try {\n      const auth = await createLongLivedTokenAuth(hassUrl, hassToken);\n      const connection = await createConnection({ auth });\n      return {\n        type: \"success\",\n        connection,\n        auth,\n      };\n    } catch (e) {\n      const message = handleError(e, hassToken);\n      return {\n        type: \"error\",\n        error: message,\n      };\n    }\n  }\n\n  const options: AuthOptions = {\n    saveTokens,\n    loadTokens: () => Promise.resolve(loadTokens(hassUrl)),\n  };\n\n  if (hassUrl && connectionType === \"user-request\") {\n    options.hassUrl = hassUrl;\n    if (options.hassUrl === \"\") {\n      return {\n        type: \"error\",\n        error: \"Please enter a Home Assistant URL.\",\n      };\n    }\n    if (options.hassUrl.indexOf(\"://\") === -1) {\n      return {\n        type: \"error\",\n        error: \"Please enter your full URL, including the protocol part (https://).\",\n      };\n    }\n    try {\n      new URL(options.hassUrl);\n    } catch (err: unknown) {\n      console.log(\"Error:\", err);\n      return {\n        type: \"error\",\n        error: \"Invalid URL\",\n      };\n    }\n  }\n  let auth: Auth;\n\n  try {\n    auth = await getAuth(options);\n  } catch (err: unknown) {\n    if (\n      (\n        err as {\n          error: string;\n        }\n      )?.error === \"invalid_grant\"\n    ) {\n      // the refresh token is incorrect and most likely from another browser / instance\n      clearTokens();\n      return tryConnection(hassUrl, hassToken);\n    }\n    if (connectionType === \"saved-tokens\" && err === ERR_CANNOT_CONNECT) {\n      return {\n        type: \"failed\",\n        cannotConnect: true,\n      };\n    }\n    return {\n      type: \"error\",\n      error: handleError(err, hassToken),\n    };\n  } finally {\n    // Clear url if we have a auth callback in url.\n    if (location && location.search.includes(\"auth_callback=1\")) {\n      history.replaceState(null, \"\", location.pathname);\n    }\n  }\n  let connection: Connection;\n  try {\n    // create the connection to the websockets\n    connection = await createConnection({ auth });\n  } catch (err) {\n    // In case of saved tokens, silently solve problems.\n    if (connectionType === \"saved-tokens\") {\n      if (err === ERR_CANNOT_CONNECT) {\n        return {\n          type: \"failed\",\n          cannotConnect: true,\n        };\n      } else if (err === ERR_INVALID_AUTH) {\n        saveTokens(null);\n      }\n    }\n    return {\n      type: \"error\",\n      error: handleError(err, hassToken),\n    };\n  }\n  return {\n    type: \"success\",\n    connection,\n    auth,\n  };\n};\n\nexport function HassProvider({ children, hassUrl, hassToken, locale, portalRoot, windowContext }: HassProviderProps) {\n  const entityUnsubscribe = useRef<UnsubscribeFunc | null>(null);\n  const authenticated = useRef(false);\n  const subscribedConfig = useRef(false);\n  const setHash = useStore((store) => store.setHash);\n  const _hash = useStore((store) => store.hash);\n  const routes = useStore((store) => store.routes);\n  const setRoutes = useStore((store) => store.setRoutes);\n  const connection = useStore((store) => store.connection);\n  const setConnection = useStore((store) => store.setConnection);\n  const _connectionRef = useRef<Connection | null>(null);\n  const entities = useStore((store) => store.entities);\n  const setEntities = useStore((store) => store.setEntities);\n  const error = useStore((store) => store.error);\n  const setError = useStore((store) => store.setError);\n  const cannotConnect = useStore((store) => store.cannotConnect);\n  const setCannotConnect = useStore((store) => store.setCannotConnect);\n  const setAuth = useStore((store) => store.setAuth);\n  const ready = useStore((store) => store.ready);\n  const setReady = useStore((store) => store.setReady);\n  const setConfig = useStore((store) => store.setConfig);\n  const setHassUrl = useStore((store) => store.setHassUrl);\n  const setPortalRoot = useStore((store) => store.setPortalRoot);\n  const setLocales = useStore((store) => store.setLocales);\n  const setWindowContext = useStore((store) => store.setWindowContext);\n\n  useEffect(() => {\n    if (portalRoot) setPortalRoot(portalRoot);\n  }, [portalRoot, setPortalRoot]);\n\n  useEffect(() => {\n    if (windowContext) setWindowContext(windowContext);\n  }, [windowContext, setWindowContext]);\n\n  const reset = useCallback(() => {\n    // when the hassUrl changes, reset some properties and re-authenticate\n    setAuth(null);\n    setConnection(null);\n    _connectionRef.current = null;\n    setEntities({});\n    setConfig(null);\n    setError(null);\n    setCannotConnect(false);\n    setReady(false);\n    setRoutes([]);\n    authenticated.current = false;\n    if (entityUnsubscribe.current) {\n      entityUnsubscribe.current();\n      entityUnsubscribe.current = null;\n    }\n  }, [setAuth, setCannotConnect, setConfig, setConnection, setEntities, setError, setReady, setRoutes]);\n\n  const logout = useCallback(async () => {\n    try {\n      reset();\n      clearTokens();\n      if (location) location.reload();\n    } catch (err: unknown) {\n      console.log(\"Error:\", err);\n      setError(\"Unable to log out!\");\n    }\n  }, [reset, setError]);\n\n  const handleConnect = useCallback(async () => {\n    // this will trigger on first mount\n    const connectionResponse = await tryConnection(hassUrl, hassToken);\n    if (connectionResponse.type === \"error\") {\n      authenticated.current = false;\n      setError(connectionResponse.error);\n    } else if (connectionResponse.type === \"failed\") {\n      authenticated.current = false;\n      setCannotConnect(true);\n    } else if (connectionResponse.type === \"success\") {\n      // store a reference to the authentication object\n      setAuth(connectionResponse.auth);\n      // store the connection to pass to the provider\n      setConnection(connectionResponse.connection);\n      _connectionRef.current = connectionResponse.connection;\n      authenticated.current = true;\n    }\n  }, [hassUrl, hassToken, setError, setAuth, setConnection, setCannotConnect]);\n\n  useEffect(() => {\n    setHassUrl(hassUrl);\n  }, [hassUrl, setHassUrl]);\n\n  const getStates = useCallback(async () => (connection === null ? null : await _getStates(connection)), [connection]);\n  const getServices = useCallback(async () => (connection === null ? null : await _getServices(connection)), [connection]);\n  const getConfig = useCallback(async () => (connection === null ? null : await _getConfig(connection)), [connection]);\n  const getUser = useCallback(async () => (connection === null ? null : await _getUser(connection)), [connection]);\n\n  const joinHassUrl = useCallback(\n    (path: string) => {\n      return new URL(path, connection?.options.auth?.data.hassUrl).toString();\n    },\n    [connection],\n  );\n\n  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 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.log(\"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\n  const fetchLocale = useCallback(\n    async (config: HassConfig | null): Promise<Record<string, string>> => {\n      const match = locales.find(({ code }) => code === (locale ?? config?.language));\n      if (!match) {\n        throw new Error(\n          `Locale \"${locale ?? config?.language}\" not found, available options are \"${locales.map(({ code }) => `${code}`).join(\", \")}\"`,\n        );\n      } else {\n        return await match.fetch();\n      }\n    },\n    [locale],\n  );\n\n  useEffect(() => {\n    if (!locale) return;\n    // purposely sending null for the config object as we're fetching a different language specified by the user\n    fetchLocale(null)\n      .then((locales) => {\n        updateLocales(locales);\n        setLocales(locales);\n      })\n      .catch((e) => {\n        setError(`Error retrieving translations from Home Assistant: ${e?.message ?? e}`);\n      });\n  }, [locale, fetchLocale, setLocales, setError]);\n\n  useEffect(() => {\n    if (!connection || subscribedConfig.current) return;\n    subscribedConfig.current = true;\n    // Subscribe to config updates\n    const unsubscribe = subscribeConfig(connection, (newConfig) => {\n      fetchLocale(newConfig)\n        .then((locales) => {\n          // purposely setting config here to delay the rendering process of the application until locales are retrieved\n          setConfig(newConfig);\n          updateLocales(locales);\n          setLocales(locales);\n        })\n        .catch((e) => {\n          setConfig(newConfig);\n          setError(`Error retrieving translations from Home Assistant: ${e?.message ?? e}`);\n        });\n    });\n    // Cleanup function to unsubscribe on unmount\n    return () => {\n      unsubscribe();\n    };\n  }, [connection, setLocales, fetchLocale, setConfig, setError]);\n\n  useEffect(() => {\n    if (location.hash === \"\") return;\n    if (location.hash.replace(\"#\", \"\") === _hash) return;\n    setHash(location.hash);\n  }, [setHash, _hash]);\n\n  useEffect(() => {\n    function onHashChange() {\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    window.addEventListener(\"hashchange\", onHashChange);\n    return () => {\n      window.removeEventListener(\"hashchange\", onHashChange);\n    };\n  }, [routes, setHash, setRoutes]);\n\n  const addRoute = useCallback(\n    (route: Omit<Route, \"active\">) => {\n      const exists = routes.find((_route) => _route.hash === route.hash) !== undefined;\n      if (!exists && typeof window !== \"undefined\") {\n        // if the current has value is the same as the hash, we're active\n        const hashWithoutPound = window.location.hash.replace(\"#\", \"\");\n        const active = hashWithoutPound !== \"\" && hashWithoutPound === route.hash;\n        setRoutes([\n          ...routes,\n          {\n            ...route,\n            active,\n          } satisfies Route,\n        ]);\n      }\n    },\n    [routes, setRoutes],\n  );\n\n  const getRoute = useCallback(\n    (hash: string) => {\n      const route = routes.find((route) => route.hash === hash);\n      return route || null;\n    },\n    [routes],\n  );\n\n  const getAllEntities = useCallback(() => entities, [entities]);\n\n  const callService = useCallback(\n    async <ResponseType extends object, T extends SnakeOrCamelDomains, M extends DomainService<T>, R extends boolean>({\n      domain,\n      service,\n      serviceData,\n      target: _target,\n      returnResponse,\n    }: CallServiceArgs<T, M, R>): Promise<R extends true ? ServiceResponse<ResponseType> : void> => {\n      const target =\n        typeof _target === \"string\" || isArray(_target)\n          ? {\n              entity_id: _target,\n            }\n          : _target;\n      if (typeof service !== \"string\") {\n        throw new Error(\"service must be a string\");\n      }\n      if (connection && ready) {\n        try {\n          const result = await _callService(\n            connection,\n            snakeCase(domain),\n            snakeCase(service),\n            // purposely cast here as we know it's correct\n            serviceData as object,\n            target,\n            returnResponse,\n          );\n          if (returnResponse) {\n            // Return the result if returnResponse is true\n            return result as R extends true ? ServiceResponse<ResponseType> : never;\n          }\n          // Otherwise, return void\n          return undefined as R extends true ? never : void;\n        } catch (e) {\n          // TODO - raise error to client here\n          console.log(\"Error:\", e);\n        }\n      }\n      return undefined as R extends true ? never : void;\n    },\n    [connection, ready],\n  );\n\n  useEffect(() => {\n    if (connection && entityUnsubscribe.current === null) {\n      entityUnsubscribe.current = subscribeEntities(connection, ($entities) => {\n        setEntities($entities);\n      });\n    }\n  }, [connection, setEntities]);\n\n  useEffect(() => {\n    return () => {\n      authenticated.current = false;\n      if (entityUnsubscribe.current) {\n        entityUnsubscribe.current();\n        entityUnsubscribe.current = null;\n      }\n    };\n  }, []);\n\n  const debounceConnect = useDebouncedCallback(\n    async () => {\n      try {\n        if (_connectionRef.current && !connection) {\n          setConnection(_connectionRef.current);\n          authenticated.current = true;\n          return;\n        }\n        if (!_connectionRef.current && connection) {\n          _connectionRef.current = connection;\n          authenticated.current = true;\n          return;\n        }\n        if (authenticated.current) return;\n        authenticated.current = true;\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    },\n    100,\n    {\n      leading: true,\n      trailing: false,\n    },\n  );\n\n  useEffect(() => {\n    // authenticate with ha\n    debounceConnect();\n  }, [debounceConnect]);\n\n  if (cannotConnect) {\n    return (\n      <p>\n        Unable to connect to ${loadTokens(hassUrl)!.hassUrl}, refresh the page and try again, or <a onClick={logout}>Logout</a>.\n      </p>\n    );\n  }\n  return (\n    <HassContext.Provider\n      value={{\n        useStore,\n        logout,\n        addRoute,\n        getRoute,\n        getStates,\n        getServices,\n        getConfig,\n        getUser,\n        callApi,\n        getAllEntities,\n        // cast here we don't have to redefine all the overloads, might fix later\n        callService: callService as HassContextProps[\"callService\"],\n        joinHassUrl,\n      }}\n    >\n      {error === null ? children(ready) : error}\n    </HassContext.Provider>\n  );\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\";\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\">;\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}: 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>\n              {onReady &&\n                !onReadyCalled.current &&\n                ((() => {\n                  onReady();\n                  onReadyCalled.current = true;\n                })(),\n                null)}\n              {children}\n            </Wrapper>\n          ) : (\n            <Wrapper>{loading}</Wrapper>\n          )}\n        </>\n      )}\n    </HassProvider>\n  );\n});\n"],"names":["useHass","context","useContext","HassContext","isEmpty","LOCALES","updateLocales","translations","localize","key","options","search","replace","fallback","useLocales","useLocale","value","setValue","useState","getConfig","useEffect","locale","localeData","locales","l","data","reactIs","require$$0","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","i","descriptor","hoistNonReactStatics_cjs","syncFallback","create","useInsertionEffect","React","useInsertionEffectAlwaysWithSyncFallback","EmotionCacheContext","createCache","withEmotionCache","func","forwardRef","props","ref","cache","ThemeContext","hasOwn","typePropName","createEmotionProps","type","newProps","_key","Insertion","_ref","serialized","isStringTag","registerStyles","insertStyles","Emotion","cssProp","WrappedComponent","registeredStyles","className","getRegisteredStyles","serializeStyles","_key2","Emotion$1","Fragment","ReactJSXRuntime","jsx","jsxs","handleError","err","hassToken","message","ERR_INVALID_AUTH","ERR_CANNOT_CONNECT","ERR_CONNECTION_LOST","ERR_HASS_HOST_REQUIRED","ERR_INVALID_HTTPS_TO_HTTP","getInheritedConnection","e","determineConnectionType","hassUrl","isAuthCallback","hasHassConnection","providedToken","savedTokens","loadTokens","tryConnection","connectionType","auth","conn","createLongLivedTokenAuth","createConnection","saveTokens","getAuth","clearTokens","connection","HassProvider","children","portalRoot","windowContext","entityUnsubscribe","useRef","authenticated","subscribedConfig","setHash","useStore","store","_hash","routes","setRoutes","setConnection","_connectionRef","entities","setEntities","error","setError","cannotConnect","setCannotConnect","setAuth","ready","setReady","setConfig","setHassUrl","setPortalRoot","setLocales","setWindowContext","reset","useCallback","logout","handleConnect","connectionResponse","getStates","_getStates","getServices","_getServices","_getConfig","getUser","_getUser","joinHassUrl","path","callApi","endpoint","response","fetchLocale","config","match","code","unsubscribe","subscribeConfig","newConfig","onHashChange","route","addRoute","_route","hashWithoutPound","active","getRoute","hash","getAllEntities","callService","domain","service","serviceData","_target","returnResponse","target","isArray","result","_callService","snakeCase","subscribeEntities","$entities","debounceConnect","useDebouncedCallback","blip","keyframes","LoaderBase","Loader","styled","Wrapper","HassConnect","memo","loading","onReady","onReadyCalled","sanitizedUrl","useMemo"],"mappings":"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","x_google_ignoreList":[2,3,4,5]}