text: """
  Custom element manager for community created elements.
  
  For more details about this integration, please refer to the documentation at
  https://hacs.xyz/
  """
  import voluptuous as vol
  from aiogithubapi import AIOGitHub
  from homeassistant import config_entries
  from homeassistant.const import EVENT_HOMEASSISTANT_START
  from homeassistant.const import __version__ as HAVERSION
  from homeassistant.exceptions import ConfigEntryNotReady
  from homeassistant.helpers.aiohttp_client import async_create_clientsession
  from homeassistant.helpers.event import async_call_later
  
  from .configuration_schema import hacs_base_config_schema, hacs_config_option_schema
  from .const import DEV_MODE, DOMAIN, ELEMENT_TYPES, STARTUP, VERSION
  from .constrains import check_constans
  from .hacsbase import Hacs
  from .hacsbase.configuration import Configuration
  from .hacsbase.data import HacsData
  from .hacsbase.migration import ValidateData
  from .setup import add_sensor, load_hacs_repository, setup_frontend
  
  SCHEMA = hacs_base_config_schema()
  SCHEMA[vol.Optional("options")] = hacs_config_option_schema()
  CONFIG_SCHEMA = vol.Schema({DOMAIN: SCHEMA}, extra=vol.ALLOW_EXTRA)
  
  
  async def async_setup(hass, config):
      """Set up this integration using yaml."""
      if DOMAIN not in config:
          return True
      hass.data[DOMAIN] = config
      Hacs.hass = hass
      Hacs.configuration = Configuration.from_dict(
          config[DOMAIN], config[DOMAIN].get("options")
      )
      Hacs.configuration.config_type = "yaml"
      await startup_wrapper_for_yaml(Hacs)
      hass.async_create_task(
          hass.config_entries.flow.async_init(
              DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data={}
          )
      )
      return True
  
  
  async def async_setup_entry(hass, config_entry):
      """Set up this integration using UI."""
      conf = hass.data.get(DOMAIN)
      if config_entry.source == config_entries.SOURCE_IMPORT:
          if conf is None:
              hass.async_create_task(
                  hass.config_entries.async_remove(config_entry.entry_id)
              )
          return False
      Hacs.hass = hass
      Hacs.configuration = Configuration.from_dict(
          config_entry.data, config_entry.options
      )
      Hacs.configuration.config_type = "flow"
      Hacs.configuration.config_entry = config_entry
      config_entry.add_update_listener(reload_hacs)
      startup_result = await hacs_startup(Hacs)
      if not startup_result:
          raise ConfigEntryNotReady
      return startup_result
  
  
  async def startup_wrapper_for_yaml(hacs):
      """Startup wrapper for yaml config."""
      startup_result = await hacs_startup(hacs)
      if not startup_result:
          hacs.hass.components.frontend.async_remove_panel(
              hacs.configuration.sidepanel_title.lower()
              .replace(" ", "_")
              .replace("-", "_")
          )
          hacs.logger.info("Could not setup HACS, trying again in 15 min")
          async_call_later(hacs.hass, 900, startup_wrapper_for_yaml(hacs))
  
  
  async def hacs_startup(hacs):
      """HACS startup tasks."""
      hacs.logger.debug(f"Configuration type: {hacs.configuration.config_type}")
      hacs.version = VERSION
      hacs.logger.info(STARTUP)
      hacs.system.config_path = hacs.hass.config.path()
      hacs.system.ha_version = HAVERSION
      hacs.system.disabled = False
      hacs.github = AIOGitHub(
          hacs.configuration.token, async_create_clientsession(hacs.hass)
      )
      hacs.data = HacsData()
  
      # Check HACS Constrains
      if not check_constans(hacs):
          if hacs.configuration.config_type == "flow":
              if hacs.configuration.config_entry is not None:
                  await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
          return False
  
      # Set up frontend
      await setup_frontend(hacs)
  
      # Load HACS
      if not await load_hacs_repository(hacs):
          if hacs.configuration.config_type == "flow":
              if hacs.configuration.config_entry is not None:
                  await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
          return False
  
      val = ValidateData()
      if not val.validate_local_data_file():
          if hacs.configuration.config_type == "flow":
              if hacs.configuration.config_entry is not None:
                  await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
          return False
  
      # Restore from storefiles
      if not await hacs.data.restore():
          hacs_repo = hacs().get_by_name("hacs/integration")
          hacs_repo.pending_restart = True
          if hacs.configuration.config_type == "flow":
              if hacs.configuration.config_entry is not None:
                  await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
          return False
  
      # Add aditional categories
      if hacs.configuration.appdaemon:
          ELEMENT_TYPES.append("appdaemon")
      if hacs.configuration.python_script:
          ELEMENT_TYPES.append("python_script")
      if hacs.configuration.theme:
          ELEMENT_TYPES.append("theme")
      hacs.common.categories = sorted(ELEMENT_TYPES)
  
      # Setup startup tasks
      if hacs.configuration.config_type == "yaml":
          hacs.hass.bus.async_listen_once(
              EVENT_HOMEASSISTANT_START, hacs().startup_tasks()
          )
      else:
          async_call_later(hacs.hass, 5, hacs().startup_tasks())
  
      # Print DEV warning
      if hacs.configuration.dev:
          hacs.logger.warning(DEV_MODE)
          hacs.hass.components.persistent_notification.create(
              title="HACS DEV MODE", message=DEV_MODE, notification_id="hacs_dev_mode"
          )
  
      # Add sensor
      add_sensor(hacs)
  
      # Set up services
      # await add_services(hacs)
  
      # Mischief managed!
      return True
  
  
  async def async_remove_entry(hass, config_entry):
      """Handle removal of an entry."""
      Hacs().logger.info("Disabling HACS")
      Hacs().logger.info("Removing recuring tasks")
      for task in Hacs().tasks:
          task()
      Hacs().logger.info("Removing sensor")
      try:
          await hass.config_entries.async_forward_entry_unload(config_entry, "sensor")
      except ValueError:
          pass
      Hacs().logger.info("Removing sidepanel")
      try:
          hass.components.frontend.async_remove_panel("hacs_web")
      except AttributeError:
          pass
      Hacs().system.disabled = True
      Hacs().logger.info("HACS is now disabled")
  
  
  async def reload_hacs(hass, config_entry):
      """Reload HACS."""
      await async_remove_entry(hass, config_entry)
      await async_setup_entry(hass, config_entry)
  