From 915ccd10ea1c6ea0571ed7103a7f18f273f93602 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 11 Dec 2024 16:07:34 -0500 Subject: [PATCH 01/20] improvement: don't fetch trip from the V3 API to define the itinerary entity --- lib/dotcom/trip_plan/alerts.ex | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index b4c0294002..052ace59f3 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -8,6 +8,8 @@ defmodule Dotcom.TripPlan.Alerts do * at the times they'll be travelling """ + import Routes.Route, only: [is_external?: 1] + alias Alerts.Alert alias Alerts.InformedEntity, as: IE alias Dotcom.TripPlan.{Itinerary, Leg, TransitDetail} @@ -42,23 +44,12 @@ defmodule Dotcom.TripPlan.Alerts do end end - defp mode_entities(%TransitDetail{route: route, trip: %{id: trip_id}}) do - trip = - if is_nil(route.external_agency_name) do - Schedules.Repo.trip(trip_id) - end - - route_type = - if route do - route.type - end - - direction_id = - if trip do - trip.direction_id - end + defp mode_entities(%TransitDetail{route: route}) when is_external?(route) do + [] + end - [%IE{route_type: route_type, route: route.id, trip: trip_id, direction_id: direction_id}] + defp mode_entities(%TransitDetail{route: %{id: route_id, type: route_type}, trip: %{id: trip_id, direction_id: direction_id}}) do + [%IE{route_type: route_type, route: route_id, trip: trip_id, direction_id: direction_id}] end defp mode_entities(_) do From 9d5e36d78f3e828a3965858b4425e502272b1720 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Wed, 11 Dec 2024 13:43:17 -0500 Subject: [PATCH 02/20] [WIP] feat: Add alert info to trip planner output Co-authored-by: Cristen Jones --- lib/dotcom/trip_plan/alerts.ex | 17 +++++++++++-- .../trip_planner/itinerary_detail.ex | 24 +++++++++++++------ .../components/trip_planner/transit_leg.ex | 21 ++++++++++++---- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index 052ace59f3..eef4241ce1 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -14,6 +14,16 @@ defmodule Dotcom.TripPlan.Alerts do alias Alerts.InformedEntity, as: IE alias Dotcom.TripPlan.{Itinerary, Leg, TransitDetail} + @spec from_itinerary(Itinerary.t()) :: [Alerts.Alert.t()] + def from_itinerary(itinerary) do + itinerary.start + |> Alerts.Repo.all() + |> Alerts.Match.match( + entities(itinerary), + itinerary.start + ) + end + @doc "Filters a list of Alerts to those relevant to the Itinerary" @spec filter_for_itinerary([Alert.t()], Itinerary.t()) :: [Alert.t()] def filter_for_itinerary(alerts, itinerary) do @@ -37,7 +47,7 @@ defmodule Dotcom.TripPlan.Alerts do |> Enum.uniq() end - defp leg_entities(%Leg{mode: mode} = leg) do + def leg_entities(%Leg{mode: mode} = leg) do for entity <- mode_entities(mode), stop_id <- Leg.stop_ids(leg) do %{entity | stop: stop_id} @@ -48,7 +58,10 @@ defmodule Dotcom.TripPlan.Alerts do [] end - defp mode_entities(%TransitDetail{route: %{id: route_id, type: route_type}, trip: %{id: trip_id, direction_id: direction_id}}) do + defp mode_entities(%TransitDetail{ + route: %{id: route_id, type: route_type}, + trip: %{id: trip_id, direction_id: direction_id} + }) do [%IE{route_type: route_type, route: route_id, trip: trip_id, direction_id: direction_id}] end diff --git a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex index a62e6eb92d..b59157a798 100644 --- a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex +++ b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex @@ -10,7 +10,9 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do import DotcomWeb.Components.TripPlanner.TransitLeg, only: [transit_leg: 1] import DotcomWeb.Components.TripPlanner.WalkingLeg, only: [walking_leg: 1] + alias Alerts.Match alias Dotcom.TripPlan.LegToSegmentHelper + alias Dotcom.TripPlan.{Alerts, PersonalDetail, TransitDetail} def itinerary_detail( %{ @@ -77,16 +79,14 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do defp specific_itinerary_detail(assigns) do assigns = - assign( - assigns, - :segments, - LegToSegmentHelper.legs_to_segments(assigns.itinerary.legs) - ) + assigns + |> assign_new(:alerts, fn -> Alerts.from_itinerary(assigns.itinerary) end) + |> assign(:segments, LegToSegmentHelper.legs_to_segments(assigns.itinerary.legs)) ~H"""
- <.segment segment={segment} /> + <.segment segment={segment} alerts={@alerts} />
""" @@ -115,7 +115,17 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do assigns = assign(assigns, :leg, leg) ~H""" - <.transit_leg leg={@leg} /> + <.transit_leg leg={@leg} alerts={alerts_for_leg(@alerts, @leg)} /> """ end + + defp alerts_for_leg(alerts, leg) when is_list(alerts) do + Match.match( + alerts, + Alerts.leg_entities(leg), + leg.start + ) + end + + defp alerts_for_leg(_, _), do: [] end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 13d03f5ba0..6e81b79b41 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -17,9 +17,10 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do @doc """ Renders a transit leg. - Must be given a `leg` + Must be given a `leg` and a list of `alerts` """ + attr :alerts, :list, default: [] attr :leg, :any, required: true def transit_leg(assigns) do @@ -32,12 +33,12 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do />
<%= if Enum.count(@leg.mode.intermediate_stops) < 2 do %> - <.leg_summary leg={@leg} /> + <.leg_summary leg={@leg} alerts={@alerts} /> <.leg_details leg={@leg} /> <% else %>
- <.leg_summary leg={@leg} /> + <.leg_summary leg={@leg} alerts={@alerts} /> <.icon name="chevron-up" class="group-open:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" @@ -81,13 +82,25 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do |> assign(:headsign, headsign(assigns.leg.mode)) ~H""" -
+
<.route_symbol route={@leg.mode.route} /> {@headsign}
<.ride_message mode={@leg.mode} /> {@stops_count} {Inflex.inflect("stop", @stops_count)}
+ <%= if @alerts do %> +
+
+ <.icon name="triangle-exclamation" class="w-4 h-4" /> + {Phoenix.Naming.humanize(alert.effect)} + +
+
+ {alert.header} +
+
+ <% end %>
""" end From b4e7a31a79d8e7ca79eda415065b6700709ab819 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 13 Dec 2024 11:59:06 -0500 Subject: [PATCH 03/20] feat: Make alert component a collapsible summary/detail --- .../components/trip_planner/transit_leg.ex | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 6e81b79b41..04418c7ac2 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -91,14 +91,17 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do
<%= if @alerts do %>
-
- <.icon name="triangle-exclamation" class="w-4 h-4" /> - {Phoenix.Naming.humanize(alert.effect)} - -
-
- {alert.header} -
+
+ + <.icon name="triangle-exclamation" class="w-4 h-4" /> + {Phoenix.Naming.humanize(alert.effect)} + Show Details + + +
+ {alert.header} +
+
<% end %>
From 69c943922f219e0c917fe479557621a33b7001b6 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 13 Dec 2024 12:04:11 -0500 Subject: [PATCH 04/20] refactor: Extract alert to its own component --- .../components/trip_planner/transit_leg.ex | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 04418c7ac2..e1a50e2211 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -91,17 +91,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do <%= if @alerts do %>
-
- - <.icon name="triangle-exclamation" class="w-4 h-4" /> - {Phoenix.Naming.humanize(alert.effect)} - Show Details - - -
- {alert.header} -
-
+ <.alert alert={alert} />
<% end %> @@ -188,4 +178,20 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do """ end + + defp alert(assigns) do + ~H""" +
+ + <.icon name="triangle-exclamation" class="w-4 h-4" /> + {Phoenix.Naming.humanize(@alert.effect)} + Show Details + + +
+ {@alert.header} +
+
+ """ + end end From 72f9b4e716efebbdff2f63dfa12fd5494de5928d Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 13 Dec 2024 12:15:05 -0500 Subject: [PATCH 05/20] fix: Little style fixes for alert component --- .../components/trip_planner/transit_leg.ex | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index e1a50e2211..4e359c876f 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -182,11 +182,13 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do defp alert(assigns) do ~H"""
- - <.icon name="triangle-exclamation" class="w-4 h-4" /> - {Phoenix.Naming.humanize(@alert.effect)} - Show Details - + + <.icon name="triangle-exclamation" class="w-3 h-3" /> + + {Phoenix.Naming.humanize(@alert.effect)} + Show Details + +
{@alert.header} From d83d92a9ba4af898f685b0ea62659a9287b7f6ab Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 13 Dec 2024 16:22:12 -0500 Subject: [PATCH 06/20] feat: Make alerts show up in the right place --- lib/dotcom/trip_plan/alerts.ex | 14 +++++ lib/dotcom/trip_plan/leg.ex | 18 ++++++ .../trip_planner/itinerary_detail.ex | 2 +- .../components/trip_planner/place.ex | 63 +++++++++++++------ .../components/trip_planner/transit_leg.ex | 40 +++++++++++- 5 files changed, 115 insertions(+), 22 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index eef4241ce1..2ec0b53470 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -54,6 +54,20 @@ defmodule Dotcom.TripPlan.Alerts do end end + def leg_entities_from(%Leg{mode: mode} = leg) do + for entity <- mode_entities(mode), + stop_id <- Leg.stop_ids_from(leg) do + %{entity | stop: stop_id} + end + end + + def leg_entities_to(%Leg{mode: mode} = leg) do + for entity <- mode_entities(mode), + stop_id <- Leg.stop_ids_to(leg) do + %{entity | stop: stop_id} + end + end + defp mode_entities(%TransitDetail{route: route}) when is_external?(route) do [] end diff --git a/lib/dotcom/trip_plan/leg.ex b/lib/dotcom/trip_plan/leg.ex index bc1796baf5..3c786e5000 100644 --- a/lib/dotcom/trip_plan/leg.ex +++ b/lib/dotcom/trip_plan/leg.ex @@ -72,6 +72,24 @@ defmodule Dotcom.TripPlan.Leg do end end + @doc "Returns the stop ID for the beginning of the leg if available" + @spec stop_ids_from(t) :: [Stops.Stop.id_t()] + def stop_ids_from(%__MODULE__{from: from}) do + for %NamedPosition{stop: stop} <- [from], + stop do + stop.id + end + end + + @doc "Returns the stop ID for the end of the leg if available" + @spec stop_ids_to(t) :: [Stops.Stop.id_t()] + def stop_ids_to(%__MODULE__{to: to}) do + for %NamedPosition{stop: stop} <- [to], + stop do + stop.id + end + end + @spec stop_is_silver_line_airport?([t], atom) :: boolean() def stop_is_silver_line_airport?([], _), do: false diff --git a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex index b59157a798..39e1c0b131 100644 --- a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex +++ b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex @@ -12,7 +12,7 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do alias Alerts.Match alias Dotcom.TripPlan.LegToSegmentHelper - alias Dotcom.TripPlan.{Alerts, PersonalDetail, TransitDetail} + alias Dotcom.TripPlan.Alerts def itinerary_detail( %{ diff --git a/lib/dotcom_web/components/trip_planner/place.ex b/lib/dotcom_web/components/trip_planner/place.ex index b0e7d26383..5a8055d24b 100644 --- a/lib/dotcom_web/components/trip_planner/place.ex +++ b/lib/dotcom_web/components/trip_planner/place.ex @@ -11,6 +11,7 @@ defmodule DotcomWeb.Components.TripPlanner.Place do attr :place, :map, required: true attr :time, :any, required: true attr :route, :map, default: nil + attr :alerts, :list, default: [] def place(assigns) do stop_url = stop_url(assigns.route, assigns.place.stop) @@ -22,24 +23,32 @@ defmodule DotcomWeb.Components.TripPlanner.Place do }) ~H""" - <.dynamic_tag - tag_name={@tag_name} - href={@stop_url} - class="bg-gray-bordered-background px-3 py-2 rounded-lg grid grid-cols-[1.5rem_auto_1fr] items-center gap-2 w-full hover:no-underline text-black" - > - <.location_icon route={@route} class="h-6 w-6" /> - - {@place.name} - <.icon - :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} - type="icon-svg" - name="icon-accessible-default" - class="h-5 w-5 ml-0.5 shrink-0" - aria-hidden="true" - /> - - - +
+ <.dynamic_tag + tag_name={@tag_name} + href={@stop_url} + class="grid grid-cols-[1.5rem_auto_1fr] items-center gap-2 w-full hover:no-underline text-black" + > + <.location_icon route={@route} class="h-6 w-6" /> + + {@place.name} + <.icon + :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} + type="icon-svg" + name="icon-accessible-default" + class="h-5 w-5 ml-0.5 shrink-0" + aria-hidden="true" + /> + + + + + <%= if @alerts do %> +
+ <.alert alert={alert} /> +
+ <% end %> +
""" end @@ -70,4 +79,22 @@ defmodule DotcomWeb.Components.TripPlanner.Place do end defp format_time(datetime), do: Timex.format!(datetime, "%-I:%M %p", :strftime) + + defp alert(assigns) do + ~H""" +
+ + <.icon name="triangle-exclamation" class="w-3 h-3" /> + + {Phoenix.Naming.humanize(@alert.effect)} + Show Details + + + +
+ {@alert.header} +
+
+ """ + end end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 4e359c876f..db04498803 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -11,7 +11,8 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do import MbtaMetro.Components.Icon, only: [icon: 1] import Routes.Route, only: [is_external?: 1, is_shuttle?: 1] - alias Dotcom.TripPlan.TransitDetail + alias Alerts.Match + alias Dotcom.TripPlan.{Alerts, NamedPosition, TransitDetail} alias Routes.Route @doc """ @@ -24,21 +25,26 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do attr :leg, :any, required: true def transit_leg(assigns) do + grouped_alerts = group_alerts(assigns.alerts, assigns.leg) + assigns = assign(assigns, grouped_alerts) + ~H"""
<.place place={@leg.from} time={@leg.start} route={if(match?(%TransitDetail{}, @leg.mode), do: @leg.mode.route)} + alerts={@alerts_for_from} /> +
<%= if Enum.count(@leg.mode.intermediate_stops) < 2 do %> - <.leg_summary leg={@leg} alerts={@alerts} /> + <.leg_summary leg={@leg} alerts={@alerts_for_mode} /> <.leg_details leg={@leg} /> <% else %>
- <.leg_summary leg={@leg} alerts={@alerts} /> + <.leg_summary leg={@leg} alerts={@alerts_for_mode} /> <.icon name="chevron-up" class="group-open:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" @@ -52,6 +58,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do place={@leg.to} time={@leg.stop} route={if(match?(%TransitDetail{}, @leg.mode), do: @leg.mode.route)} + alerts={@alerts_for_to} />
""" @@ -196,4 +203,31 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do
""" end + + defp group_alerts(alerts, leg) when is_list(alerts) do + grouped_alerts = + alerts + |> Enum.group_by(fn alert -> + alert.informed_entity.entities + |> Enum.any?(fn + %{stop: nil} -> false + _ -> true + end) + end) + + route_alerts = grouped_alerts[false] || [] + stop_alerts = grouped_alerts[true] || [] + + entities_from = Alerts.leg_entities_from(leg) + alerts_for_from = Match.match(stop_alerts, entities_from) + + entities_to = Alerts.leg_entities_to(leg) + alerts_for_to = Match.match(stop_alerts, entities_to) + + %{ + alerts_for_mode: route_alerts, + alerts_for_from: alerts_for_from, + alerts_for_to: alerts_for_to + } + end end From 9a9555d653779a0eaab6933f093100f37720bbf9 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 13 Dec 2024 16:42:39 -0500 Subject: [PATCH 07/20] refactor+fix: Extract <.alert_group /> to its own component and fix alert placement --- .../components/trip_planner/alert_group.ex | 37 +++++++++++ .../components/trip_planner/place.ex | 65 ++++++------------- .../components/trip_planner/transit_leg.ex | 27 +------- 3 files changed, 61 insertions(+), 68 deletions(-) create mode 100644 lib/dotcom_web/components/trip_planner/alert_group.ex diff --git a/lib/dotcom_web/components/trip_planner/alert_group.ex b/lib/dotcom_web/components/trip_planner/alert_group.ex new file mode 100644 index 0000000000..1fac6ecc67 --- /dev/null +++ b/lib/dotcom_web/components/trip_planner/alert_group.ex @@ -0,0 +1,37 @@ +defmodule DotcomWeb.Components.TripPlanner.AlertGroup do + @moduledoc """ + A component to display an alert for a route or location + """ + + use DotcomWeb, :component + + attr :alerts, :list, required: true + + def alert_group(assigns) do + ~H""" + <%= if @alerts do %> +
+ <.alert alert={alert} /> +
+ <% end %> + """ + end + + defp alert(assigns) do + ~H""" +
+ + <.icon name="triangle-exclamation" class="w-3 h-3" /> + + {Phoenix.Naming.humanize(@alert.effect)} + Show Details + + + +
+ {@alert.header} +
+
+ """ + end +end diff --git a/lib/dotcom_web/components/trip_planner/place.ex b/lib/dotcom_web/components/trip_planner/place.ex index 5a8055d24b..f2b6533c1c 100644 --- a/lib/dotcom_web/components/trip_planner/place.ex +++ b/lib/dotcom_web/components/trip_planner/place.ex @@ -5,6 +5,8 @@ defmodule DotcomWeb.Components.TripPlanner.Place do use DotcomWeb, :component + import DotcomWeb.Components.TripPlanner.AlertGroup, only: [alert_group: 1] + alias Routes.Route alias Stops.Stop @@ -23,32 +25,25 @@ defmodule DotcomWeb.Components.TripPlanner.Place do }) ~H""" -
- <.dynamic_tag - tag_name={@tag_name} - href={@stop_url} - class="grid grid-cols-[1.5rem_auto_1fr] items-center gap-2 w-full hover:no-underline text-black" - > - <.location_icon route={@route} class="h-6 w-6" /> - - {@place.name} - <.icon - :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} - type="icon-svg" - name="icon-accessible-default" - class="h-5 w-5 ml-0.5 shrink-0" - aria-hidden="true" - /> - - - - - <%= if @alerts do %> -
- <.alert alert={alert} /> -
- <% end %> -
+ <.dynamic_tag + tag_name={@tag_name} + href={@stop_url} + class="bg-gray-bordered-background px-3 py-2 rounded-lg grid grid-cols-[1.5rem_auto_1fr] items-center gap-2 w-full hover:no-underline text-black" + > + <.location_icon route={@route} class="h-6 w-6" /> + + {@place.name} + <.icon + :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} + type="icon-svg" + name="icon-accessible-default" + class="h-5 w-5 ml-0.5 shrink-0" + aria-hidden="true" + /> + + + <.alert_group alerts={@alerts} /> + """ end @@ -79,22 +74,4 @@ defmodule DotcomWeb.Components.TripPlanner.Place do end defp format_time(datetime), do: Timex.format!(datetime, "%-I:%M %p", :strftime) - - defp alert(assigns) do - ~H""" -
- - <.icon name="triangle-exclamation" class="w-3 h-3" /> - - {Phoenix.Naming.humanize(@alert.effect)} - Show Details - - - -
- {@alert.header} -
-
- """ - end end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index db04498803..b4fe0e2130 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -6,13 +6,14 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do use Phoenix.Component + import DotcomWeb.Components.TripPlanner.AlertGroup, only: [alert_group: 1] import DotcomWeb.Components.RouteSymbols, only: [route_symbol: 1] import DotcomWeb.Components.TripPlanner.Place import MbtaMetro.Components.Icon, only: [icon: 1] import Routes.Route, only: [is_external?: 1, is_shuttle?: 1] alias Alerts.Match - alias Dotcom.TripPlan.{Alerts, NamedPosition, TransitDetail} + alias Dotcom.TripPlan.{Alerts, TransitDetail} alias Routes.Route @doc """ @@ -96,11 +97,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do <.ride_message mode={@leg.mode} /> {@stops_count} {Inflex.inflect("stop", @stops_count)} - <%= if @alerts do %> -
- <.alert alert={alert} /> -
- <% end %> + <.alert_group alerts={@alerts} /> """ end @@ -186,24 +183,6 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do """ end - defp alert(assigns) do - ~H""" -
- - <.icon name="triangle-exclamation" class="w-3 h-3" /> - - {Phoenix.Naming.humanize(@alert.effect)} - Show Details - - - -
- {@alert.header} -
-
- """ - end - defp group_alerts(alerts, leg) when is_list(alerts) do grouped_alerts = alerts From 03a41c082b7cea10f1adad5180969e58faed991c Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Fri, 13 Dec 2024 16:54:32 -0500 Subject: [PATCH 08/20] cleanup: Move margin and grid-col classes out of <.alert_group /> --- .../components/trip_planner/alert_group.ex | 3 +- .../components/trip_planner/place.ex | 32 +++++++++---------- .../components/trip_planner/transit_leg.ex | 2 +- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/dotcom_web/components/trip_planner/alert_group.ex b/lib/dotcom_web/components/trip_planner/alert_group.ex index 1fac6ecc67..e93ab77b00 100644 --- a/lib/dotcom_web/components/trip_planner/alert_group.ex +++ b/lib/dotcom_web/components/trip_planner/alert_group.ex @@ -6,11 +6,12 @@ defmodule DotcomWeb.Components.TripPlanner.AlertGroup do use DotcomWeb, :component attr :alerts, :list, required: true + attr :class, :string, default: "" def alert_group(assigns) do ~H""" <%= if @alerts do %> -
+
<.alert alert={alert} />
<% end %> diff --git a/lib/dotcom_web/components/trip_planner/place.ex b/lib/dotcom_web/components/trip_planner/place.ex index f2b6533c1c..6f3aaa712c 100644 --- a/lib/dotcom_web/components/trip_planner/place.ex +++ b/lib/dotcom_web/components/trip_planner/place.ex @@ -25,25 +25,23 @@ defmodule DotcomWeb.Components.TripPlanner.Place do }) ~H""" - <.dynamic_tag - tag_name={@tag_name} - href={@stop_url} - class="bg-gray-bordered-background px-3 py-2 rounded-lg grid grid-cols-[1.5rem_auto_1fr] items-center gap-2 w-full hover:no-underline text-black" - > +
<.location_icon route={@route} class="h-6 w-6" /> - - {@place.name} - <.icon - :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} - type="icon-svg" - name="icon-accessible-default" - class="h-5 w-5 ml-0.5 shrink-0" - aria-hidden="true" - /> - + <.dynamic_tag class="hover:no-underline text-black" tag_name={@tag_name} href={@stop_url}> + + {@place.name} + <.icon + :if={!is_nil(@place.stop) and Stop.accessible?(@place.stop)} + type="icon-svg" + name="icon-accessible-default" + class="h-5 w-5 ml-0.5 shrink-0" + aria-hidden="true" + /> + + - <.alert_group alerts={@alerts} /> - + <.alert_group class="col-start-2 mr-4" alerts={@alerts} /> +
""" end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index b4fe0e2130..8359bf5647 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -97,7 +97,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do <.ride_message mode={@leg.mode} /> {@stops_count} {Inflex.inflect("stop", @stops_count)}
- <.alert_group alerts={@alerts} /> + <.alert_group class="col-start-2 mb-2 mr-4" alerts={@alerts} /> """ end From 4e327b25650d5635b2bc115fdca721e0d874d29c Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 15:11:56 -0500 Subject: [PATCH 09/20] refactor: Move &group_alerts/2 into TripPlan.Alerts module --- lib/dotcom/trip_plan/alerts.ex | 31 +++++++++++++++-- .../components/trip_planner/transit_leg.ex | 33 ++----------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index 2ec0b53470..ab940aa20b 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -54,14 +54,14 @@ defmodule Dotcom.TripPlan.Alerts do end end - def leg_entities_from(%Leg{mode: mode} = leg) do + defp leg_entities_from(%Leg{mode: mode} = leg) do for entity <- mode_entities(mode), stop_id <- Leg.stop_ids_from(leg) do %{entity | stop: stop_id} end end - def leg_entities_to(%Leg{mode: mode} = leg) do + defp leg_entities_to(%Leg{mode: mode} = leg) do for entity <- mode_entities(mode), stop_id <- Leg.stop_ids_to(leg) do %{entity | stop: stop_id} @@ -82,4 +82,31 @@ defmodule Dotcom.TripPlan.Alerts do defp mode_entities(_) do [] end + + def by_mode_and_stops(alerts, leg) do + grouped_alerts = + alerts + |> Enum.group_by(fn alert -> + alert.informed_entity.entities + |> Enum.any?(fn + %{stop: nil} -> false + _ -> true + end) + end) + + route_alerts = grouped_alerts[false] || [] + stop_alerts = grouped_alerts[true] || [] + + entities_from = leg_entities_from(leg) + alerts_for_from = Alerts.Match.match(stop_alerts, entities_from) + + entities_to = leg_entities_to(leg) + alerts_for_to = Alerts.Match.match(stop_alerts, entities_to) + + %{ + alerts_for_route: route_alerts, + alerts_for_from: alerts_for_from, + alerts_for_to: alerts_for_to + } + end end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 8359bf5647..2544185912 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -26,7 +26,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do attr :leg, :any, required: true def transit_leg(assigns) do - grouped_alerts = group_alerts(assigns.alerts, assigns.leg) + grouped_alerts = Alerts.by_mode_and_stops(assigns.alerts, assigns.leg) assigns = assign(assigns, grouped_alerts) ~H""" @@ -40,12 +40,12 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do
<%= if Enum.count(@leg.mode.intermediate_stops) < 2 do %> - <.leg_summary leg={@leg} alerts={@alerts_for_mode} /> + <.leg_summary leg={@leg} alerts={@alerts_for_route} /> <.leg_details leg={@leg} /> <% else %>
- <.leg_summary leg={@leg} alerts={@alerts_for_mode} /> + <.leg_summary leg={@leg} alerts={@alerts_for_route} /> <.icon name="chevron-up" class="group-open:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" @@ -182,31 +182,4 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do """ end - - defp group_alerts(alerts, leg) when is_list(alerts) do - grouped_alerts = - alerts - |> Enum.group_by(fn alert -> - alert.informed_entity.entities - |> Enum.any?(fn - %{stop: nil} -> false - _ -> true - end) - end) - - route_alerts = grouped_alerts[false] || [] - stop_alerts = grouped_alerts[true] || [] - - entities_from = Alerts.leg_entities_from(leg) - alerts_for_from = Match.match(stop_alerts, entities_from) - - entities_to = Alerts.leg_entities_to(leg) - alerts_for_to = Match.match(stop_alerts, entities_to) - - %{ - alerts_for_mode: route_alerts, - alerts_for_from: alerts_for_from, - alerts_for_to: alerts_for_to - } - end end From f23772fa84dc75de5f031fc34c337701e121974d Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 15:46:50 -0500 Subject: [PATCH 10/20] fix: Stop alert layout --- lib/dotcom_web/components/trip_planner/place.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dotcom_web/components/trip_planner/place.ex b/lib/dotcom_web/components/trip_planner/place.ex index 6f3aaa712c..81a5672357 100644 --- a/lib/dotcom_web/components/trip_planner/place.ex +++ b/lib/dotcom_web/components/trip_planner/place.ex @@ -40,7 +40,7 @@ defmodule DotcomWeb.Components.TripPlanner.Place do - <.alert_group class="col-start-2 mr-4" alerts={@alerts} /> + <.alert_group class="col-start-2 col-end-4 mr-4" alerts={@alerts} />
""" end From 8225f4e0b34d40f780b9a4da42141f7b57b05f8b Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 15:55:38 -0500 Subject: [PATCH 11/20] refactor: Clean up variable names for grouped alerts --- lib/dotcom/trip_plan/alerts.ex | 10 +++++----- lib/dotcom_web/components/trip_planner/transit_leg.ex | 11 +++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index ab940aa20b..1eff3e88af 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -98,15 +98,15 @@ defmodule Dotcom.TripPlan.Alerts do stop_alerts = grouped_alerts[true] || [] entities_from = leg_entities_from(leg) - alerts_for_from = Alerts.Match.match(stop_alerts, entities_from) + from = Alerts.Match.match(stop_alerts, entities_from) entities_to = leg_entities_to(leg) - alerts_for_to = Alerts.Match.match(stop_alerts, entities_to) + to = Alerts.Match.match(stop_alerts, entities_to) %{ - alerts_for_route: route_alerts, - alerts_for_from: alerts_for_from, - alerts_for_to: alerts_for_to + route: route_alerts, + from: from, + to: to } end end diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 2544185912..38fb644ec5 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -26,8 +26,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do attr :leg, :any, required: true def transit_leg(assigns) do - grouped_alerts = Alerts.by_mode_and_stops(assigns.alerts, assigns.leg) - assigns = assign(assigns, grouped_alerts) + assigns = assign(assigns, :alerts, Alerts.by_mode_and_stops(assigns.alerts, assigns.leg)) ~H"""
@@ -35,17 +34,17 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do place={@leg.from} time={@leg.start} route={if(match?(%TransitDetail{}, @leg.mode), do: @leg.mode.route)} - alerts={@alerts_for_from} + alerts={@alerts.from} />
<%= if Enum.count(@leg.mode.intermediate_stops) < 2 do %> - <.leg_summary leg={@leg} alerts={@alerts_for_route} /> + <.leg_summary leg={@leg} alerts={@alerts.route} /> <.leg_details leg={@leg} /> <% else %>
- <.leg_summary leg={@leg} alerts={@alerts_for_route} /> + <.leg_summary leg={@leg} alerts={@alerts.route} /> <.icon name="chevron-up" class="group-open:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" @@ -59,7 +58,7 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do place={@leg.to} time={@leg.stop} route={if(match?(%TransitDetail{}, @leg.mode), do: @leg.mode.route)} - alerts={@alerts_for_to} + alerts={@alerts.to} />
""" From 50ada4138e61f35f41dcf1f7cd3bf83fc25b9027 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:00:47 -0500 Subject: [PATCH 12/20] fix: Disambiguate stops versus alerts for CSS grouping --- lib/dotcom_web/components/trip_planner/alert_group.ex | 8 +++++--- lib/dotcom_web/components/trip_planner/transit_leg.ex | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/dotcom_web/components/trip_planner/alert_group.ex b/lib/dotcom_web/components/trip_planner/alert_group.ex index e93ab77b00..afecae4d88 100644 --- a/lib/dotcom_web/components/trip_planner/alert_group.ex +++ b/lib/dotcom_web/components/trip_planner/alert_group.ex @@ -20,13 +20,15 @@ defmodule DotcomWeb.Components.TripPlanner.AlertGroup do defp alert(assigns) do ~H""" -
+
<.icon name="triangle-exclamation" class="w-3 h-3" /> {Phoenix.Naming.humanize(@alert.effect)} - Show Details - + Show Details +
diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 38fb644ec5..9c058bf95d 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -42,12 +42,12 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do <.leg_summary leg={@leg} alerts={@alerts.route} /> <.leg_details leg={@leg} /> <% else %> -
+
<.leg_summary leg={@leg} alerts={@alerts.route} /> <.icon name="chevron-up" - class="group-open:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" + class="group-open/stops:rotate-180 w-4 h-4 absolute top-3 right-3 fill-brand-primary" /> <.leg_details leg={@leg} /> From 832bf600198785d7448c3c7cff6517234a3bfa4a Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:14:24 -0500 Subject: [PATCH 13/20] cleanup: Remove unused alias --- lib/dotcom_web/components/trip_planner/transit_leg.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/dotcom_web/components/trip_planner/transit_leg.ex b/lib/dotcom_web/components/trip_planner/transit_leg.ex index 9c058bf95d..fee31f8689 100644 --- a/lib/dotcom_web/components/trip_planner/transit_leg.ex +++ b/lib/dotcom_web/components/trip_planner/transit_leg.ex @@ -12,7 +12,6 @@ defmodule DotcomWeb.Components.TripPlanner.TransitLeg do import MbtaMetro.Components.Icon, only: [icon: 1] import Routes.Route, only: [is_external?: 1, is_shuttle?: 1] - alias Alerts.Match alias Dotcom.TripPlan.{Alerts, TransitDetail} alias Routes.Route From 02c63dc6112197cc8113c358b55c919444c6b7d2 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:14:39 -0500 Subject: [PATCH 14/20] tests: Add test for &Alerts.by_mode_and_stops/2 --- test/dotcom/trip_plan/alerts_test.exs | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/dotcom/trip_plan/alerts_test.exs b/test/dotcom/trip_plan/alerts_test.exs index 216ef55b92..cdcfec9d5f 100644 --- a/test/dotcom/trip_plan/alerts_test.exs +++ b/test/dotcom/trip_plan/alerts_test.exs @@ -165,6 +165,37 @@ defmodule Dotcom.TripPlan.AlertsTest do end end + describe "by_mode_and_stops/2" do + test "groups alerts by route, to, and from", %{itinerary: itinerary, route_id: route_id} do + [leg] = itinerary.legs + [from_stop_id, to_stop_id] = itinerary |> Itinerary.stop_ids() + + route_alert = + Alert.new( + active_period: [valid_active_period(itinerary)], + informed_entity: [%InformedEntity{route: route_id}] + ) + + from_alert = + Alert.new( + active_period: [valid_active_period(itinerary)], + informed_entity: [%InformedEntity{stop: from_stop_id}] + ) + + to_alert = + Alert.new( + active_period: [valid_active_period(itinerary)], + informed_entity: [%InformedEntity{stop: to_stop_id}] + ) + + assert by_mode_and_stops([route_alert, from_alert, to_alert], leg) == %{ + from: [from_alert], + to: [to_alert], + route: [route_alert] + } + end + end + defp assert_only_good_alert(good_alert, bad_alert, itinerary) do assert filter_for_itinerary([good_alert, bad_alert], itinerary) == [good_alert] end From 61c70b5922069e3b56c76e0580c92c32e1dfdb5e Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:18:13 -0500 Subject: [PATCH 15/20] cleanup: Replace &Enum.group_by/2 with &Enum.split_with/2 --- lib/dotcom/trip_plan/alerts.ex | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index 1eff3e88af..236018c17b 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -84,19 +84,16 @@ defmodule Dotcom.TripPlan.Alerts do end def by_mode_and_stops(alerts, leg) do - grouped_alerts = + {route_alerts, stop_alerts} = alerts - |> Enum.group_by(fn alert -> + |> Enum.split_with(fn alert -> alert.informed_entity.entities - |> Enum.any?(fn - %{stop: nil} -> false - _ -> true + |> Enum.all?(fn + %{stop: nil} -> true + _ -> false end) end) - route_alerts = grouped_alerts[false] || [] - stop_alerts = grouped_alerts[true] || [] - entities_from = leg_entities_from(leg) from = Alerts.Match.match(stop_alerts, entities_from) From b611b083955685b3bf2f6aec086b5eaca4f29b88 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:31:17 -0500 Subject: [PATCH 16/20] refactor: Move &ItineraryDetail.alerts_for_leg/2 into Alerts module --- lib/dotcom/trip_plan/alerts.ex | 12 +++++++++++- .../components/trip_planner/itinerary_detail.ex | 11 +---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index 236018c17b..09bc79882a 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -34,6 +34,16 @@ defmodule Dotcom.TripPlan.Alerts do ) end + @doc "Filters a list of Alerts to those relevant to the Leg" + @spec filter_for_leg([Alert.t()], Leg.t()) :: [Alert.t()] + def filter_for_leg(alerts, leg) do + Alerts.Match.match( + alerts, + leg_entities(leg), + leg.start + ) + end + defp intermediate_entities(itinerary) do itinerary |> Itinerary.intermediate_stop_ids() @@ -47,7 +57,7 @@ defmodule Dotcom.TripPlan.Alerts do |> Enum.uniq() end - def leg_entities(%Leg{mode: mode} = leg) do + defp leg_entities(%Leg{mode: mode} = leg) do for entity <- mode_entities(mode), stop_id <- Leg.stop_ids(leg) do %{entity | stop: stop_id} diff --git a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex index 4451e1e409..5e9f2619ce 100644 --- a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex +++ b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex @@ -10,7 +10,6 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do import DotcomWeb.Components.TripPlanner.TransitLeg, only: [transit_leg: 1] import DotcomWeb.Components.TripPlanner.WalkingLeg, only: [walking_leg: 1] - alias Alerts.Match alias Dotcom.TripPlan.LegToSegmentHelper alias Dotcom.TripPlan.Alerts @@ -112,17 +111,9 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do assigns = assign(assigns, :leg, leg) ~H""" - <.transit_leg leg={@leg} alerts={alerts_for_leg(@alerts, @leg)} /> + <.transit_leg leg={@leg} alerts={Alerts.filter_for_leg(@alerts, @leg)} /> """ end - defp alerts_for_leg(alerts, leg) when is_list(alerts) do - Match.match( - alerts, - Alerts.leg_entities(leg), - leg.start - ) - end - defp alerts_for_leg(_, _), do: [] end From 857f7e0489a7ea1f2463983180554423f1e265fe Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:36:47 -0500 Subject: [PATCH 17/20] cleanup: Remove &ItineraryDetail.alerts_for_leg/2 straggler --- lib/dotcom_web/components/trip_planner/itinerary_detail.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex index 5e9f2619ce..1c58386d99 100644 --- a/lib/dotcom_web/components/trip_planner/itinerary_detail.ex +++ b/lib/dotcom_web/components/trip_planner/itinerary_detail.ex @@ -114,6 +114,4 @@ defmodule DotcomWeb.Components.TripPlanner.ItineraryDetail do <.transit_leg leg={@leg} alerts={Alerts.filter_for_leg(@alerts, @leg)} /> """ end - - defp alerts_for_leg(_, _), do: [] end From fca04c1308feb28560e22b41251330688eade9c6 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 16:47:18 -0500 Subject: [PATCH 18/20] fix: Alerts tests --- lib/dotcom/trip_plan/alerts.ex | 26 ++++++++++++++++---------- test/dotcom/trip_plan/alerts_test.exs | 8 ++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index 09bc79882a..a9e564c7f9 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -8,8 +8,6 @@ defmodule Dotcom.TripPlan.Alerts do * at the times they'll be travelling """ - import Routes.Route, only: [is_external?: 1] - alias Alerts.Alert alias Alerts.InformedEntity, as: IE alias Dotcom.TripPlan.{Itinerary, Leg, TransitDetail} @@ -78,15 +76,23 @@ defmodule Dotcom.TripPlan.Alerts do end end - defp mode_entities(%TransitDetail{route: route}) when is_external?(route) do - [] - end + defp mode_entities(%TransitDetail{route: route, trip: %{id: trip_id}}) do + trip = + if is_nil(route.external_agency_name) do + Schedules.Repo.trip(trip_id) + end + + route_type = + if route do + route.type + end + + direction_id = + if trip do + trip.direction_id + end - defp mode_entities(%TransitDetail{ - route: %{id: route_id, type: route_type}, - trip: %{id: trip_id, direction_id: direction_id} - }) do - [%IE{route_type: route_type, route: route_id, trip: trip_id, direction_id: direction_id}] + [%IE{route_type: route_type, route: route.id, trip: trip_id, direction_id: direction_id}] end defp mode_entities(_) do diff --git a/test/dotcom/trip_plan/alerts_test.exs b/test/dotcom/trip_plan/alerts_test.exs index cdcfec9d5f..4d54683e7e 100644 --- a/test/dotcom/trip_plan/alerts_test.exs +++ b/test/dotcom/trip_plan/alerts_test.exs @@ -167,6 +167,14 @@ defmodule Dotcom.TripPlan.AlertsTest do describe "by_mode_and_stops/2" do test "groups alerts by route, to, and from", %{itinerary: itinerary, route_id: route_id} do + expect(MBTA.Api.Mock, :get_json, fn "/trips/" <> id, [] -> + %JsonApi{ + data: [ + Api.build(:trip_item, %{id: id}) + ] + } + end) + [leg] = itinerary.legs [from_stop_id, to_stop_id] = itinerary |> Itinerary.stop_ids() From e293a16264a8e9a7fd306a5585bbbd796a71c3ad Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Tue, 17 Dec 2024 17:26:02 -0500 Subject: [PATCH 19/20] cleanup: Pare down stop ID logic and remove &Leg.stop_ids_{from, to}/1 --- assets/package-lock.json | 585 +++++++++++++++++++++-------- lib/dotcom/trip_plan/alerts.ex | 22 +- lib/dotcom/trip_plan/leg.ex | 34 +- test/dotcom/trip_plan/leg_test.exs | 4 +- 4 files changed, 444 insertions(+), 201 deletions(-) diff --git a/assets/package-lock.json b/assets/package-lock.json index b7ae0ee4ec..4d14171fdf 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -157,28 +157,6 @@ "version": "3.3.1", "extraneous": true }, - "../deps/mbta_metro/priv": { - "version": "0.0.1", - "license": "GPL-3.0-or-later", - "dependencies": { - "@tailwindcss/forms": "0.5.9", - "camelcase-keys": "9.1.3", - "date-fns": "4.1.0", - "flatpickr": "4.6.13", - "maplibre-gl": "4.7.0", - "preline": "2.4.1" - }, - "devDependencies": { - "@fortawesome/fontawesome-free": "6.6.0" - } - }, - "../deps/phoenix": { - "version": "1.7.14", - "license": "MIT" - }, - "../deps/phoenix_html": { - "version": "4.1.0" - }, "../mbta_metro/assets": { "extraneous": true }, @@ -429,7 +407,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -2873,7 +2850,7 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -2884,7 +2861,7 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -4139,7 +4116,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -4156,7 +4132,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, "engines": { "node": ">=12" }, @@ -4168,7 +4143,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { "node": ">=12" }, @@ -4179,14 +4153,12 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -4203,7 +4175,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -4218,7 +4189,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -4886,7 +4856,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -4896,7 +4865,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -4927,14 +4895,12 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4946,9 +4912,94 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "dev": true }, + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.6" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojson-rewind/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", + "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==" + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==" + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.4.0.tgz", + "integrity": "sha512-AzBy3095fTFPjDjmWpR2w6HVRAZJ6hQZUCwk5Plz6EyfnfuQW1odeW5i2Ai47Y6TBA2hQnC+azscjBSALpaWgw==", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec/node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -4960,7 +5011,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -4968,7 +5018,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -4982,7 +5031,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -4994,6 +5042,15 @@ "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@remix-run/router": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz", @@ -5236,7 +5293,6 @@ "version": "0.5.9", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", - "dev": true, "dependencies": { "mini-svg-data-uri": "^1.2.3" }, @@ -5484,22 +5540,22 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/aria-query": { @@ -5692,8 +5748,15 @@ "node_modules/@types/geojson": { "version": "7946.0.14", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", - "dev": true + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "dependencies": { + "@types/geojson": "*" + } }, "node_modules/@types/googlemaps": { "version": "3.43.3", @@ -5783,6 +5846,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mapbox__point-geometry": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", + "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==" + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, "node_modules/@types/mdast": { "version": "3.0.12", "dev": true, @@ -5803,7 +5881,7 @@ }, "node_modules/@types/node": { "version": "18.11.9", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/node-forge": { @@ -5825,6 +5903,11 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" + }, "node_modules/@types/phoenix": { "version": "1.5.4", "dev": true, @@ -5977,6 +6060,14 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.5", "dev": true, @@ -6555,7 +6646,7 @@ }, "node_modules/acorn": { "version": "8.10.0", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -6802,7 +6893,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6823,12 +6913,10 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -6859,7 +6947,7 @@ }, "node_modules/arg": { "version": "4.1.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argparse": { @@ -7534,7 +7622,6 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -7579,7 +7666,6 @@ }, "node_modules/binary-extensions": { "version": "2.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7680,7 +7766,6 @@ }, "node_modules/braces": { "version": "3.0.2", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.0.1" @@ -7858,7 +7943,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -8025,7 +8109,6 @@ }, "node_modules/chokidar": { "version": "3.5.3", - "dev": true, "funding": [ { "type": "individual", @@ -8442,12 +8525,11 @@ }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -8853,7 +8935,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "dev": true, "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -9562,7 +9643,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/diff": { @@ -9601,7 +9681,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, "license": "MIT" }, "node_modules/dns-packet": { @@ -9719,11 +9798,15 @@ "dev": true, "license": "MIT" }, + "node_modules/earcut": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ecc-jsbn": { "version": "0.1.2", @@ -9759,7 +9842,6 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, "license": "MIT" }, "node_modules/emojis-list": { @@ -11097,7 +11179,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -11129,7 +11210,6 @@ }, "node_modules/fastq": { "version": "1.13.0", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -11229,7 +11309,6 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -11368,7 +11447,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -11384,7 +11462,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -11492,7 +11569,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -11506,7 +11582,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11550,6 +11625,11 @@ "node": ">=6.9.0" } }, + "node_modules/geojson-vt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==" + }, "node_modules/get-caller-file": { "version": "2.0.5", "dev": true, @@ -11640,6 +11720,11 @@ "assert-plus": "^1.0.0" } }, + "node_modules/gl-matrix": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" + }, "node_modules/glob": { "version": "7.2.3", "dev": true, @@ -11661,7 +11746,6 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -11924,7 +12008,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -12275,7 +12358,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "dev": true, "funding": [ { "type": "github", @@ -12539,7 +12621,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -12611,7 +12692,6 @@ "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -12663,7 +12743,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12671,7 +12750,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12687,7 +12765,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -12771,7 +12848,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -12995,7 +13071,6 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -14972,7 +15047,6 @@ "version": "1.21.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -15131,6 +15205,11 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==" + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "dev": true, @@ -15190,9 +15269,13 @@ "dev": true, "license": "MIT" }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" + }, "node_modules/kind-of": { "version": "6.0.3", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15279,14 +15362,12 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, "license": "MIT" }, "node_modules/listr2": { @@ -15627,7 +15708,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -15653,6 +15734,89 @@ "version": "0.1.0", "dev": true }, + "node_modules/maplibre-gl": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.0.tgz", + "integrity": "sha512-hkt7je7NxiMQE8EpCxLWP8t6tkK6SkrMe0hIBjYd4Ar/Q7BOCILxthGmGnU993Mwmkvs2mGiXnVUSOK12DeCzg==", + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^2.0.6", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", + "@types/geojson": "^7946.0.14", + "@types/geojson-vt": "3.2.5", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.0", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.3", + "global-prefix": "^4.0.0", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^3.3.0", + "potpack": "^2.0.0", + "quickselect": "^3.0.0", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0", + "vt-pbf": "^3.1.3" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, + "node_modules/maplibre-gl/node_modules/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/maplibre-gl/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/maplibre-gl/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "engines": { + "node": ">=16" + } + }, + "node_modules/maplibre-gl/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "dev": true, @@ -15663,8 +15827,87 @@ } }, "node_modules/mbta_metro": { - "resolved": "../deps/mbta_metro/priv", - "link": true + "version": "0.0.1", + "resolved": "file:../deps/mbta_metro/priv", + "license": "GPL-3.0-or-later", + "dependencies": { + "@tailwindcss/forms": "0.5.9", + "camelcase-keys": "9.1.3", + "date-fns": "4.1.0", + "flatpickr": "4.6.13", + "maplibre-gl": "4.7.0", + "preline": "2.4.1" + } + }, + "node_modules/mbta_metro/node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mbta_metro/node_modules/camelcase-keys": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-9.1.3.tgz", + "integrity": "sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg==", + "dependencies": { + "camelcase": "^8.0.0", + "map-obj": "5.0.0", + "quick-lru": "^6.1.1", + "type-fest": "^4.3.2" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mbta_metro/node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/mbta_metro/node_modules/map-obj": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-5.0.0.tgz", + "integrity": "sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mbta_metro/node_modules/quick-lru": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz", + "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mbta_metro/node_modules/type-fest": { + "version": "4.30.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.2.tgz", + "integrity": "sha512-UJShLPYi1aWqCdq9HycOL/gwsuqda1OISdBO3t8RlXQC4QvtuIz4b5FCfe2dQIWEpmlRExKmcTBfP1r9bhY7ig==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/mdast-util-from-markdown": { "version": "0.8.5", @@ -15801,7 +16044,6 @@ }, "node_modules/merge2": { "version": "1.4.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -15857,7 +16099,6 @@ }, "node_modules/micromatch": { "version": "4.0.5", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.2", @@ -15943,7 +16184,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "dev": true, "license": "MIT", "bin": { "mini-svg-data-uri": "cli.js" @@ -15969,7 +16209,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15999,7 +16238,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -16536,11 +16774,15 @@ "multicast-dns": "cli.js" } }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0", @@ -16552,7 +16794,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -16705,7 +16946,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16775,7 +17015,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17046,7 +17285,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { @@ -17143,7 +17381,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17151,14 +17388,12 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "dev": true, "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -17175,7 +17410,6 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true, "engines": { "node": "14 || >=16.14" } @@ -17212,6 +17446,18 @@ "through": "~2.3" } }, + "node_modules/pbf": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/pend": { "version": "1.2.0", "dev": true, @@ -17223,12 +17469,13 @@ "license": "MIT" }, "node_modules/phoenix": { - "resolved": "../deps/phoenix", - "link": true + "version": "1.7.14", + "resolved": "file:../deps/phoenix", + "license": "MIT" }, "node_modules/phoenix_html": { - "resolved": "../deps/phoenix_html", - "link": true + "version": "4.1.0", + "resolved": "file:../deps/phoenix_html" }, "node_modules/phoenix_live_view": { "version": "0.20.1", @@ -17239,12 +17486,10 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -17263,7 +17508,6 @@ }, "node_modules/pirates": { "version": "4.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17346,7 +17590,6 @@ "version": "8.4.41", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -17947,7 +18190,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", @@ -17965,7 +18207,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" @@ -18046,7 +18287,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -18082,7 +18322,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, "license": "MIT", "engines": { "node": ">=14" @@ -18095,7 +18334,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", - "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -18398,7 +18636,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -18952,7 +19189,6 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -19036,9 +19272,13 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "dev": true, "license": "MIT" }, + "node_modules/potpack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", + "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==" + }, "node_modules/preact": { "version": "10.18.1", "resolved": "https://registry.npmjs.org/preact/-/preact-10.18.1.tgz", @@ -19048,6 +19288,14 @@ "url": "https://opencollective.com/preact" } }, + "node_modules/preline": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/preline/-/preline-2.4.1.tgz", + "integrity": "sha512-30yx5s2gEOTBWXSTPa+Th23/kGryn9Inhmp9KPzz9G8DZPp9j/LkGyyrSvdsuXh4Clc/sJFLObumFrbI/WmB0w==", + "dependencies": { + "@popperjs/core": "^2.11.2" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -19169,6 +19417,11 @@ "reflect.ownkeys": "^0.2.0" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "dev": true, @@ -19338,7 +19591,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "dev": true, "funding": [ { "type": "github", @@ -19363,6 +19615,11 @@ "node": ">=8" } }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==" + }, "node_modules/raf": { "version": "3.4.1", "dev": true, @@ -19562,7 +19819,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "license": "MIT", "dependencies": { "pify": "^2.3.0" @@ -19572,7 +19828,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -19699,7 +19954,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -20037,7 +20291,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -20070,6 +20323,14 @@ "node": ">=8" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/resolve.exports": { "version": "1.1.0", "dev": true, @@ -20109,7 +20370,6 @@ }, "node_modules/reusify": { "version": "1.0.4", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -20158,7 +20418,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "dev": true, "funding": [ { "type": "github", @@ -20178,6 +20437,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -20542,7 +20806,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -20553,7 +20816,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -20714,7 +20976,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -21040,7 +21301,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -21056,7 +21316,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -21128,7 +21387,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -21142,7 +21400,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -21504,7 +21761,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", @@ -21527,7 +21783,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -21542,7 +21797,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -21552,7 +21806,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -21562,7 +21815,6 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -21583,7 +21835,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -21599,7 +21850,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -21640,6 +21890,14 @@ "url": "https://opencollective.com/postcss/" } }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, @@ -21684,7 +21942,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -21867,7 +22124,6 @@ "version": "3.4.10", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", - "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -21905,14 +22161,12 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, "license": "MIT" }, "node_modules/tailwindcss/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -22054,7 +22308,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0" @@ -22064,7 +22317,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" @@ -22093,6 +22345,11 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==" + }, "node_modules/tmp": { "version": "0.2.1", "dev": true, @@ -22119,7 +22376,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -22189,7 +22445,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, "license": "Apache-2.0" }, "node_modules/ts-jest": { @@ -22357,7 +22612,7 @@ }, "node_modules/ts-node": { "version": "10.9.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -22399,7 +22654,7 @@ }, "node_modules/ts-node/node_modules/acorn-walk": { "version": "8.2.0", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -22407,7 +22662,7 @@ }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -22522,7 +22777,7 @@ }, "node_modules/typescript": { "version": "4.8.4", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -22741,7 +22996,6 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/utils-merge": { @@ -22767,7 +23021,7 @@ }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -22849,6 +23103,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "dev": true, @@ -23489,7 +23753,6 @@ }, "node_modules/which": { "version": "2.0.2", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -23589,7 +23852,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -23606,7 +23868,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -23621,7 +23882,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -23632,8 +23892,7 @@ "node_modules/wrap-ansi-cjs/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", @@ -23795,7 +24054,7 @@ }, "node_modules/yn": { "version": "3.1.1", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/lib/dotcom/trip_plan/alerts.ex b/lib/dotcom/trip_plan/alerts.ex index a9e564c7f9..fb165a41b3 100644 --- a/lib/dotcom/trip_plan/alerts.ex +++ b/lib/dotcom/trip_plan/alerts.ex @@ -56,22 +56,14 @@ defmodule Dotcom.TripPlan.Alerts do end defp leg_entities(%Leg{mode: mode} = leg) do - for entity <- mode_entities(mode), - stop_id <- Leg.stop_ids(leg) do - %{entity | stop: stop_id} - end - end + %{from: from, to: to} = Leg.stop_ids(leg) - defp leg_entities_from(%Leg{mode: mode} = leg) do - for entity <- mode_entities(mode), - stop_id <- Leg.stop_ids_from(leg) do - %{entity | stop: stop_id} - end + mode_entities_with_stop_ids(mode, from ++ to) end - defp leg_entities_to(%Leg{mode: mode} = leg) do + defp mode_entities_with_stop_ids(mode, stop_ids) do for entity <- mode_entities(mode), - stop_id <- Leg.stop_ids_to(leg) do + stop_id <- stop_ids do %{entity | stop: stop_id} end end @@ -110,10 +102,12 @@ defmodule Dotcom.TripPlan.Alerts do end) end) - entities_from = leg_entities_from(leg) + %{from: from_stop_ids, to: to_stop_ids} = Leg.stop_ids(leg) + + entities_from = mode_entities_with_stop_ids(leg.mode, from_stop_ids) from = Alerts.Match.match(stop_alerts, entities_from) - entities_to = leg_entities_to(leg) + entities_to = mode_entities_with_stop_ids(leg.mode, to_stop_ids) to = Alerts.Match.match(stop_alerts, entities_to) %{ diff --git a/lib/dotcom/trip_plan/leg.ex b/lib/dotcom/trip_plan/leg.ex index 3c786e5000..4f3d0dcf59 100644 --- a/lib/dotcom/trip_plan/leg.ex +++ b/lib/dotcom/trip_plan/leg.ex @@ -66,28 +66,18 @@ defmodule Dotcom.TripPlan.Leg do @doc "Returns the stop IDs for the leg" @spec stop_ids(t) :: [Stops.Stop.id_t()] def stop_ids(%__MODULE__{from: from, to: to}) do - for %NamedPosition{stop: stop} <- [from, to], - stop do - stop.id - end - end - - @doc "Returns the stop ID for the beginning of the leg if available" - @spec stop_ids_from(t) :: [Stops.Stop.id_t()] - def stop_ids_from(%__MODULE__{from: from}) do - for %NamedPosition{stop: stop} <- [from], - stop do - stop.id - end - end - - @doc "Returns the stop ID for the end of the leg if available" - @spec stop_ids_to(t) :: [Stops.Stop.id_t()] - def stop_ids_to(%__MODULE__{to: to}) do - for %NamedPosition{stop: stop} <- [to], - stop do - stop.id - end + %{ + from: + for %NamedPosition{stop: stop} <- [from], + stop do + stop.id + end, + to: + for %NamedPosition{stop: stop} <- [to], + stop do + stop.id + end + } end @spec stop_is_silver_line_airport?([t], atom) :: boolean() diff --git a/test/dotcom/trip_plan/leg_test.exs b/test/dotcom/trip_plan/leg_test.exs index ad75bce9dd..509c2c4028 100644 --- a/test/dotcom/trip_plan/leg_test.exs +++ b/test/dotcom/trip_plan/leg_test.exs @@ -59,7 +59,7 @@ defmodule Dotcom.TripPlan.LegTest do describe "stop_ids/1" do test "returns the stop IDs @from and @to", context do - assert [@from.stop.id, @to.stop.id] == stop_ids(context.transit_leg) + assert %{from: [@from.stop.id], to: [@to.stop.id]} == stop_ids(context.transit_leg) end test "ignores nil stop IDs" do @@ -73,7 +73,7 @@ defmodule Dotcom.TripPlan.LegTest do stop: @stop ) - assert [@to.stop.id] == stop_ids(personal_leg) + assert %{from: [], to: [@to.stop.id]} == stop_ids(personal_leg) end end From bf902d8ca3c98f9437e9026b8f4a58d2dad652c7 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Tue, 17 Dec 2024 21:44:36 -0500 Subject: [PATCH 20/20] fix tests --- test/dotcom_web/live/trip_planner_test.exs | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/dotcom_web/live/trip_planner_test.exs b/test/dotcom_web/live/trip_planner_test.exs index 091e2e8607..9e38d5c668 100644 --- a/test/dotcom_web/live/trip_planner_test.exs +++ b/test/dotcom_web/live/trip_planner_test.exs @@ -13,6 +13,15 @@ defmodule DotcomWeb.Live.TripPlannerTest do expect(OpenTripPlannerClient.Mock, :plan, fn _ -> {:ok, %OpenTripPlannerClient.Plan{itineraries: itineraries}} end) + + # For certain routes, Dotcom.TripPlan.Alerts.mode_entities/1 is called to help fetch the associated alerts + stub(MBTA.Api.Mock, :get_json, fn "/trips/" <> id, [] -> + %JsonApi{ + data: [ + Test.Support.Factories.MBTA.Api.build(:trip_item, %{id: id}) + ] + } + end) end defp stub_populated_otp_results do @@ -227,6 +236,14 @@ defmodule DotcomWeb.Live.TripPlannerTest do }} end) + stub(MBTA.Api.Mock, :get_json, fn "/trips/" <> id, [] -> + %JsonApi{ + data: [ + Test.Support.Factories.MBTA.Api.build(:trip_item, %{id: id}) + ] + } + end) + {:ok, view, _html} = live(conn, ~p"/preview/trip-planner?#{params}") render_async(view) @@ -253,6 +270,14 @@ defmodule DotcomWeb.Live.TripPlannerTest do }} end) + stub(MBTA.Api.Mock, :get_json, fn "/trips/" <> id, [] -> + %JsonApi{ + data: [ + Test.Support.Factories.MBTA.Api.build(:trip_item, %{id: id}) + ] + } + end) + {:ok, view, _html} = live(conn, ~p"/preview/trip-planner?#{params}") render_async(view) @@ -276,6 +301,14 @@ defmodule DotcomWeb.Live.TripPlannerTest do }} end) + stub(MBTA.Api.Mock, :get_json, fn "/trips/" <> id, [] -> + %JsonApi{ + data: [ + Test.Support.Factories.MBTA.Api.build(:trip_item, %{id: id}) + ] + } + end) + {:ok, view, _html} = live(conn, ~p"/preview/trip-planner?#{params}") render_async(view)