├── .dockerignore ├── .editorconfig ├── .env.docker ├── .env.example ├── .env.testing ├── .envrc ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report-de.yml │ ├── bug-report-en.yml │ └── config.yml └── workflows │ ├── check-pr-title.yml │ ├── docker.yml │ ├── nodejs-audit.yml │ ├── nodejs-prod.yml │ └── phpunit.yml ├── .gitignore ├── .neoconf.json ├── .styleci.yml ├── API_CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── _ide_helper.php ├── _ide_helper_models.php ├── app ├── Casts │ └── UTCDateTime.php ├── Console │ ├── Commands │ │ ├── AccountDeletion.php │ │ ├── CacheLeaderboard.php │ │ ├── CacheYearInReview.php │ │ ├── CalculateMissingDuration.php │ │ ├── CleanUpProfilePictures.php │ │ ├── ClearDatabaseCache.php │ │ ├── DatabaseCleaner │ │ │ ├── CleanUpActivity.php │ │ │ ├── CleanUpDanglingStatuses.php │ │ │ ├── CleanUpEventSuggestions.php │ │ │ ├── CleanUpTokens.php │ │ │ ├── DatabaseCleaner.php │ │ │ ├── FailedJobs.php │ │ │ ├── MastodonServers.php │ │ │ ├── Notifications.php │ │ │ ├── PasswordResets.php │ │ │ ├── Polylines.php │ │ │ ├── PolylinesBrouter.php │ │ │ ├── RefreshPrometheusCache.php │ │ │ ├── Trips.php │ │ │ ├── TrustedUser.php │ │ │ └── User.php │ │ ├── FetchTransitousLicenses.php │ │ ├── HideStatus.php │ │ ├── PolylinesToFiles.php │ │ ├── RecalculateStatusDistance.php │ │ ├── ReduceRelevance.php │ │ ├── RefreshCurrentTrips.php │ │ └── RefreshOperatorMappings.php │ └── Kernel.php ├── DataProviders │ ├── Bahn.php │ ├── CachedDataProvider.php │ ├── DataProviderBuilder.php │ ├── DataProviderInterface.php │ ├── FptfHelper.php │ ├── Hafas.php │ ├── HafasStopoverService.php │ ├── Hydrators │ │ └── MotisHydrator.php │ ├── Motis.php │ └── Repositories │ │ ├── MotisLicenseRepository.php │ │ ├── StationRepository.php │ │ └── TripRepository.php ├── Dto │ ├── BoundingBox.php │ ├── CheckinSuccess.php │ ├── Coordinate.php │ ├── GeoJson │ │ ├── Feature.php │ │ ├── FeatureCollection.php │ │ └── Properties.php │ ├── Internal │ │ ├── BahnTrip.php │ │ ├── CheckInRequestDto.php │ │ ├── CheckinSuccessDto.php │ │ └── Departure.php │ ├── LicenseDto.php │ ├── LivePointDto.php │ ├── MentionDto.php │ ├── PointCalculation.php │ ├── Transport │ │ └── Station.php │ └── Wikidata │ │ └── WikidataEntity.php ├── Enum │ ├── BrouterProfile.php │ ├── Business.php │ ├── DataProvider.php │ ├── EventRejectionReason.php │ ├── ExportableColumn.php │ ├── HafasTravelType.php │ ├── MapProvider.php │ ├── MastodonVisibility.php │ ├── MotisCategory.php │ ├── PointReason.php │ ├── ProfileLinkName.php │ ├── ReiseloesungCategory.php │ ├── Report │ │ ├── ReportReason.php │ │ ├── ReportStatus.php │ │ └── ReportableSubject.php │ ├── StatusTagKey.php │ ├── StatusVisibility.php │ ├── TimeType.php │ ├── TravelType.php │ ├── TripSource.php │ ├── User │ │ └── FriendCheckinSetting.php │ ├── WebhookEvent.php │ └── Wikidata │ │ └── Property.php ├── Events │ ├── StatusDeleteEvent.php │ ├── StatusUpdateEvent.php │ └── UserCheckedIn.php ├── Exceptions │ ├── AlreadyAcceptedException.php │ ├── AlreadyFollowingException.php │ ├── CheckInCollisionException.php │ ├── Checkin │ │ └── AlreadyCheckedInException.php │ ├── CheckinException.php │ ├── DataOverflowException.php │ ├── DistanceDeviationException.php │ ├── HafasException.php │ ├── Handler.php │ ├── ManualTripValidationException.php │ ├── NotConnectedException.php │ ├── PermissionException.php │ ├── RateLimitExceededException.php │ ├── Referencable.php │ ├── ShouldDeleteNotificationException.php │ ├── SocialAuth │ │ └── InvalidMastodonException.php │ ├── StationNotOnTripException.php │ ├── StatusAlreadyLikedException.php │ ├── TelegramException.php │ ├── TrainCheckinAlreadyExistException.php │ ├── UnknownDataProvider.php │ ├── UserAlreadyBlockedException.php │ ├── UserAlreadyMutedException.php │ ├── UserNotBlockedException.php │ ├── UserNotMutedException.php │ └── Wikidata │ │ └── FetchException.php ├── Helpers │ ├── CacheKey.php │ ├── Formatter.php │ ├── HCK.php │ ├── Helper.php │ └── Language.php ├── Http │ ├── Controllers │ │ ├── API │ │ │ └── v1 │ │ │ │ ├── AlertController.php │ │ │ │ ├── AuthController.php │ │ │ │ ├── Controller.php │ │ │ │ ├── EventController.php │ │ │ │ ├── ExperimentalController.php │ │ │ │ ├── ExportController.php │ │ │ │ ├── FollowController.php │ │ │ │ ├── IcsController.php │ │ │ │ ├── LikesController.php │ │ │ │ ├── NotificationsController.php │ │ │ │ ├── OperatorController.php │ │ │ │ ├── PrivacyPolicyController.php │ │ │ │ ├── ReportController.php │ │ │ │ ├── SessionController.php │ │ │ │ ├── SettingsController.php │ │ │ │ ├── StationController.php │ │ │ │ ├── StatisticsController.php │ │ │ │ ├── StatusController.php │ │ │ │ ├── StatusTagController.php │ │ │ │ ├── TokenController.php │ │ │ │ ├── TransportController.php │ │ │ │ ├── TripController.php │ │ │ │ ├── TrustedUserController.php │ │ │ │ ├── UserController.php │ │ │ │ ├── WebhookController.php │ │ │ │ └── YearInReviewController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ ├── ResetPasswordController.php │ │ │ └── VerificationController.php │ │ ├── Backend │ │ │ ├── Admin │ │ │ │ ├── AlertController.php │ │ │ │ └── EventController.php │ │ │ ├── Auth │ │ │ │ ├── AccessTokenController.php │ │ │ │ ├── ApproveAuthorizationController.php │ │ │ │ ├── AuthorizationController.php │ │ │ │ └── LoginController.php │ │ │ ├── BrouterController.php │ │ │ ├── EventController.php │ │ │ ├── Export │ │ │ │ ├── ExportController.php │ │ │ │ └── Format │ │ │ │ │ └── JsonExportController.php │ │ │ ├── Helper │ │ │ │ ├── PrivacyHelper.php │ │ │ │ └── StatusHelper.php │ │ │ ├── IcsController.php │ │ │ ├── LeaderboardController.php │ │ │ ├── SettingsController.php │ │ │ ├── Social │ │ │ │ ├── MastodonController.php │ │ │ │ ├── MastodonProfileDetails.php │ │ │ │ └── SocialController.php │ │ │ ├── StatisticController.php │ │ │ ├── Stats │ │ │ │ ├── DailyStatsController.php │ │ │ │ ├── TransportStatsController.php │ │ │ │ └── YearInReviewController.php │ │ │ ├── Support │ │ │ │ ├── LocationController.php │ │ │ │ └── MentionHelper.php │ │ │ ├── Transport │ │ │ │ ├── HomeController.php │ │ │ │ ├── ManualTripCreator.php │ │ │ │ ├── PointsCalculationController.php │ │ │ │ ├── StationController.php │ │ │ │ ├── StatusController.php │ │ │ │ ├── StatusTagController.php │ │ │ │ └── TrainCheckinController.php │ │ │ ├── User │ │ │ │ ├── AccountDeletionController.php │ │ │ │ ├── BlockController.php │ │ │ │ ├── DashboardController.php │ │ │ │ ├── FollowController.php │ │ │ │ ├── ProfilePictureController.php │ │ │ │ ├── SessionController.php │ │ │ │ └── TokenController.php │ │ │ ├── UserController.php │ │ │ ├── VersionController.php │ │ │ ├── WebFingerController.php │ │ │ └── WebhookController.php │ │ ├── Controller.php │ │ ├── Frontend │ │ │ ├── AccountController.php │ │ │ ├── Admin │ │ │ │ ├── ActivityController.php │ │ │ │ ├── EventController.php │ │ │ │ ├── LicensesController.php │ │ │ │ ├── MotisSourceController.php │ │ │ │ ├── OperatorController.php │ │ │ │ ├── ReportController.php │ │ │ │ ├── StationController.php │ │ │ │ ├── StatusEditController.php │ │ │ │ ├── TripController.php │ │ │ │ └── UserController.php │ │ │ ├── ChangelogController.php │ │ │ ├── DebugController.php │ │ │ ├── DevController.php │ │ │ ├── EventController.php │ │ │ ├── IcsController.php │ │ │ ├── LandingPageController.php │ │ │ ├── LeaderboardController.php │ │ │ ├── OpenData │ │ │ │ └── WikidataController.php │ │ │ ├── SettingsController.php │ │ │ ├── Social │ │ │ │ ├── MastodonController.php │ │ │ │ └── SocialController.php │ │ │ ├── StatisticController.php │ │ │ ├── Stats │ │ │ │ └── DailyStatsController.php │ │ │ ├── Transport │ │ │ │ └── StatusController.php │ │ │ ├── User │ │ │ │ └── ProfilePictureController.php │ │ │ ├── UserController.php │ │ │ ├── VueFrontendController.php │ │ │ └── WebFingerController.php │ │ ├── FrontendStatusController.php │ │ ├── FrontendTransportController.php │ │ ├── FrontendUserController.php │ │ ├── PrivacyAgreementController.php │ │ ├── SettingsController.php │ │ ├── SitemapController.php │ │ ├── StatusController.php │ │ ├── TransportController.php │ │ └── UserController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── Api │ │ │ └── JsonMiddleware.php │ │ ├── Authenticate.php │ │ ├── CheckForMaintenanceMode.php │ │ ├── EncryptCookies.php │ │ ├── Language.php │ │ ├── PrivacyInterceptionMiddleware.php │ │ ├── PrivacyPolicyInterceptionMiddleware.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── SemiScope.php │ │ ├── TrimStrings.php │ │ ├── TrustProxies.php │ │ └── VerifyCsrfToken.php │ ├── Requests │ │ ├── CreateLicenseRequest.php │ │ ├── ManualTripCreationRequest.php │ │ ├── StoreAlertRequest.php │ │ ├── UpdateProfileInformationRequest.php │ │ └── admin │ │ │ ├── LicenseIndexFilterRequest.php │ │ │ ├── MassAssignSourceRequest.php │ │ │ └── SourceIndexFilterRequest.php │ └── Resources │ │ ├── AlertResource.php │ │ ├── AlertTranslationResource.php │ │ ├── AreaResource.php │ │ ├── CheckinSuccessResource.php │ │ ├── ClientResource.php │ │ ├── DataSourceResource.php │ │ ├── EventDetailsResource.php │ │ ├── EventResource.php │ │ ├── GdprExport │ │ └── UserExport.php │ │ ├── IcsEntryResource.php │ │ ├── LeaderboardUserResource.php │ │ ├── LightUserResource.php │ │ ├── OperatorResource.php │ │ ├── PrivacyPolicyResource.php │ │ ├── ProfileLinkResource.php │ │ ├── SessionResource.php │ │ ├── StationResource.php │ │ ├── StatisticsGlobalData.php │ │ ├── StatisticsTravelPurposeResource.php │ │ ├── StatusExportResource.php │ │ ├── StatusResource.php │ │ ├── StatusTagResource.php │ │ ├── StopoverResource.php │ │ ├── TokenResource.php │ │ ├── TransportResource.php │ │ ├── TripResource.php │ │ ├── TrustedUserResource.php │ │ ├── UserAuthResource.php │ │ ├── UserNotificationMessageResource.php │ │ ├── UserNotificationResource.php │ │ ├── UserProfileSettingsResource.php │ │ ├── UserResource.php │ │ ├── WebhookEventResource.php │ │ └── WebhookResource.php ├── Hydrators │ ├── CheckinRequestHydrator.php │ └── DepartureHydrator.php ├── Interfaces │ └── IconEnumInterface.php ├── Jobs │ ├── MonitoredCallWebhookJob.php │ ├── MonitoredPersonalDataExportJob.php │ ├── PostStatusOnMastodon.php │ ├── RefreshPolyline.php │ ├── RefreshStopover.php │ └── SendVerificationEmail.php ├── Listeners │ ├── CacheMissedListener.php │ ├── NotificationSentWebhookListener.php │ ├── RemoveAbsentWebhooksListener.php │ ├── StatusCreateCheckPolylineListener.php │ ├── StatusCreateWebhookListener.php │ └── StatusUpdateWebhookListener.php ├── Mail │ └── AccountDeletionNotificationTwoWeeksBefore.php ├── Models │ ├── Alert.php │ ├── AlertTranslation.php │ ├── Area.php │ ├── AreasStationsMap.php │ ├── Checkin.php │ ├── Event.php │ ├── EventSuggestion.php │ ├── Follow.php │ ├── FollowRequest.php │ ├── HafasOperator.php │ ├── IcsToken.php │ ├── License.php │ ├── Like.php │ ├── MastodonServer.php │ ├── Mention.php │ ├── MotisSourceLicense.php │ ├── OAuthClient.php │ ├── PolyLine.php │ ├── PrivacyAgreement.php │ ├── ProfileLink.php │ ├── Report.php │ ├── Session.php │ ├── SocialLoginProfile.php │ ├── Station.php │ ├── StationIdentifier.php │ ├── StationName.php │ ├── Status.php │ ├── StatusTag.php │ ├── Stopover.php │ ├── Trip.php │ ├── TrustedUser.php │ ├── User.php │ ├── UserBlock.php │ ├── UserMute.php │ ├── Webhook.php │ ├── WebhookCreationRequest.php │ ├── WebhookEvent.php │ └── WikidataEntity.php ├── Notifications │ ├── BaseNotification.php │ ├── EventSuggestionProcessed.php │ ├── FollowRequestApproved.php │ ├── FollowRequestIssued.php │ ├── InvalidMastodonServer.php │ ├── MastodonNotSent.php │ ├── PersonalDataExportedNotification.php │ ├── StatusLiked.php │ ├── UserFollowed.php │ ├── UserJoinedConnection.php │ ├── UserMentioned.php │ └── YouHaveBeenCheckedIn.php ├── Objects │ └── LineSegment.php ├── Observers │ ├── CheckinObserver.php │ ├── FollowObserver.php │ ├── LikeObserver.php │ ├── ReportObserver.php │ ├── StatusObserver.php │ ├── TripObserver.php │ └── UserObserver.php ├── Policies │ ├── AlertPolicy.php │ ├── FollowPolicy.php │ ├── LikePolicy.php │ ├── OperatorPolicy.php │ ├── ReportPolicy.php │ ├── StationPolicy.php │ ├── StatusPolicy.php │ ├── StatusTagPolicy.php │ ├── TokenPolicy.php │ ├── UserPolicy.php │ └── WebhookPolicy.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ ├── PrometheusServiceProvider.php │ └── RouteServiceProvider.php ├── Repositories │ ├── CheckinHydratorRepository.php │ ├── OAuthClientRepository.php │ ├── ReportRepository.php │ └── StationRepository.php ├── Rules │ ├── AuthorizedWebhookURL.php │ └── SecureUrl.php ├── Services │ ├── GeoService.php │ ├── LicenseService.php │ ├── MastodonDomainExtractionService.php │ ├── OperatorService.php │ ├── PersonalDataSelection │ │ ├── Exporters │ │ │ ├── ActivityLogExporter.php │ │ │ ├── AppsExporter.php │ │ │ ├── Base │ │ │ │ ├── AbstractExporter.php │ │ │ │ ├── DatabaseExportable.php │ │ │ │ ├── Exporter.php │ │ │ │ ├── ModelExportable.php │ │ │ │ └── RelationExportable.php │ │ │ ├── BlocksExporter.php │ │ │ ├── EventSuggestionsExporter.php │ │ │ ├── EventsExporter.php │ │ │ ├── FollowRequestsExporter.php │ │ │ ├── FollowingsExporter.php │ │ │ ├── FollowsExporter.php │ │ │ ├── FollowsRequestsExporter.php │ │ │ ├── HomeExporter.php │ │ │ ├── IcsTokenExporter.php │ │ │ ├── LikesExporter.php │ │ │ ├── MentionExporter.php │ │ │ ├── MutesExporter.php │ │ │ ├── NotificationsExporter.php │ │ │ ├── PasswordResetsExporter.php │ │ │ ├── PermissionExporter.php │ │ │ ├── ProfileLinksExporter.php │ │ │ ├── ReportsExporter.php │ │ │ ├── RoleExporter.php │ │ │ ├── SessionExporter.php │ │ │ ├── SocialProfileExporter.php │ │ │ ├── StatusExporter.php │ │ │ ├── TokenExporter.php │ │ │ ├── TripsExporter.php │ │ │ ├── TrustedUsersExporter.php │ │ │ ├── UserDataExporter.php │ │ │ ├── WebhookCreationRequestExporter.php │ │ │ └── WebhookExporter.php │ │ └── UserGdprDataService.php │ ├── PolylineStorageService.php │ ├── PrideService.php │ ├── PrivacyPolicyService.php │ ├── ReportService.php │ ├── StationService.php │ ├── TelegramService.php │ └── Wikidata │ │ ├── WikidataImportService.php │ │ └── WikidataQueryService.php ├── View │ └── Components │ │ ├── AbstractUserActionButton.php │ │ ├── BlockButton.php │ │ ├── CheckinSuccess.php │ │ ├── EventRejectionButton.php │ │ └── MuteButton.php └── Virtual │ ├── Models │ ├── BearerTokenResponse.php │ ├── CheckinRequestBody.php │ ├── EventSuggestion.php │ ├── Laravel │ │ ├── Links.php │ │ └── PaginationMeta.php │ ├── LikeResponse.php │ ├── Notification.php │ ├── Parameters │ │ └── PaginationPage.php │ ├── Points.php │ ├── PointsCalculation.php │ ├── Polyline.php │ ├── Response │ │ └── CheckinForbiddenWithUsersResponse.php │ ├── StatusTag.php │ ├── SuccessResponse.php │ └── Webhook.php │ └── RequestBodies │ └── StatusUpdateBody.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── codesize.xml ├── composer.json ├── composer.lock ├── config ├── activitylog.php ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── cors.php ├── database.php ├── filesystems.php ├── hashing.php ├── l5-swagger.php ├── logging.php ├── mail.php ├── permission.php ├── personal-data-export.php ├── prometheus.php ├── queue-monitor.php ├── queue.php ├── rate_limits.php ├── services.php ├── session.php ├── sitemap.php ├── trustedproxy.php ├── trwl.php ├── view.php └── webhook-server.php ├── database ├── .gitignore ├── README.md ├── factories │ ├── CheckinFactory.php │ ├── EventFactory.php │ ├── EventSuggestionFactory.php │ ├── FollowFactory.php │ ├── HafasOperatorFactory.php │ ├── IcsTokenFactory.php │ ├── LikeFactory.php │ ├── LocationFactory.php │ ├── RemarkFactory.php │ ├── StationFactory.php │ ├── StationIdentifierFactory.php │ ├── StatusFactory.php │ ├── StatusTagFactory.php │ ├── StopoverFactory.php │ ├── TripFactory.php │ ├── UserFactory.php │ └── UserMuteFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2016_06_01_000001_create_oauth_auth_codes_table.php │ ├── 2016_06_01_000002_create_oauth_access_tokens_table.php │ ├── 2016_06_01_000003_create_oauth_refresh_tokens_table.php │ ├── 2016_06_01_000004_create_oauth_clients_table.php │ ├── 2016_06_01_000005_create_oauth_personal_access_clients_table.php │ ├── 2018_02_05_000000_create_queue_monitor_table.php │ ├── 2019_08_06_184725_create_social_login_profiles_table.php │ ├── 2019_08_09_003647_create_statuses_table.php │ ├── 2019_08_09_003814_create_likes_table.php │ ├── 2019_08_09_003837_create_follows_table.php │ ├── 2019_08_11_233556_create_mastodon_servers_table.php │ ├── 2019_08_13_155546_create_hafas_trips_table.php │ ├── 2019_08_13_162744_create_train_stations_table.php │ ├── 2019_08_14_013806_create_train_checkins_table.php │ ├── 2019_08_19_173342_create_sessions_table.php │ ├── 2019_11_04_200120_create_privacy_agreements_table.php │ ├── 2019_11_22_220440_create_poly_lines_table.php │ ├── 2019_12_14_130742_create_events_table.php │ ├── 2019_12_18_222050_connect_statuses_and_events.php │ ├── 2019_12_20_221724_create_user_roles.php │ ├── 2020_02_20_162218_create_notifications_table.php │ ├── 2020_08_05_151702_change_train_station_table.php │ ├── 2020_09_27_190346_migrate_laravel_passport_to_v9.php │ ├── 2020_09_28_150313_migrate_notifications_to_laravel8.php │ ├── 2020_09_28_170000_add_foreign_keys_to_social_login_profiles.php │ ├── 2020_09_28_170001_unify_columns_from_train_stations.php │ ├── 2020_09_28_170002_add_foreign_keys_to_events.php │ ├── 2020_09_28_170003_add_foreign_keys_to_follows.php │ ├── 2020_09_28_170004_add_keys_to_poly_lines.php │ ├── 2020_09_28_170005_add_foreign_keys_to_hafas_trips.php │ ├── 2020_09_28_170006_add_foreign_keys_to_likes.php │ ├── 2020_09_28_170007_add_foreign_keys_to_sessions.php │ ├── 2020_09_28_170008_add_foreign_keys_to_statuses.php │ ├── 2020_09_28_170009_add_foreign_keys_to_train_checkins.php │ ├── 2020_09_28_170010_add_foreign_keys_to_users.php │ ├── 2020_10_05_184500_add_unique_key_to_events.php │ ├── 2020_10_16_175602_add_unique_key_to_likes.php │ ├── 2020_11_18_101929_add_user_private_profile_key.php │ ├── 2021_01_26_203951_create_train_stopovers_table.php │ ├── 2021_02_01_000000_add_unique_key_to_poly_lines.php │ ├── 2021_02_15_000000_create_ics_tokens_table.php │ ├── 2021_02_20_155443_remove_static_points_from_users.php │ ├── 2021_02_20_213248_add_ril_identifier_to_train_stations.php │ ├── 2021_02_23_170640_create_hafas_operators_table.php │ ├── 2021_02_23_171038_add_hafas_operator_to_hafas_trips.php │ ├── 2021_02_23_185026_change_avatar_to_be_null_on_users.php │ ├── 2021_04_21_102707_change_statuses_to_accept_business_checkin_as_integer.php │ ├── 2021_04_28_230708_add_last_accessed_and_name_to_ics_tokens.php │ ├── 2021_04_29_150026_create_follow_requests_table.php │ ├── 2021_05_01_165202_add_privacy_search_engine_to_users.php │ ├── 2021_05_10_201216_add_language_to_users.php │ ├── 2021_05_12_211411_create_user_mutes_table.php │ ├── 2021_05_26_134022_remove_train_distance_and_duration_from_users.php │ ├── 2021_05_26_172817_create_event_suggestions_table.php │ ├── 2021_06_07_145349_add_visibility_to_statuses.php │ ├── 2021_06_08_200223_add_index_to_sessions_table.php │ ├── 2021_07_03_222039_add_last_login_to_users.php │ ├── 2021_07_04_002719_drop_points_calculation_table.php │ ├── 2021_07_24_124933_create_default_visibility_on_users.php │ ├── 2021_08_05_211128_change_column_for_train_checkins.php │ ├── 2021_08_05_214231_remove_delay_from_train_checkins.php │ ├── 2021_08_05_220132_add_user_id_to_train_checkins.php │ ├── 2021_10_08_132506_make_twitter_id_unique_in_social_login_profiles.php │ ├── 2021_10_08_160350_add_foreign_key_to_social_login_profiles.php │ ├── 2021_10_12_143849_drop-blogposts-table.php │ ├── 2021_11_03_211948_add_unique_key_to_train_checkins.php │ ├── 2021_11_06_193343_make_url_nullable_at_events.php │ ├── 2021_12_14_143156_add_user_arrival_index_to_train_checkins.php │ ├── 2022_01_06_224610_add_index_to_train_stopovers.php │ ├── 2022_01_06_230418_add_index_to_hafas_trips.php │ ├── 2022_03_03_104050_add_cancelled_attribute_to_stopover.php │ ├── 2022_03_07_000000_add_hide_status_days_to_users.php │ ├── 2022_03_11_000000_migrate_train_checkin_category.php │ ├── 2022_03_18_000000_migrate_encryptables.php │ ├── 2022_03_28_000000_add_support_code_to_users.php │ ├── 2022_03_29_000000_add_index_to_train_stopovers.php │ ├── 2022_04_01_000000_remove_support_code_from_users.php │ ├── 2022_04_02_000000_change_unique_key_to_support_multiple_stopovers_per_station.php │ ├── 2022_04_02_000000_create_remarks_table.php │ ├── 2022_04_02_000001_create_trip_remarks_table.php │ ├── 2022_04_03_000000_create_user_agents_table.php │ ├── 2022_04_03_000001_create_api_logs_table.php │ ├── 2022_04_07_085923_change_status_code_datatype_in_api_logs_table.php │ ├── 2022_05_22_000000_add_station_id_to_events.php │ ├── 2022_05_29_000000_create_carriage_sequences_table.php │ ├── 2022_06_04_000000_create_jobs_table.php │ ├── 2022_06_04_000001_make_order_number_nullable_at_carriage_sequences.php │ ├── 2022_07_21_000000_add_index_to_api_logs.php │ ├── 2022_07_21_000001_add_index_to_user_agents.php │ ├── 2022_07_23_000000_add_forced_to_train_checkins.php │ ├── 2022_08_31_000000_add_last_refreshed_to_hafas_trips.php │ ├── 2022_08_31_000001_add_index2_to_train_stopovers.php │ ├── 2022_09_08_000000_create_locations_table.php │ ├── 2022_09_25_000000_create_cache_table.php │ ├── 2022_09_26_000000_fill_planned_departure_and_arrival_at_train_stopovers.php │ ├── 2022_09_26_000001_add_tweet_id_to_statuses.php │ ├── 2022_10_11_000000_create_failed_jobs_table.php │ ├── 2022_10_17_000000_default_uuid_field.php │ ├── 2022_10_22_000000_add_unique_key_to_train_stopovers.php │ ├── 2022_11_25_223003_add_toot_id_to_status_table.php │ ├── 2022_12_11_000000_drop_trip_remarks.php │ ├── 2022_12_11_000001_drop_remarks.php │ ├── 2022_12_23_000000_create_status_tags_table.php │ ├── 2022_12_25_000000_create_user_blocks_table.php │ ├── 2022_19_10_000000_add_twitter_refresh_token.php │ ├── 2023_01_08_202020_remove_always_dbl_flag_from_users_table.php │ ├── 2023_01_21_000000_add_journey_number_to_hafas_trips.php │ ├── 2023_01_28_000000_migrate_passport_from_v7_to_v8.php │ ├── 2023_01_30_173822_add_scopes_to_existing_oauth_access_tokens.php │ ├── 2023_02_04_184426_extend_oauth_clients_with_custom_data.php │ ├── 2023_02_07_202300_add_mastodon_visibility_field_to_social_login_profiles_table.php │ ├── 2023_02_11_000000_remove_api_usage.php │ ├── 2023_02_11_000001_remove_locations_table.php │ ├── 2023_03_01_000000_update_queue_monitor_table.php │ ├── 2023_03_06_000000_add_override_arrival_and_departure_to_train_checkins.php │ ├── 2023_03_23_000000_add_index_to_train_checkins.php │ ├── 2023_03_23_000000_migrate_oauth_access_tokens.php │ ├── 2023_03_23_000000_migrate_oauth_auth_codes.php │ ├── 2023_03_23_000000_migrate_oauth_clients.php │ ├── 2023_03_23_000000_migrate_oauth_personal_access_clients.php │ ├── 2023_03_23_000001_add_index_to_users.php │ ├── 2023_03_23_000002_add_index_to_train_stations.php │ ├── 2023_03_23_000003_create_webhooks_table.php │ ├── 2023_03_23_000004_create_webhook_creation_requests_table.php │ ├── 2023_03_23_215105_change_index_at_train_checkins.php │ ├── 2023_04_25_000000_add_source_to_poly_lines.php │ ├── 2023_05_03_144452_add_job_uuid_and_retried_to_queue_monitor_table.php │ ├── 2023_05_05_000000_drop_carriage_sequences.php │ ├── 2023_05_07_135454_add_likes_enabled_field_to_users_table.php │ ├── 2023_05_09_000000_make_station_id_null_on_events.php │ ├── 2023_05_10_000000_default_uuid_field.php │ ├── 2023_06_06_000000_delete_all_notifications.php │ ├── 2023_06_09_161642_add_mapprovider_field_to_users_table.php │ ├── 2023_06_13_213444_expand_event_date_restrictions.php │ ├── 2023_07_06_201721_rename_legacy_stopovers.php │ ├── 2023_07_07_183520_add_timezone_to_users.php │ ├── 2023_07_08_090008_add_time_information_to_stations.php │ ├── 2023_07_09_000000_make_hashtag_nullable_on_events.php │ ├── 2023_07_13_144452_add_queued_at_column_to_queue_monitor_table.php │ ├── 2023_07_24_000000_add_user_mastodon_index_to_statuses.php │ ├── 2023_07_26_000000_add_duration_to_train_checkins.php │ ├── 2023_08_06_000000_rename_manual_arrival_and_departure_at_train_checkins.php │ ├── 2023_08_06_000001_add_hashtag_to_event_suggestions.php │ ├── 2023_08_06_000002_rename_station_id_at_event_suggestions.php │ ├── 2023_08_19_160842_add_webhook_events_table.php │ ├── 2023_08_19_161454_migrate_webhook_events_from_bitmasks_to_table.php │ ├── 2023_08_19_174051_drop_webhook_events_column.php │ ├── 2023_09_22_194607_add_experimental_setting_to_users.php │ ├── 2023_09_23_162754_add-parent-to-polylines.php │ ├── 2023_11_20_000000_drop_user_agents.php │ ├── 2023_11_20_000001_drop_locations.php │ ├── 2023_11_20_000002_drop_remarks.php │ ├── 2023_11_21_000000_drop_twitter_secrets.php │ ├── 2023_11_21_000001_create_permission_tables.php │ ├── 2023_11_21_000003_drop_role_from_users.php │ ├── 2023_11_21_000004_drop_experimental_from_users.php │ ├── 2023_11_22_000000_add_source_to_trips.php │ ├── 2023_11_23_000000_remove_type_from_statuses.php │ ├── 2023_11_23_000001_fix_departure_column_on_train_checkins.php │ ├── 2023_11_23_000002_add_user_id_to_hafas_trips.php │ ├── 2023_11_27_000000_drop_delay_column_in_hafas_trips.php │ ├── 2023_12_17_000000_create_activity_log_table.php │ ├── 2023_12_17_000001_add_event_column_to_activity_log_table.php │ ├── 2023_12_17_000002_add_batch_uuid_column_to_activity_log_table.php │ ├── 2023_12_18_000000_add_origin_and_destination_stopover_foreign_to_train_checkins.php │ ├── 2023_12_20_000000_migrate_stopover_relation_id_in_train_checkins.php │ ├── 2023_12_29_000000_add_client_id_to_statuses.php │ ├── 2024_01_30_000001_create_reports_table.php │ ├── 2024_02_08_000000_create_mentions_table.php │ ├── 2024_03_01_000000_create_wikidata_entities_table.php │ ├── 2024_03_01_000001_add_wikidata_id_to_stations.php │ ├── 2024_03_10_211526_add_ifopt_to_stations.php │ ├── 2024_03_22_000000_add_origin_and_destination_id_to_trips.php │ ├── 2024_03_22_000001_migrate_origin_and_destination_id_in_trips.php │ ├── 2024_03_22_000002_make_trip_origin_id_and_destination_id_not_nullable.php │ ├── 2024_04_19_131906_add_index_to_poly_line_parent_id.php │ ├── 2024_05_21_000000_make_ibnr_nullable_on_stations.php │ ├── 2024_05_21_000001_remove_station_ibnr_from_hafas_trips.php │ ├── 2024_05_22_000003_drop_origin_destination_from_check_in.php │ ├── 2024_05_22_000004_add_index_operator_id_category_to_hafas_trips.php │ ├── 2024_05_22_000005_add_index_name_status_queue_on_queue_monitor.php │ ├── 2024_05_22_000008_add_index_user_id_visibility_on_statuses.php │ ├── 2024_05_25_000000_add_source_index_to_polylines.php │ ├── 2024_05_25_000001_add_trip_id_arrival_departure_index_to_train_stopovers.php │ ├── 2024_05_27_000000_drop_shadow_banned_from_users.php │ ├── 2024_05_30_000000_add_prefix_to_begin_end_on_events.php │ ├── 2024_06_28_000000_add_friend_checkin_setting_to_users.php │ ├── 2024_07_07_000000_make_display_name_not_nullable_at_users.php │ ├── 2024_07_07_000000_set_size_of_username_at_users.php │ ├── 2024_07_14_081815_add_points_setting_to_users.php │ ├── 2024_07_28_000001_add_trusted_users_table.php │ ├── 2024_07_30_000000_add_admin_notification_id_to_reports.php │ ├── 2024_08_07_000000_create_station_names_table.php │ ├── 2024_08_07_000001_drop_foreign_wikidata_entity_on_station.php │ ├── 2024_08_07_000002_drop_wikidata_entities.php │ ├── 2024_08_11_000000_drop_tweet_id_from_statuses.php │ ├── 2024_08_13_000000_add_admin_notification_id_to_event_suggestions.php │ ├── 2024_11_04_223623_add_recent_gdpr_export_to_users.php │ ├── 2025_01_08_000000_add_source_to_stations.php │ ├── 2025_01_08_000001_what_the_fuck_twitter_id.php │ ├── 2025_01_16_000000_add_moderation_notes_to_statuses.php │ ├── 2025_02_23_094950_create_station_identifiers_table.php │ ├── 2025_02_27_213311_add_motis_source_to_hafas_trips.php │ ├── 2025_02_27_221837_add_column_data_provider_to_users.php │ ├── 2025_03_04_111312_add_latitude_longitude_index_to_train_stations.php │ ├── 2025_04_11_083248_create_motis_sources_table.php │ ├── 2025_04_11_131601_add_motis_source_to_trips.php │ ├── 2025_04_11_155304_add_human_name_to_motis_licenses.php │ ├── 2025_04_12_152843_add_relevance_to_train_stations.php │ ├── 2025_04_13_000000_add_motis_id_to_operators.php │ ├── 2025_04_13_000001_make_hafas_id_nullable_at_operators.php │ ├── 2025_04_13_094142_create_licenses_table.php │ ├── 2025_04_13_094218_add_manual_license_info_to_motis_source_licenses.php │ ├── 2025_04_14_203000_convert_hafas_operator_motis_id_to_string.php │ ├── 2025_04_14_214754_add_relevance_field_to_station_identifiers.php │ ├── 2025_04_15_000000_add_wikidata_id_to_operators.php │ ├── 2025_04_18_112315_create_areas_table.php │ ├── 2025_04_18_112706_create_areas_stations_maps_table.php │ ├── 2025_04_28_000000_make_foreign_key_cascase_on_areas_station_maps.php │ ├── 2025_05_01_094518_create_alerts_table.php │ ├── 2025_05_01_094703_create_alert_translations_table.php │ ├── 2025_05_05_105202_create_profile_links_table.php │ ├── 2025_05_05_110620_add_bio_to_users_table.php │ └── 2025_05_07_203458_remove-twitter.php ├── schema │ ├── mariadb-schema.sql │ ├── mysql-schema.sql │ └── sqlite-schema.sql └── seeders │ ├── CheckinSeeder.php │ ├── ClientSeeder.php │ ├── Constants │ └── PermissionSeeder.php │ ├── DatabaseSeeder.php │ ├── EventSeeder.php │ ├── FollowTableSeeder.php │ ├── PrivacyAgreementSeeder.php │ └── UsersTableSeeder.php ├── docker-compose.yml ├── docker-entrypoint.sh ├── docs ├── contributing │ ├── README.md │ ├── api.md │ ├── dev-setup.md │ └── translations.md └── traewelling.jpg ├── flake.lock ├── flake.nix ├── lang ├── ca.json ├── cs.json ├── cy.json ├── de.json ├── de │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ ├── validation-inline.php │ └── validation.php ├── de_by.json ├── de_he.json ├── de_pfl.json ├── en.json ├── en │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ ├── validation-inline.php │ └── validation.php ├── eo.json ├── es.json ├── fr.json ├── fr │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ ├── validation-inline.php │ └── validation.php ├── is.json ├── it.json ├── nb_NO.json ├── nl.json ├── nl │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ ├── validation-inline.php │ └── validation.php ├── pl.json ├── pl │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ ├── validation-inline.php │ └── validation.php ├── pt.json ├── ru.json ├── sv.json ├── sv │ ├── auth.php │ ├── pagination.php │ ├── passwords.php │ ├── validation-inline.php │ └── validation.php └── tr.json ├── package-lock.json ├── package.json ├── phpcs.xml ├── phpunit.xml ├── public ├── .htaccess ├── fonts │ └── Nunito │ │ ├── Nunito.css │ │ ├── nunito-v11-latin-ext_latin_vietnamese-regular.eot │ │ ├── nunito-v11-latin-ext_latin_vietnamese-regular.svg │ │ ├── nunito-v11-latin-ext_latin_vietnamese-regular.ttf │ │ ├── nunito-v11-latin-ext_latin_vietnamese-regular.woff │ │ └── nunito-v11-latin-ext_latin_vietnamese-regular.woff2 ├── humans.txt ├── images │ ├── covers │ │ ├── abandoned.jpg │ │ ├── derailment.jpg │ │ ├── profile-background.png │ │ ├── time.jpg │ │ └── traffic_lights.jpg │ ├── icons │ │ ├── favicon.ico │ │ ├── logo.svg │ │ ├── logo1024.png │ │ ├── logo114.png │ │ ├── logo128.png │ │ ├── logo256.png │ │ ├── logo32.png │ │ ├── logo512.png │ │ ├── logo57.png │ │ ├── logo64.png │ │ ├── logo72.png │ │ ├── logo76.png │ │ ├── touch-icon-ipad-retina.png │ │ ├── touch-icon-ipad.png │ │ ├── touch-icon-iphone-retina.png │ │ └── touch-icon-vector.svg │ └── welcome │ │ ├── map.png │ │ ├── mobile-mockup.png │ │ └── stats.png ├── img │ ├── blog │ │ └── api-umstellung-sbb.png │ ├── bus.svg │ ├── marker │ │ ├── dot-primary.svg │ │ └── dot-secondary.svg │ ├── suburban.svg │ ├── subway.svg │ ├── tram.svg │ ├── user.png │ ├── user_christmas.png │ ├── vid1.mp4 │ └── vid2.mp4 ├── index.php ├── manifest.json ├── mix-manifest.json ├── robots.txt ├── security.txt ├── uploads │ └── avatars │ │ └── .gitkeep └── web.config ├── renovate.json ├── resources ├── css │ └── welcome.css ├── js │ ├── admin.js │ ├── api │ │ ├── Event.js │ │ ├── Follow.js │ │ ├── Status.js │ │ ├── api.d.ts │ │ └── api.js │ ├── app.js │ ├── appControls.js │ ├── bootstrap.js │ └── components │ │ ├── DarkModeToggle.js │ │ ├── business-check-in.js │ │ ├── export.js │ │ ├── maps.js │ │ ├── progressbar.js │ │ ├── settings.js │ │ ├── station-autocomplete.js │ │ ├── stats.js │ │ └── tooltips.js ├── sass │ ├── _font-awesome.scss │ ├── _variables.scss │ ├── admin.scss │ ├── app-dark.scss │ ├── app.scss │ ├── base.scss │ ├── components │ │ ├── about.scss │ │ ├── activeJourneys.scss │ │ ├── custom-buttons.scss │ │ ├── dailyStats.scss │ │ ├── eventspage.scss │ │ ├── image-box.scss │ │ ├── leaderboard.scss │ │ ├── maps.scss │ │ ├── notifications-board.scss │ │ ├── search.scss │ │ ├── settings.scss │ │ ├── station-autocomplete.scss │ │ ├── stationboard.scss │ │ ├── status.scss │ │ └── timepicker.scss │ ├── fonts │ │ ├── Nunito-Regular.ttf │ │ └── nunito.scss │ ├── site.scss │ └── small-phones.scss ├── types │ ├── Api.gen.ts │ ├── Departure.ts │ ├── Notification.ts │ ├── ProfileSettings.ts │ ├── Station.ts │ ├── TrwlEvent.ts │ ├── TrwlTags.ts │ └── User.ts ├── views │ ├── activejourneys.blade.php │ ├── admin │ │ ├── activity │ │ │ ├── page.blade.php │ │ │ └── table.blade.php │ │ ├── alerts │ │ │ ├── index.blade.php │ │ │ └── show.blade.php │ │ ├── dashboard.blade.php │ │ ├── events │ │ │ ├── form.blade.php │ │ │ ├── includes │ │ │ │ └── table.blade.php │ │ │ ├── list.blade.php │ │ │ ├── suggestion-create.blade.php │ │ │ └── suggestions.blade.php │ │ ├── layout.blade.php │ │ ├── licenses │ │ │ ├── create.blade.php │ │ │ └── index.blade.php │ │ ├── operators │ │ │ └── list.blade.php │ │ ├── reports │ │ │ ├── list.blade.php │ │ │ └── show.blade.php │ │ ├── sources │ │ │ └── index.blade.php │ │ ├── stations │ │ │ ├── list.blade.php │ │ │ └── show.blade.php │ │ ├── status │ │ │ ├── edit.blade.php │ │ │ └── main.blade.php │ │ ├── trip │ │ │ └── show.blade.php │ │ └── users │ │ │ ├── index.blade.php │ │ │ ├── show.blade.php │ │ │ └── usercard.blade.php │ ├── auth │ │ ├── authorize.blade.php │ │ ├── completeRegistration.blade.php │ │ ├── login.blade.php │ │ ├── passwords │ │ │ ├── email.blade.php │ │ │ └── reset.blade.php │ │ ├── register.blade.php │ │ └── verify.blade.php │ ├── beta │ │ └── trip-creation.blade.php │ ├── changelog.blade.php │ ├── components │ │ ├── checkin-success.blade.php │ │ ├── event-rejection-button.blade.php │ │ └── user-action-button.blade.php │ ├── dashboard.blade.php │ ├── debug │ │ └── motis-source.blade.php │ ├── dev │ │ ├── access-token.blade.php │ │ ├── apps-edit.blade.php │ │ └── apps.blade.php │ ├── errors │ │ ├── 401.blade.php │ │ ├── 403.blade.php │ │ ├── 404.blade.php │ │ ├── 419.blade.php │ │ ├── 429.blade.php │ │ ├── 500.blade.php │ │ └── 503.blade.php │ ├── events │ │ └── overview.blade.php │ ├── eventsMap.blade.php │ ├── export.blade.php │ ├── includes │ │ ├── business-dropdown.blade.php │ │ ├── delete-modal.blade.php │ │ ├── edit-modal.blade.php │ │ ├── event.blade.php │ │ ├── follow-button.blade.php │ │ ├── message-block.blade.php │ │ ├── messages │ │ │ └── mail-verification.blade.php │ │ ├── modals │ │ │ └── mastodon-auth.blade.php │ │ ├── notification.blade.php │ │ ├── station-infos.blade.php │ │ ├── status.blade.php │ │ ├── statuses.blade.php │ │ └── visibility-dropdown.blade.php │ ├── layouts │ │ ├── app.blade.php │ │ ├── illustrated-layout.blade.php │ │ ├── includes │ │ │ └── meta.blade.php │ │ ├── minimal.blade.php │ │ └── settings.blade.php │ ├── leaderboard │ │ ├── includes │ │ │ └── main-table.blade.php │ │ ├── leaderboard.blade.php │ │ └── month.blade.php │ ├── legal │ │ ├── notice.blade.php │ │ └── privacy-interception.blade.php │ ├── mail │ │ └── account_deletion_notification_two_weeks_before.blade.php │ ├── open-data │ │ └── wikidata │ │ │ └── index.blade.php │ ├── pdf │ │ └── export-template.blade.php │ ├── profile │ │ ├── partials │ │ │ ├── actions.blade.php │ │ │ ├── body.blade.php │ │ │ ├── info.blade.php │ │ │ └── statuses.blade.php │ │ └── profile.blade.php │ ├── report.blade.php │ ├── search.blade.php │ ├── settings │ │ ├── account.blade.php │ │ ├── api-token.blade.php │ │ ├── blocks.blade.php │ │ ├── cards │ │ │ ├── account-deletion.blade.php │ │ │ └── password.blade.php │ │ ├── follower.blade.php │ │ ├── ics.blade.php │ │ ├── login-providers.blade.php │ │ ├── modals │ │ │ └── deleteUserModal.blade.php │ │ ├── mutes.blade.php │ │ ├── privacy.blade.php │ │ ├── profile.blade.php │ │ ├── sessions.blade.php │ │ └── webhooks.blade.php │ ├── stats │ │ ├── daily.blade.php │ │ ├── stations.blade.php │ │ └── stats.blade.php │ ├── status.blade.php │ ├── vendor │ │ ├── l5-swagger │ │ │ ├── .gitkeep │ │ │ └── index.blade.php │ │ └── pagination │ │ │ ├── bootstrap-4.blade.php │ │ │ └── simple-bootstrap-4.blade.php │ ├── vuestationboard.blade.php │ └── welcome │ │ ├── partials │ │ ├── login.blade.php │ │ ├── mastodon-modal.blade.php │ │ └── nav-links.blade.php │ │ └── welcome.blade.php └── vue │ ├── components │ ├── ActiveJourneyMap.vue │ ├── ActiveStatusCard.vue │ ├── ApiAlerts.vue │ ├── Checkin │ │ ├── AutocompleteListEntry.vue │ │ ├── CheckinInterface.vue │ │ └── StationBoardEntry.vue │ ├── CheckinLineRun.vue │ ├── CheckinSuccessHelper.vue │ ├── EventDropdown.vue │ ├── Events │ │ └── Request.vue │ ├── FullScreenModal.vue │ ├── Helpers │ │ ├── FriendDropdown.vue │ │ ├── HelpPageLink.vue │ │ └── UserSearchDropdown.vue │ ├── LineIndicator.vue │ ├── ModalComponent.vue │ ├── NotificationBell.vue │ ├── NotificationEntry.vue │ ├── NotificationList.vue │ ├── ProductIcon.vue │ ├── Settings │ │ ├── FriendCheckinSettings.vue │ │ ├── Partials │ │ │ ├── DataLilst.vue │ │ │ ├── Input.vue │ │ │ ├── Select.vue │ │ │ ├── SelectOption.ts │ │ │ └── Textfield.vue │ │ ├── ProfileSettings.vue │ │ └── Webhooks.vue │ ├── Spinner.vue │ ├── StationAutocomplete │ │ └── StationAutocomplete.vue │ ├── Stationboard.vue │ ├── Stats │ │ ├── ChartCategories.vue │ │ ├── ChartCompanies.vue │ │ ├── ChartPurpose.vue │ │ ├── ChartVolume.vue │ │ ├── GlobalCards.vue │ │ └── StatsDashboard.vue │ ├── TagHelper.vue │ ├── TagList.vue │ ├── TagRow.vue │ ├── TripCreation │ │ ├── StationInput.vue │ │ ├── TripCreationForm.vue │ │ └── TripCreationMap.vue │ └── VisibilityDropdown.vue │ ├── helpers │ ├── DateRange.ts │ ├── DateTime.ts │ ├── NextStation.ts │ ├── NotyfHelper.ts │ └── StatusTag.js │ └── stores │ ├── activeCheckin.ts │ ├── checkinSuccess.ts │ ├── notifications.ts │ ├── profileSettings.ts │ └── user.ts ├── routes ├── api.php ├── channels.php ├── console.php ├── web.php └── web │ └── admin.php ├── scripts ├── convert-polylines.sh ├── generate-version.sh ├── install.sh └── services │ ├── README.md │ ├── traewelling-queue-export.service │ ├── traewelling-queue-webhook.service │ ├── traewelling-queue.service │ ├── traewelling-scheduler.service │ └── traewelling-scheduler.timer ├── server.php ├── storage ├── api-docs │ └── api-docs.json ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── debugbar │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── maintenance.php │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore ├── logs │ └── .gitignore └── polylines │ └── .gitignore ├── tests ├── ApiTestCase.php ├── CreatesApplication.php ├── Feature │ ├── APIv1 │ │ ├── AuthTest.php │ │ ├── CheckinTest.php │ │ ├── EventTest.php │ │ ├── FollowTest.php │ │ ├── FriendCheckinTest.php │ │ ├── IcsTest.php │ │ ├── LikesTest.php │ │ ├── NotificationsTest.php │ │ ├── OperatorTest.php │ │ ├── ReportTest.php │ │ ├── SettingsTest.php │ │ ├── StationTest.php │ │ ├── StatisticsTest.php │ │ ├── StatusTagTest.php │ │ ├── StatusTest.php │ │ ├── TrainStationTest.php │ │ ├── TransportTest.php │ │ ├── TrustedUserTest.php │ │ ├── UserBlockTest.php │ │ ├── UserDeletionTest.php │ │ ├── UserMuteTest.php │ │ └── UserSearchTest.php │ ├── Admin │ │ └── SettingPermissionsTest.php │ ├── BackendAccessTest.php │ ├── CheckinTest.php │ ├── Commands │ │ ├── AccountDeletionTest.php │ │ └── CleanUpTest.php │ ├── Dev │ │ └── EditOAuthClientTest.php │ ├── DistanceCalculationTest.php │ ├── EventSuggestionCorrectionTest.php │ ├── EventSuggestionTest.php │ ├── ExampleTest.php │ ├── ExportTripsTest.php │ ├── Frontend │ │ ├── Auth │ │ │ ├── EmailVerificationTest.php │ │ │ ├── LoginTest.php │ │ │ ├── PasswordResetTest.php │ │ │ └── RegisterTest.php │ │ └── LanguageTest.php │ ├── MentionTest.php │ ├── Privacy │ │ ├── PrivacyPolicyServiceTest.php │ │ ├── Status │ │ │ └── ViewTest.php │ │ └── StatusTagPrivacyTest.php │ ├── PrivateProfileFollowerRelationsTest.php │ ├── Profile │ │ ├── ProfileTest.php │ │ └── UserModelRelationshipTest.php │ ├── Services │ │ └── UserGdprDataServiceTest.php │ ├── Social │ │ └── MastodonControllerTest.php │ ├── StaticPagesThatMightHaveComputedPropertiesTest.php │ ├── StationSearchTest.php │ ├── Status │ │ ├── LikeTest.php │ │ ├── StatusBodyTest.php │ │ └── TimeTypeTest.php │ ├── TelegramServiceTest.php │ ├── Transport │ │ ├── BackendCheckinTest.php │ │ ├── CheckinDurationTest.php │ │ ├── ManualTripCreatorTest.php │ │ ├── TransportStatsTest.php │ │ ├── cecilienhof-departures.json │ │ ├── cecilienhof-location.json │ │ ├── cecilienhof-tripinfo.json │ │ ├── frankfurt-flughafen-tripinfo.json │ │ ├── frankfurt-flughafenbus-departures.json │ │ ├── plantagenstr-departures.json │ │ ├── plantagenstr-tripinfo.json │ │ ├── ringbahn-via-suedkreuz-departures.json │ │ ├── ringbahn-via-suedkreuz-location.json │ │ └── ringbahn-via-suedkreuz-tripinfo.json │ ├── UserBlockTest.php │ ├── UserRedirectionTest.php │ ├── WebFingerTest.php │ └── Webhooks │ │ ├── RemoveAbsentWebhooksListenerTest.php │ │ ├── WebhookNotificationTest.php │ │ └── WebhookStatusTest.php ├── FeatureTestCase.php ├── Helpers │ └── CheckinRequestTestHydrator.php ├── TestCase.php ├── TestHelpers │ └── HafasHelpers.php ├── Unit │ ├── Casts │ │ └── UTCTimeMethodTest.php │ ├── Dto │ │ └── CoordinateTest.php │ ├── EventTest.php │ ├── HelperMethodTest.php │ ├── Helpers │ │ ├── CacheKeyTest.php │ │ └── FormatterTest.php │ ├── Hydrators │ │ ├── CheckinRequestHydratorTest.php │ │ ├── MotisHydratorTest.php │ │ └── _data │ │ │ ├── motis_departures.json │ │ │ └── motis_leg.json │ ├── MentionTest.php │ ├── PrivacyHelperTest.php │ ├── ProfilePictureTest.php │ ├── Providers │ │ └── PrometheusServiceProviderTest.php │ ├── Services │ │ ├── Exporters │ │ │ ├── BaseExporterTest.php │ │ │ ├── ExporterTest.php │ │ │ └── TestBaseExporter.php │ │ ├── GeoServiceTest.php │ │ ├── MastodonDomainExtractionServiceTest.php │ │ ├── PrideServiceTest.php │ │ └── ReportServiceTest.php │ ├── Transport │ │ └── PointsCalculationTest.php │ └── UnitTestCase.php └── static │ └── avatars │ ├── stock_146ic.png │ ├── stock_146me.png │ ├── stock_218.png │ ├── stock_424.png │ ├── stock_avg_et.png │ ├── stock_cantus.png │ ├── stock_eurobahn.png │ ├── stock_ic2.png │ ├── stock_ice.png │ ├── stock_schienenbus.png │ ├── stock_sncf2.png │ ├── stock_ssb.png │ ├── stock_uestra.png │ ├── stock_vy.png │ └── stock_wikopf_sandwich.png ├── tsconfig.json └── vite.config.mts /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .env.* 3 | .github 4 | docker/ 5 | node_modules/ 6 | vendor/ 7 | *.md 8 | docs/traewelling.jpg 9 | phpunit.xml 10 | phpcs.xml 11 | Dockerfile 12 | codesize.xml 13 | api-swagger-v0.yml 14 | .styleci.yml 15 | tests/ 16 | public/css/ 17 | public/js/ 18 | database/docker-container-state/ 19 | avatars/ 20 | database-data/ 21 | Dockerfile 22 | .devenv 23 | .direnv 24 | -------------------------------------------------------------------------------- /.env.testing: -------------------------------------------------------------------------------- 1 | APP_ENV=testing 2 | APP_KEY=base64:GlZCNd4MpfM2zUFhiLhgYokTZZmYoKf8z9h+wwE5Ps4= 3 | APP_DEBUG=true 4 | APP_URL=http://127.0.0.1:8000/ 5 | 6 | DB_CONNECTION=sqlite 7 | DB_DATABASE=:memory: 8 | 9 | CACHE_DRIVER=array 10 | WEBHOOKS_ACTIVE=true 11 | WEBFINGER_ACTIVE=true 12 | 13 | PRIVACY_ACCOUNT_DELETION_SEND_NOTIFICATION=true 14 | PRIVACY_ACCOUNT_DELETION_DELETE_ACCOUNT=true 15 | 16 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use flake . --impure 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 🤔 Questions / Support 4 | url: https://github.com/Traewelling/traewelling/discussions/new?category=questions-support 5 | about: For Questions and Support in English 🇬🇧 and German 🇩🇪 6 | - name: 🚀 Feature Request 7 | url: https://github.com/Traewelling/traewelling/discussions/new?category=ideas-feature-requests 8 | about: Please check if your feature request already exists and upvote it 9 | -------------------------------------------------------------------------------- /.github/workflows/nodejs-audit.yml: -------------------------------------------------------------------------------- 1 | name: Check for node vulnerabilities 2 | 3 | on: [ push, pull_request ] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [ 20.x ] 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: Check for vulnerabilities 21 | run: npm audit 22 | -------------------------------------------------------------------------------- /.github/workflows/nodejs-prod.yml: -------------------------------------------------------------------------------- 1 | name: Resources build with `prod` 2 | 3 | on: [ push, pull_request ] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [ 18.x, 20.x ] 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: Install dependencies 21 | run: npm ci 22 | - name: Run production build 23 | run: npm run build 24 | -------------------------------------------------------------------------------- /.neoconf.json: -------------------------------------------------------------------------------- 1 | { 2 | "lspconfig": { 3 | "intelephense": { 4 | "intelephense.format.braces": "k&r" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | php: 2 | preset: laravel 3 | disabled: 4 | - unused_use 5 | finder: 6 | not-name: 7 | - index.php 8 | - server.php 9 | js: 10 | finder: 11 | not-name: 12 | - webpack.mix.js 13 | css: true 14 | -------------------------------------------------------------------------------- /app/Console/Commands/AccountDeletion.php: -------------------------------------------------------------------------------- 1 | delete(); 15 | $this->info($affectedRows . ' expired trusted users deleted.'); 16 | return 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Console/Commands/ReduceRelevance.php: -------------------------------------------------------------------------------- 1 | info('Reducing relevance of all stations by 10...'); 15 | 16 | DB::table('train_stations') 17 | ->where('relevance', '>', 0) 18 | ->update(['relevance' => DB::raw('relevance / 10')]); 19 | 20 | $this->info('Relevance reduced successfully.'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Console/Commands/RefreshOperatorMappings.php: -------------------------------------------------------------------------------- 1 | refreshFiles(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/DataProviders/FptfHelper.php: -------------------------------------------------------------------------------- 1 | upperLeft = $topLeft; 14 | $this->lowerRight = $bottomRight; 15 | } 16 | 17 | public function toArray(): array { 18 | return [ 19 | 'topLeft' => $this->upperLeft->toArray(), 20 | 'bottomRight' => $this->lowerRight->toArray() 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Dto/GeoJson/Properties.php: -------------------------------------------------------------------------------- 1 | properties = $properties; 12 | } 13 | 14 | public function addProperty(string $key, mixed $value): void 15 | { 16 | $this->properties[$key] = $value; 17 | } 18 | 19 | public function toArray(): array 20 | { 21 | return $this->properties; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Dto/LicenseDto.php: -------------------------------------------------------------------------------- 1 | licenseName = $licenseName; 21 | $this->attributionString = $attributionString; 22 | $this->licenseUrl = $licenseUrl; 23 | $this->sourceUrl = $sourceUrl; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Enum/BrouterProfile.php: -------------------------------------------------------------------------------- 1 | value)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Enum/MapProvider.php: -------------------------------------------------------------------------------- 1 | 0, 16 | self::SPAM => 10, 17 | self::OTHER => 20, 18 | self::INAPPROPRIATE => 50, 19 | self::ILLEGAL => 100, 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Enum/Report/ReportStatus.php: -------------------------------------------------------------------------------- 1 | 'time-is-planned', 15 | self::REALTIME => 'time-is-real', 16 | self::MANUAL => 'time-is-manual' 17 | }; 18 | } 19 | 20 | public function getTooltip(): string { 21 | return __(self::getTooltipStringId($this)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Enum/User/FriendCheckinSetting.php: -------------------------------------------------------------------------------- 1 | status = $status; 16 | Log::debug("Dispatching StatusDeleteEvent event for status#" . $status->id); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Events/StatusUpdateEvent.php: -------------------------------------------------------------------------------- 1 | status = $status; 18 | Log::debug("Dispatching StatusUpdateEvent event for status#" . $status->id); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Exceptions/AlreadyFollowingException.php: -------------------------------------------------------------------------------- 1 | initiator = $initiator; 23 | $this->user = $user; 24 | parent::__construct(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Exceptions/CheckInCollisionException.php: -------------------------------------------------------------------------------- 1 | checkin = $checkin; 13 | parent::__construct(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/Exceptions/Checkin/AlreadyCheckedInException.php: -------------------------------------------------------------------------------- 1 | reference = $reference ?? uniqid(); 14 | parent::__construct($message); 15 | } 16 | 17 | public function context(): array { 18 | return ['reference' => $this->reference] + $this->context; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Exceptions/ShouldDeleteNotificationException.php: -------------------------------------------------------------------------------- 1 | user = $user; 15 | $this->status = $status; 16 | parent::__construct(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Exceptions/TelegramException.php: -------------------------------------------------------------------------------- 1 | user())); 14 | } 15 | 16 | public function deleteAllSessions(): JsonResponse { 17 | SessionBackend::deleteAllSessionsFor(user: auth()->user()); 18 | 19 | return $this->sendResponse(null, 204); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Controllers/Backend/Admin/EventController.php: -------------------------------------------------------------------------------- 1 | first()) { 17 | $i = empty($i) ? 1 : $i + 1; 18 | } 19 | if (!empty($i)) { 20 | return $slug . $i; 21 | } 22 | return $slug; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Http/Controllers/Backend/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | $login, 'password' => $password], $remember)) { 15 | auth()->user()->update(['last_login' => now()]); 16 | return true; 17 | } 18 | 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Controllers/Backend/Transport/HomeController.php: -------------------------------------------------------------------------------- 1 | update(...) directly...? 18 | */ 19 | public static function setHome(User $user, Station $station): Station { 20 | $user->update([ 21 | 'home_id' => $station->id 22 | ]); 23 | return $station; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Controllers/Backend/Transport/StatusTagController.php: -------------------------------------------------------------------------------- 1 | tags->filter(function(StatusTag $tag) use ($user) { 16 | return Gate::forUser($user)->allows('view', $tag); 17 | }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Controllers/Backend/User/BlockController.php: -------------------------------------------------------------------------------- 1 | blockedUsers->contains('id', $userToCheck->id); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | findOrFail($id); 14 | return view('admin.trip.show', [ 15 | 'trip' => $trip 16 | ]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Controllers/Frontend/EventController.php: -------------------------------------------------------------------------------- 1 | with(['station']) 17 | ->paginate(15); 18 | return view('events.overview', [ 19 | 'liveAndUpcomingEvents' => $events 20 | ]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Controllers/Frontend/VueFrontendController.php: -------------------------------------------------------------------------------- 1 | Station::find((int) $request->stationId) 14 | ]); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Http/Middleware/Api/JsonMiddleware.php: -------------------------------------------------------------------------------- 1 | headers->set('Accept', 'application/json'); 20 | 21 | return $next($request); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 19 | return route('login'); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Middleware/CheckForMaintenanceMode.php: -------------------------------------------------------------------------------- 1 | check()) { 20 | return redirect('/dashboard'); 21 | } 22 | 23 | return $next($request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 'required|exists:licenses,id', 16 | 'source_ids' => 'required|array', 17 | ]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Resources/PrivacyPolicyResource.php: -------------------------------------------------------------------------------- 1 | $this->valid_at, 20 | 'en' => $this->body_md_en, 21 | 'de' => $this->body_md_de 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Http/Resources/StatisticsGlobalData.php: -------------------------------------------------------------------------------- 1 | $this->distance, 19 | 'duration' => $this->duration, 20 | 'activeUsers' => $this->user_count 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Resources/StatisticsTravelPurposeResource.php: -------------------------------------------------------------------------------- 1 | $this->reason, 19 | 'count' => $this->count, 20 | 'duration' => $this->duration 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Resources/StatusExportResource.php: -------------------------------------------------------------------------------- 1 | new StatusResource($this), 20 | "trip" => new TripResource($this->checkin->trip), 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Http/Resources/TrustedUserResource.php: -------------------------------------------------------------------------------- 1 | new LightUserResource($this->trusted), 19 | 'expiresAt' => $this->expires_at?->toIso8601String() 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Http/Resources/UserNotificationMessageResource.php: -------------------------------------------------------------------------------- 1 | $this['icon'] ?? '', 20 | 'severity' => $this['severity'] ?? 'notice', 21 | 'lead' => $this['lead'] ?? [], 22 | 'notice' => $this['notice'] ?? [] 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Resources/WebhookEventResource.php: -------------------------------------------------------------------------------- 1 | $this->event->value, 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Interfaces/IconEnumInterface.php: -------------------------------------------------------------------------------- 1 | channel !== 'database') { 12 | return; 13 | } 14 | $notification = $event->notifiable->notifications->where('id', $event->notification->id)->first(); 15 | WebhookController::sendNotificationWebhook($event->notifiable, $notification); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Listeners/StatusCreateCheckPolylineListener.php: -------------------------------------------------------------------------------- 1 | status->checkin->trip); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/Listeners/StatusCreateWebhookListener.php: -------------------------------------------------------------------------------- 1 | status, WebhookEvent::CHECKIN_CREATE); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Listeners/StatusUpdateWebhookListener.php: -------------------------------------------------------------------------------- 1 | status, WebhookEvent::CHECKIN_UPDATE); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/Models/Alert.php: -------------------------------------------------------------------------------- 1 | 'datetime', 22 | 'active_until' => 'datetime', 23 | ]; 24 | 25 | public function translations(): HasMany { 26 | return $this->hasMany(AlertTranslation::class, 'alert_id', 'id'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Models/AlertTranslation.php: -------------------------------------------------------------------------------- 1 | belongsTo(Alert::class); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/Area.php: -------------------------------------------------------------------------------- 1 | 'string', 16 | 'name' => 'string', 17 | 'adminLevel' => 'integer', 18 | ]; 19 | 20 | public function stations(): BelongsToMany { 21 | return $this->belongsToMany(Station::class, 'areas_stations_maps') 22 | ->withPivot(['default']) 23 | ->using(AreasStationsMap::class); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/IcsToken.php: -------------------------------------------------------------------------------- 1 | 'integer', 16 | 'user_id' => 'integer', 17 | 'last_accessed' => 'datetime', 18 | ]; 19 | 20 | public function user(): BelongsTo { 21 | return $this->belongsTo(User::class, 'user_id', 'id'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Models/License.php: -------------------------------------------------------------------------------- 1 | hasMany(MotisSourceLicense::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Models/Like.php: -------------------------------------------------------------------------------- 1 | 'integer', 17 | 'user_id' => 'integer', 18 | 'status_id' => 'integer', 19 | ]; 20 | 21 | public function user(): BelongsTo { 22 | return $this->belongsTo(User::class); 23 | } 24 | 25 | public function status(): BelongsTo { 26 | return $this->belongsTo(Status::class); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/Models/MastodonServer.php: -------------------------------------------------------------------------------- 1 | 'integer', 13 | ]; 14 | protected $hidden = ['client_id', 'client_secret']; 15 | 16 | public function socialProfiles(): HasMany { 17 | return $this->hasMany(SocialLoginProfile::class, 'mastodon_server', 'id'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Models/PrivacyAgreement.php: -------------------------------------------------------------------------------- 1 | 'integer', 12 | 'valid_at' => 'datetime', 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /app/Models/ProfileLink.php: -------------------------------------------------------------------------------- 1 | ProfileLinkName::class, 22 | 'created_at' => 'datetime', 23 | 'updated_at' => 'datetime', 24 | ]; 25 | 26 | public function user(): BelongsTo { 27 | return $this->belongsTo(User::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Models/Session.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Models/StationName.php: -------------------------------------------------------------------------------- 1 | 'integer', 18 | 'language' => 'string', 19 | 'name' => 'string' 20 | ]; 21 | 22 | public function station(): BelongsTo { 23 | return $this->belongsTo(Station::class, 'station_id', 'id'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/WebhookEvent.php: -------------------------------------------------------------------------------- 1 | 'integer', 19 | 'event' => WebhookEventEnum::class, 20 | ]; 21 | 22 | public function webhook(): HasOne { 23 | return $this->hasOne(Webhook::class, 'id', 'webhook_id'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/WikidataEntity.php: -------------------------------------------------------------------------------- 1 | 'string', 13 | 'data' => 'array', 14 | 'last_updated_at' => 'datetime' 15 | ]; 16 | } 17 | -------------------------------------------------------------------------------- /app/Notifications/BaseNotification.php: -------------------------------------------------------------------------------- 1 | isDirty(['origin', 'destination', 'departure', 'arrival', 'manual_departure', 'manual_arrival'])) { 12 | //if origin, destination, departure or arrival is changed, update duration 13 | TrainCheckinController::calculateCheckinDuration($checkin->fresh()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Observers/FollowObserver.php: -------------------------------------------------------------------------------- 1 | where('notifiable_id', $follow->follow_id) 16 | ->where('data->follower->id', $follow->user_id) 17 | ->delete(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Observers/LikeObserver.php: -------------------------------------------------------------------------------- 1 | where('data->status->id', $like->status_id) 15 | ->where('data->liker->id', $like->user_id) 16 | ->delete(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Observers/TripObserver.php: -------------------------------------------------------------------------------- 1 | source === TripSource::USER) { 15 | (new ReportService())->checkAndReport( 16 | $trip->linename, 17 | ReportableSubject::TRIP, 18 | $trip->id 19 | ); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/Policies/AlertPolicy.php: -------------------------------------------------------------------------------- 1 | can('alerts.manage'); 17 | } 18 | 19 | public function update(User $user, Alert $alert): bool { 20 | return $user->can('alerts.manage'); 21 | } 22 | 23 | public function delete(User $user, Alert $alert): bool { 24 | return $user->can('alerts.manage'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Policies/FollowPolicy.php: -------------------------------------------------------------------------------- 1 | cannot('disallow-social-interaction'); 15 | } 16 | 17 | public function delete(User $user, Follow $follow): bool { 18 | return $user->id == $follow->follow_id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Policies/LikePolicy.php: -------------------------------------------------------------------------------- 1 | cannot('disallow-social-interaction'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/Policies/OperatorPolicy.php: -------------------------------------------------------------------------------- 1 | hasRole('admin'); 14 | } 15 | 16 | public function update(User $user, HafasOperator $hafasOperator): bool { 17 | return $user->hasRole('admin'); 18 | } 19 | 20 | public function delete(User $user, HafasOperator $hafasOperator): bool { 21 | return $user->hasRole('admin'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/Policies/ReportPolicy.php: -------------------------------------------------------------------------------- 1 | hasRole('admin'); 12 | } 13 | 14 | public function view(User $user, Report $report): bool { 15 | return $user->hasRole('admin'); 16 | } 17 | 18 | public function update(User $user, Report $report): bool { 19 | return $user->hasRole('admin'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Policies/TokenPolicy.php: -------------------------------------------------------------------------------- 1 | user->id === $user->id; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | whereCondition ?? 'id'; 11 | 12 | return $this->model::where( 13 | $this->whereColumn, 14 | $this->user->{$condition} 15 | )->get()->toJson(); 16 | } 17 | 18 | protected function onExportValidation(): bool { 19 | return !empty($this->model) && !empty($this->whereColumn); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Services/PersonalDataSelection/Exporters/EventSuggestionsExporter.php: -------------------------------------------------------------------------------- 1 | user->isBlockedByAuthUser ? __('user.unblock-tooltip') : __('user.block-tooltip'); 10 | } 11 | 12 | public function getRoute(): string { 13 | return $this->user->isBlockedByAuthUser ? route('user.unblock') : route('user.block'); 14 | } 15 | 16 | public function getIcon(): string { 17 | return $this->user->isBlockedByAuthUser ? 'fa-unlock' : 'fa-ban'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/View/Components/EventRejectionButton.php: -------------------------------------------------------------------------------- 1 | user->muted ? __('user.unmute-tooltip') : __('user.mute-tooltip'); 9 | } 10 | 11 | public function getRoute(): string { 12 | return $this->user->muted ? route('user.unmute') : route('user.mute'); 13 | } 14 | 15 | public function getIcon(): string { 16 | return $this->user->muted ? 'fa-eye' : 'fa-eye-slash'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Virtual/Models/LikeResponse.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'max_attempts' => env('STATUS_LIKE_MAX_ATTEMPTS', 20), 6 | 'decay_minutes' => env('STATUS_LIKE_DECAY_MINUTES', 10), 7 | ], 8 | ]; 9 | 10 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | *.sqlite-journal 3 | docker-container-state 4 | -------------------------------------------------------------------------------- /database/README.md: -------------------------------------------------------------------------------- 1 | # database folder 2 | 3 | This folder holds a number of files that are related to the database and the data structure behind Träwelling. 4 | 5 | To create a new migration, please think of a speaking name and generate a migration class like this: 6 | ```cmd 7 | php artisan make:migration "add train identifier field to statuses table" 8 | ``` 9 | 10 | -------------------------------------------------------------------------------- /database/factories/FollowFactory.php: -------------------------------------------------------------------------------- 1 | User::factory(), 14 | 'follow_id' => User::factory(), 15 | ]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /database/factories/HafasOperatorFactory.php: -------------------------------------------------------------------------------- 1 | faker->company; 12 | return [ 13 | 'hafas_id' => Str::slug($companyName . $this->faker->hexColor, '_'), 14 | 'name' => $companyName, 15 | ]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /database/factories/IcsTokenFactory.php: -------------------------------------------------------------------------------- 1 | User::factory(), 15 | 'token' => $this->faker->unique()->uuid 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /database/factories/LikeFactory.php: -------------------------------------------------------------------------------- 1 | User::factory(), 14 | 'status_id' => Status::factory(), 15 | ]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /database/factories/LocationFactory.php: -------------------------------------------------------------------------------- 1 | 'DB Lounge ' . ($this->faker->boolean ? 'Premium ' : '') . $this->faker->city, 12 | 'address_street' => $this->faker->streetAddress, 13 | 'address_zip' => $this->faker->postcode, 14 | 'address_city' => $this->faker->city, 15 | 'latitude' => $this->faker->latitude(48.0, 51.0), 16 | 'longitude' => $this->faker->longitude(9.0, 10.0), 17 | ]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /database/factories/RemarkFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->sentence, 13 | 'type' => $this->faker->unique()->word, 14 | 'code' => $this->faker->unique()->word, 15 | 'summary' => $this->faker->sentence, 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /database/factories/StationIdentifierFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->numberBetween(0, 100), 13 | 'station_id' => $this->faker->numberBetween(1, 100), 14 | 'identifier' => $this->faker->uuid, 15 | 'type' => $this->faker->randomElement(['motis']), 16 | 'origin' => $this->faker->randomElement([TripSource::TRANSITOUS]), 17 | 'name' => $this->faker->city, 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/factories/StatusFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->paragraph, 15 | 'user_id' => User::factory(), 16 | 'business' => $this->faker->randomElement(Business::cases())->value, //TODO: rename to travelReason 17 | 'visibility' => StatusVisibility::PUBLIC, 18 | 'event_id' => null, 19 | ]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/factories/UserMuteFactory.php: -------------------------------------------------------------------------------- 1 | User::factory(), 15 | 'muted_id' => User::factory(), 16 | ]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /database/migrations/2016_06_01_000005_create_oauth_personal_access_clients_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 12 | $table->integer('client_id'); 13 | $table->timestamps(); 14 | }); 15 | } 16 | 17 | public function down(): void { 18 | Schema::dropIfExists('oauth_personal_access_clients'); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2019_12_20_221724_create_user_roles.php: -------------------------------------------------------------------------------- 1 | tinyInteger('role')->default('0')->after('home_id'); 17 | }); 18 | } 19 | 20 | /** 21 | * Reverse the migrations. 22 | * 23 | * @return void 24 | */ 25 | public function down() { 26 | Schema::dropColumns('users', ['role']); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database/migrations/2020_09_28_150313_migrate_notifications_to_laravel8.php: -------------------------------------------------------------------------------- 1 | where('notifiable_type', 'App\User') 16 | ->update([ 17 | 'notifiable_type' => 'App\Models\User' 18 | ]); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() { 27 | //cannot undo 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /database/migrations/2021_02_01_000000_add_unique_key_to_poly_lines.php: -------------------------------------------------------------------------------- 1 | unique(['hash']); 12 | }); 13 | } 14 | 15 | 16 | public function down(): void { 17 | Schema::table('poly_lines', function(Blueprint $table) { 18 | $table->dropUnique(['hash']); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/migrations/2021_02_20_155443_remove_static_points_from_users.php: -------------------------------------------------------------------------------- 1 | dropColumn('points'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('users', function(Blueprint $table) { 18 | $table->integer('points') 19 | ->unsigned() 20 | ->default(0) 21 | ->after('train_duration'); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /database/migrations/2021_02_23_170640_create_hafas_operators_table.php: -------------------------------------------------------------------------------- 1 | id(); 12 | $table->string('hafas_id')->unique(); 13 | $table->string('name'); 14 | $table->timestamps(); 15 | }); 16 | } 17 | 18 | public function down(): void { 19 | Schema::dropIfExists('hafas_operators'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/migrations/2021_05_10_201216_add_language_to_users.php: -------------------------------------------------------------------------------- 1 | string('language', 12) 13 | ->default(null) 14 | ->nullable() 15 | ->after('role'); 16 | }); 17 | } 18 | 19 | public function down(): void { 20 | Schema::table('users', function(Blueprint $table) { 21 | $table->dropColumn('language'); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /database/migrations/2021_06_07_145349_add_visibility_to_statuses.php: -------------------------------------------------------------------------------- 1 | unsignedTinyInteger('visibility') 12 | ->default(0) 13 | ->after('business'); 14 | }); 15 | } 16 | 17 | public function down(): void { 18 | Schema::table('statuses', function(Blueprint $table) { 19 | $table->dropColumn('visibility'); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/migrations/2021_07_04_002719_drop_points_calculation_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 16 | $table->string('type'); 17 | $table->string('transport_type')->nullable(); 18 | $table->integer('value'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /database/migrations/2021_08_05_214231_remove_delay_from_train_checkins.php: -------------------------------------------------------------------------------- 1 | dropColumn(['delay']); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('train_checkins', function(Blueprint $table) { 18 | $table->integer('delay')->nullable()->after('points'); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/migrations/2021_10_08_132506_make_twitter_id_unique_in_social_login_profiles.php: -------------------------------------------------------------------------------- 1 | unique(['twitter_id']); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('social_login_profiles', function(Blueprint $table) { 18 | $table->dropUnique(['twitter_id']); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/migrations/2021_11_03_211948_add_unique_key_to_train_checkins.php: -------------------------------------------------------------------------------- 1 | unique(['user_id', 'trip_id', 'origin', 'departure'], 'user_trip_origin_departure'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('train_checkins', function(Blueprint $table) { 18 | $table->dropUnique('user_trip_origin_departure'); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/migrations/2022_03_29_000000_add_index_to_train_stopovers.php: -------------------------------------------------------------------------------- 1 | index(['trip_id', 'train_station_id', 'arrival_planned', 'departure_planned'], 'trip_station_time'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('train_stopovers', static function(Blueprint $table) { 18 | $table->dropIndex('trip_station_time'); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_04_01_000000_remove_support_code_from_users.php: -------------------------------------------------------------------------------- 1 | mediumInteger('support_code')->unsigned()->after('role')->nullable(); 17 | }); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /database/migrations/2022_04_03_000000_create_user_agents_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | $table->string('user_agent')->unique(); 14 | $table->timestamps(); 15 | }); 16 | } 17 | 18 | public function down(): void { 19 | Schema::dropIfExists('user_agents'); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_04_07_085923_change_status_code_datatype_in_api_logs_table.php: -------------------------------------------------------------------------------- 1 | unsignedSmallInteger('status_code')->nullable()->change(); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('api_logs', static function(Blueprint $table) { 18 | $table->unsignedTinyInteger('status_code')->nullable()->change(); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_06_04_000001_make_order_number_nullable_at_carriage_sequences.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('order_number')->nullable()->change(); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('carriage_sequences', static function(Blueprint $table) { 18 | $table->unsignedInteger('order_number')->change(); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_07_21_000001_add_index_to_user_agents.php: -------------------------------------------------------------------------------- 1 | index(['id', 'user_agent']); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('user_agents', static function(Blueprint $table) { 18 | $table->dropIndex(['id', 'user_agent']); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_07_23_000000_add_forced_to_train_checkins.php: -------------------------------------------------------------------------------- 1 | boolean('forced')->default(false)->after('points'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('train_checkins', static function(Blueprint $table) { 18 | $table->dropColumn('forced'); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_08_31_000000_add_last_refreshed_to_hafas_trips.php: -------------------------------------------------------------------------------- 1 | timestamp('last_refreshed')->nullable()->after('arrival'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('hafas_trips', static function(Blueprint $table) { 18 | $table->dropColumn('last_refreshed'); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_09_26_000001_add_tweet_id_to_statuses.php: -------------------------------------------------------------------------------- 1 | string('tweet_id')->nullable()->after('event_id'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('statuses', static function(Blueprint $table) { 18 | $table->dropColumn('tweet_id'); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2022_10_17_000000_default_uuid_field.php: -------------------------------------------------------------------------------- 1 | string('uuid')->default('UUID()')->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('failed_jobs', static function(Blueprint $table) { 17 | $table->string('uuid')->default(null)->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2022_12_11_000000_drop_trip_remarks.php: -------------------------------------------------------------------------------- 1 | dropColumn('always_dbl'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('users', function(Blueprint $table) { 17 | $table->boolean('always_dbl')->default(false); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_01_21_000000_add_journey_number_to_hafas_trips.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('journey_number')->nullable()->after('linename'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('hafas_trips', static function(Blueprint $table) { 18 | $table->dropColumn('journey_number'); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2023_01_28_000000_migrate_passport_from_v7_to_v8.php: -------------------------------------------------------------------------------- 1 | string('secret', 100)->nullable()->change(); 12 | }); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000000_add_index_to_train_checkins.php: -------------------------------------------------------------------------------- 1 | index(['departure', 'arrival']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('train_checkins', static function(Blueprint $table) { 17 | $table->dropIndex(['departure', 'arrival']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000000_migrate_oauth_access_tokens.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('user_id')->nullable()->change(); 12 | $table->unsignedBigInteger('client_id')->change(); 13 | }); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000000_migrate_oauth_auth_codes.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('user_id')->change(); 12 | $table->index(['user_id']); 13 | $table->unsignedBigInteger('client_id')->change(); 14 | }); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000000_migrate_oauth_clients.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id')->change(); 12 | $table->unsignedBigInteger('user_id')->nullable()->change(); 13 | }); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000000_migrate_oauth_personal_access_clients.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('client_id')->change(); 12 | }); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000001_add_index_to_users.php: -------------------------------------------------------------------------------- 1 | unique(['email']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('users', static function(Blueprint $table) { 17 | $table->dropUnique(['email']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_03_23_000002_add_index_to_train_stations.php: -------------------------------------------------------------------------------- 1 | index(['rilIdentifier']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('train_stations', static function(Blueprint $table) { 17 | $table->dropIndex(['rilIdentifier']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_04_25_000000_add_source_to_poly_lines.php: -------------------------------------------------------------------------------- 1 | enum('source', ['hafas', 'brouter']) 12 | ->default('hafas') 13 | ->after('polyline'); 14 | }); 15 | } 16 | 17 | public function down(): void { 18 | Schema::table('poly_lines', static function(Blueprint $table) { 19 | $table->dropColumn(['source']); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2023_05_07_135454_add_likes_enabled_field_to_users_table.php: -------------------------------------------------------------------------------- 1 | boolean('likes_enabled') 12 | ->default(true) 13 | ->after('language'); 14 | }); 15 | } 16 | 17 | public function down(): void { 18 | Schema::table('users', static function(Blueprint $table) { 19 | $table->dropColumn('likes_enabled'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2023_05_09_000000_make_station_id_null_on_events.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('station_id')->default(null)->nullable()->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('events', static function(Blueprint $table) { 17 | $table->unsignedBigInteger('station_id')->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_05_10_000000_default_uuid_field.php: -------------------------------------------------------------------------------- 1 | string('uuid')->default(null)->change(); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('failed_jobs', static function(Blueprint $table) { 18 | $table->string('uuid')->default('UUID()')->change(); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2023_06_06_000000_delete_all_notifications.php: -------------------------------------------------------------------------------- 1 | delete(); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /database/migrations/2023_07_07_183520_add_timezone_to_users.php: -------------------------------------------------------------------------------- 1 | string('timezone')->default('Europe/Berlin')->after('language'); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('users', function (Blueprint $table) { 19 | $table->dropColumn('timezone'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2023_07_09_000000_make_hashtag_nullable_on_events.php: -------------------------------------------------------------------------------- 1 | string('hashtag')->nullable()->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('events', static function(Blueprint $table) { 17 | $table->string('hashtag')->nullable(false)->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_07_13_144452_add_queued_at_column_to_queue_monitor_table.php: -------------------------------------------------------------------------------- 1 | dateTime('queued_at')->nullable()->after('status'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table(config('queue-monitor.table'), static function(Blueprint $table) { 17 | $table->dropColumn('queued_at'); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/migrations/2023_07_24_000000_add_user_mastodon_index_to_statuses.php: -------------------------------------------------------------------------------- 1 | index(['user_id', 'mastodon_post_id', 'created_at']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('statuses', static function(Blueprint $table) { 17 | $table->dropIndex(['user_id', 'mastodon_post_id', 'created_at']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_08_06_000001_add_hashtag_to_event_suggestions.php: -------------------------------------------------------------------------------- 1 | string('hashtag')->nullable()->after('end'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('event_suggestions', static function(Blueprint $table) { 17 | $table->dropColumn('hashtag'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_08_06_000002_rename_station_id_at_event_suggestions.php: -------------------------------------------------------------------------------- 1 | renameColumn('train_station_id', 'station_id'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('event_suggestions', static function(Blueprint $table) { 17 | $table->renameColumn('station_id', 'train_station_id'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_08_19_174051_drop_webhook_events_column.php: -------------------------------------------------------------------------------- 1 | dropColumn('events'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('webhooks', static function (Blueprint $table) { 17 | $table->addColumn('uint', 'events'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2023_09_22_194607_add_experimental_setting_to_users.php: -------------------------------------------------------------------------------- 1 | boolean('experimental')->default(false)->after('likes_enabled'); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('users', function (Blueprint $table) { 19 | $table->dropColumn('experimental'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2023_11_20_000000_drop_user_agents.php: -------------------------------------------------------------------------------- 1 | boolean('role')->default(0)->after('privacy_hide_days'); 16 | }); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /database/migrations/2023_11_21_000004_drop_experimental_from_users.php: -------------------------------------------------------------------------------- 1 | boolean('experimental')->default(false)->after('likes_enabled'); 16 | }); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /database/migrations/2023_11_22_000000_add_source_to_trips.php: -------------------------------------------------------------------------------- 1 | string('source') 13 | ->default('hafas') 14 | ->after('arrival'); 15 | }); 16 | } 17 | 18 | public function down(): void { 19 | Schema::table('hafas_trips', static function(Blueprint $table) { 20 | $table->dropColumn('source'); 21 | }); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /database/migrations/2024_03_01_000000_create_wikidata_entities_table.php: -------------------------------------------------------------------------------- 1 | string('id')->primary(); 13 | $table->json('data')->nullable(); 14 | $table->timestamp('last_updated_at')->nullable(); 15 | $table->timestamps(); 16 | }); 17 | } 18 | 19 | public function down(): void { 20 | Schema::dropIfExists('wikidata_entities'); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2024_03_22_000001_migrate_origin_and_destination_id_in_trips.php: -------------------------------------------------------------------------------- 1 | update([ 10 | 'origin_id' => DB::raw('(SELECT id FROM train_stations WHERE ibnr = hafas_trips.origin)'), 11 | 'destination_id' => DB::raw('(SELECT id FROM train_stations WHERE ibnr = hafas_trips.destination)'), 12 | ]); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /database/migrations/2024_03_22_000002_make_trip_origin_id_and_destination_id_not_nullable.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('origin_id')->nullable(false)->change(); 12 | $table->unsignedBigInteger('destination_id')->nullable(false)->change(); 13 | }); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /database/migrations/2024_04_19_131906_add_index_to_poly_line_parent_id.php: -------------------------------------------------------------------------------- 1 | index('parent_id'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('poly_lines', static function (Blueprint $table) { 17 | $table->dropIndex(['parent_id']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_05_21_000000_make_ibnr_nullable_on_stations.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('ibnr')->nullable()->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('train_stations', static function(Blueprint $table) { 17 | $table->unsignedBigInteger('ibnr')->nullable(false)->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_05_22_000003_drop_origin_destination_from_check_in.php: -------------------------------------------------------------------------------- 1 | dropForeign(['origin']); 12 | $table->dropForeign(['destination']); 13 | $table->dropIndex('user_trip_origin_departure'); 14 | 15 | $table->dropColumn('origin'); 16 | $table->dropColumn('destination'); 17 | }); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /database/migrations/2024_05_22_000004_add_index_operator_id_category_to_hafas_trips.php: -------------------------------------------------------------------------------- 1 | index(['operator_id', 'category']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('hafas_trips', static function(Blueprint $table) { 17 | $table->dropIndex(['operator_id', 'category']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_05_22_000005_add_index_name_status_queue_on_queue_monitor.php: -------------------------------------------------------------------------------- 1 | index(['name', 'status', 'queue']); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('queue_monitor', static function(Blueprint $table) { 18 | $table->dropIndex(['name', 'status', 'queue']); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2024_05_22_000008_add_index_user_id_visibility_on_statuses.php: -------------------------------------------------------------------------------- 1 | index(['user_id', 'visibility']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('statuses', static function(Blueprint $table) { 17 | $table->dropIndex(['user_id', 'visibility']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_05_25_000000_add_source_index_to_polylines.php: -------------------------------------------------------------------------------- 1 | index(['source']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('poly_lines', static function(Blueprint $table) { 17 | $table->dropIndex(['source']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_05_27_000000_drop_shadow_banned_from_users.php: -------------------------------------------------------------------------------- 1 | dropColumn('shadow_banned'); 14 | }); 15 | } 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /database/migrations/2024_06_28_000000_add_friend_checkin_setting_to_users.php: -------------------------------------------------------------------------------- 1 | string('friend_checkin')->default('forbidden')->after('timezone'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('users', function(Blueprint $table) { 17 | $table->dropColumn('friend_checkin'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_07_07_000000_set_size_of_username_at_users.php: -------------------------------------------------------------------------------- 1 | string('username', 25)->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('users', function(Blueprint $table) { 17 | $table->string('username')->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_07_14_081815_add_points_setting_to_users.php: -------------------------------------------------------------------------------- 1 | boolean('points_enabled')->default(true)->after('likes_enabled'); 14 | }); 15 | } 16 | 17 | public function down(): void { 18 | Schema::table('users', function(Blueprint $table) { 19 | $table->dropColumn('points_enabled'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2024_07_30_000000_add_admin_notification_id_to_reports.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('admin_notification_id')->nullable()->after('reporter_id'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('reports', static function(Blueprint $table) { 17 | $table->dropColumn('admin_notification_id'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_08_07_000001_drop_foreign_wikidata_entity_on_station.php: -------------------------------------------------------------------------------- 1 | dropForeign(['wikidata_id']); 13 | }); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /database/migrations/2024_08_07_000002_drop_wikidata_entities.php: -------------------------------------------------------------------------------- 1 | dropColumn('tweet_id'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('statuses', static function(Blueprint $table) { 17 | $table->string('tweet_id')->nullable()->after('event_id'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_08_13_000000_add_admin_notification_id_to_event_suggestions.php: -------------------------------------------------------------------------------- 1 | unsignedBigInteger('admin_notification_id')->nullable()->after('hashtag'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('event_suggestions', static function(Blueprint $table) { 17 | $table->dropColumn('admin_notification_id'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2024_11_04_223623_add_recent_gdpr_export_to_users.php: -------------------------------------------------------------------------------- 1 | timestamp('recent_gdpr_export')->nullable()->after('last_login'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('users', function(Blueprint $table) { 17 | $table->dropColumn('recent_gdpr_export'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_01_08_000000_add_source_to_stations.php: -------------------------------------------------------------------------------- 1 | string('source')->nullable()->after('longitude'); 13 | }); 14 | } 15 | 16 | public function down(): void { 17 | Schema::table('train_stations', function(Blueprint $table) { 18 | $table->dropColumn('source'); 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2025_02_27_213311_add_motis_source_to_hafas_trips.php: -------------------------------------------------------------------------------- 1 | string('motis_source')->nullable()->after('source'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('hafas_trips', function(Blueprint $table) { 17 | $table->dropColumn('motis_source'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_02_27_221837_add_column_data_provider_to_users.php: -------------------------------------------------------------------------------- 1 | string('data_provider')->after('mapprovider')->default(DataProvider::DEFAULT); 13 | }); 14 | } 15 | 16 | public function down(): void 17 | { 18 | Schema::table('users', function (Blueprint $table) { 19 | $table->dropColumn('data_provider'); 20 | }); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /database/migrations/2025_03_04_111312_add_latitude_longitude_index_to_train_stations.php: -------------------------------------------------------------------------------- 1 | index(['latitude', 'longitude']); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('train_stations', function(Blueprint $table) { 17 | $table->dropIndex(['latitude', 'longitude']); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_04_11_155304_add_human_name_to_motis_licenses.php: -------------------------------------------------------------------------------- 1 | string('human_name')->nullable()->after('name'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('motis_source_licenses', function(Blueprint $table) { 17 | $table->dropColumn('human_name'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_04_12_152843_add_relevance_to_train_stations.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('relevance')->default(0)->after('source'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('train_stations', function(Blueprint $table) { 17 | $table->dropColumn('relevance'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_04_13_000001_make_hafas_id_nullable_at_operators.php: -------------------------------------------------------------------------------- 1 | string('hafas_id')->nullable()->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('hafas_operators', function(Blueprint $table) { 17 | $table->string('hafas_id')->nullable(false)->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_04_14_203000_convert_hafas_operator_motis_id_to_string.php: -------------------------------------------------------------------------------- 1 | string('motis_id')->nullable()->change(); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('string', function(Blueprint $table) { 17 | $table->unsignedBigInteger('motis_id')->nullable()->change(); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_04_14_214754_add_relevance_field_to_station_identifiers.php: -------------------------------------------------------------------------------- 1 | bigInteger('relevance')->default(0)->after('id'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('station_identifiers', function(Blueprint $table) { 17 | $table->dropColumn('relevance'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/migrations/2025_04_18_112315_create_areas_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 12 | $table->string('name'); 13 | $table->tinyInteger('adminLevel')->default(0); 14 | $table->timestamps(); 15 | }); 16 | } 17 | 18 | public function down(): void { 19 | Schema::dropIfExists('areas'); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /database/migrations/2025_05_05_110620_add_bio_to_users_table.php: -------------------------------------------------------------------------------- 1 | string('bio')->nullable()->after('avatar'); 12 | }); 13 | } 14 | 15 | public function down(): void { 16 | Schema::table('users', function(Blueprint $table) { 17 | $table->dropColumn('bio'); 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /database/seeders/FollowTableSeeder.php: -------------------------------------------------------------------------------- 1 | first(); 14 | $bob = User::where('username', 'bob')->first(); 15 | 16 | Follow::factory([ 17 | 'user_id' => $gertrud->id, 18 | 'follow_id' => $bob->id, 19 | ])->create(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /database/seeders/PrivacyAgreementSeeder.php: -------------------------------------------------------------------------------- 1 | '# Allgemeiner Hinweis und Pflicht­informationen', 15 | 'body_md_en' => '# General notes and mandatory information', 16 | 'valid_at' => Carbon::now()->subYear()->toIso8601String() 17 | ]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /docs/contributing/translations.md: -------------------------------------------------------------------------------- 1 | # Translations 2 | 3 | We currently support multiple languages. 4 | We want to become even more international and for this we need you and your language skills. 5 | 6 | We use [Weblate](https://translate.codeberg.org/engage/trawelling/) (hosted by Codeberg) to manage the translations. 7 | You can add new translations and correct errors there. 8 | -------------------------------------------------------------------------------- /docs/traewelling.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/docs/traewelling.jpg -------------------------------------------------------------------------------- /lang/de/pagination.php: -------------------------------------------------------------------------------- 1 | 'Weiter »', 17 | 'previous' => '« Zurück', 18 | ]; 19 | -------------------------------------------------------------------------------- /lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | ]; 19 | -------------------------------------------------------------------------------- /lang/eo.json: -------------------------------------------------------------------------------- 1 | { 2 | "admin.usage": "uzo", 3 | "admin.checkins": "Checkin-Inoj", 4 | "admin.greeting": "Saluton", 5 | "admin.usage-board": "Uzotaksado", 6 | "admin.statuses": "statuso", 7 | "controller.status.like-ok": "Ŝatas!" 8 | } 9 | -------------------------------------------------------------------------------- /lang/fr/pagination.php: -------------------------------------------------------------------------------- 1 | 'Suivant »', 19 | 'previous' => '« Précédent', 20 | ]; 21 | -------------------------------------------------------------------------------- /lang/nl/pagination.php: -------------------------------------------------------------------------------- 1 | 'Volgende »', 19 | 'previous' => '« Vorige', 20 | ]; 21 | -------------------------------------------------------------------------------- /lang/pl/pagination.php: -------------------------------------------------------------------------------- 1 | 'Następna »', 19 | 'previous' => '« Poprzednia', 20 | ]; 21 | -------------------------------------------------------------------------------- /lang/sv/pagination.php: -------------------------------------------------------------------------------- 1 | 'Nästa »', 19 | 'previous' => '« Föregående', 20 | ]; 21 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | #Add Line RewriteBase 9 | RewriteBase / 10 | 11 | # Redirect Trailing Slashes... 12 | RewriteRule ^(.*)/$ /$1 [L,R=301] 13 | 14 | # Handle Front Controller... 15 | RewriteCond %{REQUEST_FILENAME} !-d 16 | RewriteCond %{REQUEST_FILENAME} !-f 17 | RewriteRule ^ index.php [L] 18 | 19 | # Handle Authorization Header 20 | RewriteCond %{HTTP:Authorization} . 21 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 22 | 23 | -------------------------------------------------------------------------------- /public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.eot -------------------------------------------------------------------------------- /public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.ttf -------------------------------------------------------------------------------- /public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.woff -------------------------------------------------------------------------------- /public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/fonts/Nunito/nunito-v11-latin-ext_latin_vietnamese-regular.woff2 -------------------------------------------------------------------------------- /public/images/covers/abandoned.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/covers/abandoned.jpg -------------------------------------------------------------------------------- /public/images/covers/derailment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/covers/derailment.jpg -------------------------------------------------------------------------------- /public/images/covers/profile-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/covers/profile-background.png -------------------------------------------------------------------------------- /public/images/covers/time.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/covers/time.jpg -------------------------------------------------------------------------------- /public/images/covers/traffic_lights.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/covers/traffic_lights.jpg -------------------------------------------------------------------------------- /public/images/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/favicon.ico -------------------------------------------------------------------------------- /public/images/icons/logo1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo1024.png -------------------------------------------------------------------------------- /public/images/icons/logo114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo114.png -------------------------------------------------------------------------------- /public/images/icons/logo128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo128.png -------------------------------------------------------------------------------- /public/images/icons/logo256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo256.png -------------------------------------------------------------------------------- /public/images/icons/logo32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo32.png -------------------------------------------------------------------------------- /public/images/icons/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo512.png -------------------------------------------------------------------------------- /public/images/icons/logo57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo57.png -------------------------------------------------------------------------------- /public/images/icons/logo64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo64.png -------------------------------------------------------------------------------- /public/images/icons/logo72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo72.png -------------------------------------------------------------------------------- /public/images/icons/logo76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/logo76.png -------------------------------------------------------------------------------- /public/images/icons/touch-icon-ipad-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/touch-icon-ipad-retina.png -------------------------------------------------------------------------------- /public/images/icons/touch-icon-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/touch-icon-ipad.png -------------------------------------------------------------------------------- /public/images/icons/touch-icon-iphone-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/icons/touch-icon-iphone-retina.png -------------------------------------------------------------------------------- /public/images/welcome/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/welcome/map.png -------------------------------------------------------------------------------- /public/images/welcome/mobile-mockup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/welcome/mobile-mockup.png -------------------------------------------------------------------------------- /public/images/welcome/stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/images/welcome/stats.png -------------------------------------------------------------------------------- /public/img/blog/api-umstellung-sbb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/img/blog/api-umstellung-sbb.png -------------------------------------------------------------------------------- /public/img/marker/dot-primary.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /public/img/marker/dot-secondary.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /public/img/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/img/user.png -------------------------------------------------------------------------------- /public/img/user_christmas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/img/user_christmas.png -------------------------------------------------------------------------------- /public/img/vid1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/img/vid1.mp4 -------------------------------------------------------------------------------- /public/img/vid2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/img/vid2.mp4 -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.js", 3 | "/js/stats.js": "/js/stats.js", 4 | "/js/admin.js": "/js/admin.js", 5 | "/css/app.css": "/css/app.css", 6 | "/css/admin.css": "/css/admin.css", 7 | "/css/welcome.css": "/css/welcome.css", 8 | "/css/app-dark.css": "/css/app-dark.css" 9 | } 10 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /legal/ 3 | Disallow: /legal/privacy-policy 4 | 5 | User-agent: ia_archiver 6 | Disallow: / 7 | 8 | User-agent: SemrushBot 9 | Disallow: / 10 | 11 | User-agent: BLEXBot 12 | Disallow: / 13 | -------------------------------------------------------------------------------- /public/security.txt: -------------------------------------------------------------------------------- 1 | Contact: mailto:security@traewelling.de 2 | Encryption: not available 3 | 4 | Contact: mailto:levin@herrlev.in 5 | Encryption: not available 6 | 7 | Contact: mailto:kristian.stoeckel@k118.de 8 | Encryption: https://pgp.k118.de/ 9 | 10 | Contact: mailto:jannik@outlook.com 11 | Encryption: https://blog.iamjannik.me/2017/pgp/ 12 | 13 | Contact: https://traewelling.de/legal/ 14 | Preferred-Languages: de, en 15 | Canonical: https://traewelling.de/security.txt 16 | -------------------------------------------------------------------------------- /public/uploads/avatars/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/public/uploads/avatars/.gitkeep -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | "gitmoji" 6 | ], 7 | "packageRules": [ 8 | { 9 | "matchUpdateTypes": ["minor", "patch"], 10 | "matchCurrentVersion": "!/^0/", 11 | "automerge": true 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /resources/js/api/Event.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import API from "./api"; 3 | 4 | export class Event { 5 | static suggest(name, host, begin, end, url, hashtag, nearestStation) { 6 | API.request('/event', 'POST', { 7 | name, host, begin, end, url, hashtag, nearestStation 8 | }).then(API.handleDefaultResponse); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /resources/js/api/Follow.js: -------------------------------------------------------------------------------- 1 | import API from "./api"; 2 | 3 | export class Follow { 4 | 5 | static destroy(userId) { 6 | return API.request(`/user/${userId}/follow`, 'delete'); 7 | } 8 | 9 | static create(userId) { 10 | return API.request(`/user/${userId}/follow`, 'POST'); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /resources/js/api/api.d.ts: -------------------------------------------------------------------------------- 1 | declare module '../../js/api/api' { 2 | export default class API { 3 | static request(path: string, method?: string, data?: object, customErrorHandling?: boolean): Promise; 4 | static handleDefaultResponse(response: Response): Promise; 5 | static handleGenericError(error: any): any; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | import "lodash"; 2 | import * as Popper from '@popperjs/core'; 3 | 4 | document.addEventListener("DOMContentLoaded", function () { 5 | try { 6 | window.Popper = Popper; 7 | 8 | import("bootstrap/js/dist/collapse"); 9 | import("bootstrap/js/dist/alert"); 10 | import("bootstrap/js/dist/button"); 11 | import("bootstrap/js/dist/tab"); 12 | import("bootstrap/js/dist/dropdown"); 13 | } catch (e) { 14 | throw new Error(e); 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /resources/js/components/tooltips.js: -------------------------------------------------------------------------------- 1 | import {Tooltip} from "bootstrap"; 2 | 3 | const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]') 4 | tooltipTriggerList.forEach(tooltipTriggerEl => { 5 | new Tooltip(tooltipTriggerEl) 6 | }) 7 | -------------------------------------------------------------------------------- /resources/sass/_font-awesome.scss: -------------------------------------------------------------------------------- 1 | $fa-font-path: "@fortawesome/fontawesome-free/webfonts"; 2 | @import "@fortawesome/fontawesome-free/scss/brands"; 3 | @import "@fortawesome/fontawesome-free/scss/regular"; 4 | @import "@fortawesome/fontawesome-free/scss/solid"; 5 | @import "@fortawesome/fontawesome-free/scss/fontawesome"; 6 | -------------------------------------------------------------------------------- /resources/sass/admin.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | @import "variables"; 3 | 4 | //Override some variables 5 | $primary: $trwlRot; 6 | $secondary: #ced4da; 7 | $success: #61CE5D; 8 | $info: #1487C7; 9 | $warning: #FA5719; 10 | $danger: #941E23; 11 | $light: #fff; 12 | $dark: #000; 13 | 14 | // Bootstrap 15 | @import "bootstrap"; 16 | 17 | @import "./font-awesome"; 18 | 19 | @import "leaflet/dist/leaflet.css"; 20 | @import "awesomplete/awesomplete.css"; 21 | @import "notyf/notyf.min.css"; 22 | 23 | #navbar-top { 24 | background-color: $primary; 25 | 26 | a, 27 | span.navbar-toggler-icon { 28 | color: $white; 29 | } 30 | } 31 | 32 | .btn-secondary, 33 | .btn-outline-secondary { 34 | color: $black; 35 | } 36 | -------------------------------------------------------------------------------- /resources/sass/base.scss: -------------------------------------------------------------------------------- 1 | .btn { 2 | text-transform: uppercase; 3 | } 4 | -------------------------------------------------------------------------------- /resources/sass/components/about.scss: -------------------------------------------------------------------------------- 1 | #about-page { 2 | .blockquote, 3 | p.lead { 4 | margin-bottom: 2em; 5 | 6 | strong { 7 | font-weight: 600; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /resources/sass/components/activeJourneys.scss: -------------------------------------------------------------------------------- 1 | #activeJourneys { 2 | #map { 3 | overflow: hidden; 4 | } 5 | 6 | .statusMap { 7 | display: none; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /resources/sass/components/dailyStats.scss: -------------------------------------------------------------------------------- 1 | #daily-stats-statsbar { 2 | .col-lg-3 { 3 | border-right: 1px solid rgba(0, 0, 0, 0.125); 4 | 5 | // md to lg breakpoint 6 | @media screen and (max-width: 992px) { 7 | &:nth-child(2) { 8 | border-right: 0; 9 | } 10 | } 11 | 12 | &:last-child { 13 | border-right: 0; 14 | } 15 | 16 | // lg to xl breakpoint 17 | @media screen and (max-width: 1200px) { 18 | i { 19 | display: block; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /resources/sass/components/eventspage.scss: -------------------------------------------------------------------------------- 1 | #event-header { 2 | h2 { 3 | font-size: 145%; 4 | margin-bottom: 0; 5 | line-height: 1.5; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /resources/sass/components/image-box.scss: -------------------------------------------------------------------------------- 1 | .image-box { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | 6 | img { 7 | max-width: 100%; 8 | border-radius: 50%; 9 | } 10 | } 11 | 12 | .search-image-box { 13 | display: block !important; 14 | } 15 | -------------------------------------------------------------------------------- /resources/sass/components/leaderboard.scss: -------------------------------------------------------------------------------- 1 | #leaderboard { 2 | #top20 a:hover, 3 | #top20k a:hover, 4 | #top20f a:hover { 5 | text-decoration: underline; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /resources/sass/components/maps.scss: -------------------------------------------------------------------------------- 1 | .leaflet-tile-container img[src*="tiles.openrailwaymap.org"] { 2 | filter: grayscale(80%) opacity(0.5); 3 | } -------------------------------------------------------------------------------- /resources/sass/components/notifications-board.scss: -------------------------------------------------------------------------------- 1 | @import "../variables"; 2 | 3 | .navbar { 4 | div.navbar-toggler { 5 | padding-right: 0; 6 | 7 | button.navbar-toggler { 8 | // The toggle buttons inside the div 9 | vertical-align: middle; 10 | padding-top: 0; 11 | padding-bottom: 0; 12 | 13 | &:last-child { 14 | padding-right: 0; 15 | } 16 | } 17 | } 18 | 19 | .nav-item span.notifications-bell { 20 | &.fa, 21 | &.far { 22 | padding-left: 3px; 23 | padding-right: 3px; 24 | } 25 | } 26 | } 27 | 28 | .notifications-pill { 29 | background-color: #00476c !important; 30 | } 31 | 32 | .notifications-board-toggle { 33 | white-space: nowrap; 34 | } 35 | -------------------------------------------------------------------------------- /resources/sass/components/search.scss: -------------------------------------------------------------------------------- 1 | @import "../variables"; 2 | 3 | .navbar.navbar-dark form .md-form input:focus:not([readonly]) { 4 | border-color: $blueCounterColor; 5 | } 6 | 7 | .stationSearchButton { 8 | align-items: center; 9 | border: 1px solid #bdbdbd; 10 | border-left-width: 0; 11 | display: flex; 12 | gap: 0.25em; 13 | 14 | &:hover, 15 | &:focus { 16 | border-color: #bdbdbd !important; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /resources/sass/components/settings.scss: -------------------------------------------------------------------------------- 1 | @import "croppie/croppie.css"; 2 | 3 | .croppie-container { 4 | height: auto; 5 | } 6 | -------------------------------------------------------------------------------- /resources/sass/components/stationboard.scss: -------------------------------------------------------------------------------- 1 | 2 | #stationboard { 3 | .stationboardDivider { 4 | border-top: #fff solid 2px; 5 | text-align: center; 6 | 7 | small { 8 | color: #fff; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /resources/sass/fonts/Nunito-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/resources/sass/fonts/Nunito-Regular.ttf -------------------------------------------------------------------------------- /resources/types/ProfileSettings.ts: -------------------------------------------------------------------------------- 1 | export type ProfileSettings = { 2 | username: string; 3 | displayName: string; 4 | profilePicture: string | null; 5 | privateProfile: boolean; 6 | preventIndex: boolean; 7 | defaultStatusVisibility: number; 8 | privacyHideDays: number; 9 | password: boolean; 10 | email: string | null; 11 | emailVerified: boolean; 12 | profilePictureSet: boolean; 13 | twitter: string | null; 14 | mastodon: string | null; 15 | mastodonVisibility: number; 16 | }; 17 | -------------------------------------------------------------------------------- /resources/types/Station.ts: -------------------------------------------------------------------------------- 1 | export type ShortStation = { 2 | id: number; 3 | name: string; 4 | latitude: number; 5 | longitude: number; 6 | ibnr: number; 7 | rilIdentifier: string; 8 | areas: Area[]; 9 | } 10 | 11 | export type Area = { 12 | name: string; 13 | default: boolean; 14 | adminLevel: number; 15 | }; 16 | -------------------------------------------------------------------------------- /resources/types/TrwlEvent.ts: -------------------------------------------------------------------------------- 1 | import {ShortStation} from "./Station"; 2 | 3 | export type TrwlEvent = { 4 | id: number; 5 | begin: string; 6 | end: string; 7 | hashtag: string; 8 | host: string; 9 | name: string; 10 | slug: string; 11 | url: string; 12 | station: ShortStation|null; 13 | } 14 | -------------------------------------------------------------------------------- /resources/types/TrwlTags.ts: -------------------------------------------------------------------------------- 1 | export type TrwlTag = { 2 | key: string, 3 | value: string, 4 | visibility: Number 5 | } 6 | -------------------------------------------------------------------------------- /resources/types/User.ts: -------------------------------------------------------------------------------- 1 | import {ShortStation} from "./Station"; 2 | 3 | export type User = { 4 | displayName: string, 5 | username: string, 6 | profilePicture: string, 7 | trainDistance: number, // @todo: rename key - we have more than just trains 8 | trainDuration: number, // @todo: rename key - we have more than just trains 9 | points: number, 10 | mastodonUrl: string | null, 11 | privateProfile: boolean, 12 | privacyHideDays: number, 13 | preventIndex: boolean, 14 | role: number, 15 | home: ShortStation, 16 | language: string 17 | }; 18 | -------------------------------------------------------------------------------- /resources/views/admin/activity/page.blade.php: -------------------------------------------------------------------------------- 1 | @extends('admin.layout') 2 | 3 | @section('title', 'Activity log') 4 | 5 | @section('content') 6 |
7 |
8 |
9 |
10 | @include('admin.activity.table') 11 | {{$activities->appends(request()->input())->links()}} 12 |
13 |
14 |
15 |
16 | @endsection 17 | -------------------------------------------------------------------------------- /resources/views/admin/dashboard.blade.php: -------------------------------------------------------------------------------- 1 | @extends('admin.layout') 2 | 3 | @section('content') 4 |
5 | 6 |

