Merge remote-tracking branch 'upstream/develop' into develop
authorFloatingGhost <hannah@coffee-and-dreams.uk>
Thu, 30 Dec 2021 18:05:22 +0000 (18:05 +0000)
committerFloatingGhost <hannah@coffee-and-dreams.uk>
Thu, 30 Dec 2021 18:05:22 +0000 (18:05 +0000)
1  2 
config/config.exs
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/side_effects.ex
lib/pleroma/web/endpoint.ex
lib/pleroma/web/mastodon_api/controllers/search_controller.ex
mix.exs
mix.lock

diff --combined config/config.exs
index 581f3831a7ab452275378611a0c24a81a679af88,2bde5b8268ed61e6cf988daee6faba2ff0973ffd..9fdb2546e45a5d926d5432d2b074cdb50d7b8874
@@@ -139,6 -139,7 +139,7 @@@ config :pleroma, Pleroma.Web.Endpoint
    ],
    protocol: "https",
    secret_key_base: "aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl",
+   live_view: [signing_salt: "U5ELgdEwTD3n1+D5s0rY0AMg8/y1STxZ3Zvsl3bWh+oBcGrYdil0rXqPMRd3Glcq"],
    signing_salt: "CqaoopA2",
    render_errors: [view: Pleroma.Web.ErrorView, accepts: ~w(json)],
    pubsub_server: Pleroma.PubSub,
    ]
  
  # Configures Elixir's Logger
+ config :logger, truncate: 65536
  config :logger, :console,
    level: :debug,
    format: "\n$time $metadata[$level] $message\n",
@@@ -221,7 -224,6 +224,7 @@@ config :pleroma, :instance
      "text/markdown",
      "text/bbcode"
    ],
 +  staff_transparency: [],
    autofollowed_nicknames: [],
    autofollowing_nicknames: [],
    max_pinned_statuses: 1,
      ]
    ],
    show_reactions: true,
-   password_reset_token_validity: 60 * 60 * 24
+   password_reset_token_validity: 60 * 60 * 24,
+   profile_directory: true,
+   privileged_staff: false
  
  config :pleroma, :welcome,
    direct_message: [
@@@ -852,8 -856,13 +857,15 @@@ config :pleroma, ConcurrentLimiter, 
    {Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy, [max_running: 5, max_waiting: 5]}
  ]
  
 +config :pleroma, :search, provider: Pleroma.Search.Builtin
 +
+ config :pleroma, :telemetry,
+   slow_queries_logging: [
+     enabled: false,
+     min_duration: 500_000,
+     exclude_sources: [nil, "oban_jobs"]
+   ]
  # Import environment specific config. This must remain at the bottom
  # of this file so it overrides the configuration defined above.
  import_config "#{Mix.env()}.exs"
diff --combined lib/pleroma/user.ex
index a2cf22e554a5e9d146e1df2a01ee4d7f6809c4e1,390de1e2d95c9326f9a558930ed5a7d9c873be0c..045b6fb84e1e2d1c63011d160a387e57f3489bfa
@@@ -148,6 -148,8 +148,8 @@@ defmodule Pleroma.User d
      field(:last_active_at, :naive_datetime)
      field(:disclose_client, :boolean, default: true)
      field(:pinned_objects, :map, default: %{})
