class Lookbook::Engine

def auto_refresh?

def auto_refresh?
  opts.live_updates == true &&
    reloading? &&
    runtime_context.web? &&
    FileWatcher.evented?
end

def component_paths

def component_paths
  @_component_paths ||= begin
    paths = [*opts.component_paths, *view_paths, host_app_path]
    PathUtils.normalize_paths(paths)
  end
end

def files_changed(modified, added, removed)

def files_changed(modified, added, removed)
  changes = {modified: modified, added: added, removed: removed}
  reloaders.register_changes(changes)
  notify_clients(changes)
end

def hooks

def hooks
  @_hooks ||= HookStore.new
end

def host_app_path

def host_app_path
  Rails.application.root.join("app")
end

def host_config

def host_config
  Rails.application.config
end

def inputs

def inputs
  @_inputs ||= InputStore.init_from_config
end

def load_pages(changes = nil)

def load_pages(changes = nil)
  pages.load(Engine.page_paths, changes)
rescue => e
  Lookbook.logger.error(e)
  raise e
end

def load_previews(changes = nil)

def load_previews(changes = nil)
  changed_files = [*changes[:added], *changes[:modified]] if changes
  parser.parse(changed_files) do |code_objects|
    previews.load(code_objects.all(:class), changes)
  end
rescue => e
  Lookbook.logger.error(e)
  raise e
end

def mount_path

def mount_path
  routes.find_script_name({})
end

def mounted?

def mounted?
  mount_path.present?
end

def notify_clients(changes = nil)

def notify_clients(changes = nil)
  return unless changes.present?
  websocket.broadcast(:reload)
  run_hooks(:after_change, changes.to_h)
end

def opts

def opts
  Lookbook.config
end

def page_paths

def page_paths
  @_page_paths ||= PathUtils.normalize_paths(opts.page_paths)
end

def pages

def pages
  @_pages ||= PageCollection.new
end

def panels

def panels
  @_panels ||= PanelStore.init_from_config
end

def parser

def parser
  @_parser ||= PreviewParser.new(opts.preview_paths, Engine.tags)
end

def preview_controller

def preview_controller
  @_preview_controller = opts.preview_controller.constantize
  @_preview_controller.include PreviewControllerActions
end

def preview_embeds_allowed?

def preview_embeds_allowed?
  opts.preview_embeds.enabled == true && opts.preview_embeds.policy != "DENY"
end

def preview_paths

def preview_paths
  @_preview_paths ||= PathUtils.normalize_paths(opts.preview_paths)
end

def preview_watch_paths

def preview_watch_paths
  @_preview_watch_paths ||= begin
    paths = [*opts.preview_paths, *opts.component_paths, *opts.listen_paths, *view_paths].uniq
    PathUtils.normalize_paths(paths)
  end
end

def previews

def previews
  @_previews ||= PreviewCollection.new
end

def reloaders

def reloaders
  @_reloaders ||= Reloaders.new
end

def reloading?

def reloading?
  opts.reload_on_change
end

def run_hooks(event_name, *args)

def run_hooks(event_name, *args)
  hooks.for_event(event_name).each do |hook|
    hook.call(Lookbook, *args)
  end
end

def runtime_context

def runtime_context
  @_runtime_context ||= RuntimeContext.new(env: Rails.env)
end

def tags

def tags
  @_tags ||= TagStore.init_from_config
end

def theme

def theme
  @_theme ||= Lookbook::Theme.new(opts.ui_theme, opts.ui_theme_overrides)
end

def view_paths

def view_paths
  # handle view path registry changes in Rails 7.1
  paths = if defined?(ActionView::PathRegistry)
    ActionView::PathRegistry.all_file_system_resolvers.map(&:path)
  else
    ActionView::ViewPaths.all_view_paths.flat_map(&paths)
  end
  paths.map { |path| Pathname(path.to_s) }
end

def websocket

def websocket
  @_websocket ||= auto_refresh? ? Websocket.new(mount_path, logger: Lookbook.logger) : NullWebsocket.new
end