7 | Welcome dear 8 | @if(auth()->user()->hasRole('admin')) 9 | Admin! 10 | @elseif(auth()->user()->hasRole('event-moderator')) 11 | Event Moderator! 12 | @else 13 | Hacker! 14 | @endif 15 |
16 | Don't do anything stupid! 17 |

18 |
19 | @endsection 20 | -------------------------------------------------------------------------------- /resources/views/beta/trip-creation.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('title', 'Create trip manually') 4 | 5 | @section('content') 6 |
7 | 8 |
9 | @endsection 10 | -------------------------------------------------------------------------------- /resources/views/errors/401.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.illustrated-layout') 2 | 3 | @section('image', asset('images/covers/traffic_lights.jpg')) 4 | @section('title', __('error.401')) 5 | @section('code', '401') 6 | @section('message', __('error.401')) 7 | -------------------------------------------------------------------------------- /resources/views/errors/403.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.illustrated-layout') 2 | 3 | @section('image', asset('images/covers/traffic_lights.jpg')) 4 | @section('title', __('error.403')) 5 | @section('code', '403') 6 | @section('message', $exception->getMessage() ?: __('error.403')) 7 | -------------------------------------------------------------------------------- /resources/views/errors/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.illustrated-layout') 2 | 3 | @section('image', asset('images/covers/abandoned.jpg')) 4 | @section('title', __('error.404')) 5 | @section('code', '404') 6 | @section('message', __('error.404')) 7 | -------------------------------------------------------------------------------- /resources/views/errors/419.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.illustrated-layout') 2 | 3 | @section('image', asset('images/covers/time.jpg')) 4 | @section('title', __('error.419')) 5 | @section('code', '419') 6 | @section('message', __('error.419')) 7 | -------------------------------------------------------------------------------- /resources/views/errors/429.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.illustrated-layout') 2 | 3 | 4 | @section('title', __('error.429')) 5 | @section('code', '429') 6 | @section('message', __('error.429')) 7 | -------------------------------------------------------------------------------- /resources/views/errors/500.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.illustrated-layout') 2 | @php 3 | if (!$exception instanceof \App\Exceptions\Referencable) { 4 | $exception = $exception->getPrevious(); 5 | } 6 | @endphp 7 | 8 | @section('image', asset('images/covers/derailment.jpg')) 9 | @section('title', __('error.500')) 10 | @section('code', '500') 11 | @section('message', __('error.500')) 12 | @section('reference', errorMessage($exception, '')) 13 | -------------------------------------------------------------------------------- /resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.minimal') 2 | 3 | @section('code', '503') 4 | 5 | @section('content') 6 |
7 |