+     field(:is_suggested, :boolean, default: false)
+     field(:last_status_at, :naive_datetime)
  
      embeds_one(
        :notification_settings,
  
    def update_and_set_cache(changeset) do
      with {:ok, user} <- Repo.update(changeset, stale_error_field: :id) do
 +      Pleroma.Elasticsearch.maybe_put_into_elasticsearch(user)
        set_cache(user)
      end
    end
  
    def confirm(%User{} = user), do: {:ok, user}
  
+   def set_suggestion(users, is_suggested) when is_list(users) do
+     Repo.transaction(fn ->
+       Enum.map(users, fn user ->
+         with {:ok, user} <- set_suggestion(user, is_suggested), do: user
+       end)
+     end)
+   end
+   def set_suggestion(%User{is_suggested: is_suggested} = user, is_suggested), do: {:ok, user}
+   def set_suggestion(%User{} = user, is_suggested) when is_boolean(is_suggested) do
+     user
+     |> change(is_suggested: is_suggested)
+     |> update_and_set_cache()
+   end
    def update_notification_settings(%User{} = user, settings) do
      user
      |> cast(%{notification_settings: settings}, [])
      |> where([u], u.local == true)
      |> Repo.aggregate(:count)
    end
+   def update_last_status_at(user) do
+     User
+     |> where(id: ^user.id)
+     |> update([u], set: [last_status_at: fragment("NOW()")])
+     |> select([u], u)
+     |> Repo.update_all([])
+     |> case do
+       {1, [user]} -> set_cache(user)
+       _ -> {:error, user}
+     end
+   end
  end
index 0878e773bf9fe796baaebaab5663a2b09e1fd851,7560969525f041506c629c488a700aa92cee0d92..b43929891fb95fa1b92a24faffd6c98543794bba
@@@ -81,6 -81,10 +81,10 @@@ defmodule Pleroma.Web.ActivityPub.Activ
      if is_public?(object), do: User.decrease_note_count(actor), else: {:ok, actor}
    end
  
+   def update_last_status_at_if_public(actor, object) do
+     if is_public?(object), do: User.update_last_status_at(actor), else: {:ok, actor}
+   end
    defp increase_replies_count_if_reply(%{
           "object" => %{"inReplyTo" => reply_ap_id} = object,
           "type" => "Create"
           _ <- increase_replies_count_if_reply(create_data),
           {:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
           {:ok, _actor} <- increase_note_count_if_public(actor, activity),
+          {:ok, _actor} <- update_last_status_at_if_public(actor, activity),
           _ <- notify_and_stream(activity),
           :ok <- maybe_schedule_poll_notifications(activity),
           :ok <- maybe_federate(activity) do
        fetch_activities_query_ap_ids_ops(opts)
  
      config = %{
 -      skip_thread_containment: Config.get([:instance, :skip_thread_containment])
 +      skip_thread_containment: true
      }
  
      query =
index a93961922e54719ea7b7d71b7e04e4d1a54d1660,39d37fbcb8210e982d43021b02c7325d6f5bdc5a..0460289b77c63152dbd9f6bd16ff14ae5a4274c3
@@@ -199,8 -199,9 +199,9 @@@ defmodule Pleroma.Web.ActivityPub.SideE
           %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
        {:ok, notifications} = Notification.create_notifications(activity, do_send: false)
        {:ok, _user} = ActivityPub.increase_note_count_if_public(user, object)
+       {:ok, _user} = ActivityPub.update_last_status_at_if_public(user, object)
  
-       if in_reply_to = object.data["inReplyTo"] && object.data["type"] != "Answer" do
+       if in_reply_to = object.data["type"] != "Answer" && object.data["inReplyTo"] do
          Object.increase_replies_count(in_reply_to)
        end
  
    end
  
    @impl true
 +  def handle_after_transaction(%Pleroma.Activity{data: %{"type" => "Create"}} = activity) do
 +    Pleroma.Elasticsearch.put_by_id(:activity, activity.id)
 +  end
 +
 +  def handle_after_transaction(%Pleroma.Activity{}) do
 +    :ok
 +  end
 +
 +  def handle_after_transaction(%Pleroma.Object{}) do
 +    :ok
 +  end
 +
    def handle_after_transaction(meta) do
      meta
      |> send_notifications()
index 0cb6aff160afd0620976fd4278b52db5d3fd2593,75484fac5ee768c401082a4f9ab5e3183ab3a589..9d73cf0f8a30c0fdf88d990775020eadac907bc1
@@@ -10,6 -10,7 +10,7 @@@ defmodule Pleroma.Web.Endpoint d
    alias Pleroma.Config
  
    socket("/socket", Pleroma.Web.UserSocket)
+   socket("/live", Phoenix.LiveView.Socket)
  
    plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint])
  
      }
    )
  
 +  plug(Plug.Static.IndexHtml, at: "/pleroma/fedife/")
 +
 +  plug(Pleroma.Web.Plugs.FrontendStatic,
 +    at: "/pleroma/fedife",
 +    frontend_type: :fedife,
 +    gzip: true,
 +    cache_control_for_etags: @static_cache_control,
 +    headers: %{
 +      "cache-control" => @static_cache_control
 +    }
 +  )
 +
    # Serve at "/" the static files from "priv/static" directory.
    #
    # You should set gzip to true if you are running phoenix.digest
