├── .codecov.yml
├── .dockerignore
├── .eslintignore
├── .eslintrc.js
├── .git-blame-ignore-revs
├── .github
├── pull_request_template.md
└── workflows
│ ├── dev-pipeline.yml
│ ├── prod-pipeline.yml
│ └── scripts
│ ├── push_prod.sh
│ └── slack_message.sh
├── .gitignore
├── .lvimrc
├── .nvmrc
├── .nycrc.json
├── .stylelintrc.json
├── .yarn
├── plugins
│ └── @yarnpkg
│ │ ├── plugin-interactive-tools.cjs
│ │ └── plugin-version.cjs
├── releases
│ └── yarn-3.4.1.cjs
└── versions
│ └── 41447b25.yml
├── .yarnrc.yml
├── COPYING
├── Dockerfile
├── LICENSE-AGPL.txt
├── LICENSE-EUPL.txt
├── README.md
├── app
├── action
│ ├── CanceledLegsBarActions.js
│ ├── CountryActions.js
│ ├── FavouriteActions.js
│ ├── FutureRoutesActions.js
│ ├── MapLayerActions.js
│ ├── MessageActions.js
│ ├── PositionActions.js
│ ├── SearchActions.js
│ ├── SearchSettingsActions.js
│ ├── ViaPointActions.js
│ ├── destinationActions.js
│ ├── originActions.js
│ ├── realTimeClientAction.js
│ ├── userActions.js
│ └── userPreferencesActions.js
├── app.js
├── buildInfo.js
├── client.js
├── component
│ ├── 404.js
│ ├── AboutPage.js
│ ├── AddressRow.js
│ ├── AgencyInfo.js
│ ├── AlertBanner.js
│ ├── AlertList.js
│ ├── AlertRow.js
│ ├── AppBar.js
│ ├── AppBarContainer.js
│ ├── AppBarHsl.js
│ ├── Availability.js
│ ├── BackButton.js
│ ├── BubbleDialog.js
│ ├── CanceledLegsBar.js
│ ├── CapacityModal.js
│ ├── Card.js
│ ├── CardHeader.js
│ ├── Checkbox.js
│ ├── CookieSettingsButton.js
│ ├── CustomInputTime.js
│ ├── DTModal.js
│ ├── DatetimepickerContainer.js
│ ├── DepartureListContainer.js
│ ├── DepartureRow.js
│ ├── DesktopView.js
│ ├── DisruptionBanner.js
│ ├── DisruptionBannerAlert.js
│ ├── DisruptionInfo.js
│ ├── DisruptionInfoButton.js
│ ├── DisruptionInfoButtonContainer.js
│ ├── DisruptionListContainer.js
│ ├── ErrorBoundary.js
│ ├── ErrorHandlerSSR.js
│ ├── ExternalLink.js
│ ├── Favourite.js
│ ├── FavouriteStopContainer.js
│ ├── FavouriteVehicleRentalStationContainer.js
│ ├── FavouritesContainer.js
│ ├── FromMapModal.js
│ ├── Geolocator.js
│ ├── Geomover.js
│ ├── Icon.js
│ ├── IconWithBigCaution.js
│ ├── IconWithIcon.js
│ ├── IndexPage.js
│ ├── IndexPageMeta.js
│ ├── LangSelect.js
│ ├── LazilyLoad.js
│ ├── Loading.js
│ ├── LoadingPage.js
│ ├── LoginButton.js
│ ├── LogoSmall.js
│ ├── MainMenu.js
│ ├── MainMenuContainer.js
│ ├── MainMenuLinks.js
│ ├── MapLayersDialogContent.js
│ ├── MapRoutingButton.js
│ ├── MenuDrawer.js
│ ├── MenuItem.js
│ ├── Message.js
│ ├── MessageBar.js
│ ├── MessageBarMessage.js
│ ├── MobileFooter.js
│ ├── MobileView.js
│ ├── NetworkError.js
│ ├── ParkAndRideContent.js
│ ├── ParkContainer.js
│ ├── ParkOrStationHeader.js
│ ├── PlatformNumber.js
│ ├── RentalVehicle.js
│ ├── RentalVehicleContent.js
│ ├── RentalVehiclePageMapContainer.js
│ ├── RouteNumber.js
│ ├── RouteNumberContainer.js
│ ├── ScrollableWrapper.js
│ ├── SecondaryButton.js
│ ├── Select.js
│ ├── SelectFromMapHeader.js
│ ├── SelectedStopPopupContent.js
│ ├── ServiceAlertIcon.js
│ ├── Slider.js
│ ├── SplitBars.js
│ ├── StopCode.js
│ ├── SwipeableTabs.js
│ ├── Title.js
│ ├── Toggle.js
│ ├── ToggleMapTracking.js
│ ├── TopLevel.js
│ ├── TruncatedMessage.js
│ ├── UserMenu.js
│ ├── VehicleIcon.js
│ ├── VehicleParkMapContainer.js
│ ├── VehicleRentalAvailability.js
│ ├── VehicleRentalStation.js
│ ├── VehicleRentalStationContent.js
│ ├── VehicleRentalStationMapContainer.js
│ ├── WithSearchContext.js
│ ├── ZoneIcon.js
│ ├── alert-banner.scss
│ ├── app-bar-hsl.scss
│ ├── bike-park-rental-station.scss
│ ├── bubble-dialog.scss
│ ├── checkbox.scss
│ ├── city-bike.scss
│ ├── date-select.scss
│ ├── departure.scss
│ ├── disruption.scss
│ ├── embedded
│ │ ├── EmbeddedSearch.js
│ │ ├── EmbeddedSearchContainer.js
│ │ ├── EmbeddedSearchGenerator.js
│ │ ├── embedded-search-generator.scss
│ │ ├── embedded-search.scss
│ │ └── hooks
│ │ │ └── useUTMCampaignParams.js
│ ├── favourite-icon-table.scss
│ ├── from-map-modal.scss
│ ├── front-page.scss
│ ├── itinerary
│ │ ├── AirplaneLeg.js
│ │ ├── AirportCheckInLeg.js
│ │ ├── AirportCollectLuggageLeg.js
│ │ ├── AlternativeItineraryBar.js
│ │ ├── AlternativeLegsInfo.js
│ │ ├── BicycleLeg.js
│ │ ├── BikeParkLeg.js
│ │ ├── CallAgencyLeg.js
│ │ ├── CarLeg.js
│ │ ├── CarParkLeg.js
│ │ ├── ChangeDepartureTimeLink.js
│ │ ├── CustomizeSearch.js
│ │ ├── Duration.js
│ │ ├── Emissions.js
│ │ ├── EmissionsInfo.js
│ │ ├── EndLeg.js
│ │ ├── ErrorCard.js
│ │ ├── FareDisclaimer.js
│ │ ├── FeedbackPrompt.js
│ │ ├── InterlineInfo.js
│ │ ├── IntermediateLeg.js
│ │ ├── ItinerariesNotFound.js
│ │ ├── Itinerary.js
│ │ ├── ItineraryCircleLine.js
│ │ ├── ItineraryCircleLineLong.js
│ │ ├── ItineraryCircleLineWithIcon.js
│ │ ├── ItineraryDetails.js
│ │ ├── ItineraryDistance.js
│ │ ├── ItineraryList.js
│ │ ├── ItineraryListContainer.js
│ │ ├── ItineraryListHeader.js
│ │ ├── ItineraryMapAction.js
│ │ ├── ItineraryNotification.js
│ │ ├── ItineraryPage.js
│ │ ├── ItineraryPageContainer.js
│ │ ├── ItineraryPageControls.js
│ │ ├── ItineraryPageMeta.js
│ │ ├── ItineraryPageTitle.js
│ │ ├── ItineraryPageUtils.js
│ │ ├── ItinerarySummary.js
│ │ ├── ItineraryTabs.js
│ │ ├── LegAgencyInfo.js
│ │ ├── LegInfo.js
│ │ ├── Legs.js
│ │ ├── MobileTicketPurchaseInformation.js
│ │ ├── NationalServiceLink.js
│ │ ├── NearestQuery.js
│ │ ├── NoItinerariesNote.js
│ │ ├── OriginDestinationBar.js
│ │ ├── PastLink.js
│ │ ├── Profile.js
│ │ ├── RightOffcanvasToggle.js
│ │ ├── ScooterLinkContainer.js
│ │ ├── SearchSettings.js
│ │ ├── StartNavi.js
│ │ ├── StopInfo.js
│ │ ├── StreetModeSelectorButton.js
│ │ ├── StreetModeSelectorShimmer.js
│ │ ├── StreetModeSelectorWeather.js
│ │ ├── StreetSummary.js
│ │ ├── TaxiLeg.js
│ │ ├── TaxiLinkContainer.js
│ │ ├── TicketInformation.js
│ │ ├── TimeSummary.js
│ │ ├── TransitLeg.js
│ │ ├── VehicleRentalDurationInfo.js
│ │ ├── VehicleRentalLeg.js
│ │ ├── ViaLeg.js
│ │ ├── WaitLeg.js
│ │ ├── WalkLeg.js
│ │ ├── WeatherDetailsPopup.js
│ │ ├── ZoneTicket.js
│ │ ├── alt-travel-bar.scss
│ │ ├── customize-search.scss
│ │ ├── customizesearch
│ │ │ ├── AccessibilityOptionSection.js
│ │ │ ├── BikingOptionsSection.js
│ │ │ ├── FareZoneSelector.js
│ │ │ ├── MinTransferTimeSection.js
│ │ │ ├── RentalNetworkSelector.js
│ │ │ ├── RestoreDefaultSettingSection.js
│ │ │ ├── ScooterNetworkSelector.js
│ │ │ ├── SearchSettingsDropdown.js
│ │ │ ├── StreetModeSelectorPanel.js
│ │ │ ├── TaxiOptionsSection.js
│ │ │ ├── TransferOptionsSection.js
│ │ │ ├── TransportModesSection.js
│ │ │ └── WalkingOptionsSection.js
│ │ ├── errorCardProperties.js
│ │ ├── findErrorMessageIds.js
│ │ ├── itinerary-list-header.scss
│ │ ├── itinerary-page.scss
│ │ ├── itinerary-profile.scss
│ │ ├── itinerary-summary.scss
│ │ ├── itinerary.scss
│ │ ├── mobile-ticket-purchase-information.scss
│ │ ├── navigator
│ │ │ ├── BoardingInfo.js
│ │ │ ├── NaviBottom.js
│ │ │ ├── NaviCard.js
│ │ │ ├── NaviCardContainer.js
│ │ │ ├── NaviCardExtension.js
│ │ │ ├── NaviContainer.js
│ │ │ ├── NaviInstructions.js
│ │ │ ├── NaviMessage.js
│ │ │ ├── NaviStack.js
│ │ │ ├── NaviStarter.js
│ │ │ ├── NaviUtils.js
│ │ │ ├── NavigatorModal.js
│ │ │ ├── hooks
│ │ │ │ ├── useLegState.js
│ │ │ │ ├── useLogo.js
│ │ │ │ ├── usePrevious.js
│ │ │ │ ├── useRealtimeLegs.js
│ │ │ │ └── utils
│ │ │ │ │ └── realtimeLegUtils.js
│ │ │ ├── navigator.scss
│ │ │ ├── navigatorgeolocation
│ │ │ │ ├── NaviGeolocationInfo.js
│ │ │ │ ├── NaviGeolocationInfoModal.js
│ │ │ │ └── navigator-geolocation.scss
│ │ │ ├── navigatorintro
│ │ │ │ ├── NavigatorIntro.js
│ │ │ │ ├── NavigatorIntroFeature.js
│ │ │ │ ├── NavigatorIntroModal.js
│ │ │ │ └── navigator-intro.scss
│ │ │ └── navigatoroutro
│ │ │ │ ├── NavigatorOutro.js
│ │ │ │ ├── NavigatorOutroModal.js
│ │ │ │ └── navigator-outro.scss
│ │ ├── origin-destination-bar.scss
│ │ ├── queries
│ │ │ ├── ItineraryDetailsFragment.js
│ │ │ ├── ItineraryFragment.js
│ │ │ ├── ItineraryListContainerPlanEdges.js
│ │ │ ├── ItineraryListPlanEdges.js
│ │ │ ├── LegAgencyInfoFragment.js
│ │ │ ├── LegQuery.js
│ │ │ └── PlanConnection.js
│ │ ├── search-settings-dropdown.scss
│ │ ├── settings-panel.scss
│ │ ├── street-mode-selector-button.scss
│ │ ├── street-mode-selector-shimmer.scss
│ │ ├── street-mode-selector.scss
│ │ └── weather-details.scss
│ ├── map
│ │ ├── ConfirmLocationFromMapButton.js
│ │ ├── EntranceMarker.js
│ │ ├── GenericMarker.js
│ │ ├── GeoJSON.js
│ │ ├── IconMarker.js
│ │ ├── IndexPageMap.js
│ │ ├── ItineraryLine.js
│ │ ├── ItineraryPageMap.js
│ │ ├── Line.js
│ │ ├── LocationMarker.js
│ │ ├── LocationMarkerWithPermanentTooltip.js
│ │ ├── Map.js
│ │ ├── MapBottomsheetContext.js
│ │ ├── MapContainer.js
│ │ ├── MapWithTracking.js
│ │ ├── MarkerPopupBottom.js
│ │ ├── NearYouMap.js
│ │ ├── PointFeatureMarker.js
│ │ ├── PopupHeader.js
│ │ ├── PositionMarker.js
│ │ ├── RoutePageMap.js
│ │ ├── SelectFromMap.js
│ │ ├── SpeechBubble.js
│ │ ├── StopPageMap.js
│ │ ├── VehicleMarkerContainer.js
│ │ ├── WalkQuery.js
│ │ ├── map.scss
│ │ ├── non-tile-layer
│ │ │ ├── LegMarker.js
│ │ │ ├── StopMarker.js
│ │ │ ├── TransitLegMarkers.js
│ │ │ ├── VehicleMarker.js
│ │ │ └── VehicleMarkerContainer.js
│ │ ├── popups
│ │ │ ├── LocationPopup.js
│ │ │ ├── SelectedStopPopup.js
│ │ │ ├── ViaPointPopup.js
│ │ │ └── marker-popup.scss
│ │ ├── route
│ │ │ ├── PopupHeader.js
│ │ │ ├── RouteLine.js
│ │ │ └── TripMarkerPopup.js
│ │ ├── tile-layer
│ │ │ ├── MarkerSelectPopup.js
│ │ │ ├── ParkAndRide.js
│ │ │ ├── ParkAndRideForBikes.js
│ │ │ ├── ParkAndRideForCars.js
│ │ │ ├── RentalVehicles.js
│ │ │ ├── SelectParkAndRideRow.js
│ │ │ ├── SelectRentalVehicleClusterRow.js
│ │ │ ├── SelectStopRow.js
│ │ │ ├── SelectTerminalRow.js
│ │ │ ├── SelectVehicleContainer.js
│ │ │ ├── SelectVehicleRentalRow.js
│ │ │ ├── SelectVehicleRow.js
│ │ │ ├── Stops.js
│ │ │ ├── TileContainer.js
│ │ │ ├── TileLayerContainer.js
│ │ │ ├── VectorTileLayerContainer.js
│ │ │ └── VehicleRentalStations.js
│ │ └── withGeojsonObjects.js
│ ├── navigation.scss
│ ├── nearyou
│ │ ├── NearYouPage.js
│ │ ├── NearYouPageMeta.js
│ │ ├── StopNearYou.js
│ │ ├── StopNearYouContainer.js
│ │ ├── StopNearYouDepartureRowContainer.js
│ │ ├── StopNearYouHeader.js
│ │ ├── StopsNearYouContainer.js
│ │ ├── StopsNearYouFavorites.js
│ │ ├── StopsNearYouFavoritesMapContainer.js
│ │ ├── StopsNearYouFavouritesContainer.js
│ │ ├── StopsNearYouMapContainer.js
│ │ ├── StopsNearYouSearch.js
│ │ ├── VehicleRentalStationNearYou.js
│ │ └── stops-near-you.scss
│ ├── no-favourites-panel.scss
│ ├── nolocation-panel.scss
│ ├── rental-vehicle-content.scss
│ ├── routepage
│ │ ├── CallAgencyWarning.js
│ │ ├── DepartureTime.js
│ │ ├── FavouriteRouteContainer.js
│ │ ├── FuzzyTripLink.js
│ │ ├── PatternRedirector.js
│ │ ├── PatternStopsContainer.js
│ │ ├── RouteAgencyInfo.js
│ │ ├── RouteAlertsContainer.js
│ │ ├── RouteControlPanel.js
│ │ ├── RouteNotification.js
│ │ ├── RoutePage.js
│ │ ├── RoutePageMeta.js
│ │ ├── RoutePatternSelect.js
│ │ ├── RouteStop.js
│ │ ├── RouteStopListContainer.js
│ │ ├── RouteTitle.js
│ │ ├── ScheduleContainer.js
│ │ ├── ScheduleDebugData.js
│ │ ├── ScheduleDropdown.js
│ │ ├── ScheduleHeader.js
│ │ ├── ScheduleTripRow.js
│ │ ├── TripLink.js
│ │ ├── TripLinkWithScroll.js
│ │ ├── TripRouteStop.js
│ │ ├── TripStopListContainer.js
│ │ ├── TripStopsContainer.js
│ │ ├── route-schedule-dropdown.scss
│ │ └── route.scss
│ ├── select-maplayers-dialog.scss
│ ├── stop
│ │ ├── DateSelect.js
│ │ ├── FilterTimeTableModal.js
│ │ ├── StopAlerts.js
│ │ ├── StopAlertsContainer.js
│ │ ├── StopCardHeader.js
│ │ ├── StopCardHeaderContainer.js
│ │ ├── StopPageContentContainer.js
│ │ ├── StopPageHeader.js
│ │ ├── StopPageHeaderContainer.js
│ │ ├── StopPageMapContainer.js
│ │ ├── StopPageMeta.js
│ │ ├── StopPageTabContainer.js
│ │ ├── StopPageTabs.js
│ │ ├── StopTimetablePage.js
│ │ ├── StopTitle.js
│ │ ├── TerminalAlertsContainer.js
│ │ ├── TerminalPageContentContainer.js
│ │ ├── TerminalPageHeaderContainer.js
│ │ ├── TerminalPageMapContainer.js
│ │ ├── TerminalPageMeta.js
│ │ ├── TerminalPageTabContainer.js
│ │ ├── TerminalTimetablePage.js
│ │ ├── TerminalTitle.js
│ │ ├── TimeTableOptionsPanel.js
│ │ ├── Timetable.js
│ │ ├── TimetableRow.js
│ │ ├── queries
│ │ │ └── TimetableFragment.js
│ │ ├── stop-cards.scss
│ │ └── stop.scss
│ ├── timetable.scss
│ ├── toggle.scss
│ ├── util.scss
│ ├── visual
│ │ ├── OverlayWithSpinner.js
│ │ ├── index.scss
│ │ └── overlay-with-spinner.scss
│ └── zone-icon.scss
├── config.js
├── configurations
│ ├── config.default.js
│ ├── config.hameenlinna.js
│ ├── config.hsl.js
│ ├── config.joensuu.js
│ ├── config.jyvaskyla.js
│ ├── config.kela.js
│ ├── config.kotka.js
│ ├── config.kouvola.js
│ ├── config.kuopio.js
│ ├── config.lahti.js
│ ├── config.lappeenranta.js
│ ├── config.matka.js
│ ├── config.mikkeli.js
│ ├── config.oulu.js
│ ├── config.pori.js
│ ├── config.raasepori.js
│ ├── config.rovaniemi.js
│ ├── config.tampere.js
│ ├── config.turku.js
│ ├── config.vaasa.js
│ ├── config.varely.js
│ ├── config.waltti.js
│ ├── config.walttiOpas.js
│ ├── images
│ │ ├── default
│ │ │ ├── default-favicon.png
│ │ │ ├── digitransit-logo.png
│ │ │ ├── dotted-line-bg.png
│ │ │ ├── dotted-line-bg2.png
│ │ │ └── dotted-line.svg
│ │ ├── hameenlinna
│ │ │ ├── hameenlinna-favicon.png
│ │ │ ├── logo.png
│ │ │ └── secondary-logo.png
│ │ ├── hsl
│ │ │ ├── geolocation.svg
│ │ │ ├── hsl-favicon.png
│ │ │ ├── navigator-logo.svg
│ │ │ ├── reittiopas-logo.svg
│ │ │ ├── thumbs-up.svg
│ │ │ └── traffic-light.svg
│ │ ├── joensuu
│ │ │ ├── joensuu-favicon.png
│ │ │ └── jojo-logo.png
│ │ ├── jyvaskyla
│ │ │ └── jyvaskyla-favicon.png
│ │ ├── kotka
│ │ │ └── kotka.png
│ │ ├── kouvola
│ │ │ ├── kouvola-favicon.png
│ │ │ ├── logo.png
│ │ │ └── secondary-logo.png
│ │ ├── kuopio
│ │ │ ├── kuopio-favicon.png
│ │ │ ├── logo.png
│ │ │ └── secondary-logo.png
│ │ ├── lahti
│ │ │ ├── lahti-favicon.png
│ │ │ ├── lahti-logo.png
│ │ │ └── secondary-lahti-logo.png
│ │ ├── lappeenranta
│ │ │ ├── lappeenranta-favicon.jpg
│ │ │ ├── logo.png
│ │ │ └── secondary-logo.png
│ │ ├── matka
│ │ │ ├── matka-favicon.svg
│ │ │ └── matka-logo.svg
│ │ ├── oulu
│ │ │ ├── oulu-favicon.png
│ │ │ ├── oulu-logo.png
│ │ │ └── secondary-oulu-logo.png
│ │ ├── pori
│ │ │ ├── pori-favicon.png
│ │ │ └── pori_logo.svg
│ │ ├── raasepori
│ │ │ ├── raasepori-favicon.png
│ │ │ ├── raasepori_logo_musta.png
│ │ │ └── raasepori_logo_valkoinen.png
│ │ ├── rovaniemi
│ │ │ ├── rovaniemi-favicon.png
│ │ │ └── rovaniemi-logo.svg
│ │ ├── tampere
│ │ │ ├── tampere-favicon.png
│ │ │ └── tampere-logo.png
│ │ ├── turku
│ │ │ ├── foli-logo.png
│ │ │ └── turku-favicon.png
│ │ ├── vaasa
│ │ │ ├── secondary-logo.png
│ │ │ └── vaasa-favicon.png
│ │ ├── varely
│ │ │ ├── seutuplus-logo-white.svg
│ │ │ ├── seutuplus-logo.svg
│ │ │ └── varely-favicon.png
│ │ └── walttiOpas
│ │ │ ├── waltti-logo-secondary.png
│ │ │ ├── waltti-logo.png
│ │ │ └── walttiOpas-favicon.png
│ ├── realtimeUtils.js
│ └── timetableConfigUtils.js
├── constants.js
├── hooks
│ └── useWindowSize.js
├── meta.js
├── routeRoutes.js
├── routes.js
├── server.js
├── ssrmeta.json
├── stopRoutes.js
├── store
│ ├── CanceledLegsBarStore.js
│ ├── CountryStore.js
│ ├── DestinationStore.js
│ ├── FavouriteStore.js
│ ├── FutureRouteStore.js
│ ├── GeoJsonStore.js
│ ├── MapLayerStore.js
│ ├── MessageStore.js
│ ├── OldSearchesStore.js
│ ├── OriginStore.js
│ ├── PositionStore.js
│ ├── PreferencesStore.js
│ ├── RealTimeInformationStore.js
│ ├── RoutingSettingsStore.js
│ ├── TimeStore.js
│ ├── UserStore.js
│ ├── ViaPointStore.js
│ ├── localStorage.js
│ └── sessionStorage.js
├── translations.js
└── util
│ ├── DTSearchContextInitializer.js
│ ├── ParkAndRideUtils.js
│ ├── StoreListeningIntlProvider.js
│ ├── alertUtils.js
│ ├── analyticsUtils.js
│ ├── apiUtils.js
│ ├── browser.js
│ ├── colorUtils.js
│ ├── configMerger.js
│ ├── configure-moment.js
│ ├── configureCountry.js
│ ├── dateParamUtils.js
│ ├── emissions.js
│ ├── envUtils.js
│ ├── events.js
│ ├── fareUtils.js
│ ├── feedScopedIdUtils.js
│ ├── feedbackly.js
│ ├── fetchUtils.js
│ ├── filterUtils.js
│ ├── font-sw.js
│ ├── geo-utils.js
│ ├── geolocationMessages.js
│ ├── get-selector.js
│ ├── getIterator.js
│ ├── glfun.js
│ ├── gtfs.js
│ ├── gtfsRtParser.js
│ ├── gtfsrt.js
│ ├── hashUtil.js
│ ├── jankmeter.js
│ ├── legUtils.js
│ ├── manifestUtils.js
│ ├── mapIconUtils.js
│ ├── mapLayerUtils.js
│ ├── messageUtils.js
│ ├── metaUtils.js
│ ├── modeUtils.js
│ ├── mqttClient.js
│ ├── occupancyUtil.js
│ ├── oldParamParser.js
│ ├── otpStrings.js
│ ├── path.js
│ ├── patternUtils.js
│ ├── planParamUtil.js
│ ├── publicPath.js
│ ├── queryUtils.js
│ ├── relayUtils.js
│ ├── route-compare.js
│ ├── routePatternSelectUtil.js
│ ├── routerUtils.js
│ ├── safeJsonParser.js
│ ├── scheduleParamUtils.js
│ ├── scroll.js
│ ├── searchContext.js
│ ├── searchRoutes.js
│ ├── shapes.js
│ ├── slicedToArray.js
│ ├── sortUtils.js
│ ├── storeUtils.js
│ ├── supportsInputType.js
│ ├── timeUtils.js
│ ├── urlUtils.js
│ ├── vehicleRentalUtils.js
│ ├── vehicleStateUtils.js
│ ├── withBreakpoint.js
│ ├── xhrPromise.js
│ └── zoneIconUtils.js
├── babel.config.js
├── build
├── add-theme.js
├── check_translations.js
├── contextHelper.js
├── generate-schema.js
├── schema.graphql
└── template.waltti.js
├── config
├── babel.config.js
└── rollup.config.js
├── digitransit-component
├── CONTRIBUTING.md
├── packages
│ ├── digitransit-component-abtesting
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-autosuggest-panel
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── Select.js
│ │ │ │ ├── select.scss
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-autosuggest
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── MobileNoScroll.scss
│ │ │ │ ├── MobileSearch.js
│ │ │ │ ├── MobileSearch.scss
│ │ │ │ ├── styles.scss
│ │ │ │ ├── translations.js
│ │ │ │ └── withScrollLock.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-control-panel
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── styles.js
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-datetimepicker
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── Datetimepicker.js
│ │ │ │ ├── DesktopDatetimepicker.js
│ │ │ │ ├── MobileDatepicker.js
│ │ │ │ ├── MobilePickerModal.js
│ │ │ │ ├── MobileTimepicker.js
│ │ │ │ ├── dateTimeInputIsSupported.js
│ │ │ │ ├── mobileDetection.js
│ │ │ │ ├── styles.scss
│ │ │ │ ├── translations.js
│ │ │ │ └── utils.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-dialog-modal
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-favourite-bar
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-favourite-editing-modal
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── ModalContent.js
│ │ │ │ ├── modal-content.scss
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-favourite-modal
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── DesktopModal.js
│ │ │ │ ├── MobileModal.js
│ │ │ │ ├── desktop.scss
│ │ │ │ ├── mobile.scss
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-icon
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── assets
│ │ │ │ ├── airplane.svg
│ │ │ │ ├── arrow.svg
│ │ │ │ ├── attention.svg
│ │ │ │ ├── bike-park.svg
│ │ │ │ ├── bus-express.svg
│ │ │ │ ├── bus-local.svg
│ │ │ │ ├── bus-waltti.svg
│ │ │ │ ├── bus.svg
│ │ │ │ ├── bus_stop.svg
│ │ │ │ ├── calendar.svg
│ │ │ │ ├── car-park.svg
│ │ │ │ ├── caution_white_exclamation.svg
│ │ │ │ ├── check.svg
│ │ │ │ ├── city.svg
│ │ │ │ ├── citybike-stop-default-secondary.svg
│ │ │ │ ├── citybike-stop-default.svg
│ │ │ │ ├── citybike-stop-digitransit-secondary.svg
│ │ │ │ ├── citybike-stop-digitransit.svg
│ │ │ │ ├── citybike-waltti.svg
│ │ │ │ ├── citybike.svg
│ │ │ │ ├── close.svg
│ │ │ │ ├── dropdown.svg
│ │ │ │ ├── edit.svg
│ │ │ │ ├── ellipsis.svg
│ │ │ │ ├── ferry-waltti.svg
│ │ │ │ ├── ferry.svg
│ │ │ │ ├── funicular.svg
│ │ │ │ ├── home.svg
│ │ │ │ ├── icon-route.svg
│ │ │ │ ├── locate.svg
│ │ │ │ ├── map.svg
│ │ │ │ ├── mapmarker-via.svg
│ │ │ │ ├── mapmarker.svg
│ │ │ │ ├── mode_airplane.svg
│ │ │ │ ├── mode_bus.svg
│ │ │ │ ├── mode_citybike.svg
│ │ │ │ ├── mode_digi_citybike.svg
│ │ │ │ ├── mode_digi_funicular.svg
│ │ │ │ ├── mode_digi_tram.svg
│ │ │ │ ├── mode_ferry.svg
│ │ │ │ ├── mode_rail.svg
│ │ │ │ ├── mode_tram.svg
│ │ │ │ ├── opposite.svg
│ │ │ │ ├── place.svg
│ │ │ │ ├── plus.svg
│ │ │ │ ├── position.svg
│ │ │ │ ├── rail-waltti.svg
│ │ │ │ ├── rail.svg
│ │ │ │ ├── school.svg
│ │ │ │ ├── search-airplane-digitransit.svg
│ │ │ │ ├── search-bus-station-digitransit.svg
│ │ │ │ ├── search-bus-stop-default.svg
│ │ │ │ ├── search-bus-stop-digitransit.svg
│ │ │ │ ├── search-bus-stop-express-default.svg
│ │ │ │ ├── search-bustram-stop-digitransit.svg
│ │ │ │ ├── search-ferry-default.svg
│ │ │ │ ├── search-ferry-digitransit.svg
│ │ │ │ ├── search-ferry-stop-default.svg
│ │ │ │ ├── search-ferry-stop-digitransit.svg
│ │ │ │ ├── search-rail-station-digitransit.svg
│ │ │ │ ├── search-rail-stop-default.svg
│ │ │ │ ├── search-rail-stop-digitransit.svg
│ │ │ │ ├── search-speedtram-stop-default.svg
│ │ │ │ ├── search-streetname.svg
│ │ │ │ ├── search-tram-stop-default.svg
│ │ │ │ ├── search-tram-stop-digitransit.svg
│ │ │ │ ├── search.svg
│ │ │ │ ├── select-from-map.svg
│ │ │ │ ├── shopping.svg
│ │ │ │ ├── speedtram.svg
│ │ │ │ ├── sport.svg
│ │ │ │ ├── star.svg
│ │ │ │ ├── station.svg
│ │ │ │ ├── subway.svg
│ │ │ │ ├── time.svg
│ │ │ │ ├── tram-waltti.svg
│ │ │ │ ├── tram.svg
│ │ │ │ ├── trash.svg
│ │ │ │ ├── viapoint.svg
│ │ │ │ └── work.svg
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-suggestion-item
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ └── styles.scss
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-traffic-now-link
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── helpers
│ │ │ │ ├── styles.scss
│ │ │ │ └── translations.js
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-component-with-breakpoint
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.js
│ │ └── test.js
│ └── digitransit-component
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── index.mjs
│ │ ├── package.json
│ │ └── test.js
└── scripts
│ ├── create-new-module
│ ├── generate-readmes
│ └── installation.md
├── digitransit-search-util
├── CONTRIBUTING.md
├── packages
│ ├── digitransit-search-util-distance
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-execute-search-immidiate
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-filter-matching-to-input
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-get-geocoding-results
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-get-json
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-get-label
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-helpers
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-is-duplicate
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-query-utils
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── schema
│ │ │ └── schema.graphql
│ │ ├── src
│ │ │ └── index.js
│ │ └── test.js
│ ├── digitransit-search-util-route-name-compare
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-serialize
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-suggestion-to-location
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-search-util-tru-eq
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ └── digitransit-search-util-uniq-by-label
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
└── scripts
│ ├── create-new-module
│ ├── generate-readmes
│ └── installation.md
├── digitransit-store
├── CONTRIBUTING.md
├── packages
│ ├── digitransit-store-common-functions
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── mock-localstorage.js
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.js
│ │ └── test.js
│ └── digitransit-store-future-route
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── mock-localstorage.js
│ │ ├── package.json
│ │ ├── src
│ │ └── index.js
│ │ └── test.js
└── scripts
│ ├── create-new-module
│ ├── generate-readmes
│ └── installation.md
├── digitransit-util
├── CONTRIBUTING.md
├── packages
│ ├── digitransit-util-day-range-allowed-diff
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-util-day-range-pattern
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-util-enrich-patterns
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ ├── digitransit-util-route-pattern-option-text
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── README.md
│ │ ├── helpers
│ │ │ └── translations.js
│ │ ├── index.js
│ │ ├── package.json
│ │ └── test.js
│ └── digitransit-util
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE-AGPL.txt
│ │ ├── LICENSE-EUPL.txt
│ │ ├── index.mjs
│ │ ├── package.json
│ │ └── test.js
└── scripts
│ ├── create-new-module
│ ├── generate-readmes
│ └── installation.md
├── docs
├── Architecture.md
├── Docker.md
├── GeoJson.md
├── GraphQL.md
├── Installation.md
├── JSBenchmark.md
├── Location.md
├── Navigation.md
├── Position.md
├── Terms.md
├── Tests.md
├── Themes.md
├── ZIndex.md
└── images
│ ├── architecture.png
│ ├── hierarchy.png
│ ├── location.png
│ ├── position.png
│ └── up.png
├── lerna.json
├── package.json
├── postcss.config.js
├── sass
├── _main.scss
├── base
│ ├── _base.scss
│ ├── _button.scss
│ ├── _elements.scss
│ ├── _form.scss
│ ├── _helper-classes-after-foundations.scss
│ ├── _helper-classes.scss
│ ├── _helper-mixins.scss
│ ├── _radius.scss
│ ├── _spacing.scss
│ ├── _waltti.scss
│ └── _zindex.scss
└── themes
│ ├── default
│ ├── _theme.scss
│ ├── default-spinner.png
│ └── main.scss
│ ├── hameenlinna
│ ├── _theme.scss
│ └── main.scss
│ ├── hsl
│ ├── _theme.scss
│ ├── hsl-spinner.png
│ └── main.scss
│ ├── joensuu
│ ├── _theme.scss
│ └── main.scss
│ ├── jyvaskyla
│ ├── _theme.scss
│ └── main.scss
│ ├── kela
│ ├── _theme.scss
│ └── main.scss
│ ├── kotka
│ ├── _theme.scss
│ └── main.scss
│ ├── kouvola
│ ├── _theme.scss
│ └── main.scss
│ ├── kuopio
│ ├── _theme.scss
│ └── main.scss
│ ├── lahti
│ ├── _theme.scss
│ └── main.scss
│ ├── lappeenranta
│ ├── _theme.scss
│ └── main.scss
│ ├── matka
│ ├── _theme.scss
│ └── main.scss
│ ├── mikkeli
│ ├── _theme.scss
│ └── main.scss
│ ├── oulu
│ ├── _theme.scss
│ └── main.scss
│ ├── pori
│ ├── _theme.scss
│ └── main.scss
│ ├── raasepori
│ ├── _theme.scss
│ └── main.scss
│ ├── rovaniemi
│ ├── _theme.scss
│ └── main.scss
│ ├── tampere
│ ├── _theme.scss
│ └── main.scss
│ ├── turku
│ ├── _theme.scss
│ ├── foli-spinner.png
│ └── main.scss
│ ├── vaasa
│ ├── _theme.scss
│ └── main.scss
│ ├── varely
│ ├── _theme.scss
│ └── main.scss
│ └── walttiOpas
│ ├── _theme.scss
│ └── main.scss
├── scripts
├── README.md
└── ui.sh
├── server
├── passport-openid-connect
│ ├── Strategy.js
│ ├── User.js
│ └── openidConnect.js
├── proxyTester.js
├── reittiopasParameterMiddleware.js
├── server.js
└── swInjection.js
├── static
├── assets
│ ├── geojson
│ │ ├── hml_zone_lines_20230214.geojson
│ │ ├── hsl_zone_lines_20190508.geojson
│ │ ├── jkl_zone_lines_20240531.geojson
│ │ ├── joensuu_zone_lines_20250402.geojson
│ │ ├── kotka_zone_lines_20250114.geojson
│ │ ├── kuopio_zone_lines_20240508.geojson
│ │ ├── lahti_zone_lines_20230105.geojson
│ │ ├── lpr_zone_lines_20250515.geojson
│ │ ├── oulu_zone_lines_20241011.geojson
│ │ ├── tre_zone_lines_20250606.geojson
│ │ └── vaasa_zone_lines_20231220.geojson
│ ├── svg-sprite.default.svg
│ ├── svg-sprite.hsl.svg
│ └── temporary
│ │ └── tampere-servicepoints-20250305.geojson
├── crossdomain.xml
├── favicon.ico
├── hsl_zone_areas.json
├── hsl_zone_lines.json
├── img
│ ├── default-social-share.png
│ ├── hsl-social-share.png
│ ├── nearby-stop_animation.gif
│ └── nearby-stop_desktop-animation.gif
└── robots.txt
├── test
├── accessibility.sh
├── accessibility
│ └── run-test.js
├── e2e
│ ├── FrontPage.test.js
│ ├── RoutePage.test.js
│ ├── StopPage.test.js
│ ├── SummaryPage.test.js
│ ├── __image_snapshots__
│ │ ├── chromium
│ │ │ ├── hsl
│ │ │ │ ├── front-page-desktop-snap.png
│ │ │ │ ├── front-page-mobile-snap.png
│ │ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ │ ├── itinerary-details-mobile-snap.png
│ │ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ │ ├── itinerary-suggestions-mobile-snap.png
│ │ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ │ ├── route-page-stop-list-mobile-snap.png
│ │ │ │ ├── stop-page-departure-list-desktop-snap.png
│ │ │ │ └── stop-page-departure-list-mobile-snap.png
│ │ │ ├── matka
│ │ │ │ ├── front-page-desktop-snap.png
│ │ │ │ ├── front-page-mobile-snap.png
│ │ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ │ ├── itinerary-details-mobile-snap.png
│ │ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ │ ├── itinerary-suggestions-mobile-snap.png
│ │ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ │ ├── route-page-stop-list-mobile-snap.png
│ │ │ │ ├── stop-page-departure-list-desktop-snap.png
│ │ │ │ └── stop-page-departure-list-mobile-snap.png
│ │ │ └── tampere
│ │ │ │ ├── front-page-desktop-snap.png
│ │ │ │ ├── front-page-mobile-snap.png
│ │ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ │ ├── itinerary-details-mobile-snap.png
│ │ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ │ ├── itinerary-suggestions-mobile-snap.png
│ │ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ │ ├── route-page-stop-list-mobile-snap.png
│ │ │ │ ├── stop-page-departure-list-desktop-snap.png
│ │ │ │ └── stop-page-departure-list-mobile-snap.png
│ │ ├── firefox
│ │ │ ├── hsl
│ │ │ │ ├── front-page-desktop-snap.png
│ │ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ │ └── stop-page-departure-list-desktop-snap.png
│ │ │ ├── matka
│ │ │ │ ├── front-page-desktop-snap.png
│ │ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ │ └── stop-page-departure-list-desktop-snap.png
│ │ │ └── tampere
│ │ │ │ ├── front-page-desktop-snap.png
│ │ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ │ └── stop-page-departure-list-desktop-snap.png
│ │ └── webkit
│ │ │ ├── hsl
│ │ │ ├── front-page-desktop-snap.png
│ │ │ ├── front-page-mobile-snap.png
│ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ ├── itinerary-details-mobile-snap.png
│ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ ├── itinerary-suggestions-mobile-snap.png
│ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ ├── route-page-stop-list-mobile-snap.png
│ │ │ ├── stop-page-departure-list-desktop-snap.png
│ │ │ └── stop-page-departure-list-mobile-snap.png
│ │ │ ├── matka
│ │ │ ├── front-page-desktop-snap.png
│ │ │ ├── front-page-mobile-snap.png
│ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ ├── itinerary-details-mobile-snap.png
│ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ ├── itinerary-suggestions-mobile-snap.png
│ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ ├── route-page-stop-list-mobile-snap.png
│ │ │ ├── stop-page-departure-list-desktop-snap.png
│ │ │ └── stop-page-departure-list-mobile-snap.png
│ │ │ └── tampere
│ │ │ ├── front-page-desktop-snap.png
│ │ │ ├── front-page-mobile-snap.png
│ │ │ ├── itinerary-details-desktop-snap.png
│ │ │ ├── itinerary-details-mobile-snap.png
│ │ │ ├── itinerary-suggestions-desktop-snap.png
│ │ │ ├── itinerary-suggestions-mobile-snap.png
│ │ │ ├── route-page-stop-list-desktop-snap.png
│ │ │ ├── route-page-stop-list-mobile-snap.png
│ │ │ ├── stop-page-departure-list-desktop-snap.png
│ │ │ └── stop-page-departure-list-mobile-snap.png
│ ├── helpers
│ │ ├── image-reporter.js
│ │ ├── image-snapshot-config.js
│ │ └── mock-request-helper.js
│ ├── jest-playwright-desktop.config.js
│ ├── jest-playwright-mobile.config.js
│ ├── jest.config.js
│ ├── jest.image.js
│ └── mock-data
│ │ ├── RoutePageStopListQueryResponse.json
│ │ ├── RoutePageStopListTampereResponse.json
│ │ ├── StopPageContenQueryResponse.json
│ │ ├── SummaryPageQueryResponse.json
│ │ ├── WalkBikeQueryResponse.json
│ │ └── weatherMock.xml
├── install.sh
└── unit
│ ├── .eslintrc.js
│ ├── AppBar.test.js
│ ├── AppBarHsl.test.js
│ ├── CanceledLegsBar.test.js
│ ├── Checkbox.test.js
│ ├── ItineraryDetails.test.js
│ ├── ItinerarySummary.test.js
│ ├── LogoSmall.test.js
│ ├── OldSearchesStore.test.js
│ ├── PlatformNumber.test.js
│ ├── Select.test.js
│ ├── TicketInformation.test.js
│ ├── WalkLeg.test.js
│ ├── browser.test.js
│ ├── component
│ ├── AboutPage.test.js
│ ├── AlertList.test.js
│ ├── AlertsRow.test.js
│ ├── Availability.test.js
│ ├── BicycleLeg.test.js
│ ├── BubbleDialog.test.js
│ ├── CardHeader.test.js
│ ├── DateSelect.test.js
│ ├── DepartureTime.test.js
│ ├── DisruptionBanner.test.js
│ ├── DisruptionListContainer.test.js
│ ├── FuzzyTripLink.test.js
│ ├── Icon.test.js
│ ├── IconWithBigCaution.test.js
│ ├── IconWithIcon.test.js
│ ├── IntermediateLeg.test.js
│ ├── LangSelect.test.js
│ ├── Legs.test.js
│ ├── MapLayersDialogContent.test.js
│ ├── MessageBar.test.js
│ ├── MessageBarMessage.test.js
│ ├── NoItinerariesNote.test.js
│ ├── Profile.test.js
│ ├── RouteAlertsContainer.test.js
│ ├── RouteControlPanel.test.js
│ ├── RouteNumber.test.js
│ ├── RoutePatternSelect.test.js
│ ├── RouteStop.test.js
│ ├── RouteStopListContainer.test.js
│ ├── ScheduleContainer.test.js
│ ├── ScheduleTripRow.test.js
│ ├── SearchSettings.test.js
│ ├── ServiceAlertIcon.test.js
│ ├── StopAlerts.test.js
│ ├── StopCardHeader.test.js
│ ├── StopPageContentContainer.test.js
│ ├── StopPageMap.test.js
│ ├── StopPageTabs.test.js
│ ├── Timetable.test.js
│ ├── TimetableRow.test.js
│ ├── TransitLeg.test.js
│ ├── TripLink.test.js
│ ├── TripRouteStop.test.js
│ ├── TripStopListContainer.test.js
│ ├── TripStopsContainer.test.js
│ ├── UserMenu.test.js
│ ├── VehicleIcon.test.js
│ ├── VehicleRentalStationAvailability.test.js
│ ├── ZoneIcon.test.js
│ └── map
│ │ ├── GenericMarker.test.js
│ │ ├── GeoJSON.test.js
│ │ ├── LocationMarker.test.js
│ │ ├── MapWithTracking.test.js
│ │ ├── MarkerPopupBottom.test.js
│ │ ├── PointFeatureMarker.test.js
│ │ ├── VehicleMarkerContainer.test.js
│ │ ├── route
│ │ └── TripMarkerPopup.test.js
│ │ └── tile-layer
│ │ ├── MarkerSelectPopup.test.js
│ │ ├── SelectVehicleRentalStationRow.test.js
│ │ ├── Stops.test.js
│ │ ├── TileLayerContainer.test.js
│ │ └── non-tile-layer
│ │ └── StopMarker.test.js
│ ├── config.test.js
│ ├── configurations
│ ├── config.default.test.js
│ ├── config.hsl.test.js
│ └── config.tampere.test.js
│ ├── helpers
│ ├── babel-register.js
│ ├── init.js
│ ├── mock-context.js
│ ├── mock-intl-enzyme.js
│ └── mock-router.js
│ ├── hooks
│ └── useWindowSize.test.js
│ ├── localStorage.test.js
│ ├── reittiopasParameterMiddleware.test.js
│ ├── sessionStorage.test.js
│ ├── store
│ ├── GeoJsonStore.test.js
│ ├── MessageStore.test.js
│ ├── PositionStore.test.js
│ ├── RealTimeInformationStore.test.js
│ └── ViaPointsStore.test.js
│ ├── test-data
│ ├── dcw12.js
│ ├── dcw28.js
│ ├── dcw31.js
│ ├── dt2587.js
│ ├── dt2715a.js
│ ├── dt2715b.js
│ ├── dt2720.js
│ ├── dt2734.js
│ ├── dt2830.js
│ ├── dt2831.js
│ ├── dt2887.js
│ └── dt2887b.js
│ ├── translations.test.js
│ ├── util
│ ├── alertUtils.test.js
│ ├── analyticsUtils.test.js
│ ├── configMerger.test.js
│ ├── fareUtils.test.js
│ ├── fetchUtil.test.js
│ ├── findErrorMessageIds.test.js
│ ├── geo-utils.test.js
│ ├── gtfsRtParser.test.js
│ ├── hashUtil.test.js
│ ├── legUtils.test.js
│ ├── manifestUtils.test.js
│ ├── mapLayerUtils.test.js
│ ├── messageUtils.test.js
│ ├── metaUtils.test.js
│ ├── modeUtils.test.js
│ ├── mqttClient.test.js
│ ├── otpStrings.test.js
│ ├── path.test.js
│ ├── planParamUtil.test.js
│ ├── queryUtils.test.js
│ ├── suggestionUtils.test.js
│ ├── timeUtils.test.js
│ ├── timetableConfigUtils.test.js
│ └── vehiclerental.test.js
│ └── views
│ └── ItineraryPage
│ ├── ItineraryPageUtils.test.js
│ └── component
│ ├── Itinerary.test.js
│ ├── ItineraryList.test.js
│ └── NavigatorIntro.test.js
├── webpack.config.babel.js
├── win-launch-scripts
├── hsl-win-launch-script.bat
└── national-win-launch-script.bat
└── yarn.lock
/.codecov.yml:
--------------------------------------------------------------------------------
1 | ignore:
2 | - "app/util/gtfsrt.js" # this file is auto-generated by pbf v3.1.0
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .gitignore
3 | .*swp
4 |
5 | .github
6 |
7 | LICENSE*
8 | Changelog.md
9 | win-launch-scripts/
10 | docs/
11 | /test
12 |
13 | /Dockerfile
14 |
15 | node_modules
16 | /.yarn
17 | # todo: keep?
18 | # !/.yarn/install-state.gz
19 | !/.yarn/plugins
20 | !/.yarn/releases
21 | !/.yarn/versions
22 |
23 | _static
24 | /app/__generated__
25 | /app/**/__generated__
26 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | _static
3 | static
4 | app/buildInfo.js
5 | build/schema.graphql
6 | digitransit-search-util/packages/digitransit-search-util-query-utils/schema/schema.graphql
7 | digitransit-component/packages/**/lib
8 | digitransit-store/packages/**/lib
9 | digitransit-search-util/packages/**/lib
10 |
--------------------------------------------------------------------------------
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # Prettier style formatting
2 | f6e7192cc6e45b4aafb0798ab0e2ee50c8ba1408
3 | 6ae10969b173ee5b5465976883c265ca83e5a5c0
4 |
5 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Proposed Changes
2 |
3 | -
4 |
5 | ## Pull Request Check List
6 |
7 | - A reasonable set of unit tests is included
8 | - Console does not show new warnings/errors
9 | - Changes are documented or they are self explanatory
10 | - This pull request does not have any merge conflicts
11 | - All existing tests pass in CI build
12 |
13 | ## Review
14 |
15 | - Read and verify the code changes
16 | - Test the functionality by running the UI locally with all popular browsers available in your platform
17 | - Check that the implementation matches the design, when such one is defined in a Jira issue
18 | - Merge the pull request
19 |
--------------------------------------------------------------------------------
/.github/workflows/scripts/push_prod.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | DOCKER_IMAGE="hsldevcom/digitransit-ui"
5 | DOCKER_TAG=${DOCKER_BASE_TAG:-prod}
6 | DOCKER_DEV_TAG=${DOCKER_DEV_TAG:-latest}
7 |
8 | COMMIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
9 |
10 | DOCKER_TAG_LONG=$DOCKER_TAG-$(date +"%Y-%m-%dT%H.%M.%S")-$COMMIT_HASH
11 | DOCKER_IMAGE_TAG=$DOCKER_IMAGE:$DOCKER_TAG
12 | DOCKER_IMAGE_TAG_LONG=$DOCKER_IMAGE:$DOCKER_TAG_LONG
13 | DOCKER_IMAGE_DEV=$DOCKER_IMAGE:$DOCKER_DEV_TAG
14 |
15 | docker login -u $DOCKER_USER -p $DOCKER_AUTH
16 |
17 | echo "processing prod release"
18 | docker pull $DOCKER_IMAGE_DEV
19 | docker tag $DOCKER_IMAGE_DEV $DOCKER_IMAGE_TAG
20 | docker tag $DOCKER_IMAGE_DEV $DOCKER_IMAGE_TAG_LONG
21 | docker push $DOCKER_IMAGE_TAG
22 | docker push $DOCKER_IMAGE_TAG_LONG
23 |
24 | echo Build completed
25 |
--------------------------------------------------------------------------------
/.github/workflows/scripts/slack_message.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [ -n "${SLACK_CHANNEL_ID}" ]; then
5 | MSG='{"channel": "'$SLACK_CHANNEL_ID'","text":"'"${PUBLISHED_PACKAGES}"'\n", "username": "NPM publisher"}'
6 | curl -X POST -H 'Content-Type: application/json' -H "Authorization: Bearer $SLACK_ACCESS_TOKEN" -H 'Accept: */*' -d "$MSG" 'https://slack.com/api/chat.postMessage'
7 | fi
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | _static
3 | npm-debug.log
4 | node_modules
5 | filesizes.html
6 | stats.json
7 | manifest.json
8 | test/credentials.json
9 | test/binaries
10 | *.swp
11 | .idea
12 | .vscode
13 | *.iml
14 | *~
15 | test_output
16 | test/binaries
17 | selenium-debug.log
18 | tags
19 | .nyc_output
20 | coverage
21 | sessions/
22 | run*.sh
23 | app/**/__generated__
24 | digitransit-component/packages/**/*.generated
25 | digitransit-component/packages/**/lib
26 | digitransit-search-util/packages/**/__generated__
27 | digitransit-search-util/packages/**/lib/
28 | digitransit-store/packages/**/*.generated
29 | digitransit-store/packages/**/lib
30 | yarn-error.log
31 | dump.rdb
32 | .yarn/*
33 | !.yarn/patches
34 | !.yarn/releases
35 | !.yarn/plugins
36 | !.yarn/sdks
37 | !.yarn/versions
38 | .pnp.*
39 | .npmrc
40 |
--------------------------------------------------------------------------------
/.lvimrc:
--------------------------------------------------------------------------------
1 | set tabstop=2
2 | set shiftwidth=2
3 | set softtabstop=2
4 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v20
2 |
--------------------------------------------------------------------------------
/.nycrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "all": true,
3 | "sourceMap": false,
4 | "instrument": false,
5 | "require": [
6 | "@babel/register"
7 | ],
8 | "include": [
9 | "app/**/*.js"
10 | ],
11 | "reporter": [
12 | "lcovonly",
13 | "html",
14 | "text-summary"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | Copyright 2015 Finnish Transport Agency and Helsinki Regional Transport Authority HSL
2 |
3 | The source code of this program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses.
4 |
--------------------------------------------------------------------------------
/app/action/CanceledLegsBarActions.js:
--------------------------------------------------------------------------------
1 | export default function updateShowCanceledLegsBannerState(actionContext, val) {
2 | actionContext.dispatch('updateShowCanceledLegsBannerState', val);
3 | }
4 |
--------------------------------------------------------------------------------
/app/action/CountryActions.js:
--------------------------------------------------------------------------------
1 | export const updateCountries = (actionContext, countries) => {
2 | actionContext.dispatch('UpdateCountries', countries);
3 | };
4 |
5 | export default updateCountries;
6 |
--------------------------------------------------------------------------------
/app/action/FutureRoutesActions.js:
--------------------------------------------------------------------------------
1 | export function saveFutureRoute(actionContext, futureRoute) {
2 | actionContext.dispatch('saveFutureRoute', futureRoute);
3 | }
4 |
--------------------------------------------------------------------------------
/app/action/MapLayerActions.js:
--------------------------------------------------------------------------------
1 | export const updateMapLayers = (actionContext, mapLayerSettings) => {
2 | actionContext.dispatch('UpdateMapLayers', mapLayerSettings);
3 | };
4 |
5 | export default updateMapLayers;
6 |
--------------------------------------------------------------------------------
/app/action/MessageActions.js:
--------------------------------------------------------------------------------
1 | export function addMessage(actionContext, message) {
2 | actionContext.dispatch('AddMessage', message);
3 | }
4 |
5 | export function markMessageAsRead(actionContext, id) {
6 | actionContext.dispatch('MarkMessageAsRead', id);
7 | }
8 |
--------------------------------------------------------------------------------
/app/action/SearchActions.js:
--------------------------------------------------------------------------------
1 | export function saveSearch(actionContext, endpoint) {
2 | actionContext.dispatch('SaveSearch', endpoint);
3 | }
4 |
5 | export function removeSearch(actionContext, endpoint) {
6 | actionContext.dispatch('RemoveSearch', endpoint);
7 | }
8 |
9 | export function saveSearchItems(actionContext, items) {
10 | actionContext.dispatch('SaveSearchItems', items);
11 | }
12 |
--------------------------------------------------------------------------------
/app/action/SearchSettingsActions.js:
--------------------------------------------------------------------------------
1 | export function saveRoutingSettings(actionContext, settings) {
2 | actionContext.dispatch('saveRoutingSettings', settings);
3 | }
4 |
--------------------------------------------------------------------------------
/app/action/ViaPointActions.js:
--------------------------------------------------------------------------------
1 | export function addViaPoint(actionContext, val) {
2 | actionContext.dispatch('addViaPoint', val);
3 | }
4 |
5 | export function setViaPoints(actionContext, points) {
6 | actionContext.dispatch('setViaPoints', points);
7 | }
8 |
--------------------------------------------------------------------------------
/app/action/destinationActions.js:
--------------------------------------------------------------------------------
1 | export default function storeDestination(actionContext, destination) {
2 | actionContext.dispatch('SetDestination', destination);
3 | }
4 |
--------------------------------------------------------------------------------
/app/action/originActions.js:
--------------------------------------------------------------------------------
1 | export default function storeOrigin(actionContext, origin) {
2 | actionContext.dispatch('SetOrigin', origin);
3 | }
4 |
--------------------------------------------------------------------------------
/app/action/realTimeClientAction.js:
--------------------------------------------------------------------------------
1 | import { startMqttClient, changeTopics } from '../util/mqttClient';
2 |
3 | export function startRealTimeClient(actionContext, settings, done) {
4 | /* settings may have changed, so reset old store content */
5 | if (actionContext.config.NODE_ENV === 'test') {
6 | return;
7 | }
8 | actionContext.dispatch('RealTimeClientReset');
9 | startMqttClient(settings, actionContext).then(data => {
10 | actionContext.dispatch('RealTimeClientStarted', data);
11 | done();
12 | });
13 | }
14 |
15 | export function stopRealTimeClient(actionContext, client, done) {
16 | client.end();
17 | actionContext.dispatch('RealTimeClientStopped');
18 | done();
19 | }
20 |
21 | export function changeRealTimeClientTopics(actionContext, settings, done) {
22 | // remove existing vehicles/topics
23 | actionContext.dispatch('RealTimeClientReset');
24 |
25 | changeTopics(settings, actionContext);
26 | done();
27 | }
28 |
--------------------------------------------------------------------------------
/app/action/userActions.js:
--------------------------------------------------------------------------------
1 | export default function setUser(actionContext, user) {
2 | actionContext.dispatch('setUser', user);
3 | }
4 |
--------------------------------------------------------------------------------
/app/action/userPreferencesActions.js:
--------------------------------------------------------------------------------
1 | export function setLanguage(actionContext, language) {
2 | actionContext.dispatch('SetLanguage', language);
3 | }
4 |
--------------------------------------------------------------------------------
/app/buildInfo.js:
--------------------------------------------------------------------------------
1 | export const COMMIT_ID = 'unset';
2 | export const BUILD_TIME = 'unset';
3 |
--------------------------------------------------------------------------------
/app/component/AgencyInfo.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | import ExternalLink from './ExternalLink';
5 |
6 | function AgencyInfo({ agencyName, url }) {
7 | if (agencyName && url) {
8 | const link = url.indexOf('://') === -1 ? `//${url}` : url;
9 |
10 | return (
11 |
12 |
13 | 30 ? 'overflow-fade' : ''}>
14 | {agencyName}
15 |
16 |
17 |
18 | );
19 | }
20 | return null;
21 | }
22 |
23 | AgencyInfo.propTypes = {
24 | agencyName: PropTypes.string.isRequired,
25 | url: PropTypes.string.isRequired,
26 | };
27 |
28 | export default AgencyInfo;
29 |
--------------------------------------------------------------------------------
/app/component/Card.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import cx from 'classnames';
4 |
5 | export default function Card({ className, children }) {
6 | return {children}
;
7 | }
8 |
9 | Card.displayName = 'Card';
10 |
11 | Card.propTypes = {
12 | className: PropTypes.string,
13 | children: PropTypes.node.isRequired,
14 | };
15 |
16 | Card.defaultProps = { className: undefined };
17 |
--------------------------------------------------------------------------------
/app/component/CookieSettingsButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { FormattedMessage } from 'react-intl';
3 |
4 | export default function CookieSettingsButton() {
5 | return (
6 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/app/component/DTModal.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | const DTModal = ({ show, children }) => {
5 | const showClassname = show ? 'dtmodal display-block' : 'modal display-none';
6 |
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | DTModal.propTypes = {
15 | show: PropTypes.bool.isRequired,
16 | children: PropTypes.node,
17 | };
18 |
19 | DTModal.defaultProps = {
20 | children: [],
21 | };
22 |
23 | export default DTModal;
24 |
--------------------------------------------------------------------------------
/app/component/ErrorHandlerSSR.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { FormattedMessage } from 'react-intl';
4 | import Icon from './Icon';
5 |
6 | export default function ErrorHandlerSSR() {
7 | return (
8 |
9 |
10 |
11 |
15 |
16 |
17 |
27 |
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/app/component/IndexPageMeta.js:
--------------------------------------------------------------------------------
1 | import { Helmet } from 'react-helmet';
2 | import compose from 'recompose/compose';
3 | import getContext from 'recompose/getContext';
4 | import mapProps from 'recompose/mapProps';
5 | import { configShape } from '../util/shapes';
6 | import { generateManifestUrl } from '../util/manifestUtils';
7 | import { isBrowser } from '../util/browser';
8 |
9 | export default compose(
10 | getContext({ config: configShape }),
11 | mapProps(({ config }) => {
12 | if (!isBrowser) {
13 | return false;
14 | }
15 | return {
16 | link: [
17 | {
18 | rel: 'manifest',
19 | href: generateManifestUrl(config, window.location, {
20 | ignorePathname: true,
21 | }),
22 | },
23 | ],
24 | };
25 | }),
26 | )(Helmet);
27 |
--------------------------------------------------------------------------------
/app/component/Loading.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { FormattedMessage } from 'react-intl';
4 | import ContainerSpinner from '@hsl-fi/container-spinner';
5 |
6 | const defaultMessage = (
7 |
8 |
9 |
10 | );
11 |
12 | export default function Loading(props) {
13 | return (
14 |
15 | {props?.children || defaultMessage}
16 |
17 | );
18 | }
19 |
20 | Loading.displayName = 'Loading';
21 |
22 | Loading.propTypes = { children: PropTypes.node };
23 | Loading.defaultProps = { children: undefined };
24 |
--------------------------------------------------------------------------------
/app/component/LoadingPage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Loading from './Loading';
3 |
4 | export default function LoadingPage() {
5 | return (
6 |
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/app/component/LoginButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Icon from './Icon';
4 |
5 | const LoginButton = ({ loginUrl }) => {
6 | const loginClick = event => {
7 | event.preventDefault();
8 | window.location.href = loginUrl;
9 | };
10 |
11 | return (
12 |
13 |
16 |
17 | );
18 | };
19 |
20 | LoginButton.propTypes = {
21 | loginUrl: PropTypes.string.isRequired,
22 | };
23 |
24 | export default LoginButton;
25 |
--------------------------------------------------------------------------------
/app/component/MainMenuContainer.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Suspense, lazy } from 'react';
3 |
4 | const MenuDrawer = lazy(() => import('./MenuDrawer'));
5 | const MainMenu = lazy(() => import('./MainMenu'));
6 |
7 | export default function MainMenuContainer({ breakpoint, closeMenu, ...rest }) {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | );
15 | }
16 |
17 | MainMenuContainer.propTypes = {
18 | breakpoint: PropTypes.string,
19 | closeMenu: PropTypes.func.isRequired,
20 | };
21 |
22 | MainMenuContainer.defaultProps = {
23 | breakpoint: 'small',
24 | };
25 |
--------------------------------------------------------------------------------
/app/component/Message.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { FormattedMessage } from 'react-intl';
4 |
5 | export default function Message({ labelId, defaultMessage }) {
6 | if (labelId) {
7 | return ;
8 | }
9 | if (defaultMessage) {
10 | return {defaultMessage} ;
11 | }
12 | return null;
13 | }
14 |
15 | Message.propTypes = {
16 | labelId: PropTypes.string,
17 | defaultMessage: PropTypes.string,
18 | };
19 |
20 | Message.defaultProps = {
21 | labelId: undefined,
22 | defaultMessage: undefined,
23 | };
24 |
--------------------------------------------------------------------------------
/app/component/NetworkError.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { matchShape } from 'found';
4 |
5 | import { FormattedMessage } from 'react-intl';
6 | import Link from 'found/Link';
7 | import Icon from './Icon';
8 |
9 | const NetworkError = ({ retry }, { match }) => (
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 |
26 | NetworkError.propTypes = { retry: PropTypes.func.isRequired };
27 | NetworkError.contextTypes = {
28 | match: matchShape.isRequired,
29 | };
30 |
31 | export default NetworkError;
32 |
--------------------------------------------------------------------------------
/app/component/ParkContainer.js:
--------------------------------------------------------------------------------
1 | import { createFragmentContainer, graphql } from 'react-relay';
2 | import ParkAndRideContent from './ParkAndRideContent';
3 |
4 | const containerComponent = createFragmentContainer(ParkAndRideContent, {
5 | vehicleParking: graphql`
6 | fragment ParkContainer_vehicleParking on VehicleParking {
7 | availability {
8 | bicycleSpaces
9 | carSpaces
10 | }
11 | capacity {
12 | carSpaces
13 | }
14 | name
15 | lat
16 | lon
17 | tags
18 | realtime
19 | }
20 | `,
21 | });
22 |
23 | export { containerComponent as default, ParkAndRideContent as Component };
24 |
--------------------------------------------------------------------------------
/app/component/RentalVehicle.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import Icon from './Icon';
4 | import {
5 | getRentalNetworkIcon,
6 | getRentalNetworkConfig,
7 | } from '../util/vehicleRentalUtils';
8 | import { rentalVehicleShape } from '../util/shapes';
9 |
10 | const RentalVehicle = ({ rentalVehicle }, { config }) => {
11 | const vehicleIcon = getRentalNetworkIcon(
12 | getRentalNetworkConfig(rentalVehicle.rentalNetwork.networkId, config),
13 | );
14 | return (
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | RentalVehicle.contextTypes = {
22 | config: PropTypes.shape({
23 | vehicleRental: { networks: PropTypes.arrayOf(PropTypes.string.isRequired) },
24 | }).isRequired,
25 | };
26 | RentalVehicle.propTypes = {
27 | rentalVehicle: rentalVehicleShape.isRequired,
28 | };
29 | export default RentalVehicle;
30 |
--------------------------------------------------------------------------------
/app/component/SplitBars.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | const SplitBars = ({ children }) => {
5 | let splits = [];
6 | children.forEach(child => {
7 | splits.push({child}
);
8 | splits.push();
9 | });
10 | splits = splits.splice(0, splits.length - 1);
11 | return {splits}
;
12 | };
13 |
14 | SplitBars.displayName = 'SplitBars';
15 |
16 | SplitBars.propTypes = {
17 | children: PropTypes.node.isRequired,
18 | };
19 |
20 | export default SplitBars;
21 |
--------------------------------------------------------------------------------
/app/component/StopCode.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 |
4 | const StopCode = ({ code }) =>
5 | code && {code};
6 |
7 | StopCode.displayName = 'StopCode';
8 | StopCode.propTypes = {
9 | code: PropTypes.string.isRequired,
10 | };
11 | export default StopCode;
12 |
--------------------------------------------------------------------------------
/app/component/Title.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { configShape } from '../util/shapes';
3 |
4 | const TitleComponent = (props, { config: { title } }) => {title};
5 |
6 | TitleComponent.contextTypes = { config: configShape.isRequired };
7 |
8 | export default TitleComponent;
9 |
--------------------------------------------------------------------------------
/app/component/ToggleMapTracking.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import Icon from './Icon';
4 |
5 | /* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
6 | function ToggleMapTracking(props) {
7 | return (
8 |
15 |
16 |
17 | );
18 | }
19 |
20 | ToggleMapTracking.propTypes = {
21 | handleClick: PropTypes.func.isRequired,
22 | className: PropTypes.string.isRequired,
23 | img: PropTypes.string.isRequired,
24 | ariaLabel: PropTypes.string.isRequired,
25 | };
26 |
27 | export default ToggleMapTracking;
28 |
--------------------------------------------------------------------------------
/app/component/app-bar-hsl.scss:
--------------------------------------------------------------------------------
1 | .hslfi-cb__button-primary {
2 | &:hover {
3 | background-color: #0062a1 !important;
4 | color: white !important;
5 | }
6 | }
7 |
8 | .hslfi-cb__button-secondary {
9 | &:hover {
10 | color: #0062a1 !important;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/component/embedded/EmbeddedSearchContainer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { matchShape } from 'found';
3 | import LazilyLoad, { importLazy } from '../LazilyLoad';
4 |
5 | const modules = {
6 | EmbeddedSearch: () => importLazy(import('./EmbeddedSearch')),
7 | };
8 |
9 | const EmbeddedSearchContainer = props => {
10 | return (
11 |
12 | {({ EmbeddedSearch }) => }
13 |
14 | );
15 | };
16 |
17 | EmbeddedSearchContainer.propTypes = {
18 | match: matchShape.isRequired,
19 | };
20 |
21 | export default EmbeddedSearchContainer;
22 |
--------------------------------------------------------------------------------
/app/component/itinerary/AirplaneLeg.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { FormattedMessage } from 'react-intl';
4 | import { legShape } from '../../util/shapes';
5 |
6 | import TransitLeg from './TransitLeg';
7 |
8 | const AirplaneLeg = ({ leg, focusAction, index }) => (
9 |
16 |
23 |
24 | );
25 |
26 | AirplaneLeg.propTypes = {
27 | leg: legShape.isRequired,
28 | index: PropTypes.number.isRequired,
29 | focusAction: PropTypes.func.isRequired,
30 | };
31 |
32 | export default AirplaneLeg;
33 |
--------------------------------------------------------------------------------
/app/component/itinerary/ChangeDepartureTimeLink.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import cx from 'classnames';
3 | import { matchShape } from 'found';
4 | import { FormattedMessage } from 'react-intl';
5 |
6 | const ChangeDepartureTimeLink = ({ match }) => (
7 |
12 | );
13 |
14 | ChangeDepartureTimeLink.propTypes = {
15 | match: matchShape.isRequired,
16 | };
17 |
18 | export default ChangeDepartureTimeLink;
19 |
--------------------------------------------------------------------------------
/app/component/itinerary/Duration.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { FormattedMessage } from 'react-intl';
4 |
5 | function Duration({ duration }) {
6 | const dur = Math.max(duration, 0);
7 | const hours = Math.floor(dur / 3600000);
8 | const mins = Math.floor(dur / 60000 - hours * 60);
9 | if (hours >= 1) {
10 | return (
11 |
15 | );
16 | }
17 | return (
18 |
22 | );
23 | }
24 |
25 | Duration.propTypes = { duration: PropTypes.number.isRequired };
26 |
27 | export default Duration;
28 |
--------------------------------------------------------------------------------
/app/component/itinerary/FeedbackPrompt.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { FormattedMessage } from 'react-intl';
3 | import { configShape } from '../../util/shapes';
4 |
5 | export default function FeedbackPrompt(props, { config }) {
6 | return config.useRoutingFeedbackPrompt ? (
7 |
20 | ) : null;
21 | }
22 |
23 | FeedbackPrompt.contextTypes = {
24 | config: configShape,
25 | };
26 |
--------------------------------------------------------------------------------
/app/component/itinerary/ItineraryDistance.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React from 'react';
3 | import { FormattedMessage } from 'react-intl';
4 |
5 | const Distance = props => {
6 | let approxDistance;
7 |
8 | if (props.distance > 0) {
9 | approxDistance = Math.round(props.distance / 50) * 50;
10 |
11 | if (approxDistance > 50) {
12 | return (
13 |
18 | );
19 | }
20 | }
21 |
22 | return null;
23 | };
24 |
25 | Distance.propTypes = {
26 | distance: PropTypes.number.isRequired,
27 | };
28 |
29 | export default Distance;
30 |
--------------------------------------------------------------------------------
/app/component/itinerary/ItineraryNotification.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { FormattedMessage } from 'react-intl';
4 | import Icon from '../Icon';
5 |
6 | export default function ItineraryNotification({ headerId, bodyId, iconId }) {
7 | return (
8 |
9 |
{iconId && }
10 |
11 |
{headerId && }
12 |
{bodyId && }
13 |
14 |
15 | );
16 | }
17 |
18 | ItineraryNotification.propTypes = {
19 | headerId: PropTypes.string,
20 | bodyId: PropTypes.string,
21 | iconId: PropTypes.string,
22 | };
23 |
24 | ItineraryNotification.defaultProps = {
25 | headerId: undefined,
26 | bodyId: undefined,
27 | iconId: undefined,
28 | };
29 |
--------------------------------------------------------------------------------
/app/component/itinerary/ItineraryPageTitle.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { matchShape } from 'found';
3 | import { FormattedMessage } from 'react-intl';
4 |
5 | export default function ItineraryPageTitle(props) {
6 | return (
7 |
8 | {props.match.params.hash == null ? (
9 |
13 | ) : (
14 |
18 | )}
19 |
20 | );
21 | }
22 |
23 | ItineraryPageTitle.propTypes = {
24 | match: matchShape.isRequired,
25 | };
26 |
--------------------------------------------------------------------------------
/app/component/itinerary/PastLink.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { matchShape } from 'found';
3 | import { FormattedMessage } from 'react-intl';
4 | import cx from 'classnames';
5 |
6 | const PastLink = ({ match }) => (
7 |
12 | );
13 |
14 | PastLink.propTypes = {
15 | match: matchShape.isRequired,
16 | };
17 |
18 | export default PastLink;
19 |
--------------------------------------------------------------------------------
/app/component/itinerary/itinerary-profile.scss:
--------------------------------------------------------------------------------
1 | .itinerary-profile-container {
2 | display: flex;
3 | align-items: center;
4 | justify-content: space-between;
5 | margin-left: 15px;
6 | font-size: 15px;
7 | line-height: 18px;
8 | margin-top: 7px;
9 | margin-bottom: 7px;
10 |
11 | &.small {
12 | font-size: 10pt;
13 | }
14 |
15 | .itinerary-profile-item-title {
16 | @include font-book;
17 |
18 | color: $gray;
19 | display: inline-block;
20 | }
21 |
22 | .itinerary-profile-item-value {
23 | color: $black;
24 | display: inline-block;
25 | margin-left: 0.25rem;
26 | }
27 |
28 | @media print {
29 | margin-bottom: 16px;
30 | }
31 |
32 | button {
33 | display: none;
34 |
35 | @include min-width(tablet) {
36 | display: flex;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/component/itinerary/navigator/hooks/useLogo.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, useCallback } from 'react';
2 |
3 | const useLogo = logoPath => {
4 | const [logo, setLogo] = useState(null);
5 | const [loading, setLoading] = useState(true);
6 |
7 | const fetchLogo = useCallback(async () => {
8 | setLoading(true);
9 | try {
10 | const importedLogo = await import(
11 | /* webpackChunkName: "main" */ `../../../../configurations/images/${logoPath}`
12 | );
13 | setLogo(importedLogo.default);
14 | } catch (error) {
15 | // eslint-disable-next-line no-console
16 | console.error('Error loading logo:', error);
17 | } finally {
18 | setLoading(false);
19 | }
20 | }, [logoPath]);
21 |
22 | useEffect(() => {
23 | fetchLogo();
24 | }, [fetchLogo]);
25 |
26 | return { logo, loading };
27 | };
28 |
29 | export { useLogo };
30 |
--------------------------------------------------------------------------------
/app/component/itinerary/navigator/hooks/usePrevious.js:
--------------------------------------------------------------------------------
1 | import { useRef } from 'react';
2 |
3 | const usePrevious = (value, comparingFunc) => {
4 | const ref = useRef({
5 | value,
6 | prev: null,
7 | });
8 |
9 | const current = ref.current.value;
10 | let isEqual = false;
11 |
12 | if (
13 | comparingFunc
14 | ? !comparingFunc(current, value)
15 | : JSON.stringify(value) !== JSON.stringify(current)
16 | ) {
17 | ref.current = {
18 | value,
19 | prev: current,
20 | };
21 | isEqual = true;
22 | }
23 |
24 | return { previous: ref.current.prev, isEqual };
25 | };
26 |
27 | export default usePrevious;
28 |
--------------------------------------------------------------------------------
/app/component/itinerary/navigator/navigatorgeolocation/navigator-geolocation.scss:
--------------------------------------------------------------------------------
1 | .navigator-modal-content {
2 | .geolocation-body {
3 | display: flex;
4 | flex-direction: column;
5 | flex-wrap: wrap;
6 | align-items: stretch;
7 | align-content: center;
8 | gap: var(--space-m);
9 |
10 | &.slide-in {
11 | animation: slideUpFromBottom 0.5s ease-in-out;
12 | }
13 |
14 | h2 {
15 | text-align: center;
16 | margin: unset;
17 | }
18 |
19 | p {
20 | margin: 0 0 var(--space-m) 0;
21 | line-height: 1.3;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/component/itinerary/origin-destination-bar.scss:
--------------------------------------------------------------------------------
1 | .origin-destination-bar {
2 | background-color: #fff;
3 | display: flex;
4 | justify-content: space-around;
5 | align-items: initial;
6 |
7 | &.bp-large {
8 | margin: 0 60px;
9 | }
10 | }
11 |
12 | .mobile {
13 | .origin-destination-bar {
14 | z-index: 999;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/component/itinerary/queries/ItineraryListContainerPlanEdges.js:
--------------------------------------------------------------------------------
1 | import { graphql } from 'react-relay';
2 |
3 | export const ItineraryListContainerPlanEdges = graphql`
4 | fragment ItineraryListContainerPlanEdges on PlanEdge @relay(plural: true) {
5 | ...ItineraryListPlanEdges
6 | node {
7 | legs {
8 | mode
9 | }
10 | }
11 | }
12 | `;
13 |
--------------------------------------------------------------------------------
/app/component/itinerary/queries/ItineraryListPlanEdges.js:
--------------------------------------------------------------------------------
1 | import { graphql } from 'react-relay';
2 |
3 | export const ItineraryListPlanEdges = graphql`
4 | fragment ItineraryListPlanEdges on PlanEdge @relay(plural: true) {
5 | node {
6 | ...ItineraryFragment
7 | emissionsPerPerson {
8 | co2
9 | }
10 | legs {
11 | transitLeg
12 | mode
13 | route {
14 | mode
15 | type
16 | }
17 | }
18 | }
19 | }
20 | `;
21 |
--------------------------------------------------------------------------------
/app/component/itinerary/queries/LegAgencyInfoFragment.js:
--------------------------------------------------------------------------------
1 | import { graphql } from 'react-relay';
2 |
3 | export const LegAgencyInfoFragment = graphql`
4 | fragment LegAgencyInfoFragment on Leg {
5 | agency {
6 | name
7 | url
8 | fareUrl
9 | }
10 | }
11 | `;
12 |
--------------------------------------------------------------------------------
/app/component/map/MapBottomsheetContext.js:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react';
2 |
3 | // undefined value used in desktop
4 | export default createContext(undefined);
5 |
--------------------------------------------------------------------------------
/app/component/map/tile-layer/ParkAndRideForBikes.js:
--------------------------------------------------------------------------------
1 | import ParkAndRide from './ParkAndRide';
2 | import { ParkTypes } from '../../../constants';
3 |
4 | export default class ParkAndRideForBikes extends ParkAndRide {
5 | constructor(tile, config, mapLayers, relayEnvironment, lang) {
6 | super(tile, config, relayEnvironment, lang);
7 | }
8 |
9 | static getName = () => 'parkAndRideForBikes';
10 |
11 | getPromise(lang) {
12 | return this.fetchAndDrawParks(ParkTypes.Bicycle, lang);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/component/map/tile-layer/ParkAndRideForCars.js:
--------------------------------------------------------------------------------
1 | import ParkAndRide from './ParkAndRide';
2 | import { ParkTypes } from '../../../constants';
3 |
4 | export default class ParkAndRideForCars extends ParkAndRide {
5 | constructor(tile, config, mapLayers, relayEnvironment, lang) {
6 | super(tile, config, relayEnvironment, lang);
7 | }
8 |
9 | static getName = () => 'parkAndRide';
10 |
11 | getPromise(lang) {
12 | return this.fetchAndDrawParks(ParkTypes.Car, lang);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/component/no-favourites-panel.scss:
--------------------------------------------------------------------------------
1 | /* No favourites image */
2 |
3 | .front-page {
4 | .nofavs-img {
5 | height: 80px;
6 | width: 100%;
7 | max-width: 160px;
8 | margin: 0 auto;
9 | margin-top: 4.5em;
10 | }
11 |
12 | .no-favourites-icon {
13 | fill: transparent;
14 | stroke: $link-color;
15 | stroke-width: 25px;
16 | width: 56px;
17 | height: 56px;
18 | }
19 |
20 | .nofavs-p {
21 | width: 70%;
22 | margin-left: 15%;
23 | margin-right: 15%;
24 | font-size: $font-size-small;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/component/select-maplayers-dialog.scss:
--------------------------------------------------------------------------------
1 | .select-map-layers-dialog-content {
2 | display: flex;
3 | flex-direction: column;
4 | margin-top: 0.25em;
5 | position: relative;
6 |
7 | &.bubble-dialog-content--large {
8 | white-space: nowrap;
9 | }
10 |
11 | .checkbox-grouping + .checkbox-grouping {
12 | margin-top: 2em;
13 |
14 | &::before {
15 | border-top: 1px solid $light-gray;
16 | content: '';
17 | left: 0;
18 | margin-top: -1.05em;
19 | right: 0;
20 | position: absolute;
21 | }
22 | }
23 |
24 | .option-checkbox-container + .option-checkbox-container {
25 | margin-top: 0.25em;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/component/stop/StopCardHeaderContainer.js:
--------------------------------------------------------------------------------
1 | import connectToStores from 'fluxible-addons-react/connectToStores';
2 | import { createFragmentContainer, graphql } from 'react-relay';
3 |
4 | import StopCardHeader from './StopCardHeader';
5 |
6 | export default createFragmentContainer(
7 | connectToStores(StopCardHeader, ['TimeStore'], context => ({
8 | currentTime: context.getStore('TimeStore').getCurrentTime(),
9 | })),
10 | {
11 | stop: graphql`
12 | fragment StopCardHeaderContainer_stop on Stop {
13 | gtfsId
14 | name
15 | code
16 | desc
17 | zoneId
18 | alerts {
19 | alertSeverityLevel
20 | effectiveEndDate
21 | effectiveStartDate
22 | }
23 | lat
24 | lon
25 | stops {
26 | name
27 | desc
28 | }
29 | }
30 | `,
31 | },
32 | );
33 |
--------------------------------------------------------------------------------
/app/component/stop/StopPageHeader.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import mapProps from 'recompose/mapProps';
3 | import getContext from 'recompose/getContext';
4 | import compose from 'recompose/compose';
5 |
6 | import StopCardHeaderContainer from './StopCardHeaderContainer';
7 | import withBreakpoint from '../../util/withBreakpoint';
8 |
9 | const StopPageHeader = compose(
10 | withBreakpoint,
11 | getContext({
12 | executeAction: PropTypes.func.isRequired,
13 | }),
14 | mapProps(props => ({
15 | stop: props.stop || props.station,
16 | className: 'stop-page header',
17 | headingStyle: 'h3',
18 | icons: [],
19 | breakpoint: props.breakpoint,
20 | isTerminal: props.isTerminal,
21 | })),
22 | )(StopCardHeaderContainer);
23 |
24 | StopPageHeader.displayName = 'StopPageHeader';
25 |
26 | export default StopPageHeader;
27 |
--------------------------------------------------------------------------------
/app/component/stop/StopPageHeaderContainer.js:
--------------------------------------------------------------------------------
1 | import { createFragmentContainer, graphql } from 'react-relay';
2 | import connectToStores from 'fluxible-addons-react/connectToStores';
3 |
4 | import StopPageHeader from './StopPageHeader';
5 |
6 | export default createFragmentContainer(
7 | connectToStores(
8 | StopPageHeader,
9 | ['FavouriteStore'],
10 | ({ getStore }, { match }) => ({
11 | favourite: getStore('FavouriteStore').isFavourite(
12 | match.params.stopId,
13 | 'stop',
14 | ),
15 | }),
16 | ),
17 | {
18 | stop: graphql`
19 | fragment StopPageHeaderContainer_stop on Stop {
20 | ...StopCardHeaderContainer_stop
21 | }
22 | `,
23 | },
24 | );
25 |
--------------------------------------------------------------------------------
/app/component/stop/StopTitle.js:
--------------------------------------------------------------------------------
1 | import withProps from 'recompose/withProps';
2 | import { FormattedMessage } from 'react-intl';
3 |
4 | export default withProps({
5 | id: 'stop-page.title-short',
6 | defaultMessage: 'Stop',
7 | })(FormattedMessage);
8 |
--------------------------------------------------------------------------------
/app/component/stop/TerminalPageHeaderContainer.js:
--------------------------------------------------------------------------------
1 | import { createFragmentContainer, graphql } from 'react-relay';
2 | import connectToStores from 'fluxible-addons-react/connectToStores';
3 |
4 | import StopPageHeader from './StopPageHeader';
5 |
6 | export default createFragmentContainer(
7 | connectToStores(
8 | StopPageHeader,
9 | ['FavouriteStore'],
10 | ({ getStore }, { match }) => ({
11 | favourite: getStore('FavouriteStore').isFavourite(
12 | match.params.terminalId,
13 | 'station',
14 | ),
15 | isTerminal: true,
16 | }),
17 | ),
18 | {
19 | station: graphql`
20 | fragment TerminalPageHeaderContainer_station on Stop {
21 | ...StopCardHeaderContainer_stop
22 | }
23 | `,
24 | },
25 | );
26 |
--------------------------------------------------------------------------------
/app/component/stop/TerminalTitle.js:
--------------------------------------------------------------------------------
1 | import withProps from 'recompose/withProps';
2 | import { FormattedMessage } from 'react-intl';
3 |
4 | export default withProps({
5 | id: 'terminal-page.title-short',
6 | defaultMessage: 'Terminal',
7 | })(FormattedMessage);
8 |
--------------------------------------------------------------------------------
/app/component/stop/queries/TimetableFragment.js:
--------------------------------------------------------------------------------
1 | import { graphql } from 'react-relay';
2 |
3 | export const TimetableFragment = graphql`
4 | fragment TimetableFragment on Stop
5 | @argumentDefinitions(date: { type: "String" }) {
6 | gtfsId
7 | name
8 | url
9 | locationType
10 | stoptimesForServiceDate(date: $date, omitCanceled: false) {
11 | pattern {
12 | headsign
13 | code
14 | route {
15 | id
16 | shortName
17 | longName
18 | type
19 | mode
20 | agency {
21 | id
22 | name
23 | }
24 | }
25 | }
26 | stoptimes {
27 | realtimeState
28 | scheduledDeparture
29 | serviceDay
30 | headsign
31 | pickupType
32 | }
33 | }
34 | }
35 | `;
36 |
--------------------------------------------------------------------------------
/app/component/visual/OverlayWithSpinner.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { FormattedMessage } from 'react-intl';
3 | import Loading from '../Loading';
4 |
5 | const OverlayWithSpinner = () => (
6 |
15 | );
16 |
17 | export default OverlayWithSpinner;
18 |
--------------------------------------------------------------------------------
/app/component/visual/index.scss:
--------------------------------------------------------------------------------
1 | @import 'overlay-with-spinner';
2 |
--------------------------------------------------------------------------------
/app/component/visual/overlay-with-spinner.scss:
--------------------------------------------------------------------------------
1 | div.overlay-with-spinner {
2 | background-color: rgba(255, 255, 255, 0.6);
3 | z-index: 2001;
4 | width: 100%;
5 | height: 100%;
6 | position: absolute;
7 | top: 0;
8 | right: 0;
9 | justify-content: center;
10 | display: flex;
11 | flex-direction: column;
12 |
13 | div {
14 | display: flex;
15 | height: 68px;
16 | justify-content: center;
17 | margin-bottom: 20px;
18 | }
19 |
20 | span {
21 | text-align: center;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/component/zone-icon.scss:
--------------------------------------------------------------------------------
1 | .zone-icon-container {
2 | .circle {
3 | display: flex;
4 | justify-content: center;
5 | width: 0.875rem;
6 | height: 0.875rem;
7 | border-radius: 50%;
8 | font-size: 12px;
9 | color: #fff;
10 | letter-spacing: 0;
11 | padding: 0 2px 0 2px;
12 | line-height: 1.2;
13 | background: $primary-color;
14 | font-weight: $font-weight-medium;
15 |
16 | &.multi-letter {
17 | border-radius: 10px;
18 | width: max-content;
19 | }
20 | }
21 |
22 | .unknown {
23 | text-align: center;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/configurations/images/default/default-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/default/default-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/default/digitransit-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/default/digitransit-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/default/dotted-line-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/default/dotted-line-bg.png
--------------------------------------------------------------------------------
/app/configurations/images/default/dotted-line-bg2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/default/dotted-line-bg2.png
--------------------------------------------------------------------------------
/app/configurations/images/default/dotted-line.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/configurations/images/hameenlinna/hameenlinna-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/hameenlinna/hameenlinna-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/hameenlinna/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/hameenlinna/logo.png
--------------------------------------------------------------------------------
/app/configurations/images/hameenlinna/secondary-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/hameenlinna/secondary-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/hsl/hsl-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/hsl/hsl-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/joensuu/joensuu-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/joensuu/joensuu-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/joensuu/jojo-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/joensuu/jojo-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/jyvaskyla/jyvaskyla-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/jyvaskyla/jyvaskyla-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/kotka/kotka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kotka/kotka.png
--------------------------------------------------------------------------------
/app/configurations/images/kouvola/kouvola-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kouvola/kouvola-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/kouvola/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kouvola/logo.png
--------------------------------------------------------------------------------
/app/configurations/images/kouvola/secondary-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kouvola/secondary-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/kuopio/kuopio-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kuopio/kuopio-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/kuopio/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kuopio/logo.png
--------------------------------------------------------------------------------
/app/configurations/images/kuopio/secondary-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/kuopio/secondary-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/lahti/lahti-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/lahti/lahti-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/lahti/lahti-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/lahti/lahti-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/lahti/secondary-lahti-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/lahti/secondary-lahti-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/lappeenranta/lappeenranta-favicon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/lappeenranta/lappeenranta-favicon.jpg
--------------------------------------------------------------------------------
/app/configurations/images/lappeenranta/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/lappeenranta/logo.png
--------------------------------------------------------------------------------
/app/configurations/images/lappeenranta/secondary-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/lappeenranta/secondary-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/oulu/oulu-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/oulu/oulu-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/oulu/oulu-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/oulu/oulu-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/oulu/secondary-oulu-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/oulu/secondary-oulu-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/pori/pori-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/pori/pori-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/raasepori/raasepori-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/raasepori/raasepori-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/raasepori/raasepori_logo_musta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/raasepori/raasepori_logo_musta.png
--------------------------------------------------------------------------------
/app/configurations/images/raasepori/raasepori_logo_valkoinen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/raasepori/raasepori_logo_valkoinen.png
--------------------------------------------------------------------------------
/app/configurations/images/rovaniemi/rovaniemi-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/rovaniemi/rovaniemi-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/tampere/tampere-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/tampere/tampere-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/tampere/tampere-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/tampere/tampere-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/turku/foli-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/turku/foli-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/turku/turku-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/turku/turku-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/vaasa/secondary-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/vaasa/secondary-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/vaasa/vaasa-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/vaasa/vaasa-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/varely/varely-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/varely/varely-favicon.png
--------------------------------------------------------------------------------
/app/configurations/images/walttiOpas/waltti-logo-secondary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/walttiOpas/waltti-logo-secondary.png
--------------------------------------------------------------------------------
/app/configurations/images/walttiOpas/waltti-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/walttiOpas/waltti-logo.png
--------------------------------------------------------------------------------
/app/configurations/images/walttiOpas/walttiOpas-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/app/configurations/images/walttiOpas/walttiOpas-favicon.png
--------------------------------------------------------------------------------
/app/store/CanceledLegsBarStore.js:
--------------------------------------------------------------------------------
1 | import Store from 'fluxible/addons/BaseStore';
2 |
3 | class CanceledLegsBarStore extends Store {
4 | static storeName = 'CanceledLegsBarStore';
5 |
6 | showCanceledLegsBanner = false;
7 |
8 | updateShowCanceledLegsBannerState(val) {
9 | this.showCanceledLegsBanner = val;
10 | this.emit('change');
11 | }
12 |
13 | getShowCanceledLegsBanner() {
14 | return this.showCanceledLegsBanner;
15 | }
16 |
17 | static handlers = {
18 | updateShowCanceledLegsBannerState: 'updateShowCanceledLegsBannerState',
19 | getShowCanceledLegsBanner: 'getShowCanceledLegsBanner',
20 | };
21 | }
22 |
23 | export default CanceledLegsBarStore;
24 |
--------------------------------------------------------------------------------
/app/store/CountryStore.js:
--------------------------------------------------------------------------------
1 | import Store from 'fluxible/addons/BaseStore';
2 | import { getCountries, setCountries } from './localStorage';
3 |
4 | class CountryStore extends Store {
5 | static handlers = {
6 | UpdateCountries: 'updateCountries',
7 | };
8 |
9 | static storeName = 'CountryStore';
10 |
11 | countries = getCountries();
12 |
13 | getCountries = () => {
14 | return this.countries;
15 | };
16 |
17 | updateCountries = countries => {
18 | this.countries = countries;
19 | setCountries(countries);
20 | this.emitChange();
21 | };
22 | }
23 |
24 | export default CountryStore;
25 |
--------------------------------------------------------------------------------
/app/store/DestinationStore.js:
--------------------------------------------------------------------------------
1 | import Store from 'fluxible/addons/BaseStore';
2 |
3 | class DestinationStore extends Store {
4 | static storeName = 'DestinationStore';
5 |
6 | constructor(...args) {
7 | super(...args);
8 | this.destination = {};
9 | }
10 |
11 | getDestination() {
12 | return this.destination;
13 | }
14 |
15 | setDestination(destination) {
16 | this.destination = destination;
17 | this.emitChange();
18 | }
19 |
20 | static handlers = {
21 | SetDestination: 'setDestination',
22 | };
23 | }
24 |
25 | export default DestinationStore;
26 |
--------------------------------------------------------------------------------
/app/store/OriginStore.js:
--------------------------------------------------------------------------------
1 | import Store from 'fluxible/addons/BaseStore';
2 |
3 | class OriginStore extends Store {
4 | static storeName = 'OriginStore';
5 |
6 | constructor(...args) {
7 | super(...args);
8 | this.origin = {};
9 | }
10 |
11 | getOrigin() {
12 | return this.origin;
13 | }
14 |
15 | setOrigin(origin) {
16 | this.origin = origin;
17 | this.emitChange();
18 | }
19 |
20 | static handlers = {
21 | SetOrigin: 'setOrigin',
22 | };
23 | }
24 |
25 | export default OriginStore;
26 |
--------------------------------------------------------------------------------
/app/store/UserStore.js:
--------------------------------------------------------------------------------
1 | import Store from 'fluxible/addons/BaseStore';
2 |
3 | class UserStore extends Store {
4 | static storeName = 'UserStore';
5 |
6 | user = {};
7 |
8 | getUser() {
9 | return this.user;
10 | }
11 |
12 | setUser(user) {
13 | this.user = user;
14 | this.emitChange();
15 | }
16 |
17 | static handlers = {
18 | setUser: 'setUser',
19 | };
20 | }
21 |
22 | export default UserStore;
23 |
--------------------------------------------------------------------------------
/app/store/ViaPointStore.js:
--------------------------------------------------------------------------------
1 | import Store from 'fluxible/addons/BaseStore';
2 |
3 | class ViaPointStore extends Store {
4 | static storeName = 'ViaPointStore';
5 |
6 | viaPoints = [];
7 |
8 | addViaPoint(val) {
9 | this.viaPoints.push(val);
10 | this.emitChange();
11 | }
12 |
13 | setViaPoints(viaPoints) {
14 | this.viaPoints = [...viaPoints];
15 | this.emitChange();
16 | }
17 |
18 | getViaPoints() {
19 | return this.viaPoints;
20 | }
21 |
22 | static handlers = {
23 | addViaPoint: 'addViaPoint',
24 | setViaPoints: 'setViaPoints',
25 | };
26 | }
27 |
28 | export default ViaPointStore;
29 |
--------------------------------------------------------------------------------
/app/util/StoreListeningIntlProvider.js:
--------------------------------------------------------------------------------
1 | import { IntlProvider, addLocaleData } from 'react-intl';
2 | import connectToStores from 'fluxible-addons-react/connectToStores';
3 |
4 | export default connectToStores(
5 | IntlProvider,
6 | ['PreferencesStore'],
7 | (context, props) => {
8 | const language = context.getStore('PreferencesStore').getLanguage();
9 |
10 | // eslint-disable-next-line global-require, import/no-dynamic-require
11 | addLocaleData(require(`react-intl/locale-data/${language}`));
12 |
13 | return {
14 | locale: language,
15 | messages: props.translations[language],
16 | };
17 | },
18 | );
19 |
--------------------------------------------------------------------------------
/app/util/emissions.js:
--------------------------------------------------------------------------------
1 | export default function getCo2Value(itinerary) {
2 | return typeof itinerary.emissionsPerPerson?.co2 === 'number' &&
3 | itinerary.emissionsPerPerson?.co2 >= 0
4 | ? Math.round(itinerary.emissionsPerPerson?.co2)
5 | : null;
6 | }
7 |
--------------------------------------------------------------------------------
/app/util/envUtils.js:
--------------------------------------------------------------------------------
1 | /** Check if application is running in a dev environment. RUN_ENV is defined in kubernetes-deploy for dev instances. For running dev locally, NODE_ENV is checked * */
2 | export const isDevelopmentEnvironment = config => {
3 | return (
4 | config?.RUN_ENV === 'development' || process.env.NODE_ENV === 'development'
5 | );
6 | };
7 |
--------------------------------------------------------------------------------
/app/util/events.js:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'events';
2 |
3 | const dtEmitter = new EventEmitter();
4 | export default dtEmitter;
5 |
--------------------------------------------------------------------------------
/app/util/filterUtils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Filters object that contains objects so that only objects that have
3 | * a certain key with the correct value defined are returned.
4 | *
5 | * @param {*} obj object to filter
6 | * @param {String} filter key on object's child objects
7 | * @param {*} filterValue the key's intended value
8 | * @returns filtered object
9 | */
10 | export const filterObject = (obj, filter, filterValue) =>
11 | Object.keys(obj).reduce(
12 | (acc, val) =>
13 | obj[val][filter] === filterValue
14 | ? {
15 | ...acc,
16 | [val]: obj[val],
17 | }
18 | : acc,
19 | {},
20 | );
21 |
--------------------------------------------------------------------------------
/app/util/getIterator.js:
--------------------------------------------------------------------------------
1 | function isObject(it) {
2 | return typeof it === 'object' ? it !== null : typeof it === 'function';
3 | }
4 |
5 | export default function iter(it) {
6 | const iterFn = it[Symbol.iterator];
7 | if (typeof iterFn !== 'function') {
8 | throw TypeError(`${it} is not iterable!`);
9 | }
10 | if (!isObject(it)) {
11 | throw TypeError(`${it} is not an object!`);
12 | }
13 | return iterFn.call(it);
14 | }
15 |
--------------------------------------------------------------------------------
/app/util/gtfs.js:
--------------------------------------------------------------------------------
1 | export const typeToName = {
2 | 0: 'tram',
3 | 1: 'subway',
4 | 2: 'rail',
5 | 3: 'bus',
6 | 4: 'ferry',
7 | 7: 'funicular',
8 | 109: 'rail',
9 | };
10 |
--------------------------------------------------------------------------------
/app/util/hashUtil.js:
--------------------------------------------------------------------------------
1 | import isString from 'lodash/isString';
2 |
3 | /**
4 | * A simple Java-like hash function for strings.
5 | *
6 | * see: https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
7 | * @param {string} str the string to hash.
8 | */
9 | const hashCode = str => {
10 | if (!str || str.length === 0 || !isString(str)) {
11 | return 0;
12 | }
13 |
14 | let hash = 0;
15 | for (let i = 0; i < str.length; i++) {
16 | const chr = str.charCodeAt(i);
17 | hash = (hash << 5) - hash + chr; // eslint-disable-line no-bitwise
18 | hash |= 0; // eslint-disable-line no-bitwise
19 | }
20 | return hash;
21 | };
22 |
23 | export default hashCode;
24 |
--------------------------------------------------------------------------------
/app/util/patternUtils.js:
--------------------------------------------------------------------------------
1 | import moment from 'moment';
2 | /**
3 | Helper for determining is current date in active dates.
4 | Return false if pattern doesn't have active dates information available
5 | or if current day is not found in active days
6 | * */
7 | export const isActiveDate = pattern => {
8 | if (!pattern || !pattern.activeDates) {
9 | return false;
10 | }
11 |
12 | const activeDates = pattern.activeDates.reduce((dates, activeDate) => {
13 | return dates.concat(activeDate.day);
14 | }, []);
15 | const now = moment().format('YYYYMMDD');
16 | return activeDates.indexOf(now) > -1;
17 | };
18 |
--------------------------------------------------------------------------------
/app/util/publicPath.js:
--------------------------------------------------------------------------------
1 | if (window.ASSET_URL) {
2 | // eslint-disable-next-line camelcase, no-undef
3 | __webpack_public_path__ = window.ASSET_URL;
4 | }
5 |
--------------------------------------------------------------------------------
/app/util/relayUtils.js:
--------------------------------------------------------------------------------
1 | export default function isRelayNetworkError(error) {
2 | return (
3 | typeof error === 'string' &&
4 | (error ===
5 | 'Server does not return response for request at index 0.\nResponse should have an array with 1 item(s).' ||
6 | error.includes('Reached request timeout'))
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/app/util/safeJsonParser.js:
--------------------------------------------------------------------------------
1 | export default function safeJsonParse(jsonString) {
2 | try {
3 | return JSON.parse(jsonString);
4 | } catch (e) {
5 | return undefined;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/app/util/scroll.js:
--------------------------------------------------------------------------------
1 | import { isBrowser } from './browser';
2 |
3 | export default function scrollTop() {
4 | if (isBrowser) {
5 | window.scrollTo(0, 0);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/app/util/searchRoutes.js:
--------------------------------------------------------------------------------
1 | import { graphql } from 'react-relay';
2 |
3 | export default graphql`
4 | query searchRoutesQuery($feeds: [String!]!, $name: String) {
5 | viewer {
6 | routes(feeds: $feeds, name: $name) {
7 | gtfsId
8 | agency {
9 | name
10 | }
11 | shortName
12 | mode
13 | longName
14 | patterns {
15 | code
16 | }
17 | }
18 | }
19 | }
20 | `;
21 |
--------------------------------------------------------------------------------
/app/util/urlUtils.js:
--------------------------------------------------------------------------------
1 | export default function localizedUrl(object, lang) {
2 | if (!object) {
3 | return null;
4 | }
5 | return object[lang] || object[Object.keys(object)[0]];
6 | }
7 |
--------------------------------------------------------------------------------
/app/util/zoneIconUtils.js:
--------------------------------------------------------------------------------
1 | export default function getZoneId(config, propertiesZones, dataZones) {
2 | function zoneFilter(zones) {
3 | return Array.isArray(zones)
4 | ? zones.filter(
5 | zone => zone && config.feedIds.includes(zone.split(':')[0]),
6 | )
7 | : [];
8 | }
9 |
10 | const filteredZones = propertiesZones
11 | ? zoneFilter(propertiesZones)
12 | : zoneFilter(dataZones);
13 | const zone = filteredZones.length > 0 ? filteredZones[0] : undefined;
14 | return zone ? zone.split(':')[1] : undefined;
15 | }
16 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | targets: {
7 | node: 'current',
8 | browsers: [],
9 | },
10 | },
11 | ],
12 | '@babel/preset-react',
13 | ],
14 | plugins: [
15 | 'dynamic-import-node',
16 | 'relay',
17 | '@babel/plugin-syntax-dynamic-import',
18 | '@babel/plugin-transform-class-properties',
19 | '@babel/plugin-transform-json-strings',
20 | ],
21 | };
22 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-abtesting/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-abtesting/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This package is used to ab test other components
3 | * Use this by importing specific components by name.
4 | *
5 | * Currently unused
6 | */
7 | export {}; // eslint-disable-line import/prefer-default-export
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-abtesting/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | // import React from 'react';
3 | // import Adapter from 'enzyme-adapter-react-16';
4 | // import { expect } from 'chai';
5 | // import { describe, it } from 'mocha';
6 | // import { shallow, configure } from 'enzyme';
7 |
8 | // configure({ adapter: new Adapter() });
9 |
10 | // describe('Testing something', () => {
11 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-autosuggest-panel/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-autosuggest-panel/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import AutosuggestPanel from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-autosuggest-panel module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-autosuggest/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-autosuggest/src/helpers/MobileNoScroll.scss:
--------------------------------------------------------------------------------
1 | @import './MobileSearch';
2 |
3 | .suggestionsContainerOpen {
4 | -ms-overflow-style: none; /* Internet Explorer 10+ */
5 | scrollbar-width: none; /* Firefox */
6 | &::-webkit-scrollbar {
7 | display: none; /* Safari and Chrome */
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-autosuggest/src/helpers/withScrollLock.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import hooks from '@hsl-fi/hooks';
3 |
4 | const withScrollLock = Component => {
5 | return props => {
6 | const { lock, unlock } = hooks.useScrollLock();
7 |
8 | return ;
9 | };
10 | };
11 |
12 | export default withScrollLock;
13 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-autosuggest/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import Autosuggest from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-autosuggest module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-control-panel/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-datetimepicker/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-datetimepicker/src/helpers/dateTimeInputIsSupported.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Detect if input type="date" and type="time" are supported in by the browser
3 | *
4 | * @return {boolean}
5 | */
6 | function dateTimeInputIsSupported() {
7 | if (typeof window === 'undefined' || window === null) {
8 | return false;
9 | }
10 | const elem = document.createElement('input');
11 | elem.type = 'date';
12 | if (elem.type !== 'date') {
13 | return false;
14 | }
15 | elem.type = 'time';
16 | if (elem.type !== 'time') {
17 | return false;
18 | }
19 | return true;
20 | }
21 |
22 | export default dateTimeInputIsSupported;
23 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-datetimepicker/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import Datetimepicker from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-datetimepicker module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-dialog-modal/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-dialog-modal/src/helpers/translations.js:
--------------------------------------------------------------------------------
1 | const translations = {
2 | de: {
3 | 'close-modal': 'Schließe den Dialog',
4 | },
5 | en: {
6 | 'close-modal': 'Close the modal',
7 | },
8 | fi: {
9 | 'close-modal': 'Sulje modaali',
10 | },
11 | pl: {
12 | 'close-modal': 'Zamknij modal',
13 | },
14 | sv: {
15 | 'close-modal': 'Stäng modalen',
16 | },
17 | };
18 |
19 | export default translations;
20 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-dialog-modal/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import DialogModal from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-dialog-modal module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-bar/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-bar/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import FavouriteBar from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-favourite-bar module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-editing-modal/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-editing-modal/src/helpers/ModalContent.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable jsx-a11y/click-events-have-key-events */
2 | import React from 'react';
3 | import PropTypes from 'prop-types';
4 | import styles from './modal-content.scss';
5 |
6 | const ModalContent = ({ headerText, renderList }) => {
7 | return (
8 |
9 |
10 |
11 | {headerText}
12 |
13 |
14 | {renderList()}
15 |
16 | );
17 | };
18 |
19 | ModalContent.propTypes = {
20 | headerText: PropTypes.string.isRequired,
21 | renderList: PropTypes.func.isRequired,
22 | };
23 |
24 | export default ModalContent;
25 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-editing-modal/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import FavouriteEditingModal from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-favourite-editing-modal module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-modal/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-favourite-modal/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import FavouriteModal from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-favourite-modal module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/airplane.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/arrow.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/attention.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/caution_white_exclamation.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/check.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/dropdown.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/edit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/ellipsis.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/home.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/locate.svg:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/mapmarker-via.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/mapmarker.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/mode_airplane.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/place.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/plus.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/search-airplane-digitransit.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/search.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/shopping.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/time.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/src/assets/trash.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-icon/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import Icon from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-icon module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-suggestion-item/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-suggestion-item/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import SuggestionItem from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-suggestion-item module', () => {
12 | const item = {};
13 | const content = ['suggestionType', 'label', 'name'];
14 | const wrapper = shallow();
15 |
16 | it('should render', () => {
17 | expect(wrapper.isEmptyRender()).to.equal(false);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-traffic-now-link/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 |
3 | if (process.env.NODE_ENV === 'development') {
4 | module.exports = require('./lib/index.development.js');
5 | } else {
6 | module.exports = require('./lib/index.js');
7 | }
8 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-traffic-now-link/src/helpers/styles.scss:
--------------------------------------------------------------------------------
1 | @import '~@hsl-fi/sass/colors';
2 | @import '~@hsl-fi/sass/mixins/screen';
3 | @import '~@hsl-fi/sass/mixins/text';
4 |
5 | .text {
6 | display: flex;
7 | line-height: 1;
8 | font-size: 18px;
9 | padding-left: 15px;
10 | font-weight: var(--font-weight-medium);
11 | letter-spacing: -0.67px;
12 | color: #333;
13 | margin-left: -1px;
14 |
15 | @include min-width(tablet) {
16 | font-size: 20px;
17 | }
18 | }
19 |
20 | .banner {
21 | font-size: 16px;
22 | cursor: pointer;
23 | display: flex;
24 | margin-top: 0;
25 |
26 | @include min-width(tablet) {
27 | padding: 7px 13px 6px 16px;
28 | }
29 |
30 | padding: 6px 13px 6px 16px;
31 | justify-content: space-between;
32 | }
33 |
34 | .caution {
35 | margin-top: 0;
36 | display: flex;
37 | }
38 |
39 | .container {
40 | margin: 0;
41 | }
42 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-traffic-now-link/src/helpers/translations.js:
--------------------------------------------------------------------------------
1 | const translations = {
2 | de: {
3 | traffic: 'Aktuelle Verbindungen',
4 | },
5 | en: {
6 | traffic: 'Changes and disruptions',
7 | },
8 | pl: {
9 | traffic: 'Zmiany i zakłócenia',
10 | },
11 | sv: {
12 | traffic: 'Störningar och ändringar',
13 | },
14 | fi: {
15 | traffic: 'Häiriöt ja muutokset',
16 | },
17 | };
18 | export default translations;
19 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-traffic-now-link/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import TrafficNowLink from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-traffic-now-link module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/packages/digitransit-component-with-breakpoint/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import Adapter from 'enzyme-adapter-react-16';
4 | import { expect } from 'chai';
5 | import { describe, it } from 'mocha';
6 | import { shallow, configure } from 'enzyme';
7 | import WithBreakpoint from './src';
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe('Testing @digitransit-component/digitransit-component-with-breakpoint module', () => {
12 | const wrapper = shallow();
13 |
14 | it('should render', () => {
15 | expect(wrapper.isEmptyRender()).to.equal(false);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/digitransit-component/scripts/installation.md:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | ---
7 |
8 | This module is part of the Digitransit-ui project. It is maintained in the
9 | [HSLdevcom/digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) repository, where you can create
10 | PRs and issues.
11 |
12 | ### Installation
13 |
14 | Install this module individually:
15 |
16 | ```sh
17 | $ npm install {module}
18 | ```
19 |
20 | Or install the digitransit-component module that includes it as a class:
21 |
22 | ```sh
23 | $ npm install @digitransit-component/digitransit-component
24 | ```
25 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-distance/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-distance",
3 | "version": "0.0.8",
4 | "description": "digitransit-search-util distance module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-util",
19 | "distance"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)"
23 | }
24 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-distance/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | import distance from '.';
5 |
6 | describe('Testing @digitransit-util/digitransit-util-distance module', () => {
7 | it('Checking that distance is calculated', () => {
8 | const latlon1 = {
9 | lat: 3,
10 | lon: 2,
11 | };
12 | const latlon2 = {
13 | lat: 4,
14 | lon: 1,
15 | };
16 |
17 | const retValue = distance(latlon1, latlon2);
18 | expect(157105.77709637067).to.be.equal(retValue);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-execute-search-immidiate/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | // import executeSearchImmidiate from '.';
5 |
6 | describe('Testing @digitransit-search-util/digitransit-search-util-execute-search-immidiate module', () => {
7 | it('Checking that true is true', () => {
8 | // const retValue = executeSearchImmidiate(param1, param2);
9 | expect(true).to.be.equal(true);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-filter-matching-to-input/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-filter-matching-to-input",
3 | "version": "0.0.3",
4 | "description": "digitransit-search-util filter-matching-to-input module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "filter-matching-to-input"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "lodash": "4.17.21"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-geocoding-results/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-get-geocoding-results",
3 | "version": "0.0.8",
4 | "description": "digitransit-search-util get-geocoding-results module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "get-geocoding-results"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "@digitransit-search-util/digitransit-search-util-get-json": "0.0.7"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-geocoding-results/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | // import getGeocodingResults from '.';
5 |
6 | describe('Testing @digitransit-search-util/digitransit-search-util-get-geocoding-results module', () => {
7 | it('Checking that true is true', () => {
8 | // TODO: const retValue = getGeocodingResults(param1, param2);
9 | expect(true).to.be.equal(true);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-json/index.js:
--------------------------------------------------------------------------------
1 | import serialize from '@digitransit-search-util/digitransit-search-util-serialize';
2 | /**
3 | * Return Promise for a url json get request
4 | *
5 | * @name getJson
6 | * @param {String} url
7 | * @param {Array} params
8 | * @returns {Object} response
9 | * @example
10 | * digitransit-search-util.getJson(param1, param2);
11 | * //=response
12 | */
13 | const axios = require('axios').default;
14 |
15 | export default function getJson(url, params) {
16 | return axios
17 | .get(
18 | encodeURI(url) +
19 | (params
20 | ? (url.search(/\?/) === -1 ? '?' : '&') + serialize(params)
21 | : ''),
22 | {
23 | timeout: 10000,
24 | method: 'GET',
25 |
26 | headers: {
27 | Accept: 'application/json',
28 | },
29 | },
30 | )
31 | .then(res => {
32 | return res.data;
33 | });
34 | }
35 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-json/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-get-json",
3 | "version": "0.0.7",
4 | "description": "digitransit-search-util get-json module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "get-json"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "@digitransit-search-util/digitransit-search-util-serialize": "0.0.2",
25 | "axios": "1.9.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-json/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | import getJson from '.';
5 |
6 | describe('Testing @digitransit-search-util/digitransit-search-util-get-json module', () => {
7 | it('Checking that null returns empty ', () => {
8 | const retValue = getJson(null, null);
9 | const test = retValue === {};
10 | expect(test).to.be.equal(false);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-label/index.js:
--------------------------------------------------------------------------------
1 | import { getNameLabel } from '@digitransit-search-util/digitransit-search-util-uniq-by-label';
2 | /**
3 | * Returns label for properties
4 | *
5 | * @name getLabel
6 | * @param {*} properties object
7 | * @returns {Boolean} true/false
8 | */
9 | export default function getLabel(properties) {
10 | const parts = getNameLabel(properties, true);
11 | switch (properties.layer) {
12 | case 'selectFromMap':
13 | case 'currentPosition':
14 | case 'ownLocations':
15 | case 'back':
16 | return parts[1] || parts[0];
17 | case 'favouriteVehicleRentalStation':
18 | case 'favouritePlace':
19 | return parts[0];
20 | default:
21 | return parts.length > 1 && parts[1] !== ''
22 | ? parts.join(', ')
23 | : parts[1] || parts[0];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-label/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-get-label",
3 | "version": "1.0.1",
4 | "description": "digitransit-search-util get-label module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "get-label"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "@digitransit-search-util/digitransit-search-util-uniq-by-label": "^2.1.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-get-label/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | // eslint-disable-next-line no-unused-vars
5 | import getLabel from '.';
6 |
7 | describe('Testing @digitransit-search-util/digitransit-search-util-get-label module', () => {
8 | it('Checking that true is true', () => {
9 | // const retValue = getLabel(param1, param2);
10 | expect(true).to.be.equal(true);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-helpers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-helpers",
3 | "version": "2.0.1",
4 | "description": "digitransit-search-util helpers module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "helpers"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "@digitransit-search-util/digitransit-search-util-is-duplicate": "2.1.0",
25 | "lodash": "4.17.21"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-helpers/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | import { sortSearchResults } from './index';
5 |
6 | describe('Testing @digitransit-search-util/digitransit-search-util-helpers module', () => {
7 | it('Checking that sortSearchresults verifies array', () => {
8 | const retValue = sortSearchResults(null, null);
9 | expect(retValue).to.be.equal(null);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-is-duplicate/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-is-duplicate",
3 | "version": "2.1.0",
4 | "description": "digitransit-search-util is-duplicate module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-util",
19 | "is-duplicate"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "@digitransit-search-util/digitransit-search-util-tru-eq": "0.0.2"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-query-utils/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | /* eslint-disable import/no-extraneous-dependencies */
3 | import { expect } from 'chai';
4 | import { describe, it } from 'mocha';
5 | // import searchQueryUtils from '.';
6 |
7 | // describe('Testing @digitransit-search-util/digitransit-search-util-query-utils module', () => {
8 | // it('Checking that true is true', () => {
9 | // //const retValue = searchQueryUtils(param1, param2);
10 | // expect(true).to.be.equal(true);
11 | // });
12 | // });
13 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-route-name-compare/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-route-name-compare",
3 | "version": "0.0.2",
4 | "description": "digitransit-search-util route-name-compare module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "route-name-compare"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)"
23 | }
24 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-serialize/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Serializes objects
3 | *
4 | * @name serialize
5 | * @param {Object} obj Object to be serialized
6 | * @param {Any} prefix
7 | * @returns {String} Serialized object
8 | * @example
9 | * digitransit-search-util.serialize(param1, param2);
10 | * //=true
11 | */
12 | export default function serialize(obj, prefix) {
13 | if (!obj) {
14 | return '';
15 | }
16 | return Object.keys(obj)
17 | .map(p => {
18 | const k = prefix || p;
19 | const v = obj[p];
20 |
21 | return typeof v === 'object'
22 | ? serialize(v, k)
23 | : `${encodeURIComponent(k)}=${encodeURIComponent(v)}`;
24 | })
25 | .join('&');
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-serialize/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-serialize",
3 | "version": "0.0.2",
4 | "description": "digitransit-search-util serialize module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "serialize"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)"
23 | }
24 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-serialize/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | import serialize from '.';
5 |
6 | describe('Testing @digitransit-search-util/digitransit-search-util-serialize module', () => {
7 | it('Checking that null returns empty', () => {
8 | const retValue = serialize(null, 'hello');
9 | expect('').to.be.equal(retValue);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-suggestion-to-location/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-suggestion-to-location",
3 | "version": "1.0.1",
4 | "description": "digitransit-search-util suggestion-to-location module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "suggestion-to-location"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "@digitransit-search-util/digitransit-search-util-get-label": "1.0.1"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-suggestion-to-location/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 | // eslint-disable-next-line no-unused-vars
5 | import suggestionToLocation from '.';
6 |
7 | describe('Testing @digitransit-search-util/digitransit-search-util-suggestion-to-location module', () => {
8 | it('Checking that true is true', () => {
9 | // const retValue = suggestionToLocation(param1, param2);
10 | expect(true).to.be.equal(true);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-tru-eq/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * accept equality of non nullish values
3 | *
4 | * @name truEq
5 | * @param {Boolean|Number|BigInt|String|Symbol|Object} val1 First value to be compared
6 | * @param {Boolean|Number|BigInt|String|Symbol|Object} param2 Second value to be compared
7 | * @returns {Boolean} true/false
8 | * @example
9 | * digitransit-util.truEq('2', '2');
10 | * //=true
11 | */
12 | export default function truEq(val1, val2) {
13 | return val1 && val2 && val1 === val2;
14 | }
15 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-tru-eq/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-tru-eq",
3 | "version": "0.0.2",
4 | "description": "digitransit-search-util tru-eq module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-util",
19 | "tru-eq"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)"
23 | }
24 |
--------------------------------------------------------------------------------
/digitransit-search-util/packages/digitransit-search-util-uniq-by-label/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-search-util/digitransit-search-util-uniq-by-label",
3 | "version": "2.1.0",
4 | "description": "digitransit-search-util uniq-by-label module",
5 | "main": "index.js",
6 | "publishConfig": {
7 | "access": "public"
8 | },
9 | "scripts": {
10 | "test": "mocha -r esm test.js",
11 | "docs": "node -r esm ../../scripts/generate-readmes"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
16 | },
17 | "keywords": [
18 | "digitransit-search-util",
19 | "uniq-by-label"
20 | ],
21 | "author": "Digitransit Authors",
22 | "license": "(AGPL-3.0 OR EUPL-1.2)",
23 | "dependencies": {
24 | "lodash": "4.17.21",
25 | "lodash-es": "4.17.21"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/digitransit-search-util/scripts/installation.md:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | ---
7 |
8 | This module is part of the Digitransit-ui project. It is maintained in the
9 | [HSLdevcom/digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) repository, where you can create
10 | PRs and issues.
11 |
12 | ### Installation
13 |
14 | Install this module individually:
15 |
16 | ```sh
17 | $ npm install {module}
18 | ```
19 |
20 | Or install the digitransit-search-util module that includes it as a function:
21 |
22 | ```sh
23 | $ npm install @digitransit-search-util/digitransit-search-util
24 | ```
25 |
--------------------------------------------------------------------------------
/digitransit-store/packages/digitransit-store-common-functions/mock-localstorage.js:
--------------------------------------------------------------------------------
1 | import 'mock-local-storage';
2 |
3 | global.window = {};
4 | window.localStorage = global.localStorage;
5 |
--------------------------------------------------------------------------------
/digitransit-store/packages/digitransit-store-future-route/mock-localstorage.js:
--------------------------------------------------------------------------------
1 | import 'mock-local-storage';
2 |
3 | global.window = {};
4 | window.localStorage = global.localStorage;
5 |
--------------------------------------------------------------------------------
/digitransit-store/scripts/installation.md:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | ---
7 |
8 | This module is part of the Digitransit-ui project. It is maintained in the
9 | [HSLdevcom/digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) repository, where you can create
10 | PRs and issues.
11 |
12 | ### Installation
13 |
14 | Install this module individually:
15 |
16 | ```sh
17 | $ npm install {module}
18 | ```
19 |
20 | Or install the Digitransit-store module that includes it as a function:
21 |
22 | ```sh
23 | $ npm install @digitransit-store/digitransit-store
24 | ```
25 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-day-range-allowed-diff/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | # 1.1.0 (2020-03-06)
6 |
7 |
8 | ### Bug Fixes
9 |
10 | * setting initial version 0.0.1 ([8a3d681](https://github.com/HSLdevcom/digitransit-ui/commit/8a3d681c894950dbac949fbb71dd4ff583a05554))
11 | * typo, added repository and lerna commands ([045d08e](https://github.com/HSLdevcom/digitransit-ui/commit/045d08eeae734da913a81052eee7ebaab4994fbc))
12 | * version numbers and length of undefenined ([f650d5e](https://github.com/HSLdevcom/digitransit-ui/commit/f650d5e23084622c1042fec9736d24c5c02a9758))
13 |
14 |
15 | ### Features
16 |
17 | * initial version ([c57ff7c](https://github.com/HSLdevcom/digitransit-ui/commit/c57ff7c469e9618881e281167b06e28f081ed830))
18 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-day-range-allowed-diff/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-util/digitransit-util-day-range-allowed-diff",
3 | "version": "1.0.4",
4 | "description": "digitransit-util digitransit-util-day-range-allowed-diff module",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "mocha -r esm test.js",
8 | "docs": "node -r esm ../../scripts/generate-readmes"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
13 | },
14 | "keywords": [
15 | "digitransit-util",
16 | "dayRangeAllowedDiff"
17 | ],
18 | "author": "Digitransit Authors",
19 | "license": "(AGPL-3.0 OR EUPL-1.2)"
20 | }
21 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-day-range-pattern/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | # 1.1.0 (2020-03-06)
6 |
7 |
8 | ### Bug Fixes
9 |
10 | * setting initial version 0.0.1 ([8a3d681](https://github.com/HSLdevcom/digitransit-ui/commit/8a3d681c894950dbac949fbb71dd4ff583a05554))
11 | * typo and create-new-module ([ac64af7](https://github.com/HSLdevcom/digitransit-ui/commit/ac64af76d20f99e77aad58c797098c57678b00ea))
12 | * typo, added repository and lerna commands ([045d08e](https://github.com/HSLdevcom/digitransit-ui/commit/045d08eeae734da913a81052eee7ebaab4994fbc))
13 | * version numbers and length of undefenined ([f650d5e](https://github.com/HSLdevcom/digitransit-ui/commit/f650d5e23084622c1042fec9736d24c5c02a9758))
14 |
15 |
16 | ### Features
17 |
18 | * initial version ([c57ff7c](https://github.com/HSLdevcom/digitransit-ui/commit/c57ff7c469e9618881e281167b06e28f081ed830))
19 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-day-range-pattern/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-util/digitransit-util-day-range-pattern",
3 | "version": "1.1.0",
4 | "description": "digitransit-util digitransit-util-day-range-pattern module",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "mocha -r esm test.js",
8 | "docs": "node -r esm ../../scripts/generate-readmes"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
13 | },
14 | "keywords": [
15 | "digitransit-util",
16 | "dayRangePattern"
17 | ],
18 | "author": "Digitransit Authors",
19 | "license": "(AGPL-3.0 OR EUPL-1.2)"
20 | }
21 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-enrich-patterns/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | # 1.1.0 (2020-03-06)
6 |
7 |
8 | ### Bug Fixes
9 |
10 | * setting initial version 0.0.1 ([8a3d681](https://github.com/HSLdevcom/digitransit-ui/commit/8a3d681c894950dbac949fbb71dd4ff583a05554))
11 | * typo, added repository and lerna commands ([045d08e](https://github.com/HSLdevcom/digitransit-ui/commit/045d08eeae734da913a81052eee7ebaab4994fbc))
12 | * version numbers and length of undefenined ([f650d5e](https://github.com/HSLdevcom/digitransit-ui/commit/f650d5e23084622c1042fec9736d24c5c02a9758))
13 |
14 |
15 | ### Features
16 |
17 | * initial version ([c57ff7c](https://github.com/HSLdevcom/digitransit-ui/commit/c57ff7c469e9618881e281167b06e28f081ed830))
18 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-enrich-patterns/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-util/digitransit-util-enrich-patterns",
3 | "version": "1.1.3",
4 | "description": "digitransit-util enrich-patterns module",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "mocha -r esm test.js",
8 | "docs": "node -r esm ../../scripts/generate-readmes"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
13 | },
14 | "keywords": [
15 | "digitransit-util",
16 | "enrichPatterns"
17 | ],
18 | "author": "Digitransit Authors",
19 | "license": "(AGPL-3.0 OR EUPL-1.2)",
20 | "dependencies": {
21 | "@digitransit-util/digitransit-util-day-range-allowed-diff": "^1.0.4",
22 | "@digitransit-util/digitransit-util-day-range-pattern": "^1.1.0"
23 | },
24 | "peerDependencies": {
25 | "lodash": "4.17.21",
26 | "lodash-es": "4.17.21"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util-route-pattern-option-text/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-util/digitransit-util-route-pattern-option-text",
3 | "version": "1.1.3",
4 | "description": "digitransit-util route-pattern-option-text module",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "mocha -r esm test.js",
8 | "docs": "node -r esm ../../scripts/generate-readmes"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/HSLdevcom/digitransit-ui.git"
13 | },
14 | "keywords": [
15 | "digitransit-util",
16 | "routePatternOptionText"
17 | ],
18 | "author": "Digitransit Authors",
19 | "license": "(AGPL-3.0 OR EUPL-1.2)",
20 | "peerDependencies": {
21 | "i18next": "^19.2.0",
22 | "i18next-xhr-backend": "^3.2.2",
23 | "lodash": "4.17.21",
24 | "lodash-es": "4.17.21"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | # 1.1.0 (2020-03-06)
6 |
7 |
8 | ### Bug Fixes
9 |
10 | * missing .name from stop[x] ([47e76bf](https://github.com/HSLdevcom/digitransit-ui/commit/47e76bf87381ef4704518601d396b85abc355c3c))
11 | * setting initial version 0.0.1 ([8a3d681](https://github.com/HSLdevcom/digitransit-ui/commit/8a3d681c894950dbac949fbb71dd4ff583a05554))
12 | * typo, added repository and lerna commands ([045d08e](https://github.com/HSLdevcom/digitransit-ui/commit/045d08eeae734da913a81052eee7ebaab4994fbc))
13 | * version numbers and length of undefenined ([f650d5e](https://github.com/HSLdevcom/digitransit-ui/commit/f650d5e23084622c1042fec9736d24c5c02a9758))
14 |
15 |
16 | ### Features
17 |
18 | * initial version ([c57ff7c](https://github.com/HSLdevcom/digitransit-ui/commit/c57ff7c469e9618881e281167b06e28f081ed830))
19 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util/index.mjs:
--------------------------------------------------------------------------------
1 | /**
2 | * Digitransit-util is a util library for digitransit-ui written in JavaScript.
3 | *
4 | * @module digitransit-util
5 | * @summary Util library for Digitransit-ui
6 | */
7 | export { default as dayRangeAllowedDiff } from '@digitransit-util/digitransit-util-day-range-allowed-diff';
8 | export { default as dayRangePattern } from '@digitransit-util/digitransit-util-day-range-pattern';
9 | export { default as enrichPatterns } from '@digitransit-util/digitransit-util-enrich-patterns';
10 | export { default as routePatternOptionText } from '@digitransit-util/digitransit-util-route-pattern-option-text';
11 |
--------------------------------------------------------------------------------
/digitransit-util/packages/digitransit-util/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@digitransit-util/digitransit-util",
3 | "version": "1.0.6",
4 | "description": "a JavaScript library for Digitransit",
5 | "main": "digitransit-util",
6 | "module": "digitransit-util.mjs",
7 | "keywords": [
8 | "digitransit-util"
9 | ],
10 | "author": "Digitransit Authors",
11 | "license": "(AGPL-3.0 OR EUPL-1.2)",
12 | "scripts": {
13 | "test": "mocha -r esm test.js",
14 | "docs": "node -r esm ../../scripts/generate-readmes"
15 | },
16 | "dependencies": {
17 | "@digitransit-util/digitransit-util-day-range-allowed-diff": "^1.0.4",
18 | "@digitransit-util/digitransit-util-day-range-pattern": "^1.1.0",
19 | "@digitransit-util/digitransit-util-enrich-patterns": "^1.1.3",
20 | "@digitransit-util/digitransit-util-route-pattern-option-text": "^1.1.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/digitransit-util/scripts/installation.md:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | ---
7 |
8 | This module is part of the Digitransit-ui project. It is maintained in the
9 | [HSLdevcom/digitransit-ui](https://github.com/HSLdevcom/digitransit-ui) repository, where you can create
10 | PRs and issues.
11 |
12 | ### Installation
13 |
14 | Install this module individually:
15 |
16 | ```sh
17 | $ npm install {module}
18 | ```
19 |
20 | Or install the Digitransit-util module that includes it as a function:
21 |
22 | ```sh
23 | $ npm install @digitransit-util/digitransit-util
24 | ```
25 |
--------------------------------------------------------------------------------
/docs/GraphQL.md:
--------------------------------------------------------------------------------
1 | - If the data schema available from the OTP backend changes
2 | (for example if new query types are added),
3 | you need to regenerate the schema (schema.graphql) by running
4 | `cd build; node generate-schema.js`
5 |
6 | If you need to fetch the schema from some non-default location, `SCHEMA_SRC` changes
7 | the URL or filepath for the schema file in graphls format:
8 |
9 | `cd build; SCHEMA_SRC=where-schema-file-is-located node generate-schema.js`
10 |
11 | When copying from a local OTP clone, usually something like this works:
12 |
13 | `cd build; SCHEMA_SRC=~/OpenTripPlanner/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls node generate-schema.js`
14 |
--------------------------------------------------------------------------------
/docs/Location.md:
--------------------------------------------------------------------------------
1 | Location has two functions. Firstly, it marks routing start and stop location and possibly a routing via point. Secondly, from location can be used for nearby stop search.
2 |
3 | 
4 |
5 | |State|Description|
6 | |--------|-------|
7 | |**No location**|We have no location information set|
8 | |**From Location set**|User's from location is set|
9 | |**To Location set**|User's to location is set|
10 | |**Route set**|Both from and to locations are set|
11 | |**Route via point set**|Both from and to locations are set and also a route via point|
12 |
--------------------------------------------------------------------------------
/docs/Terms.md:
--------------------------------------------------------------------------------
1 | |Term|Explanation|
2 | |--------|-------|
3 | |**Position**|User's position received through HTML5 geolocation interface|
4 | |**Location**|User's given value for position. Used for finding services near to defined location, e.g. nearest stops or routing. "route start location"|
5 |
6 |
--------------------------------------------------------------------------------
/docs/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/docs/images/architecture.png
--------------------------------------------------------------------------------
/docs/images/hierarchy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/docs/images/hierarchy.png
--------------------------------------------------------------------------------
/docs/images/location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/docs/images/location.png
--------------------------------------------------------------------------------
/docs/images/position.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/docs/images/position.png
--------------------------------------------------------------------------------
/docs/images/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/docs/images/up.png
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | "digitransit-util/packages/*",
4 | "digitransit-search-util/packages/*",
5 | "digitransit-component/packages/*",
6 | "digitransit-store/packages/*"
7 | ],
8 | "version": "independent",
9 | "npmClient": "yarn",
10 | "useWorkspaces": true,
11 | "command": {
12 | "publish": {
13 | "conventionalCommits": false
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | plugins:
3 | env === 'production' ? ['postcss-flexbugs-fixes', 'autoprefixer'] : [],
4 | });
5 |
--------------------------------------------------------------------------------
/sass/base/_button.scss:
--------------------------------------------------------------------------------
1 | button {
2 | border: 0;
3 | margin: 0;
4 | padding: 0;
5 | font-size: 100%;
6 | background: none;
7 | border-style: none;
8 | border-width: 0;
9 | cursor: pointer;
10 | font-family: $button-font-family;
11 | position: relative;
12 | background-color: transparent;
13 | transition: none;
14 | display: inline-block;
15 | text-decoration: none;
16 | font-weight: inherit;
17 | appearance: none;
18 | color: inherit;
19 |
20 | &:focus {
21 | background-color: transparent;
22 | color: inherit;
23 | }
24 |
25 | &:active {
26 | background-color: transparent;
27 | color: inherit;
28 | }
29 |
30 | &:hover {
31 | background-color: transparent;
32 | color: inherit;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/sass/base/_helper-mixins.scss:
--------------------------------------------------------------------------------
1 | /* Using these avoids making mistakes when some font settings are inherited
2 | from a parent using different font-family. */
3 |
4 | @mixin font-book {
5 | font-family: $font-family;
6 | font-weight: $font-weight-book;
7 | letter-spacing: $letter-spacing;
8 | }
9 |
10 | @mixin font-medium {
11 | font-family: $font-family;
12 | font-weight: $font-weight-medium;
13 | letter-spacing: $letter-spacing;
14 | }
15 |
16 | @mixin font-map-container {
17 | font-family: $font-family;
18 | font-weight: $font-weight-map-container;
19 | letter-spacing: $letter-spacing;
20 | }
21 |
22 | @mixin font-narrow-book {
23 | font-family: $font-family-narrow;
24 | font-weight: $font-narrow-weight-book;
25 | letter-spacing: $narrow-letter-spacing;
26 | }
27 |
28 | @mixin font-narrow-medium {
29 | font-family: $font-family-narrow;
30 | font-weight: $font-narrow-weight-medium;
31 | letter-spacing: $narrow-letter-spacing;
32 | }
33 |
--------------------------------------------------------------------------------
/sass/base/_radius.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | --radius-s: 4px;
3 | --radius-m: 8px;
4 | --radius-l: 16px;
5 | --radius-xl: 24px;
6 | --radius-pill: 999px;
7 | }
8 |
--------------------------------------------------------------------------------
/sass/base/_waltti.scss:
--------------------------------------------------------------------------------
1 | /* waltti 'virtual' base theme */
2 |
3 | @import '../themes/default/theme';
4 |
5 | /* Component palette */
6 | $standalone-btn-hover-color: $gray;
7 | $standalone-btn-active-color: $gray;
8 |
--------------------------------------------------------------------------------
/sass/base/_zindex.scss:
--------------------------------------------------------------------------------
1 | $zindex: base, map-container, map-gradient, map-fullscreen-toggle, map-buttons,
2 | mobile-drawer, mobile-drawer-drag-line, context-panel, search-panel,
3 | search-overlay, stop-route-station-input, destination-input, viapoint-input-5,
4 | viapoint-input-4, viapoint-input-3, viapoint-input-2, viapoint-input-1,
5 | origin-input, search-input-focus, search-input-icon,
6 | autosuggest-suggestion-container, before-scrollable-area,
7 | click-prevent-overlay, front;
8 | $leaflet-overlay: 800;
9 |
--------------------------------------------------------------------------------
/sass/themes/default/default-spinner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/sass/themes/default/default-spinner.png
--------------------------------------------------------------------------------
/sass/themes/default/main.scss:
--------------------------------------------------------------------------------
1 | /* Theme */
2 | @import 'theme';
3 | @import '../../main';
4 |
--------------------------------------------------------------------------------
/sass/themes/hameenlinna/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: rgb(196, 40, 31);
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 |
13 | /* Component palette */
14 | $desktop-title-color: $primary-color;
15 | $desktop-title-arrow-icon-color: $secondary-color;
16 | $link-color: $primary-color;
17 | $top-bar-color: rgb(236, 236, 236);
18 |
19 | /* Navbar dimensions */
20 | $nav-logo-height: 3em;
21 |
--------------------------------------------------------------------------------
/sass/themes/hameenlinna/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/hsl/hsl-spinner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/sass/themes/hsl/hsl-spinner.png
--------------------------------------------------------------------------------
/sass/themes/hsl/main.scss:
--------------------------------------------------------------------------------
1 | /* Theme */
2 | @import 'theme';
3 | @import '../../main';
4 |
--------------------------------------------------------------------------------
/sass/themes/joensuu/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/jyvaskyla/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #7dc02d;
5 | $secondary-color: #489227;
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $secondary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $primary-color;
18 |
--------------------------------------------------------------------------------
/sass/themes/jyvaskyla/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/kela/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #003580;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: rgb(253, 185, 19);
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: #003580;
18 |
--------------------------------------------------------------------------------
/sass/themes/kela/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/kotka/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #0001ff;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: rgb(130, 189, 83);
18 |
--------------------------------------------------------------------------------
/sass/themes/kotka/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/kouvola/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #000;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $primary-color;
18 |
--------------------------------------------------------------------------------
/sass/themes/kouvola/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/kuopio/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #0ab1c8;
5 | $secondary-color: #724f9f;
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $secondary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $secondary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 | $rail-color: #0e7f3c;
14 |
15 | /* Component palette */
16 | $desktop-title-color: $primary-color;
17 | $desktop-title-arrow-icon-color: $secondary-color;
18 | $top-bar-color: $primary-color;
19 |
--------------------------------------------------------------------------------
/sass/themes/kuopio/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/lahti/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #0066b3;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $primary-color;
18 |
--------------------------------------------------------------------------------
/sass/themes/lahti/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/lappeenranta/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #d4007a;
5 | $secondary-color: #3c974c;
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $standalone-btn-hover-color: $secondary-color;
13 | $standalone-btn-active-color: $secondary-color;
14 | $link-color: $primary-color;
15 |
16 | /* Component palette */
17 | $desktop-title-color: $primary-color;
18 | $desktop-title-arrow-icon-color: $secondary-color;
19 | $top-bar-color: $primary-color;
20 |
21 | /* Navbar dimensions */
22 | $nav-logo-height: 4.5em;
23 |
--------------------------------------------------------------------------------
/sass/themes/lappeenranta/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/matka/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/mikkeli/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #167cac;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $primary-color;
18 | $nav-content-color: #fff;
19 |
--------------------------------------------------------------------------------
/sass/themes/mikkeli/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/oulu/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $ouluColor: #e10669;
5 | $primary-color: $ouluColor;
6 | $secondary-color: darken($primary-color, 20%);
7 | $hilight-color: $ouluColor;
8 | $action-color: $ouluColor;
9 | $bus-color: $ouluColor;
10 | $viewpoint-marker-color: $ouluColor;
11 | $current-location-color: $primary-color;
12 | $standalone-btn-color: $primary-color;
13 | $link-color: $primary-color;
14 | $banner-disruption-color: rgb(24, 59, 224);
15 |
16 | /* Component palette */
17 | $desktop-title-color: $primary-color;
18 | $desktop-title-arrow-icon-color: $secondary-color;
19 | $top-bar-color: $primary-color;
20 |
--------------------------------------------------------------------------------
/sass/themes/oulu/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/pori/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $poriColor: #1f1f66;
5 | $primary-color: $poriColor;
6 | $secondary-color: darken($primary-color, 20%);
7 | $hilight-color: $poriColor;
8 | $action-color: $poriColor;
9 | $bus-color: $poriColor;
10 | $viewpoint-marker-color: $poriColor;
11 | $current-location-color: $primary-color;
12 | $standalone-btn-color: $primary-color;
13 | $link-color: $primary-color;
14 |
15 | /* Component palette */
16 | $desktop-title-color: $primary-color;
17 | $desktop-title-arrow-icon-color: $secondary-color;
18 | $top-bar-color: $primary-color;
19 |
--------------------------------------------------------------------------------
/sass/themes/pori/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/raasepori/_theme.scss:
--------------------------------------------------------------------------------
1 | /* Raasepori theme */
2 |
3 | /* Base theme */
4 | @import '../../base/waltti';
5 |
6 | /* Operator palette */
7 | $raasepori-green: #5b7b32;
8 |
9 | /* Application palette */
10 | $primary-color: $raasepori-green;
11 | $favourite-color: $raasepori-green;
12 | $current-location-color: $primary-color;
13 |
14 | /* Component palette */
15 | $viewpoint-marker-color: $raasepori-green;
16 | $link-color: $primary-color;
17 | $desktop-title-color: $primary-color;
18 | $top-bar-color: $primary-color;
19 | $top-navigation-icon-color: white;
20 |
21 | /* Vehicle palette */
22 | $bus-color: $raasepori-green;
23 |
24 | /* Navbar dimensions */
25 | $nav-logo-height: 3em;
26 |
--------------------------------------------------------------------------------
/sass/themes/raasepori/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/rovaniemi/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #34b233;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $primary-color;
18 |
--------------------------------------------------------------------------------
/sass/themes/rovaniemi/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/tampere/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #1c57cf;
5 | $secondary-color: darken($primary-color, 20%);
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: #1a4a8f;
9 | $tram-color: #da2128;
10 | $rail-color: #0e7f3c;
11 | $viewpoint-marker-color: $primary-color;
12 | $current-location-color: $primary-color;
13 | $selected-lang-background: #1a4a8f;
14 |
15 | /* Component palette */
16 |
17 | $standalone-btn-color: $primary-color;
18 | $link-color: $primary-color;
19 | $desktop-title-color: #40ba54;
20 | $desktop-title-arrow-icon-color: $white;
21 | $caution-icon-color: #ec5e47;
22 | $caution-icon-font-color: $white;
23 | $top-bar-color: $primary-color;
24 |
25 | /* Navbar dimensions */
26 | $nav-logo-height: 2.5em;
27 |
--------------------------------------------------------------------------------
/sass/themes/tampere/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/turku/foli-spinner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/sass/themes/turku/foli-spinner.png
--------------------------------------------------------------------------------
/sass/themes/turku/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/vaasa/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #000a8c;
5 | $secondary-color: #0096aa;
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $primary-color;
18 |
--------------------------------------------------------------------------------
/sass/themes/vaasa/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/varely/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #008161;
5 | $secondary-color: #00bf6f;
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $white;
17 | $link-color: $primary-color;
18 | $top-bar-color: #008061;
19 |
--------------------------------------------------------------------------------
/sass/themes/varely/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/sass/themes/walttiOpas/_theme.scss:
--------------------------------------------------------------------------------
1 | @import '../../base/waltti';
2 |
3 | /* main theme colors */
4 | $primary-color: #5959a8;
5 | $secondary-color: #17083b;
6 | $hilight-color: $primary-color;
7 | $action-color: $primary-color;
8 | $bus-color: $primary-color;
9 | $viewpoint-marker-color: $primary-color;
10 | $current-location-color: $primary-color;
11 | $standalone-btn-color: $primary-color;
12 | $link-color: $primary-color;
13 |
14 | /* Component palette */
15 | $desktop-title-color: $primary-color;
16 | $desktop-title-arrow-icon-color: $secondary-color;
17 | $top-bar-color: $secondary-color;
18 |
--------------------------------------------------------------------------------
/sass/themes/walttiOpas/main.scss:
--------------------------------------------------------------------------------
1 | @import 'theme';
2 | @import '../../main';
3 |
--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------
1 | # Using scripts
2 |
3 | See the `themeMap` in `app/configurations/config.default.js` for configuration options.
4 |
5 | ## Before using
6 | ```
7 | source ui.sh
8 | ```
9 | ## Usage examples
10 |
11 | Using remote instance of OTP with subscription key:
12 | ```
13 | SUBSCRIPTION_KEY= ui hsl
14 | ```
15 | Using local instance of OTP on port `9080`:
16 | ```
17 | SUBSCRIPTION_KEY= uiotp matka
18 | ```
19 | In case you do not need features usable with a subscription key when running a local instance of OTP on port `9080`:
20 | ```
21 | NO_SUBSCRIPTION_KEY=true uiotp matka
22 | ```
23 |
--------------------------------------------------------------------------------
/scripts/ui.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # See the themeMap in app/configurations/config.default.js for configuration options.
4 |
5 | ui () {
6 | if [ "$SUBSCRIPTION_KEY" = "" -a "$NO_SUBSCRIPTION_KEY" != "true" ]; then
7 | echo "In order to use the UI you need to set the SUBSCRIPTION_KEY environment variable."
8 | echo "If you want to run the UI without a subscription key, set NO_SUBSCRIPTION_KEY=true."
9 | return 1 2>/dev/null
10 | fi
11 | CONFIG=$1 API_SUBSCRIPTION_QUERY_PARAMETER_NAME=digitransit-subscription-key API_SUBSCRIPTION_HEADER_NAME=digitransit-subscription-key API_SUBSCRIPTION_TOKEN=$SUBSCRIPTION_KEY yarn run dev
12 | }
13 |
14 | uiotp () {
15 | OTP_URL=http://localhost:9080/otp/ ui $1
16 | }
17 |
--------------------------------------------------------------------------------
/server/passport-openid-connect/User.js:
--------------------------------------------------------------------------------
1 | class User {
2 | constructor(data) {
3 | this.data = data;
4 | }
5 |
6 | serialize() {
7 | const x = {
8 | data: this.data,
9 | };
10 | if (this.token) {
11 | x.token = this.token;
12 | }
13 | if (this.idtoken) {
14 | x.idtoken = this.idtoken;
15 | }
16 | return x;
17 | }
18 |
19 | static unserialize(obj) {
20 | const u = new User(obj.data);
21 | if (obj.token) {
22 | u.token = obj.token;
23 | }
24 | if (obj.idtoken) {
25 | u.idtoken = obj.idtoken;
26 | }
27 | return u;
28 | }
29 | }
30 |
31 | exports.User = User;
32 |
--------------------------------------------------------------------------------
/server/proxyTester.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | const express = require('express');
3 | const proxy = require('express-http-proxy');
4 |
5 | const app = express();
6 |
7 | const port = 9000;
8 |
9 | app.use('/proxy', proxy('http://localhost:8080/'));
10 |
11 | const server = app.listen(port, () =>
12 | console.log('Digitransit-ui available on port %d', server.address().port),
13 | );
14 |
15 | /*
16 | This file enables toy to test CDN functionality locally by starting with
17 | node server/proxyTester.js && \
18 | ASSET_URL="http://localhost:9000/proxy" yarn run start
19 | */
20 |
--------------------------------------------------------------------------------
/server/swInjection.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef, no-restricted-syntax */
2 | __wpo.assets.main = __wpo.assets.main.map(asset =>
3 | __wpo.externals.includes(asset) ? asset : `ASSET_URL${asset}`,
4 | );
5 | __wpo.assets.additional = __wpo.assets.additional.map(asset =>
6 | __wpo.externals.includes(asset) ? asset : `ASSET_URL${asset}`,
7 | );
8 | __wpo.assets.optional = __wpo.assets.optional.map(asset =>
9 | __wpo.externals.includes(asset) ? asset : `ASSET_URL${asset}`,
10 | );
11 | for (const key in __wpo.hashesMap) {
12 | if (!__wpo.externals.includes(__wpo.hashesMap[key])) {
13 | __wpo.hashesMap[key] = `ASSET_URL${__wpo.hashesMap[key]}`;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/static/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/static/favicon.ico
--------------------------------------------------------------------------------
/static/img/default-social-share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/static/img/default-social-share.png
--------------------------------------------------------------------------------
/static/img/hsl-social-share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/static/img/hsl-social-share.png
--------------------------------------------------------------------------------
/static/img/nearby-stop_animation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/static/img/nearby-stop_animation.gif
--------------------------------------------------------------------------------
/static/img/nearby-stop_desktop-animation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/static/img/nearby-stop_desktop-animation.gif
--------------------------------------------------------------------------------
/static/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/front-page-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/front-page-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/itinerary-details-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/itinerary-details-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/itinerary-suggestions-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/itinerary-suggestions-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/route-page-stop-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/route-page-stop-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/hsl/stop-page-departure-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/hsl/stop-page-departure-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/front-page-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/front-page-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/itinerary-details-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/itinerary-details-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/itinerary-suggestions-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/itinerary-suggestions-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/route-page-stop-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/route-page-stop-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/matka/stop-page-departure-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/matka/stop-page-departure-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/front-page-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/front-page-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/itinerary-details-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/itinerary-details-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/itinerary-suggestions-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/itinerary-suggestions-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/route-page-stop-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/route-page-stop-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/chromium/tampere/stop-page-departure-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/chromium/tampere/stop-page-departure-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/hsl/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/hsl/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/hsl/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/hsl/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/hsl/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/hsl/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/hsl/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/hsl/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/hsl/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/hsl/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/matka/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/matka/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/matka/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/matka/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/matka/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/matka/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/matka/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/matka/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/matka/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/matka/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/tampere/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/tampere/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/tampere/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/tampere/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/tampere/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/tampere/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/tampere/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/tampere/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/firefox/tampere/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/firefox/tampere/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/front-page-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/front-page-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/itinerary-details-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/itinerary-details-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/itinerary-suggestions-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/itinerary-suggestions-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/route-page-stop-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/route-page-stop-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/hsl/stop-page-departure-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/hsl/stop-page-departure-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/front-page-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/front-page-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/itinerary-details-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/itinerary-details-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/itinerary-suggestions-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/itinerary-suggestions-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/route-page-stop-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/route-page-stop-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/matka/stop-page-departure-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/matka/stop-page-departure-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/front-page-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/front-page-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/front-page-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/front-page-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/itinerary-details-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/itinerary-details-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/itinerary-details-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/itinerary-details-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/itinerary-suggestions-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/itinerary-suggestions-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/itinerary-suggestions-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/itinerary-suggestions-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/route-page-stop-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/route-page-stop-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/route-page-stop-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/route-page-stop-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/stop-page-departure-list-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/stop-page-departure-list-desktop-snap.png
--------------------------------------------------------------------------------
/test/e2e/__image_snapshots__/webkit/tampere/stop-page-departure-list-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/e2e/__image_snapshots__/webkit/tampere/stop-page-departure-list-mobile-snap.png
--------------------------------------------------------------------------------
/test/e2e/helpers/image-snapshot-config.js:
--------------------------------------------------------------------------------
1 | const getConfig = (
2 | customSnapshotIdentifier,
3 | customSnapshotsDir,
4 | customDiffDir,
5 | ) => {
6 | return {
7 | diffDirection: 'vertical',
8 | dumpDiffToConsole: false,
9 | comparisonMethod: 'pixelmatch',
10 | failureThreshold: process.env.UPDATE_E2E ? 0 : 0.0125,
11 | failureThresholdType: 'percent',
12 | customSnapshotsDir,
13 | customDiffDir,
14 | customSnapshotIdentifier,
15 | };
16 | };
17 |
18 | export default getConfig;
19 |
--------------------------------------------------------------------------------
/test/e2e/jest-playwright-desktop.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | serverOptions: {
3 | command: `CONFIG=${
4 | process.env.CONFIG || 'hsl'
5 | } NODE_OPTS=--max_old_space_size=1000 yarn start-test`,
6 | port: 8080,
7 | protocol: 'http',
8 | launchTimeout: 200000,
9 | debug: true,
10 | usedPortAction: 'ignore',
11 | },
12 | launchOptions: {
13 | headless: !process.env.DEBUG,
14 | },
15 | contextOptions: {
16 | viewport: {
17 | width: 1920,
18 | height: 1080,
19 | },
20 | },
21 | browsers: ['chromium', 'firefox', 'webkit'],
22 | };
23 |
--------------------------------------------------------------------------------
/test/e2e/jest-playwright-mobile.config.js:
--------------------------------------------------------------------------------
1 | const { devices } = require('playwright');
2 |
3 | const iPhone12 = devices['iPhone 12'];
4 |
5 | module.exports = {
6 | serverOptions: {
7 | command: `CONFIG=${
8 | process.env.CONFIG || 'hsl'
9 | } NODE_OPTS=--max_old_space_size=1000 yarn start-test`,
10 | port: 8080,
11 | protocol: 'http',
12 | launchTimeout: 200000,
13 | debug: true,
14 | usedPortAction: 'ignore',
15 | },
16 | launchOptions: {
17 | headless: !process.env.DEBUG,
18 | },
19 | contextOptions: {
20 | viewport: iPhone12.viewport,
21 | },
22 | isMobile: true,
23 | devices: ['iPhone 12'],
24 | browsers: ['chromium'],
25 | };
26 |
--------------------------------------------------------------------------------
/test/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | process.env.JEST_PLAYWRIGHT_CONFIG = `./test/e2e/jest-playwright-${
2 | (process.env.MOBILE === 'true' && 'mobile') || 'desktop'
3 | }.config.js`;
4 |
5 | module.exports = {
6 | verbose: true,
7 | rootDir: '../..',
8 | roots: ['./test/e2e'],
9 | testMatch: ['**/?(*.)+(test).js'],
10 | testPathIgnorePatterns: ['/node_modules/', 'app', 'build', '_static'],
11 | testTimeout: 200000,
12 | preset: 'jest-playwright-preset',
13 | setupFilesAfterEnv: ['./test/e2e/jest.image.js'],
14 | reporters: ['default', './test/e2e/helpers/image-reporter.js'],
15 | };
16 |
--------------------------------------------------------------------------------
/test/e2e/jest.image.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 | import { toMatchImageSnapshot } from 'jest-image-snapshot';
3 |
4 | expect.extend({ toMatchImageSnapshot });
5 |
--------------------------------------------------------------------------------
/test/install.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 |
3 | set -e
4 |
5 | yarn setup
6 | yarn lint
7 | yarn build
8 |
--------------------------------------------------------------------------------
/test/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: '../../.eslintrc.js',
3 | env: {
4 | mocha: true,
5 | },
6 | globals: {
7 | expect: true,
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/test/unit/CanceledLegsBar.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 | import React from 'react';
4 | import { shallowWithIntl } from './helpers/mock-intl-enzyme';
5 | import { mockContext } from './helpers/mock-context';
6 |
7 | import { component as CanceledLegsBar } from '../../app/component/CanceledLegsBar';
8 |
9 | describe('', () => {
10 | it('should render the banner if there are canceled legs', () => {
11 | const props = {
12 | showCanceledLegsBanner: true,
13 | };
14 | const wrapper = shallowWithIntl(, {
15 | context: { ...mockContext },
16 | });
17 | expect(
18 | wrapper.find('.canceled-legs-banner').prop('style'),
19 | ).to.have.property('display', 'block');
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/test/unit/Checkbox.test.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HSLdevcom/digitransit-ui/549ae8c9f3eb9fd26c66a372bc188f749575575f/test/unit/Checkbox.test.js
--------------------------------------------------------------------------------
/test/unit/component/IconWithIcon.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { shallowWithIntl } from '../helpers/mock-intl-enzyme';
4 | import Icon from '../../../app/component/Icon';
5 | import IconWithIcon from '../../../app/component/IconWithIcon';
6 |
7 | describe('', () => {
8 | it('should apply the given sub icon shape', () => {
9 | const props = {
10 | img: 'img',
11 | subIcon: 'sub-img',
12 | subIconShape: 'circle',
13 | };
14 | const wrapper = shallowWithIntl();
15 | expect(wrapper.find(Icon).at(1).prop('backgroundShape')).to.equal('circle');
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/test/unit/component/LangSelect.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 | import React from 'react';
4 | import moment from 'moment';
5 |
6 | import { mockContext } from '../helpers/mock-context';
7 | import { shallowWithIntl } from '../helpers/mock-intl-enzyme';
8 | import { Component as LangSelect } from '../../../app/component/LangSelect';
9 |
10 | describe('LangSelect', () => {
11 | after(() => {
12 | moment.locale('en');
13 | });
14 |
15 | describe('', () => {
16 | it('should render', () => {
17 | const wrapper = shallowWithIntl(, {
18 | context: {
19 | ...mockContext,
20 | executeAction: () => true,
21 | config: { availableLanguages: ['fi', 'sv', 'en'] },
22 | },
23 | });
24 | expect(wrapper.isEmptyRender()).to.equal(false);
25 | });
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/test/unit/component/ScheduleTripRow.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 |
5 | import { shallowWithIntl } from '../helpers/mock-intl-enzyme';
6 | import ScheduleTripRow from '../../../app/component/routepage/ScheduleTripRow';
7 |
8 | describe('', () => {
9 | it('should highlight a canceled departure', () => {
10 | const props = {
11 | isCanceled: true,
12 | departureTime: '10.50',
13 | arrivalTime: '11.55',
14 | };
15 | const wrapper = shallowWithIntl();
16 | expect(wrapper.find('.trip-from.canceled')).to.have.lengthOf(1);
17 | expect(wrapper.find('.trip-to.canceled')).to.have.lengthOf(1);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/test/unit/component/StopPageMap.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 | import React from 'react';
4 |
5 | import { shallowWithIntl } from '../helpers/mock-intl-enzyme';
6 | import { Component as StopPageMap } from '../../../app/component/map/StopPageMap';
7 |
8 | describe('', () => {
9 | it('should render empty if stop information is missing', () => {
10 | const props = {
11 | breakpoint: 'large',
12 | params: {
13 | stopId: 'HSL:2211275',
14 | },
15 | routes: [],
16 | stop: null,
17 | };
18 | const wrapper = shallowWithIntl();
19 | expect(wrapper.find('.map').length).to.equal(0);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/test/unit/component/StopPageTabs.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 | import React from 'react';
4 |
5 | import { shallowWithIntl } from '../helpers/mock-intl-enzyme';
6 | import { Component as StopPageTabs } from '../../../app/component/stop/StopPageTabs';
7 |
8 | const context = {
9 | match: {
10 | location: {
11 | pathname: 'foobar',
12 | },
13 | params: {
14 | stopId: 'HSL:2211275',
15 | },
16 | },
17 | };
18 |
19 | describe('', () => {
20 | it('should render empty if stop information is missing', () => {
21 | const props = {
22 | breakpoint: 'large',
23 | children: ,
24 | routes: [],
25 | stop: null,
26 | };
27 | const wrapper = shallowWithIntl(, {
28 | context,
29 | });
30 | expect(wrapper.isEmptyRender()).to.equal(true);
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/test/unit/component/TripStopsContainer.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 | import React from 'react';
4 |
5 | import { shallowWithIntl } from '../helpers/mock-intl-enzyme';
6 | import { Component as TripStopsContainer } from '../../../app/component/routepage/TripStopsContainer';
7 | import { mockMatch } from '../helpers/mock-router';
8 |
9 | describe('', () => {
10 | it('should render empty if trip information is missing', () => {
11 | const props = {
12 | breakpoint: 'large',
13 | routes: [],
14 | trip: null,
15 | match: mockMatch,
16 | };
17 | const wrapper = shallowWithIntl();
18 | expect(wrapper.isEmptyRender()).to.equal(true);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/test/unit/component/map/MarkerPopupBottom.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { expect } from 'chai';
3 | import { describe, it } from 'mocha';
4 |
5 | import { mountWithIntl } from '../../helpers/mock-intl-enzyme';
6 | import { Component as MarkerPopupBottomWithoutLeaflet } from '../../../../app/component/map/MarkerPopupBottom';
7 |
8 | describe('', () => {
9 | it('should render a viapoint button when asked so', () => {
10 | const props = {
11 | location: {},
12 | leaflet: {
13 | map: {
14 | closePopup: () => {},
15 | },
16 | },
17 | locationPopup: 'all',
18 | onSelectLocation: () => null,
19 | };
20 |
21 | const wrapper = mountWithIntl(
22 | ,
23 | {},
24 | );
25 |
26 | expect(wrapper.find('.route-add-viapoint').length).to.equal(1);
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/test/unit/configurations/config.default.test.js:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'mocha';
2 | import { expect } from 'chai';
3 |
4 | import defaultConfig from '../../../app/configurations/config.default';
5 |
6 | describe('default configuration', () => {
7 | describe('realTime', () => {
8 | it('routeSelector should map the given props to something', () => {
9 | const props = {
10 | route: {
11 | gtfsId: 'HSL:12345',
12 | },
13 | };
14 | const result = defaultConfig.realTime.HSL.routeSelector(props);
15 | expect(result).to.equal('12345');
16 | });
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/test/unit/configurations/config.hsl.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 |
4 | import config from '../../../app/configurations/config.hsl';
5 |
6 | describe('HSL Configuration', () => {
7 | describe('fareMapping', () => {
8 | it('should return fare name without feedId', () => {
9 | expect(config.fareMapping('HSL:AB')).to.equal('AB');
10 | });
11 |
12 | it('should work with a missing fareId', () => {
13 | expect(config.fareMapping(undefined)).to.equal('');
14 | expect(config.fareMapping(null)).to.equal('');
15 | });
16 |
17 | it('should work with a malformed fareId', () => {
18 | expect(config.fareMapping('HSL:')).to.equal('');
19 | });
20 |
21 | it('should work with a non-string fareId', () => {
22 | expect(config.fareMapping({})).to.equal('');
23 | expect(config.fareMapping(1234)).to.equal('');
24 | });
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/test/unit/helpers/babel-register.js:
--------------------------------------------------------------------------------
1 | require('@babel/register')({
2 | // This will override `node_modules` ignoring - you can alternatively pass
3 | // an array of strings to be explicitly matched or a regex / glob
4 | ignore: [
5 | /node_modules\/(?!react-leaflet|@babel\/runtime\/helpers\/esm|lodash-es|@digitransit-util|@digitransit-component)/,
6 | ],
7 | });
8 |
--------------------------------------------------------------------------------
/test/unit/helpers/mock-router.js:
--------------------------------------------------------------------------------
1 | const mockMatcher = {
2 | routeConfig: [],
3 | match: () => {},
4 | getRoutes: () => {},
5 | isActive: () => {},
6 | format: () => {},
7 | };
8 |
9 | export const mockRouter = {
10 | push: () => {},
11 | replace: () => {},
12 | go: () => {},
13 | createHref: () => {},
14 | createLocation: () => {},
15 | addNavigationListener: () => {},
16 | matcher: mockMatcher,
17 | replaceRouteConfig: () => {},
18 | isActive: () => {},
19 | };
20 |
21 | export const mockMatch = {
22 | location: {
23 | action: '',
24 | pathname: '',
25 | search: '',
26 | hash: '',
27 | index: 0,
28 | delta: 0,
29 | query: {},
30 | },
31 | routeIndices: [],
32 | routeParams: {},
33 | params: {},
34 | routes: [],
35 | router: mockRouter,
36 | route: {
37 | getComponent: () => {},
38 | },
39 | };
40 |
--------------------------------------------------------------------------------
/test/unit/store/ViaPointsStore.test.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import { describe, it } from 'mocha';
3 |
4 | import ViaPointStore from '../../../app/store/ViaPointStore';
5 |
6 | describe('ViaPointsStore', () => {
7 | it('Should store via points', () => {
8 | const store = new ViaPointStore();
9 | store.addViaPoint({ via: 'point' });
10 | expect(store.getViaPoints()[0].via).to.deep.equal('point');
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/test/unit/util/hashUtil.test.js:
--------------------------------------------------------------------------------
1 | import hashCode from '../../../app/util/hashUtil';
2 |
3 | describe('hashUtil', () => {
4 | it('should return 0 if the input string is falsy', () => {
5 | expect(hashCode(undefined)).to.equal(0);
6 | });
7 |
8 | it('should return 0 if the input string has zero length', () => {
9 | expect(hashCode('')).to.equal(0);
10 | });
11 |
12 | it('should return 0 if the input is not a string', () => {
13 | expect(hashCode(['f', 'o', 'o'])).to.equal(0);
14 | });
15 |
16 | it('should return a numeric hash value', () => {
17 | expect(hashCode('foo')).to.equal(101574);
18 | expect(hashCode('bar')).to.equal(97299);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/win-launch-scripts/hsl-win-launch-script.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | START "Start node server" CMD /K "CD..&& set NODE_ENV=development&& set CONFIG=hsl&& nodemon -e js,css,scss,html --watch ./app/ server/server.js"
3 | START "Start node hot load server" CMD /K "CD..&& set NODE_ENV=development&& set CONFIG=hsl&& yarn run webpack-dev-server"
4 |
--------------------------------------------------------------------------------
/win-launch-scripts/national-win-launch-script.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | START "Start node server" CMD /K "CD..&& set NODE_ENV=development&& nodemon -e js,css,scss,html --watch ./app/ server/server.js"
3 | START "Start node hot load server" CMD /K "CD..&& set NODE_ENV=development&& yarn run webpack-dev-server"
4 |
--------------------------------------------------------------------------------