503

8 |

9 | 10 | {{ __('maintenance.title') }} 11 |

12 |

13 | {{__('maintenance.subtitle')}} {{__('maintenance.try-later')}} :)

14 | {{__('maintenance.prolonged')}} 15 |

16 |
17 |
18 | @endsection 19 | -------------------------------------------------------------------------------- /resources/views/mail/account_deletion_notification_two_weeks_before.blade.php: -------------------------------------------------------------------------------- 1 | {{ __('mail.hello', ['username' => $user->username]) }},
2 |
3 | {{ __('mail.account_deletion_notification_two_weeks_before.body1') }}
4 | {{ __('mail.account_deletion_notification_two_weeks_before.body2') }}
5 |
6 | {{ __('mail.account_deletion_notification_two_weeks_before.body3') }}
7 |
8 | {{ __('mail.bye') }},
9 | {{ __('mail.signature') }}
10 |
11 | https://traewelling.de 12 | -------------------------------------------------------------------------------- /resources/views/profile/partials/actions.blade.php: -------------------------------------------------------------------------------- 1 | @auth 2 | @include('includes.follow-button') 3 | @if(auth()->user()->id != $user->id) 4 | 5 | 6 | @endif 7 | @if(auth()->user()->hasRole('admin')) 8 | 10 | 11 | 12 | @endif 13 | @endauth 14 | -------------------------------------------------------------------------------- /resources/views/settings/account.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.settings') 2 | @section('title', __('settings.tab.account')) 3 | 4 | @section('content') 5 |
6 |
7 | @include('settings.cards.password') 8 | @include('settings.cards.account-deletion') 9 |
10 |
11 | @endsection 12 | -------------------------------------------------------------------------------- /resources/views/settings/cards/account-deletion.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
{{ __('settings.delete-account') }}
3 |
4 | 7 |
8 |
9 | 10 | @include('settings.modals.deleteUserModal') 11 | -------------------------------------------------------------------------------- /resources/views/settings/webhooks.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.settings') 2 | @section('title', __('settings.title-webhooks')) 3 | 4 | @section('content') 5 |
6 | 7 |
8 | @endsection 9 | -------------------------------------------------------------------------------- /resources/views/stats/stats.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('title', __('stats')) 4 | 5 | @section('head') 6 | @parent 7 | @endsection 8 | 9 | @section('content') 10 |
11 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | @endsection 21 | -------------------------------------------------------------------------------- /resources/views/vendor/l5-swagger/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Traewelling/traewelling/096f19e139fbab879654b37fd684f8a5f03d2000/resources/views/vendor/l5-swagger/.gitkeep -------------------------------------------------------------------------------- /resources/views/welcome/partials/nav-links.blade.php: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | {{ __('menu.about') }} 4 | 5 |
  • 6 |
  • 7 | {{ __('menu.active') }} 8 |
  • 9 |
  • 10 | {{ __('menu.leaderboard') }} 11 |
  • 12 | -------------------------------------------------------------------------------- /resources/vue/components/Helpers/HelpPageLink.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /resources/vue/components/Settings/Partials/SelectOption.ts: -------------------------------------------------------------------------------- 1 | export interface SelectOption { 2 | value: string; 3 | label?: string; 4 | translationKey?: string; 5 | } 6 | -------------------------------------------------------------------------------- /resources/vue/components/Spinner.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /resources/vue/helpers/NextStation.ts: -------------------------------------------------------------------------------- 1 | import {StopoverResource} from "../../types/Api.gen"; 2 | 3 | export class NextStation { 4 | public static getNextStation(stations: StopoverResource[]): StopoverResource | null { 5 | stations = stations.filter((stopover: StopoverResource) => { 6 | const time = stopover.departure ?? stopover.arrival ?? null; 7 | return time && Date.parse(time).toFixed() >= Date.now().toFixed(); 8 | }); 9 | 10 | return stations.shift() ?? null; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /resources/vue/helpers/NotyfHelper.ts: -------------------------------------------------------------------------------- 1 | export function showApiValidationErrors( 2 | notyf: any, 3 | errors: Record, 4 | ): void { 5 | // foreach error and show it 6 | Object.keys(errors).forEach((key: string) => { 7 | errors[key].forEach((error: string) => { 8 | notyf.error(error); 9 | }); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /resources/vue/stores/checkinSuccess.ts: -------------------------------------------------------------------------------- 1 | import {defineStore} from "pinia"; 2 | import {CheckinResponse} from "../../types/Api.gen"; 3 | 4 | export const checkinSuccessStore = defineStore("checkinSuccess", { 5 | persist: true, 6 | state: () => ({ 7 | checkinResponse: null as CheckinResponse | null, 8 | }), 9 | getters: { 10 | getCheckinResponse(): CheckinResponse | null { 11 | return this.checkinResponse; 12 | } 13 | }, 14 | actions: { 15 | setResponse(checkinResponse: CheckinResponse | any): void { 16 | this.checkinResponse = checkinResponse; 17 | }, 18 | reset(): void { 19 | this.checkinResponse = null; 20 | } 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/polylines/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 17 | 18 | return $app; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Feature/Transport/cecilienhof-location.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "stop", 4 | "id": "736222", 5 | "name": "Schloss Cecilienhof, Potsdam", 6 | "location": { 7 | "type": "location", 8 | "id": "736222", 9 | "latitude": 52.419544, 10 | "longitude": 13.067916 11 | } 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /tests/Feature/Transport/ringbahn-via-suedkreuz-location.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "stop", 3 | "id": "8089110", 4 | "name": "Berlin Messe Nord/ICC (Witzleben)", 5 | "location": { 6 | "type": "location", 7 | "id": "8089110", 8 | "latitude": 52.507539, 9 | "longitude": 13.28345 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 |