index c8f820f003949e17dcf0fe903432715b5aaab199,1459fc49233962e023454d3adfb508741292355a..86ad388fd9d7aeba6da71b8fb91ff610d89aa0ed
@@@ -5,14 -5,20 +5,16 @@@
  defmodule Pleroma.Web.MastodonAPI.SearchController do
    use Pleroma.Web, :controller
  
 -  alias Pleroma.Activity
 -  alias Pleroma.Repo
    alias Pleroma.User
    alias Pleroma.Web.ControllerHelper
 -  alias Pleroma.Web.Endpoint
    alias Pleroma.Web.MastodonAPI.AccountView
 -  alias Pleroma.Web.MastodonAPI.StatusView
    alias Pleroma.Web.Plugs.OAuthScopesPlug
    alias Pleroma.Web.Plugs.RateLimiter
  
    require Logger
  
+   @search_limit 40
    plug(Pleroma.Web.ApiSpec.CastAndValidate)
  
    # Note: Mastodon doesn't allow unauthenticated access (requires read:accounts / read:search)
    def search2(conn, params), do: do_search(:v2, conn, params)
    def search(conn, params), do: do_search(:v1, conn, params)
  
 -  defp do_search(version, %{assigns: %{user: user}} = conn, %{q: query} = params) do
 -    query = String.trim(query)
 -    options = search_options(params, user)
 -    timeout = Keyword.get(Repo.config(), :timeout, 15_000)
 -    default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []}
 -
 -    result =
 -      default_values
 -      |> Enum.map(fn {resource, default_value} ->
 -        if params[:type] in [nil, resource] do
 -          {resource, fn -> resource_search(version, resource, query, options) end}
 -        else
 -          {resource, fn -> default_value end}
 -        end
 -      end)
 -      |> Task.async_stream(fn {resource, f} -> {resource, with_fallback(f)} end,
 -        timeout: timeout,
 -        on_timeout: :kill_task
 -      )
 -      |> Enum.reduce(default_values, fn
 -        {:ok, {resource, result}}, acc ->
 -          Map.put(acc, resource, result)
 -
 -        _error, acc ->
 -          acc
 -      end)
 -
 -    json(conn, result)
 +  defp do_search(version, %{assigns: %{user: user}} = conn, params) do
 +    options =
 +      search_options(params, user)
 +      |> Keyword.put(:version, version)
 +
 +    search_provider = Pleroma.Config.get([:search, :provider])
 +    json(conn, search_provider.search(conn, params, options))
    end
  
    defp search_options(params, user) do
      [
        resolve: params[:resolve],
        following: params[:following],
-       limit: params[:limit],
+       limit: min(params[:limit], @search_limit),
        offset: params[:offset],
        type: params[:type],
        author: get_author(params),
      |> Enum.filter(&elem(&1, 1))
    end
  
 -  defp resource_search(_, "accounts", query, options) do
 -    accounts = with_fallback(fn -> User.search(query, options) end)
 -
 -    AccountView.render("index.json",
 -      users: accounts,
 -      for: options[:for_user],
 -      embed_relationships: options[:embed_relationships]
 -    )
 -  end
 -
 -  defp resource_search(_, "statuses", query, options) do
 -    statuses = with_fallback(fn -> Activity.search(options[:for_user], query, options) end)
 -
 -    StatusView.render("index.json",
 -      activities: statuses,
 -      for: options[:for_user],
 -      as: :activity
 -    )
 -  end
 -
 -  defp resource_search(:v2, "hashtags", query, options) do
 -    tags_path = Endpoint.url() <> "/tag/"
 -
 -    query
 -    |> prepare_tags(options)
 -    |> Enum.map(fn tag ->
 -      %{name: tag, url: tags_path <> tag}
 -    end)
 -  end
 -
 -  defp resource_search(:v1, "hashtags", query, options) do
 -    prepare_tags(query, options)
 -  end
 -
 -  defp prepare_tags(query, options) do
 -    tags =
 -      query
 -      |> preprocess_uri_query()
 -      |> String.split(~r/[^#\w]+/u, trim: true)
 -      |> Enum.uniq_by(&String.downcase/1)
 -
 -    explicit_tags = Enum.filter(tags, fn tag -> String.starts_with?(tag, "#") end)
 -
 -    tags =
 -      if Enum.any?(explicit_tags) do
 -        explicit_tags
 -      else
 -        tags
 -      end
 -
 -    tags = Enum.map(tags, fn tag -> String.trim_leading(tag, "#") end)
 -
 -    tags =
 -      if Enum.empty?(explicit_tags) && !options[:skip_joined_tag] do
 -        add_joined_tag(tags)
 -      else
 -        tags
 -      end
 -
 -    Pleroma.Pagination.paginate(tags, options)
 -  end
 -
 -  defp add_joined_tag(tags) do
 -    tags
 -    |> Kernel.++([joined_tag(tags)])
 -    |> Enum.uniq_by(&String.downcase/1)
 -  end
 -
 -  # If `query` is a URI, returns last component of its path, otherwise returns `query`
 -  defp preprocess_uri_query(query) do
 -    if query =~ ~r/https?:\/\// do
 -      query
 -      |> String.trim_trailing("/")
 -      |> URI.parse()
 -      |> Map.get(:path)
 -      |> String.split("/")
 -      |> Enum.at(-1)
 -    else
 -      query
 -    end
 -  end
 -
 -  defp joined_tag(tags) do
 -    tags
 -    |> Enum.map(fn tag -> String.capitalize(tag) end)
 -    |> Enum.join()
 -  end
 -
 -  defp with_fallback(f, fallback \\ []) do
 -    try do
 -      f.()
 -    rescue
 -      error ->
 -        Logger.error("#{__MODULE__} search error: #{inspect(error)}")
 -        fallback
 -    end
 -  end
 -
    defp get_author(%{account_id: account_id}) when is_binary(account_id),
      do: User.get_cached_by_id(account_id)
  
diff --combined mix.exs
index 195fd3a9dd67a566d6da636e3788a9e817ef61ea,360d499050ab28766a1ae676079c400b6b44486d..170bea95bc874338a59cf68b2090054e65ad399a
+++ b/mix.exs
@@@ -8,7 -8,7 +8,7 @@@ defmodule Pleroma.Mixfile d
        elixir: "~> 1.9",
        elixirc_paths: elixirc_paths(Mix.env()),
        compilers: [:phoenix, :gettext] ++ Mix.compilers(),
-       elixirc_options: [warnings_as_errors: warnings_as_errors(Mix.env())],
+       elixirc_options: [warnings_as_errors: warnings_as_errors()],
        xref: [exclude: [:eldap]],
        start_permanent: Mix.env() == :prod,
        aliases: aliases(),
@@@ -79,6 -79,7 +79,7 @@@
          :comeonin,
          :quack,
          :fast_sanitize,
+         :os_mon,
          :ssl
        ],
        included_applications: [:ex_syslogger]
@@@ -90,8 -91,7 +91,7 @@@
    defp elixirc_paths(:test), do: ["lib", "test/support"]
    defp elixirc_paths(_), do: ["lib"]
  
-   defp warnings_as_errors(:prod), do: false
-   defp warnings_as_errors(_), do: true
+   defp warnings_as_errors, do: System.get_env("CI") == "true"
  
    # Specifies OAuth dependencies.
    defp oauth_deps do
        {:trailing_format_plug, "~> 0.0.7"},
        {:fast_sanitize, "~> 0.2.0"},
        {:html_entities, "~> 0.5", override: true},
-       {:phoenix_html, "~> 2.14"},
+       {:phoenix_html, "~> 3.1", override: true},
        {:calendar, "~> 1.0"},
        {:cachex, "~> 3.2"},
        {:poison, "~> 3.0", override: true},
        {:castore, "~> 0.1"},
        {:cowlib, "~> 2.9", override: true},
        {:gun, "~> 2.0.0-rc.1", override: true},
+       {:finch, "~> 0.10.0"},
        {:jason, "~> 1.2"},
        {:mogrify, "~> 0.9.1"},
        {:ex_aws, "~> 2.1.6"},
         git: "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git",
         ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"},
        {:restarter, path: "./restarter"},
-       {:majic,
-        git: "https://git.pleroma.social/pleroma/elixir-libraries/majic.git",
-        ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"},
+       {:majic, "~> 1.0"},
        {:eblurhash, "~> 1.1.0"},
        {:open_api_spex, "~> 3.10"},
 +      {:elastix, ">= 0.0.0"},
 +      {:search_parser,
 +       git: "https://github.com/FloatingGhost/pleroma-contrib-search-parser.git",
 +       ref: "08971a81e68686f9ac465cfb6661d51c5e4e1e7f"},
 +      {:nimble_parsec, "~> 1.0", override: true},
+       {:phoenix_live_dashboard, "~> 0.6.2"},
+       {:ecto_psql_extras, "~> 0.6"},
  
        # indirect dependency version override
        {:plug, "~> 1.10.4", override: true},
diff --combined mix.lock
index 20e95c19f703bc90f2937cae8370dcbfd139176a,f371a6e41d6ed80b5a8184f2ed4da8b7a5c5a1c4..1d0f71d80a6ae4bc45ec3da72b7b00132a9d22c0
+++ b/mix.lock
    "eblurhash": {:hex, :eblurhash, "1.1.0", "e10ccae762598507ebfacf0b645ed49520f2afa3e7e9943e73a91117dffce415", [:rebar3], [], "hexpm", "2e6b889d09fddd374e3c5ac57c486138768763264e99ac1074ae5fa7fc9ab51d"},
    "ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"},
    "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
+   "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.4", "5d43fd088d39a158c860b17e8d210669587f63ec89ea122a4654861c8c6e2db4", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.15.7", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "311db02f1b772e3d0dc7f56a05044b5e1499d78ed6abf38885e1ca70059449e5"},
    "ecto_sql": {:hex, :ecto_sql, "3.6.2", "9526b5f691701a5181427634c30655ac33d11e17e4069eff3ae1176c764e0ba3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ec9d7e6f742ea39b63aceaea9ac1d1773d574ea40df5a53ef8afbd9242fdb6b"},
    "eimp": {:hex, :eimp, "1.0.14", "fc297f0c7e2700457a95a60c7010a5f1dcb768a083b6d53f49cd94ab95a28f22", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "501133f3112079b92d9e22da8b88bf4f0e13d4d67ae9c15c42c30bd25ceb83b6"},
 +  "elasticsearch": {:hex, :elasticsearch, "1.0.1", "8339538d90af6b280f10ecd02b1eae372f09373e629b336a13461babf7366495", [:mix], [{:httpoison, ">= 0.0.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sigaws, "~> 0.7", [hex: :sigaws, repo: "hexpm", optional: true]}, {:vex, "~> 0.6", [hex: :vex, repo: "hexpm", optional: false]}], "hexpm", "83e7d8b8bee3e7e19a06ab4d357d24845ac1da894e79678227fd52c0b7f71867"},
 +  "elastix": {:hex, :elastix, "0.10.0", "7567da885677ba9deffc20063db5f3ca8cd10f23cff1ab3ed9c52b7063b7e340", [:mix], [{:httpoison, "~> 1.4", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0", [hex: :poison, repo: "hexpm", optional: true]}, {:retry, "~> 0.8", [hex: :retry, repo: "hexpm", optional: false]}], "hexpm", "5fb342ce068b20f7845f5dd198c2dc80d967deafaa940a6e51b846db82696d1d"},
    "elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
    "esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm", "d73e341e3009d390aa36387dc8862860bf9f874c94d9fd92ade2926376f49981"},
    "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
    "ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"},
    "ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
    "excoveralls": {:hex, :excoveralls, "0.12.3", "2142be7cb978a3ae78385487edda6d1aff0e482ffc6123877bb7270a8ffbcfe0", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "568a3e616c264283f5dea5b020783ae40eef3f7ee2163f7a67cbd7b35bcadada"},
-   "fast_html": {:hex, :fast_html, "2.0.4", "4910ee49f2f6b19692e3bf30bf97f1b6b7dac489cd6b0f34cd0fe3042c56ba30", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "3bb49d541dfc02ad5e425904f53376d758c09f89e521afc7d2b174b3227761ea"},
+   "fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"},
    "fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"},
    "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
+   "finch": {:hex, :finch, "0.10.0", "8e5e6101ae98e7f1ef830594f774411a2f9cbce4f92d8179502da69fbbff52bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "80324ba22edbdebca6fac05c8517e7457b79dfe101e3bf6b2f7c5c65c93a9077"},
    "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"},
    "floki": {:hex, :floki, "0.30.1", "75d35526d3a1459920b6e87fdbc2e0b8a3670f965dd0903708d2b267e0904c55", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e9c03524447d1c4cbfccd672d739b8c18453eee377846b119d4fd71b1a176bb8"},
    "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
@@@ -70,7 -70,7 +72,7 @@@
    "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
    "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"},
    "linkify": {:hex, :linkify, "0.5.1", "6dc415cbc948b2f6ecec7cb226aab7ba9d3a1815bb501ae33e042334d707ecee", [:mix], [], "hexpm", "a3128c7e22fada4aa7214009501d8131e1fa3faf2f0a68b33dba379dc84ff944"},
-   "majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "289cda1b6d0d70ccb2ba508a2b0bd24638db2880", [ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"]},
+   "majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"},
    "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
    "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
    "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
    "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
    "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
    "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
+   "mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"},
    "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
    "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"},
    "mogrify": {:hex, :mogrify, "0.9.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"},
    "mox": {:hex, :mox, "1.0.0", "4b3c7005173f47ff30641ba044eb0fe67287743eec9bd9545e37f3002b0a9f8b", [:mix], [], "hexpm", "201b0a20b7abdaaab083e9cf97884950f8a30a1350a1da403b3145e213c6f4df"},
    "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]},
 -  "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm", "5c040b8469c1ff1b10093d3186e2e10dbe483cd73d79ec017993fb3985b8a9b3"},
+   "nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"},
-   "nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"},
 +  "nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"},
+   "nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"},
    "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
    "oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"},
    "open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"},
@@@ -93,7 -95,9 +97,9 @@@
    "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
    "phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"},
    "phoenix_ecto": {:hex, :phoenix_ecto, "4.2.1", "13f124cf0a3ce0f1948cf24654c7b9f2347169ff75c1123f44674afee6af3b03", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "478a1bae899cac0a6e02be1deec7e2944b7754c04e7d4107fc5a517f877743c0"},
-   "phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
+   "phoenix_html": {:hex, :phoenix_html, "3.1.0", "0b499df05aad27160d697a9362f0e89fa0e24d3c7a9065c2bd9d38b4d1416c09", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0c0a98a2cefa63433657983a2a594c7dee5927e4391e0f1bfd3a151d1def33fc"},
+   "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.6.2", "0769470265eb13af01b5001b29cb935f4710d6adaa1ffc18417a570a337a2f0f", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.3", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5bc6c6b38a2ca8b5020b442322fcee6afd5e641637a0b1fb059d4bd89bc58e7b"},
+   "phoenix_live_view": {:hex, :phoenix_live_view, "0.17.5", "63f52a6f9f6983f04e424586ff897c016ecc5e4f8d1e2c22c2887af1c57215d8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c5586e6a3d4df71b8214c769d4f5eb8ece2b4001711a7ca0f97323c36958b0e3"},
    "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
    "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.3", "039435dd975f7e55953525b88f1d596f26c6141412584c16f4db109708a8ee68", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4a540cea32e05356541737033d666ee7fea7700eb2101bf76783adbfe06601cd"},
    "plug": {:hex, :plug, "1.10.4", "41eba7d1a2d671faaf531fa867645bd5a3dce0957d8e2a3f398ccff7d2ef017f", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad1e233fe73d2eec56616568d260777b67f53148a999dc2d048f4eb9778fe4a0"},
    "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
    "recon": {:hex, :recon, "2.5.1", "430ffa60685ac1efdfb1fe4c97b8767c92d0d92e6e7c3e8621559ba77598678a", [:mix, :rebar3], [], "hexpm", "5721c6b6d50122d8f68cccac712caa1231f97894bab779eff5ff0f886cb44648"},
    "remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8", [ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"]},
 +  "retry": {:hex, :retry, "0.15.0", "ba6aaeba92905a396c18c299a07e638947b2ba781e914f803202bc1b9ae867c3", [:mix], [], "hexpm", "93d3310bce78c0a30cc94610684340a14adfc9136856a3f662e4d9ce6013c784"},
 +  "search_parser": {:git, "https://github.com/FloatingGhost/pleroma-contrib-search-parser.git", "08971a81e68686f9ac465cfb6661d51c5e4e1e7f", [ref: "08971a81e68686f9ac465cfb6661d51c5e4e1e7f"]},
    "sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"},
    "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
    "sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"},
    "swoosh": {:hex, :swoosh, "1.3.11", "34f79c57f19892b43bd2168de9ff5de478a721a26328ef59567aad4243e7a77b", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "f1e2a048db454f9982b9cf840f75e7399dd48be31ecc2a7dc10012a803b913af"},
    "syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"},
+   "table_rex": {:hex, :table_rex, "3.1.1", "0c67164d1714b5e806d5067c1e96ff098ba7ae79413cc075973e17c38a587caa", [:mix], [], "hexpm", "678a23aba4d670419c23c17790f9dcd635a4a89022040df7d5d772cb21012490"},
    "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
+   "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
    "tesla": {:hex, :tesla, "1.4.1", "ff855f1cac121e0d16281b49e8f066c4a0d89965f98864515713878cca849ac8", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "95f5de35922c8c4b3945bee7406f66eb680b0955232f78f5fb7e853aa1ce201a"},
    "timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"},
    "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
    "ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"},
    "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
    "unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
 +  "vex": {:hex, :vex, "0.9.0", "613ea5eb3055662e7178b83e25b2df0975f68c3d8bb67c1645f0573e1a78d606", [:mix], [], "hexpm", "c69fff44d5c8aa3f1faee71bba1dcab05dd36364c5a629df8bb11751240c857f"},
    "web_push_encryption": {:git, "https://github.com/lanodan/elixir-web-push-encryption.git", "026a043037a89db4da8f07560bc8f9c68bcf0cc0", [branch: "bugfix/otp-24"]},
    "websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []},
  }