Full Code of RSS-Bridge/rss-bridge for AI

master d44856db173e cached
726 files
3.3 MB
904.6k tokens
3209 symbols
1 requests
Download .txt
Showing preview only (3,608K chars total). Download the full file or copy to clipboard to get everything.
Repository: RSS-Bridge/rss-bridge
Branch: master
Commit: d44856db173e
Files: 726
Total size: 3.3 MB

Directory structure:
gitextract_888ghlns/

├── .devcontainer/
│   ├── Dockerfile
│   ├── devcontainer.json
│   ├── launch.json
│   ├── nginx.conf
│   ├── post-create-command.sh
│   └── xdebug.ini
├── .dockerignore
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── .gitignore
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── bridge-request.md
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── prtester-requirements.txt
│   ├── prtester.py
│   └── workflows/
│       ├── dockerbuild.yml
│       ├── documentation.yml
│       ├── lint.yml
│       ├── prhtmlgenerator.yml
│       └── tests.yml
├── .gitignore
├── CONTRIBUTORS.md
├── Dockerfile
├── README.md
├── UNLICENSE
├── actions/
│   ├── ConnectivityAction.php
│   ├── DetectAction.php
│   ├── DisplayAction.php
│   ├── FindfeedAction.php
│   ├── FrontpageAction.php
│   ├── HealthAction.php
│   └── ListAction.php
├── app.json
├── bridges/
│   ├── ABCNewsBridge.php
│   ├── ABolaBridge.php
│   ├── AO3Bridge.php
│   ├── ARDAudiothekBridge.php
│   ├── ARDMediathekBridge.php
│   ├── ARMCommunityBridge.php
│   ├── ASRockNewsBridge.php
│   ├── AcademiaBridge.php
│   ├── AcrimedBridge.php
│   ├── ActivisionResearchBridge.php
│   ├── AirBreizhBridge.php
│   ├── AkamaiBridge.php
│   ├── AlbionOnlineBridge.php
│   ├── AlfaBankByBridge.php
│   ├── AllSidesBridge.php
│   ├── AllegroBridge.php
│   ├── AllocineFRBridge.php
│   ├── AllocineFRSortiesBridge.php
│   ├── AlpinePackagesBridge.php
│   ├── AmazonBridge.php
│   ├── AmazonPriceTrackerBridge.php
│   ├── AnfrBridge.php
│   ├── AnidexBridge.php
│   ├── AnimeUltimeBridge.php
│   ├── AnisearchBridge.php
│   ├── AnnasArchiveBridge.php
│   ├── AppleAppStoreBridge.php
│   ├── AppleMusicBridge.php
│   ├── ArsTechnicaBridge.php
│   ├── ArtStationBridge.php
│   ├── Arte7Bridge.php
│   ├── AsahiShimbunAJWBridge.php
│   ├── AssociatedPressNewsBridge.php
│   ├── AstrophysicsDataSystemBridge.php
│   ├── AtmoNouvelleAquitaineBridge.php
│   ├── AtmoOccitanieBridge.php
│   ├── AuctionetBridge.php
│   ├── AutoJMBridge.php
│   ├── AwwwardsBridge.php
│   ├── BAEBridge.php
│   ├── BMDSystemhausBlogBridge.php
│   ├── BadDragonBridge.php
│   ├── BakaUpdatesMangaReleasesBridge.php
│   ├── BandcampBridge.php
│   ├── BandcampDailyBridge.php
│   ├── BarraqueiroBridgeAbstract.php
│   ├── BarraqueiroOesteBridge.php
│   ├── BastaBridge.php
│   ├── BazarakiBridge.php
│   ├── BinanceBridge.php
│   ├── BlaguesDeMerdeBridge.php
│   ├── BleepingComputerBridge.php
│   ├── BlizzardNewsBridge.php
│   ├── BlueskyBridge.php
│   ├── BoaViagemBridge.php
│   ├── BodaccBridge.php
│   ├── BookMyShowBridge.php
│   ├── BooruprojectBridge.php
│   ├── BrotFuerDieWeltBridge.php
│   ├── BruegelBridge.php
│   ├── BrutBridge.php
│   ├── BugzillaBridge.php
│   ├── BukowskisBridge.php
│   ├── BundesbankBridge.php
│   ├── BundestagParteispendenBridge.php
│   ├── BundesverbandFuerFreieKammernBridge.php
│   ├── CBCEditorsBlogBridge.php
│   ├── CMetropolitanaBridge.php
│   ├── CNETBridge.php
│   ├── CNETFranceBridge.php
│   ├── CVEDetailsBridge.php
│   ├── CachetBridge.php
│   ├── CarThrottleBridge.php
│   ├── CaschyBridge.php
│   ├── CastorusBridge.php
│   ├── CdactionBridge.php
│   ├── CentreFranceBridge.php
│   ├── CeskaTelevizeBridge.php
│   ├── CodebergBridge.php
│   ├── CollegeDeFranceBridge.php
│   ├── ComboiosDePortugalBridge.php
│   ├── ComickBridge.php
│   ├── ComicsKingdomBridge.php
│   ├── CommonDreamsBridge.php
│   ├── CopieDoubleBridge.php
│   ├── CorreioDaFeiraBridge.php
│   ├── CourrierInternationalBridge.php
│   ├── CraigslistBridge.php
│   ├── CrewbayBridge.php
│   ├── CryptomeBridge.php
│   ├── CssSelectorBridge.php
│   ├── CssSelectorComplexBridge.php
│   ├── CssSelectorFeedExpanderBridge.php
│   ├── CubariBridge.php
│   ├── CubariProxyBridge.php
│   ├── CybernewsBridge.php
│   ├── DRKBlutspendeBridge.php
│   ├── DacksnackBridge.php
│   ├── DagensNyheterDirektBridge.php
│   ├── DailymotionBridge.php
│   ├── DailythanthiBridge.php
│   ├── DanbooruBridge.php
│   ├── DarkReadingBridge.php
│   ├── DauphineLibereBridge.php
│   ├── DealabsBridge.php
│   ├── DemoBridge.php
│   ├── DemosBerlinBridge.php
│   ├── DerpibooruBridge.php
│   ├── DesoutterBridge.php
│   ├── DeutscheWelleBridge.php
│   ├── DeutscherAeroClubBridge.php
│   ├── DevToBridge.php
│   ├── DeveloppezDotComBridge.php
│   ├── DiarioDeNoticiasBridge.php
│   ├── DiarioDoAlentejoBridge.php
│   ├── DiceBridge.php
│   ├── DiscogsBridge.php
│   ├── DjMagDotComBridge.php
│   ├── DockerHubBridge.php
│   ├── DonnonsBridge.php
│   ├── DoujinStyleBridge.php
│   ├── DribbbleBridge.php
│   ├── Drive2ruBridge.php
│   ├── DuckDuckGoBridge.php
│   ├── DuvarOrgBridge.php
│   ├── EASeedBridge.php
│   ├── EBayBridge.php
│   ├── EDDHPiRepsBridge.php
│   ├── EDDHPresseschauBridge.php
│   ├── EZTVBridge.php
│   ├── EconomistBridge.php
│   ├── EconomistWorldInBriefBridge.php
│   ├── EdfPricesBridge.php
│   ├── ElektroARGOSBridge.php
│   ├── EliteDangerousGalnetBridge.php
│   ├── ElloBridge.php
│   ├── ElsevierBridge.php
│   ├── EngadgetBridge.php
│   ├── EpicGamesFreeBridge.php
│   ├── EpicgamesBridge.php
│   ├── ErowallBridge.php
│   ├── EsquerdaNetBridge.php
│   ├── EstCeQuonMetEnProdBridge.php
│   ├── EtsyBridge.php
│   ├── EuronewsBridge.php
│   ├── ExecuteProgramBridge.php
│   ├── ExplosmBridge.php
│   ├── FB2Bridge.php
│   ├── FDroidRepoBridge.php
│   ├── FFXIVLodestoneNewsBridge.php
│   ├── FM4Bridge.php
│   ├── FSecureBlogBridge.php
│   ├── FabBridge.php
│   ├── FabriceBellardBridge.php
│   ├── FacebookBridge.php
│   ├── FallGuysBridge.php
│   ├── FanaticalBridge.php
│   ├── FarsideNitterBridge.php
│   ├── FeedExpanderExampleBridge.php
│   ├── FeedExpanderTestBridge.php
│   ├── FeedMergeBridge.php
│   ├── FeedReducerBridge.php
│   ├── FiaBridge.php
│   ├── FicbookBridge.php
│   ├── FiderBridge.php
│   ├── FilterBridge.php
│   ├── FinanzflussBridge.php
│   ├── FindACrewBridge.php
│   ├── FirefoxAddonsBridge.php
│   ├── FirefoxReleaseNotesBridge.php
│   ├── FlaschenpostBridge.php
│   ├── FlashbackBridge.php
│   ├── FlickrBridge.php
│   ├── FliegermagazinBridge.php
│   ├── FolhaDeSaoPauloBridge.php
│   ├── ForGifsBridge.php
│   ├── ForensicArchitectureBridge.php
│   ├── Formula1Bridge.php
│   ├── FourchanBridge.php
│   ├── FreeCodeCampBridge.php
│   ├── FreeTelechargerBridge.php
│   ├── FunkBridge.php
│   ├── FurAffinityBridge.php
│   ├── FurAffinityUserBridge.php
│   ├── FuturaSciencesBridge.php
│   ├── GBAtempBridge.php
│   ├── GGDealsBridge.php
│   ├── GOGBridge.php
│   ├── GQMagazineBridge.php
│   ├── GULPProjekteBridge.php
│   ├── GabBridge.php
│   ├── GameBananaBridge.php
│   ├── GatesNotesBridge.php
│   ├── GelbooruBridge.php
│   ├── GenshinImpactBridge.php
│   ├── GettrBridge.php
│   ├── GiphyBridge.php
│   ├── GitHubGistBridge.php
│   ├── GiteaBridge.php
│   ├── GithubIssueBridge.php
│   ├── GithubPackagesBridge.php
│   ├── GithubPullRequestBridge.php
│   ├── GithubReleaseBridge.php
│   ├── GithubSearchBridge.php
│   ├── GithubTrendingBridge.php
│   ├── GitlabIssueBridge.php
│   ├── GizmodoBridge.php
│   ├── GlassdoorBridge.php
│   ├── GlowficBridge.php
│   ├── GoAccessBridge.php
│   ├── GoComicsBridge.php
│   ├── GogsBridge.php
│   ├── GolemBridge.php
│   ├── GoodreadsBridge.php
│   ├── GoogleGroupsBridge.php
│   ├── GooglePlayStoreBridge.php
│   ├── GoogleScholarBridge.php
│   ├── GoogleSearchBridge.php
│   ├── GovTrackBridge.php
│   ├── GrandComicsDatabaseBridge.php
│   ├── GroupBundNaturschutzBridge.php
│   ├── HDWallpapersBridge.php
│   ├── HackerNewsUserThreadsBridge.php
│   ├── HanimeBridge.php
│   ├── HarvardBusinessReviewBridge.php
│   ├── HarvardHealthBlogBridge.php
│   ├── HashnodeBridge.php
│   ├── HaveIBeenPwnedBridge.php
│   ├── HeiseBridge.php
│   ├── HinduTamilBridge.php
│   ├── HonkaiImpactSeaBridge.php
│   ├── HotUKDealsBridge.php
│   ├── HumbleBundleBridge.php
│   ├── HuntShowdownNewsBridge.php
│   ├── HytaleBridge.php
│   ├── I4wifiBridge.php
│   ├── IGNBridge.php
│   ├── IKWYDBridge.php
│   ├── IPBBridge.php
│   ├── IdealoBridge.php
│   ├── IdenticaBridge.php
│   ├── ImgsedBridge.php
│   ├── IndeedBridge.php
│   ├── IndiegogoBridge.php
│   ├── InstagramBridge.php
│   ├── InstituteForTheStudyOfWarBridge.php
│   ├── InstructablesBridge.php
│   ├── InternationalInstituteForStrategicStudiesBridge.php
│   ├── InternetArchiveBridge.php
│   ├── InvestorsObserverBridge.php
│   ├── ItakuBridge.php
│   ├── ItchioBridge.php
│   ├── IvooxBridge.php
│   ├── JapanExpoBridge.php
│   ├── JohannesBlickBridge.php
│   ├── JornalNBridge.php
│   ├── JustETFBridge.php
│   ├── JustWatchBridge.php
│   ├── Kanali6Bridge.php
│   ├── KemonoBridge.php
│   ├── KernelBugTrackerBridge.php
│   ├── KhinsiderBridge.php
│   ├── KilledbyGoogleBridge.php
│   ├── KilledbyMicrosoftBridge.php
│   ├── KitsuBridge.php
│   ├── KleinanzeigenBridge.php
│   ├── KoFiBridge.php
│   ├── KonachanBridge.php
│   ├── KoreusBridge.php
│   ├── KununuBridge.php
│   ├── LWNprevBridge.php
│   ├── LaCentraleBridge.php
│   ├── LaTeX3ProjectNewslettersBridge.php
│   ├── LeBonCoinBridge.php
│   ├── LeMondeInformatiqueBridge.php
│   ├── LeagueOfLegendsNewsBridge.php
│   ├── LegifranceJOBridge.php
│   ├── LegoIdeasBridge.php
│   ├── LesJoiesDuCodeBridge.php
│   ├── LfcPlBridge.php
│   ├── LinuxBlogBridge.php
│   ├── ListverseBridge.php
│   ├── LogicMastersBridge.php
│   ├── LolibooruBridge.php
│   ├── LuftfahrtBundesAmtBridge.php
│   ├── LuftsportSHBridge.php
│   ├── MaalaimalarBridge.php
│   ├── MagellantvBridge.php
│   ├── MagicTheGatheringBridge.php
│   ├── Mailman2Bridge.php
│   ├── MallTvBridge.php
│   ├── MangaDexBridge.php
│   ├── MangaReaderBridge.php
│   ├── ManyVidsBridge.php
│   ├── MarktplaatsBridge.php
│   ├── MastodonBridge.php
│   ├── MediapartBlogsBridge.php
│   ├── MediapartBridge.php
│   ├── MicrosoftOfficeUpdatesBridge.php
│   ├── MilbooruBridge.php
│   ├── MinecraftBridge.php
│   ├── MistralAIBridge.php
│   ├── MixCloudBridge.php
│   ├── MixologyBridge.php
│   ├── ModelKarteiBridge.php
│   ├── ModifyBridge.php
│   ├── ModrinthBridge.php
│   ├── MoebooruBridge.php
│   ├── MoinMoinBridge.php
│   ├── MondeDiploBridge.php
│   ├── MotatosBridge.php
│   ├── MozillaBugTrackerBridge.php
│   ├── MozillaSecurityBridge.php
│   ├── MsnMondeBridge.php
│   ├── MspabooruBridge.php
│   ├── MydealsBridge.php
│   ├── N26Bridge.php
│   ├── NACSouthGermanyMediaLibraryBridge.php
│   ├── NFLRUSBridge.php
│   ├── NHKWorldJapanShowBridge.php
│   ├── NOSBridge.php
│   ├── NPRBridge.php
│   ├── NYTBridge.php
│   ├── NasaApodBridge.php
│   ├── NasestrechaBridge.php
│   ├── NationalGeographicBridge.php
│   ├── NautiljonBridge.php
│   ├── NewOnNetflixBridge.php
│   ├── NewgroundsBridge.php
│   ├── NextInkBridge.php
│   ├── NextgovBridge.php
│   ├── NiceMatinBridge.php
│   ├── NikonDownloadCenterBridge.php
│   ├── NineGagBridge.php
│   ├── NintendoBridge.php
│   ├── NordbayernBridge.php
│   ├── NotAlwaysBridge.php
│   ├── NovayaGazetaEuropeBridge.php
│   ├── NovelUpdatesBridge.php
│   ├── NpciBridge.php
│   ├── NurembergerNachrichtenBridge.php
│   ├── NvidiaDriverBridge.php
│   ├── NyaaTorrentsBridge.php
│   ├── OLXBridge.php
│   ├── OMonlineBridge.php
│   ├── OglafBridge.php
│   ├── OllamaBridge.php
│   ├── OnVaSortirBridge.php
│   ├── OneFortuneADayBridge.php
│   ├── OpenCVEBridge.php
│   ├── OpenwhydBridge.php
│   ├── OpenwrtSecurityBridge.php
│   ├── OtrkeyFinderBridge.php
│   ├── OvertakeBridge.php
│   ├── PanneauPocketBridge.php
│   ├── ParksOnTheAirBridge.php
│   ├── ParlerBridge.php
│   ├── ParuVenduImmoBridge.php
│   ├── PatreonBridge.php
│   ├── PaulGrahamBridge.php
│   ├── PcGamerBridge.php
│   ├── PepperBridgeAbstract.php
│   ├── PhoronixBridge.php
│   ├── PicalaBridge.php
│   ├── PicartoBridge.php
│   ├── PickyWallpapersBridge.php
│   ├── PicnobBridge.php
│   ├── PicukiBridge.php
│   ├── PikabuBridge.php
│   ├── PillowfortBridge.php
│   ├── PinterestBridge.php
│   ├── PirateCommunityBridge.php
│   ├── PixivBridge.php
│   ├── PlantUMLReleasesBridge.php
│   ├── PokemonNewsBridge.php
│   ├── PornhubBridge.php
│   ├── PresidenciaPTBridge.php
│   ├── PriviblurBridge.php
│   ├── QnapBridge.php
│   ├── QwantzBridge.php
│   ├── QwenBlogBridge.php
│   ├── QwerteeBridge.php
│   ├── RadioFranceBridge.php
│   ├── RadioMelodieBridge.php
│   ├── RainLoopBridge.php
│   ├── RainbowSixSiegeBridge.php
│   ├── RedditBridge.php
│   ├── Releases3DSBridge.php
│   ├── ReleasesSwitchBridge.php
│   ├── RemixAudioBridge.php
│   ├── ReporterreBridge.php
│   ├── ReutersBridge.php
│   ├── RibatejanaBridge.php
│   ├── RiptApparelBridge.php
│   ├── RoadAndTrackBridge.php
│   ├── RobinhoodSnacksBridge.php
│   ├── RoosterTeethBridge.php
│   ├── RtsBridge.php
│   ├── Rue89Bridge.php
│   ├── Rule34Bridge.php
│   ├── Rule34pahealBridge.php
│   ├── RumbleBridge.php
│   ├── RutubeBridge.php
│   ├── SIMARBridge.php
│   ├── SafebooruBridge.php
│   ├── SamMobileUpdateBridge.php
│   ├── SamsungMobileChangelogBridge.php
│   ├── ScalableCapitalBlogBridge.php
│   ├── SchweinfurtBuergerinformationenBridge.php
│   ├── ScientificAmericanBridge.php
│   ├── ScmbBridge.php
│   ├── ScoopItBridge.php
│   ├── ScribbleHubBridge.php
│   ├── ScribdBridge.php
│   ├── SensCritiqueBridge.php
│   ├── SeznamZpravyBridge.php
│   ├── ShadertoyBridge.php
│   ├── ShanaprojectBridge.php
│   ├── Shimmie2Bridge.php
│   ├── SitemapBridge.php
│   ├── SkimfeedBridge.php
│   ├── SkyArteBridge.php
│   ├── SleeperFantasyFootballBridge.php
│   ├── SlusheBridge.php
│   ├── SongkickBridge.php
│   ├── SoundcloudBridge.php
│   ├── SplCenterBridge.php
│   ├── SpotifyBridge.php
│   ├── SpottschauBridge.php
│   ├── StanfordSIRbookreviewBridge.php
│   ├── SteamAppNewsBridge.php
│   ├── SteamBridge.php
│   ├── SteamCommunityBridge.php
│   ├── SteamGroupAnnouncementsBridge.php
│   ├── StockFilingsBridge.php
│   ├── StorytelBridge.php
│   ├── StravaBridge.php
│   ├── StreamCzBridge.php
│   ├── StripeAPIChangeLogBridge.php
│   ├── SubitoBridge.php
│   ├── SubstackBridge.php
│   ├── SubstackProfileBridge.php
│   ├── SummitsOnTheAirBridge.php
│   ├── SuperSmashBlogBridge.php
│   ├── SymfonyCastsBridge.php
│   ├── TCBScansBridge.php
│   ├── TagesspiegelBridge.php
│   ├── TapasBridge.php
│   ├── TarnkappeBridge.php
│   ├── TbibBridge.php
│   ├── TebeoBridge.php
│   ├── TeefuryBridge.php
│   ├── TelegramBridge.php
│   ├── TestFaktaBridge.php
│   ├── TheDriveBridge.php
│   ├── TheFarSideBridge.php
│   ├── TheGuardianBridge.php
│   ├── TheHackerNewsBridge.php
│   ├── TheOatmealBridge.php
│   ├── ThePirateBayBridge.php
│   ├── TheRedHandFilesBridge.php
│   ├── TheWhiteboardBridge.php
│   ├── TheYeteeBridge.php
│   ├── ThreadsBridge.php
│   ├── TicketioBridge.php
│   ├── TikTokBridge.php
│   ├── TinyLetterBridge.php
│   ├── TldrTechBridge.php
│   ├── TomsToucheBridge.php
│   ├── TorrentGalaxyBridge.php
│   ├── TraktBridge.php
│   ├── TrelloBridge.php
│   ├── TriabolosNewsBridge.php
│   ├── TwitScoopBridge.php
│   ├── TwitchBridge.php
│   ├── TwitterBridge.php
│   ├── TwitterEngineeringBridge.php
│   ├── TwitterV2Bridge.php
│   ├── UberNewsroomBridge.php
│   ├── UniverseTodayBridge.php
│   ├── UnogsBridge.php
│   ├── UnraidCommunityApplicationsBridge.php
│   ├── UnsplashBridge.php
│   ├── UrlebirdBridge.php
│   ├── UsbekEtRicaBridge.php
│   ├── UsenixBridge.php
│   ├── UsesTechBridge.php
│   ├── VarietyBridge.php
│   ├── ViadeoCompanyBridge.php
│   ├── ViceBridge.php
│   ├── VideoCardzBridge.php
│   ├── VieDeMerdeBridge.php
│   ├── VimeoBridge.php
│   ├── VixenBridge.php
│   ├── Vk2Bridge.php
│   ├── VkBridge.php
│   ├── VproTegenlichtBridge.php
│   ├── WKYTNewsBridge.php
│   ├── WYMTNewsBridge.php
│   ├── WaggaCouncilBridge.php
│   ├── WallmineNewsBridge.php
│   ├── WallpaperflareBridge.php
│   ├── WarhammerComBridge.php
│   ├── WeLiveSecurityBridge.php
│   ├── WebfailBridge.php
│   ├── WhatsAppBlogBridge.php
│   ├── WikiLeaksBridge.php
│   ├── WikipediaBridge.php
│   ├── WirecutterDealsBridge.php
│   ├── WiredBridge.php
│   ├── WordPressBridge.php
│   ├── WordPressMadaraBridge.php
│   ├── WordPressPluginUpdateBridge.php
│   ├── WorldOfTanksBridge.php
│   ├── WorldbankBridge.php
│   ├── XPathBridge.php
│   ├── XbooruBridge.php
│   ├── XenForoBridge.php
│   ├── YGGTorrentBridge.php
│   ├── YandereBridge.php
│   ├── YandexZenBridge.php
│   ├── YeggiBridge.php
│   ├── YorushikaBridge.php
│   ├── YouTubeCommunityTabBridge.php
│   ├── YouTubeFeedExpanderBridge.php
│   ├── YoutubeBridge.php
│   ├── ZDFMediathekBridge.php
│   ├── ZDNetBridge.php
│   ├── ZeitBridge.php
│   ├── ZenodoBridge.php
│   └── ZonebourseBridge.php
├── caches/
│   ├── ArrayCache.php
│   ├── FileCache.php
│   ├── MemcachedCache.php
│   ├── NullCache.php
│   └── SQLiteCache.php
├── composer.json
├── config/
│   ├── nginx.conf
│   ├── php-fpm.conf
│   └── php.ini
├── config.default.ini.php
├── contrib/
│   └── .gitkeep
├── docker-bake.hcl
├── docker-compose.yml
├── docker-entrypoint.sh
├── docs/
│   ├── 01_General/
│   │   ├── 01_Project-goals.md
│   │   ├── 02_Contribute.md
│   │   ├── 03_Requirements.md
│   │   ├── 04_Screenshots.md
│   │   ├── 05_FAQ.md
│   │   └── 06_Public_Hosts.md
│   ├── 02_CLI/
│   │   └── index.md
│   ├── 03_For_Hosts/
│   │   ├── 01_Installation.md
│   │   ├── 02_Updating.md
│   │   ├── 04_Heroku_Installation.md
│   │   ├── 05_Whitelisting.md
│   │   ├── 06_Authentication.md
│   │   ├── 07_Customizations.md
│   │   ├── 08_Custom_Configuration.md
│   │   └── index.md
│   ├── 04_For_Developers/
│   │   ├── 01_Coding_style_policy.md
│   │   ├── 02_Pull_Request_policy.md
│   │   ├── 03_Folder_structure.md
│   │   ├── 04_Actions.md
│   │   ├── 05_Debug_mode.md
│   │   ├── 06_Github_Codespaces_Tutorial.md
│   │   ├── 07_Development_Environment_Setup.md
│   │   └── index.md
│   ├── 05_Bridge_API/
│   │   ├── 01_How_to_create_a_new_bridge.md
│   │   ├── 02_BridgeAbstract.md
│   │   ├── 03_FeedExpander.md
│   │   ├── 04_WebDriverAbstract.md
│   │   ├── 05_XPathAbstract.md
│   │   └── index.md
│   ├── 06_Helper_functions/
│   │   └── index.md
│   ├── 07_Cache_API/
│   │   ├── 01_How_to_create_a_new_cache.md
│   │   ├── 02_CacheInterface.md
│   │   └── index.md
│   ├── 09_Technical_recommendations/
│   │   └── index.md
│   ├── 10_Bridge_Specific/
│   │   ├── ActivityPub_(Mastodon).md
│   │   ├── Economist.md
│   │   ├── FacebookBridge.md
│   │   ├── FurAffinityBridge.md
│   │   ├── Furaffinityuser.md
│   │   ├── Instagram.md
│   │   ├── PixivBridge.md
│   │   ├── Substack.md
│   │   ├── Telegram.md
│   │   ├── TwitterV2.md
│   │   └── Vk2.md
│   ├── 99_Theme/
│   │   └── rssbridge/
│   │       └── config.json
│   ├── config.json
│   ├── index.md
│   └── readme.md
├── formats/
│   ├── AtomFormat.php
│   ├── HtmlFormat.php
│   ├── JsonFormat.php
│   ├── MrssFormat.php
│   ├── PlaintextFormat.php
│   └── SfeedFormat.php
├── index.php
├── lib/
│   ├── ActionInterface.php
│   ├── BridgeAbstract.php
│   ├── BridgeFactory.php
│   ├── CacheFactory.php
│   ├── CacheInterface.php
│   ├── Configuration.php
│   ├── Container.php
│   ├── FeedExpander.php
│   ├── FeedItem.php
│   ├── FeedParser.php
│   ├── FormatAbstract.php
│   ├── FormatFactory.php
│   ├── ParameterValidator.php
│   ├── RssBridge.php
│   ├── TwitterClient.php
│   ├── WebDriverAbstract.php
│   ├── XPathAbstract.php
│   ├── bootstrap.php
│   ├── config.php
│   ├── contents.php
│   ├── dependencies.php
│   ├── html.php
│   ├── http.php
│   ├── logger.php
│   ├── parsedown/
│   │   ├── LICENSE.txt
│   │   └── Parsedown.php
│   ├── php-urljoin/
│   │   ├── LICENSE
│   │   └── src/
│   │       └── urljoin.php
│   ├── php8backports.php
│   ├── seotags.php
│   ├── simplehtmldom/
│   │   ├── LICENSE
│   │   └── simple_html_dom.php
│   ├── url.php
│   └── utils.php
├── middlewares/
│   ├── BasicAuthMiddleware.php
│   ├── CacheMiddleware.php
│   ├── ExceptionMiddleware.php
│   ├── MaintenanceMiddleware.php
│   ├── Middleware.php
│   ├── SecurityMiddleware.php
│   └── TokenAuthenticationMiddleware.php
├── phpcompatibility.xml
├── phpcs.xml
├── phpunit.xml
├── scalingo.json
├── static/
│   ├── connectivity.css
│   ├── connectivity.js
│   ├── rss-bridge.js
│   └── style.css
├── templates/
│   ├── base.html.php
│   ├── bridge-error.html.php
│   ├── connectivity.html.php
│   ├── error.html.php
│   ├── exception.html.php
│   ├── frontpage.html.php
│   ├── html-format.html.php
│   └── token.html.php
└── tests/
    ├── BridgeCardTest.php
    ├── BridgeFactoryTest.php
    ├── BridgeImplementationTest.php
    ├── CacheImplementationTest.php
    ├── CacheTest.php
    ├── ConfigurationTest.php
    ├── FeedItemTest.php
    ├── FeedParserTest.php
    ├── FormatTest.php
    ├── Formats/
    │   ├── AtomFormatTest.php
    │   ├── BaseFormatTest.php
    │   ├── FormatImplementationTest.php
    │   ├── JsonFormatTest.php
    │   ├── MrssFormatTest.php
    │   └── samples/
    │       ├── expectedAtomFormat/
    │       │   ├── feed.common.xml
    │       │   ├── feed.empty.xml
    │       │   ├── feed.emptyItems.xml
    │       │   └── feed.microblog.xml
    │       ├── expectedJsonFormat/
    │       │   ├── feed.common.json
    │       │   ├── feed.empty.json
    │       │   ├── feed.emptyItems.json
    │       │   └── feed.microblog.json
    │       ├── expectedMrssFormat/
    │       │   ├── feed.common.xml
    │       │   ├── feed.empty.xml
    │       │   ├── feed.emptyItems.xml
    │       │   └── feed.microblog.xml
    │       ├── feed.common.json
    │       ├── feed.empty.json
    │       ├── feed.emptyItems.json
    │       └── feed.microblog.json
    ├── ParameterValidatorTest.php
    ├── RedditBridgeTest.php
    ├── UrlTest.php
    └── UtilsTest.php

================================================
FILE CONTENTS
================================================

================================================
FILE: .devcontainer/Dockerfile
================================================
FROM rssbridge/rss-bridge:latest

COPY --chmod=755 post-create-command.sh /usr/local/bin/post-create-command

ADD https://raw.githubusercontent.com/docker-library/php/master/docker-php-ext-enable /usr/local/bin/docker-php-ext-enable
RUN chmod u+x /usr/local/bin/docker-php-ext-enable

ADD https://getcomposer.org/installer /usr/local/bin/composer-installer.php
RUN chmod u+x /usr/local/bin/composer-installer.php
RUN php /usr/local/bin/composer-installer.php --check && \
    php /usr/local/bin/composer-installer.php --filename=composer --install-dir=/usr/local/bin

RUN apt-get update && \
    apt-get install -y \
      git \
      php-dev \
      make \
      unzip

RUN pecl install xdebug && \
    PHP_INI_DIR=/etc/php/8.2/fpm docker-php-ext-enable xdebug


================================================
FILE: .devcontainer/devcontainer.json
================================================
{
	"name": "rss-bridge dev",
	"build": { "dockerfile": "Dockerfile" },
	"customizations": {
		// Configure properties specific to VS Code.
		"vscode": {
			// Set *default* container specific settings.json values on container create.
			"settings": {
				"php.validate.executablePath": "/usr/bin/php",
				"phpSniffer.executablesFolder": "/root/.config/composer/vendor/bin",
				"phpcs.executablePath": "/root/.config/composer/vendor/bin/phpcs",
				"phpcs.lintOnType": false
			},

			// Add the IDs of extensions you want installed when the container is created.
			"extensions": [
				"xdebug.php-debug",
				"bmewburn.vscode-intelephense-client",
				"philfontaine.autolaunch",
				"eamodio.gitlens",
				"shevaua.phpcs"
			]
		}
	},
	"remoteEnv": {
		"PATH": "${containerEnv:PATH}:/root/.config/composer/vendor/bin",
	},
	"forwardPorts": [3100, 9000, 9003],
	"postCreateCommand": "/usr/local/bin/post-create-command"
}

================================================
FILE: .devcontainer/launch.json
================================================
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "auto": true,
            "log": true
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 0,
            "runtimeArgs": [
                "-dxdebug.start_with_request=yes"
            ],
            "env": {
                "XDEBUG_MODE": "debug,develop",
                "XDEBUG_CONFIG": "client_port=${port}"
            }
        },
        {
            "name": "Launch Built-in web server",
            "type": "php",
            "request": "launch",
            "runtimeArgs": [
                "-dxdebug.mode=debug",
                "-dxdebug.start_with_request=yes",
                "-S",
                "localhost:0"
            ],
            "program": "",
            "cwd": "${workspaceRoot}",
            "port": 9003,
            "serverReadyAction": {
                "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
                "uriFormat": "http://localhost:%s",
                "action": "openExternally"
            }
        }
    ]
}

================================================
FILE: .devcontainer/nginx.conf
================================================
server {
    listen 3100 default_server;
    root /workspaces/rss-bridge;
    access_log /var/log/nginx/rssbridge.access.log;
    error_log /var/log/nginx/rssbridge.error.log;
    index index.php;

    location ~ /(\.|vendor|tests) {
        deny all;
        return 403; # Forbidden
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    }
}


================================================
FILE: .devcontainer/post-create-command.sh
================================================
#/bin/sh

cp .devcontainer/nginx.conf /etc/nginx/conf.d/default.conf
cp .devcontainer/xdebug.ini /etc/php/8.2/fpm/conf.d/xdebug.ini

#  This should download some dev-dependencies, like phpunit and the PHP code sniffers
composer global require "phpunit/phpunit:^9"
composer global require "squizlabs/php_codesniffer:^3.6"
composer global require "phpcompatibility/php-compatibility:^9.3"

#  We need to this manually for running the PHPCompatibility ruleset
phpcs --config-set installed_paths /root/.config/composer/vendor/phpcompatibility/php-compatibility

mkdir -p .vscode
cp .devcontainer/launch.json .vscode

echo '*' > whitelist.txt 

chmod a+x $(pwd)
rm -rf /var/www/html 
ln -s $(pwd) /var/www/html 

# Solves possible issue of cache directory not being accessible
chown www-data:www-data -R $(pwd)/cache 

nginx
php-fpm8.2 -D

================================================
FILE: .devcontainer/xdebug.ini
================================================
[xdebug]
xdebug.mode=develop,debug
xdebug.client_host=localhost
xdebug.client_port=9003
xdebug.start_with_request=yes
xdebug.discover_client_host=false
xdebug.log='/var/www/html/xdebug.log'

================================================
FILE: .dockerignore
================================================
.git
!.git/HEAD
!.git/refs/heads/*
.gitattributes
.github/*
.travis.yml
cache/*
CONTRIBUTING.md
DEBUG
Dockerfile
phpcompatibility.xml
phpcs.xml
phpcs.xml
scalingo.json
tests/*
whitelist.txt

================================================
FILE: .git-blame-ignore-revs
================================================
# Reformat code base to PSR12
4f75591060d95208a301bc6bf460d875631b29cc
# Fix coding style missed by phpbcf
951092eef374db048b77bac85e75e3547bfac702


================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
*.sh text eol=lf

# Custom for Visual Studio
*.cs     diff=csharp
*.sln    merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc   diff=astextplain
*.DOC   diff=astextplain
*.docx  diff=astextplain
*.DOCX  diff=astextplain
*.dot   diff=astextplain
*.DOT   diff=astextplain
*.pdf   diff=astextplain
*.PDF   diff=astextplain
*.rtf   diff=astextplain
*.RTF   diff=astextplain

# Ignore files in git archive (i.e. GitHub release builds)

## Docker
Dockerfile                              export-ignore
.dockerignore                           export-ignore

## Travis
.travis.yml                             export-ignore

## GitHub
.github/                                export-ignore

## Git
.gitattributes                          export-ignore
.gitignore                              export-ignore

## Scalingo
scalingo.json                           export-ignore

## RSS-Bridge
phpunit.xml                             export-ignore
phpcs.xml                               export-ignore
phpcompatibility.xml                    export-ignore
tests/                                  export-ignore
cache/.gitkeep                          export-ignore

## Composer
#
# Keep the following lines commented out. Heroku does
# not function if the composer files are ignored during
# export. For more information see
# https://github.com/rss-bridge/rss-bridge/issues/1165
#
# composer.json                         export-ignore
# composer.lock                         export-ignore

## Heroku
#
# Keep the following line commented out. Heroku does
# not function if app.json is ignored during export.
# For more information see
# https://github.com/rss-bridge/rss-bridge/issues/1165
#
# app.json                              export-ignore


================================================
FILE: .github/.gitignore
================================================
# Visual Studio Code
.vscode/*

# Generated files
comment*.md
comment*.txt
*.html


================================================
FILE: .github/CONTRIBUTING.md
================================================
### Pull request policy

See the [Pull request policy page on the documentation](https://rss-bridge.github.io/rss-bridge/For_Developers/Pull_Request_policy.html) for more information on the pull request policy.

### Coding style

See the [Coding style policy page on the documentation](https://rss-bridge.github.io/rss-bridge/For_Developers/Coding_style_policy.html) for more information on the coding style of the project.


================================================
FILE: .github/ISSUE_TEMPLATE/bridge-request.md
================================================
---
name: Bridge request
about: Use this template for requesting a new bridge
title: Bridge request for ...
labels: Bridge-Request
assignees: ''

---

# Bridge request

<!--
This is a bridge request. Start by adding a descriptive title (i.e. `Bridge request for GitHub`). Use the "Preview" button to see a preview of your request. Make sure your request is complete before submitting!

Notice: This comment is only visible to you while you work on your request. Please do not remove any of the lines in the template (you may add your own outside the "<!--" and "- ->" lines!)
-->

## General information

<!--
Please describe what you expect from the bridge. Whenever possible provide sample links and screenshots (you can just paste them here) to express your expectations and help others understand your request. If possible, mark relevant areas in your screenshot. Use the following questions for reference:
-->

- _Host URI for the bridge_ (i.e. `https://github.com`):

- Which information would you like to see?



- How should the information be displayed/formatted?



- Which of the following parameters do you expect?

  - [X] Title
  - [X] URI (link to the original article)
  - [ ] Author
  - [ ] Timestamp
  - [X] Content (the content of the article)
  - [ ] Enclosures (pictures, videos, etc...)
  - [ ] Categories (categories, tags, etc...)

## Options

<!--Select options from the list below. Add your own option if one is missing:-->

- [ ] Limit number of returned items
  - _Default limit_: 5
- [ ] Load full articles
  - _Cache articles_ (articles are stored in a local cache on first request): yes
  - _Cache timeout_ : 24 hours
- [X] Balance requests (RSS-Bridge uses cached versions to reduce bandwith usage)
  - _Timeout_ (default = 5 minutes): 5 minutes

<!--Be aware that some options might not be available for your specific request due to technical limitations!-->

<!--
## Additional notes

Keep in mind that opening a request does not guarantee the bridge being implemented! That depends entirely on the interest and time of others to make the bridge for you.

You can also implement your own bridge (with support of the community if needed). Find more information in the [RSS-Bridge Documentation](https://rss-bridge.github.io/rss-bridge/For_Developers/index.html) developer section.
-->


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: Bug-Report
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: Feature-Request
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/prtester-requirements.txt
================================================
beautifulsoup4>=4.10.0
requests>=2.26.0

================================================
FILE: .github/prtester.py
================================================
import argparse
import requests
import re
from bs4 import BeautifulSoup
from datetime import datetime
from typing import Iterable
import os
import glob
import urllib

# This script is specifically written to be used in automation for https://github.com/RSS-Bridge/rss-bridge
#
# This will scrape the whitelisted bridges in the current state (port 3000) and the PR state (port 3001) of
# RSS-Bridge, generate a feed for each of the bridges and save the output as html files.
# It also add a <base> tag with the url of em's public instance, so viewing
# the HTML file locally will actually work as designed.

ARTIFACT_FILE_EXTENSION = '.html'

class Instance:
    name = ''
    url = ''

def main(instances: Iterable[Instance], with_artifacts: bool, with_reduced_artifacts: bool, artifacts_directory: str, artifacts_base_url: str, title: str, output_file: str):
    start_date = datetime.now()

    for file in glob.glob(f'*{ARTIFACT_FILE_EXTENSION}', root_dir=artifacts_directory):
        os.remove(file)

    table_rows = []
    for instance in instances:
        page = requests.get(instance.url) # Use python requests to grab the rss-bridge main page
        soup = BeautifulSoup(page.content, "html.parser") # use bs4 to turn the page into soup
        bridge_cards = soup.select('.bridge-card') # get a soup-formatted list of all bridges on the rss-bridge page
        table_rows += testBridges(
            instance=instance,
            bridge_cards=bridge_cards,
            with_artifacts=with_artifacts,
            with_reduced_artifacts=with_reduced_artifacts,
            artifacts_directory=artifacts_directory,
            artifacts_base_url=artifacts_base_url) # run the main scraping code with the list of bridges
    with open(file=output_file, mode='w+', encoding='utf-8') as file:
        table_rows_value = '\n'.join(sorted(table_rows))
        file.write(f'''
## {title}
| Bridge | Context | Status |
| - | - | - |
{table_rows_value}

*last change: {start_date.strftime("%A %Y-%m-%d %H:%M:%S")}*
        '''.strip())

def testBridges(instance: Instance, bridge_cards: Iterable, with_artifacts: bool, with_reduced_artifacts: bool, artifacts_directory: str, artifacts_base_url: str) -> Iterable:
    instance_suffix = ''
    if instance.name:
        instance_suffix = f' ({instance.name})'
    table_rows = []
    for bridge_card in bridge_cards:
        bridgeid = bridge_card.get('id')
        bridgeid = bridgeid.split('-')[1] # this extracts a readable bridge name from the bridge metadata
        print(f'{bridgeid}{instance_suffix}')
        bridge_name = bridgeid.replace('Bridge', '')
        context_forms = bridge_card.find_all("form")
        form_number = 1
        for context_form in context_forms:
            # a bridge can have multiple contexts, named 'forms' in html
            # this code will produce a fully working url that should create a working feed when called
            # this will create an example feed for every single context, to test them all
            context_parameters = {}
            error_messages = []
            context_name = '*untitled*'
            context_name_element = context_form.find_previous_sibling('h5')
            if context_name_element and context_name_element.text.strip() != '':
                context_name = context_name_element.text
            parameters = context_form.find_all("input")
            lists = context_form.find_all("select")
            # this for/if mess cycles through all available input parameters, checks if it required, then pulls
            # the default or examplevalue and then combines it all together into the url parameters
            # if an example or default value is missing for a required attribute, it will throw an error
            # any non-required fields are not tested!!!
            for parameter in parameters:
                parameter_type = parameter.get('type')
                parameter_name = parameter.get('name')
                if parameter_type == 'hidden':
                    context_parameters[parameter_name] = parameter.get('value')
                if parameter_type == 'number' or parameter_type == 'text':
                    if parameter.has_attr('required'):
                        if parameter.get('placeholder') == '':
                            if parameter.get('value') == '':
                                error_messages.append(f'Missing example or default value for parameter "{parameter_name}"')
                            else:
                                context_parameters[parameter_name] = parameter.get('value')
                        else:
                            context_parameters[parameter_name] = parameter.get('placeholder')
                # same thing, just for checkboxes. If a checkbox is checked per default, it gets added to the url parameters
                if parameter_type == 'checkbox':
                    if parameter.has_attr('checked'):
                        context_parameters[parameter_name] = 'on'
            for listing in lists:
                selectionvalue = ''
                listname = listing.get('name')
                cleanlist = []
                options = listing.find_all('option')
                for option in options:
                    if 'optgroup' in option.name:
                        cleanlist.extend(option)
                    else:
                        cleanlist.append(option)
                firstselectionentry = 1
                for selectionentry in cleanlist:
                    if firstselectionentry:
                        selectionvalue = selectionentry.get('value')
                        firstselectionentry = 0
                    else:
                        if 'selected' in selectionentry.attrs:
                            selectionvalue = selectionentry.get('value')
                            break
                context_parameters[listname] = selectionvalue
            artifact_url = 'about:blank'
            if error_messages:
                status = '<br>'.join(map(lambda m: f'❌ `{m}`', error_messages))
            else:
                # if all example/default values are present, form the full request url, run the request, add a <base> tag with
                # the url of em's public instance to the response text (so that relative paths work, e.g. to the static css file) and
                # then save it to a html file.
                context_parameters.update({
                    'action': 'display',
                    'bridge': bridgeid,
                    'format': 'Html',
                })
                request_url = f'{instance.url}/?{urllib.parse.urlencode(context_parameters)}'
                response = requests.get(request_url)
                page_text = response.text.replace('<head>','<head><base href="https://rss-bridge.org/bridge01/" target="_blank">')
                page_text = page_text.encode("utf_8")
                soup = BeautifulSoup(page_text, "html.parser")
                status_messages = []
                if response.status_code != 200:
                    status_messages += [f'❌ `HTTP status {response.status_code} {response.reason}`']
                else:
                    feed_items = soup.select('.feeditem')
                    feed_items_length = len(feed_items)
                    if feed_items_length <= 0:
                        status_messages += [f'⚠️ `The feed has no items`']
                    elif feed_items_length == 1 and len(soup.select('.error')) > 0:
                        status_messages += [f'❌ `{getFirstLine(feed_items[0].text)}`']
                status_messages += map(lambda e: f'❌ `{getFirstLine(e.text)}`', soup.select('.error .error-type') + soup.select('.error .error-message'))
                for item_element in soup.select('.feeditem'): # remove all feed items to not accidentally selected <pre> tags from item content
                    item_element.decompose()
                status_messages += map(lambda e: f'⚠️ `{getFirstLine(e.text)}`', soup.find_all('pre'))
                status_messages = list(dict.fromkeys(status_messages)) # remove duplicates
                status = '<br>'.join(status_messages)
                status_is_ok = status == '';
                if status_is_ok:
                    status = '✔️'
                if with_artifacts and (not with_reduced_artifacts or not status_is_ok):
                    filename = f'{bridge_name} {form_number}{instance_suffix}{ARTIFACT_FILE_EXTENSION}'
                    filename = re.sub(r'[^a-z0-9 \_\-\.]', '', filename, flags=re.I).replace(' ', '_')
                    with open(file=f'{artifacts_directory}/{filename}', mode='wb') as file:
                        file.write(page_text)
                    artifact_url = f'{artifacts_base_url}/{filename}'
            table_rows.append(f'| {bridge_name} | [{form_number} {context_name}{instance_suffix}]({artifact_url}) | {status} |')
            form_number += 1
    return table_rows

def getFirstLine(value: str) -> str:
     # trim whitespace and remove text that can break the table or is simply unnecessary
    clean_value = re.sub(r'^\[[^\]]+\]\s*rssbridge\.|[\|`]', '', value.strip())
    first_line = next(iter(clean_value.splitlines()), '')
    max_length = 250
    if (len(first_line) > max_length):
        first_line = first_line[:max_length] + '...'
    return first_line

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--instances', nargs='+')
    parser.add_argument('--no-artifacts', action='store_true')
    parser.add_argument('--reduced-artifacts', action='store_true')
    parser.add_argument('--artifacts-directory', default=os.getcwd())
    parser.add_argument('--artifacts-base-url', default='')
    parser.add_argument('--title', default='Pull request artifacts')
    parser.add_argument('--output-file', default=os.getcwd() + '/comment.md')
    args = parser.parse_args()
    instances = []
    if args.instances:
        for instance_arg in args.instances:
            instance_arg_parts = instance_arg.split('::')
            instance = Instance()
            instance.name = instance_arg_parts[1].strip() if len(instance_arg_parts) >= 2 else ''
            instance.url = instance_arg_parts[0].strip().rstrip("/")
            instances.append(instance)
    else:
        instance = Instance()
        instance.name = 'current'
        instance.url = 'http://localhost:3000'
        instances.append(instance)
        instance = Instance()
        instance.name = 'pr'
        instance.url = 'http://localhost:3001'
        instances.append(instance)
    main(
        instances=instances,
        with_artifacts=not args.no_artifacts,
        with_reduced_artifacts=args.reduced_artifacts and not args.no_artifacts,
        artifacts_directory=args.artifacts_directory,
        artifacts_base_url=args.artifacts_base_url,
        title=args.title,
        output_file=args.output_file
    );


================================================
FILE: .github/workflows/dockerbuild.yml
================================================
name: Build Container Image

on:
  push:
    branches:
      - 'master'
    tags:
      - '20*'
  pull_request:
    branches:
      - 'master'
    paths:
      - .github/workflows/**
      - Dockerfile

permissions:
  contents: read
  packages: write

env:
  DOCKERHUB_SLUG: rssbridge/rss-bridge
  GHCR_SLUG: ghcr.io/rss-bridge/rss-bridge

jobs:
  bake:
    runs-on: ubuntu-24.04-arm
    steps:
      - name: Docker meta
        id: docker_meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ env.DOCKERHUB_SLUG }}
            ${{ env.GHCR_SLUG }}
          tags: |
            type=raw,value=latest,enable=${{ github.event_name != 'pull_request' }}
            type=sha
            type=ref,event=tag,enable=${{ startsWith(github.ref, 'refs/tags/20') }}
            type=raw,value=stable,enable=${{ startsWith(github.ref, 'refs/tags/20') }}
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to DockerHub
        uses: docker/login-action@v3
        if: ${{ github.event_name != 'pull_request' }}
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        if: ${{ github.event_name != 'pull_request' }}
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        uses: docker/bake-action@v6
        with:
          files: |
            ./docker-bake.hcl
            cwd://${{ steps.docker_meta.outputs.bake-file }}
          targets: image-all
          push: ${{ github.event_name != 'pull_request' }}


================================================
FILE: .github/workflows/documentation.yml
================================================
name: Documentation

on:
  push:
    paths:
    - 'docs/**'
  pull_request:
    branches:
      - 'master'
    paths:
      - .github/workflows/**
      - 'docs/**'

permissions:
  contents: write

jobs:
  documentation:
    runs-on: ubuntu-24.04-arm
    steps:
    - uses: actions/checkout@v5
      with:
        persist-credentials: false
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: 8.0
    - name: Install dependencies
      run: composer global require daux/daux.io
    - name: Generate documentation
      run: daux generate
    - name: Deploy same repository 🚀
      if: ${{ github.event_name != 'pull_request' }}
      uses: JamesIves/github-pages-deploy-action@v4
      with:
        folder: "static"
        branch: gh-pages


================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

permissions:
  contents: read

jobs:
  phpcs:
    runs-on: ubuntu-24.04-arm
    strategy:
      matrix:
        php-versions: ['7.4']
    steps:
      - uses: actions/checkout@v5
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
          tools: phpcs
      - run: phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p

  phpcompatibility:
    runs-on: ubuntu-24.04-arm
    strategy:
      matrix:
        php-versions: ['7.4']
    steps:
      - uses: actions/checkout@v5
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
      - run: composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
      - run: composer global require dealerdirect/phpcodesniffer-composer-installer phpcompatibility/php-compatibility
      - run: ~/.composer/vendor/bin/phpcs . --standard=phpcompatibility.xml --warning-severity=0 --extensions=php -p

  executable_php_files_check:
    runs-on: ubuntu-24.04-arm
    steps:
      - uses: actions/checkout@v5
      - run: |
          if find -name "*.php" -executable -type f -print -exec false {} +
          then
            echo 'Good, no executable php scripts found'
          else
            echo 'Please unmark php scripts above as non-executable'
            exit 1
          fi


================================================
FILE: .github/workflows/prhtmlgenerator.yml
================================================
name: 'PR Testing'

on:
  pull_request_target:
    branches: [ master ]

permissions:
  contents: read

jobs:
  checks:
    name: Check if bridges were changed
    runs-on: ubuntu-24.04-arm
    outputs:
      BRIDGES: ${{ steps.check_bridges.outputs.BRIDGES }}
      WITH_UPLOAD: ${{ steps.check_upload.outputs.WITH_UPLOAD }}
    steps:
      - name: Check number of bridges
        id: check_bridges
        run: |
          PR=${{ github.event.number || 'none' }};
          wget https://patch-diff.githubusercontent.com/raw/$GITHUB_REPOSITORY/pull/$PR.patch;
          bridgeamount=$(cat $PR.patch | grep "\bbridges/[A-Za-z0-9]*Bridge\.php\b" | sed "s=.*\bbridges/\([A-Za-z0-9]*\)Bridge\.php\b.*=\1=g" | sort | uniq | wc -l);
          echo "BRIDGES=$bridgeamount" >> "$GITHUB_OUTPUT"
      - name: "Check upload token secret RSSTESTER_SSH_KEY is set"
        id: check_upload
        run: |
          echo "WITH_UPLOAD=$([ -n "${{ secrets.RSSTESTER_SSH_KEY }}" ] && echo "true" || echo "false")" >> "$GITHUB_OUTPUT"

  test-pr:
    name: Generate HTML files
    runs-on: ubuntu-24.04-arm
    needs: checks
    if: needs.checks.outputs.BRIDGES > 0
    outputs:
      COMMENT_LENGTH: ${{ steps.run-tests.outputs.bodylength }}
    steps:
      - name: Checkout - PR
        uses: actions/checkout@v5
        with:
          ref: ${{github.event.pull_request.head.ref}}
          repository: ${{github.event.pull_request.head.repo.full_name}}
      - name: Build docker image - PR
        run: docker build -t rss-bridge-pr .
      - name: Clear workspace
        run: rm -r * .*
      - name: Checkout - Current
        uses: actions/checkout@v5
      - name: Build docker image - Current
        run: docker build -t rss-bridge-current .
      - name: Create configuration files
        run: |
          touch DEBUG;
          PR=${{ github.event.number || 'none' }};
          wget https://patch-diff.githubusercontent.com/raw/$GITHUB_REPOSITORY/pull/$PR.patch;
          cat $PR.patch | grep "\bbridges/[A-Za-z0-9]*Bridge\.php\b" | sed "s=.*\bbridges/\([A-Za-z0-9]*\)Bridge\.php\b.*=\1=g" | sort | uniq > whitelist.txt;
          echo "whitelist.txt:";
          cat whitelist.txt
      - name: Run docker container - Current
        run: docker run -v $GITHUB_WORKSPACE/whitelist.txt:/app/whitelist.txt -v $GITHUB_WORKSPACE/DEBUG:/app/DEBUG --detach --pull never -p 3000:80 rss-bridge-current
      - name: Run docker container - PR
        run: docker run -v $GITHUB_WORKSPACE/whitelist.txt:/app/whitelist.txt -v $GITHUB_WORKSPACE/DEBUG:/app/DEBUG --detach --pull never -p 3001:80 rss-bridge-pr
      - name: Setup python
        uses: actions/setup-python@v6
        with:
          python-version: '3.13'
          cache: 'pip'
          cache-dependency-path: '**/*requirements*.txt'
      - name: Install requirements
        run: pip install -r ./.github/prtester-requirements.txt
      - name: Run bridge tests
        id: run-tests
        env:
          PYTHONUNBUFFERED: 1
        run: |
          python ./.github/prtester.py --artifacts-base-url "https://${{ github.repository_owner }}.github.io/${{ vars.ARTIFACTS_REPO || 'rss-bridge-tests' }}/prs/${{ github.event.number || 'none' }}";
          body="$(cat comment.md)";
          body="${body//'%'/'%25'}";
          body="${body//$'\n'/'%0A'}";
          body="${body//$'\r'/'%0D'}";
          echo "bodylength=${#body}" >> $GITHUB_OUTPUT
      - name: Upload test results
        if: steps.run-tests.outputs.bodylength > 130
        uses: actions/upload-artifact@v5
        with:
          name: test-results
          path: |
            comment.md
            *.html
          if-no-files-found: error

  comment-pr:
    name: Create or update PR comment
    runs-on: ubuntu-24.04-arm
    needs: test-pr
    if: needs.test-pr.outputs.COMMENT_LENGTH > 130
    permissions:
      pull-requests: write
    steps:
      - name: Download test results
        uses: actions/download-artifact@v5
        with:
          name: test-results
      - name: Add comment to job summary
        run: cat comment.md >> $GITHUB_STEP_SUMMARY
      - name: Find Comment
        uses: peter-evans/find-comment@v4
        id: find-comment
        with:
          issue-number: ${{ github.event.pull_request.number }}
          comment-author: 'github-actions[bot]'
          body-includes: Pull request artifacts
      - name: Create or update comment
        uses: peter-evans/create-or-update-comment@v5
        with:
          comment-id: ${{ steps.find-comment.outputs.comment-id }}
          issue-number: ${{ github.event.pull_request.number }}
          body-file: comment.md
          edit-mode: replace

  upload-test-results:
    name: Upload to GitHub Pages repository
    runs-on: ubuntu-24.04-arm
    needs: test-pr
    if: needs.test-pr.outputs.COMMENT_LENGTH > 130 && needs.checks.outputs.WITH_UPLOAD == 'true'
    steps:
      - uses: actions/checkout@v5
        with:
          repository: "${{ github.repository_owner }}/${{ vars.ARTIFACTS_REPO || 'rss-bridge-tests' }}"
          ref: 'main'
          ssh-key:  ${{ secrets.RSSTESTER_SSH_KEY }}
      - name: Setup git config
        run: |
          git config --global user.name "GitHub Actions"
          git config --global user.email "<>"
      - name: Download test results
        uses: actions/download-artifact@v5
        with:
          name: test-results
      - name: Move test results
        run: |
          DIRECTORY="$GITHUB_WORKSPACE/prs/${{ github.event.number || 'none' }}"
          rm -rf $DIRECTORY
          mkdir -p $DIRECTORY
          cd $DIRECTORY
          mv -f $GITHUB_WORKSPACE/comment.md ./README.md
          mv -f $GITHUB_WORKSPACE/*.html .
      - name: Commit and push test results
        run: |
          export COMMIT_MESSAGE="Test results for PR ${{ github.event.number || 'none' }}"
          git add .
          git commit -m "$COMMIT_MESSAGE" || exit 0
          git push


================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

permissions:
  contents: read

jobs:
  phpunit8:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']
    steps:
      - uses: actions/checkout@v5
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
        env:
          update: true
      - run: composer install
      - run: composer test


================================================
FILE: .gitignore
================================================
#################
## Eclipse
#################
vendor/*
data/
*.pydevproject
.project
.metadata
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath


#################
## Visual Studio
#################

## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.sln.docstates

# Build results

[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
*.ncrunch*
.*crunch*.local.xml

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.Publish.xml
*.pubxml

# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/

# Windows Azure Build Output
csx
*.build.csdef

# Windows Store app package directory
AppPackages/

# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
App_Data/*.mdf
App_Data/*.ldf

#################
## Other ide stuff
#################
.idea/*
[#]*[#]

#############
## Windows detritus
#############

# Windows image file caches
Thumbs.db
ehthumbs.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Mac crap
.DS_Store


#############
## Python
#############

*.py[co]

# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg

# Installer logs
pip-log.txt

# Unit test / coverage reports
.coverage
.phpunit.result.cache
.tox

#Translations
*.mo

#Mr Developer
.mr.developer.cfg

##############
## RSS-Bridge
##############
/cache
/whitelist.txt
DEBUG
config.ini.php
config/*
!config/nginx.conf
!config/php-fpm.conf
!config/php.ini
favicon.gif
favicon.ico

######################
## VisualStudioCode ##
######################
.vscode/*

#Builder
.buildconfig

#Auth
.htaccess
.htpasswd

#Crawler
robots.txt


================================================
FILE: CONTRIBUTORS.md
================================================
# Contributors

* [16mhz](https://github.com/16mhz)
* [adamchainz](https://github.com/adamchainz)
* [Ahiles3005](https://github.com/Ahiles3005)
* [akirk](https://github.com/akirk)
* [Albirew](https://github.com/Albirew)
* [aledeg](https://github.com/aledeg)
* [alex73](https://github.com/alex73)
* [alexAubin](https://github.com/alexAubin)
* [Alkarex](https://github.com/Alkarex)
* [AmauryCarrade](https://github.com/AmauryCarrade)
* [arnd-s](https://github.com/arnd-s)
* [ArthurHoaro](https://github.com/ArthurHoaro)
* [Astalaseven](https://github.com/Astalaseven)
* [Astyan-42](https://github.com/Astyan-42)
* [austinhuang0131](https://github.com/austinhuang0131)
* [axor-mst](https://github.com/axor-mst)
* [ayacoo](https://github.com/ayacoo)
* [az5he6ch](https://github.com/az5he6ch)
* [b1nj](https://github.com/b1nj)
* [benasse](https://github.com/benasse)
* [Binnette](https://github.com/Binnette)
* [BoboTiG](https://github.com/BoboTiG)
* [Bockiii](https://github.com/Bockiii)
* [brtsos](https://github.com/brtsos)
* [captn3m0](https://github.com/captn3m0)
* [chemel](https://github.com/chemel)
* [Chouchen](https://github.com/Chouchen)
* [ckiw](https://github.com/ckiw)
* [cn-tools](https://github.com/cn-tools)
* [cnlpete](https://github.com/cnlpete)
* [corenting](https://github.com/corenting)
* [couraudt](https://github.com/couraudt)
* [csisoap](https://github.com/csisoap)
* [da2x](https://github.com/da2x)
* [dabenzel](https://github.com/dabenzel)
* [Daiyousei](https://github.com/Daiyousei)
* [dawidsowa](https://github.com/dawidsowa)
* [DevonHess](https://github.com/DevonHess)
* [dhuschde](https://github.com/dhuschde)
* [disk0x](https://github.com/disk0x)
* [DJCrashdummy](https://github.com/DJCrashdummy)
* [Djuuu](https://github.com/Djuuu)
* [DnAp](https://github.com/DnAp)
* [dominik-th](https://github.com/dominik-th)
* [Draeli](https://github.com/Draeli)
* [Dreckiger-Dan](https://github.com/Dreckiger-Dan)
* [drego85](https://github.com/drego85)
* [drklee3](https://github.com/drklee3)
* [DRogueRonin](https://github.com/DRogueRonin)
* [dvikan](https://github.com/dvikan)
* [eggwhalefrog](https://github.com/eggwhalefrog)
* [em92](https://github.com/em92)
* [eMerzh](https://github.com/eMerzh)
* [EtienneM](https://github.com/EtienneM)
* [f0086](https://github.com/f0086)
* [fanch317](https://github.com/fanch317)
* [fatuuse](https://github.com/fatuuse)
* [fivefilters](https://github.com/fivefilters)
* [floviolleau](https://github.com/floviolleau)
* [fluffy-critter](https://github.com/fluffy-critter)
* [fmachen](https://github.com/fmachen)
* [Frenzie](https://github.com/Frenzie)
* [fulmeek](https://github.com/fulmeek)
* [ggiessen](https://github.com/ggiessen)
* [gileri](https://github.com/gileri)
* [Ginko-Aloe](https://github.com/Ginko-Aloe)
* [girlpunk](https://github.com/girlpunk)
* [Glandos](https://github.com/Glandos)
* [gloony](https://github.com/gloony)
* [GregThib](https://github.com/GregThib)
* [griffaurel](https://github.com/griffaurel)
* [Grummfy](https://github.com/Grummfy)
* [gsantner](https://github.com/gsantner)
* [guigot](https://github.com/guigot)
* [hollowleviathan](https://github.com/hollowleviathan)
* [hpacleb](https://github.com/hpacleb)
* [hunhejj](https://github.com/hunhejj)
* [husim0](https://github.com/husim0)
* [IceWreck](https://github.com/IceWreck)
* [imagoiq](https://github.com/imagoiq)
* [j0k3r](https://github.com/j0k3r)
* [JackNUMBER](https://github.com/JackNUMBER)
* [jacquesh](https://github.com/jacquesh)
* [jakubvalenta](https://github.com/jakubvalenta)
* [JasonGhent](https://github.com/JasonGhent)
* [jcgoette](https://github.com/jcgoette)
* [jdesgats](https://github.com/jdesgats)
* [jdigilio](https://github.com/jdigilio)
* [JeremyRand](https://github.com/JeremyRand)
* [JimDog546](https://github.com/JimDog546)
* [jNullj](https://github.com/jNullj)
* [Jocker666z](https://github.com/Jocker666z)
* [johnnygroovy](https://github.com/johnnygroovy)
* [johnpc](https://github.com/johnpc)
* [joni1993](https://github.com/joni1993)
* [jtojnar](https://github.com/jtojnar)
* [KamaleiZestri](https://github.com/KamaleiZestri)
* [kkoyung](https://github.com/kkoyung)
* [klimplant](https://github.com/klimplant)
* [KN4CK3R](https://github.com/KN4CK3R)
* [kolarcz](https://github.com/kolarcz)
* [kranack](https://github.com/kranack)
* [kraoc](https://github.com/kraoc)
* [krisu5](https://github.com/krisu5)
* [l1n](https://github.com/l1n)
* [laBecasse](https://github.com/laBecasse)
* [lagaisse](https://github.com/lagaisse)
* [lalannev](https://github.com/lalannev)
* [langfingaz](https://github.com/langfingaz)
* [lassana](https://github.com/lassana)
* [ldidry](https://github.com/ldidry)
* [Leomaradan](https://github.com/Leomaradan)
* [leyrer](https://github.com/leyrer)
* [liamka](https://github.com/liamka)
* [Limero](https://github.com/Limero)
* [LogMANOriginal](https://github.com/LogMANOriginal)
* [lorenzos](https://github.com/lorenzos)
* [lukasklinger](https://github.com/lukasklinger)
* [m0zes](https://github.com/m0zes)
* [Mar-Koeh](https://github.com/Mar-Koeh)
* [marcus-at-localhost](https://github.com/marcus-at-localhost)
* [marius8510000-bot](https://github.com/marius8510000-bot)
* [matthewseal](https://github.com/matthewseal)
* [mcbyte-it](https://github.com/mcbyte-it)
* [mdemoss](https://github.com/mdemoss)
* [melangue](https://github.com/melangue)
* [metaMMA](https://github.com/metaMMA)
* [mibe](https://github.com/mibe)
* [mickaelBert](https://github.com/mickaelBert)
* [mightymt](https://github.com/mightymt)
* [mitsukarenai](https://github.com/mitsukarenai)
* [Monocularity](https://github.com/Monocularity)
* [MonsieurPoutounours](https://github.com/MonsieurPoutounours)
* [mr-flibble](https://github.com/mr-flibble)
* [mro](https://github.com/mro)
* [mschwld](https://github.com/mschwld)
* [muekoeff](https://github.com/muekoeff)
* [mw80](https://github.com/mw80)
* [mxmehl](https://github.com/mxmehl)
* [Mynacol](https://github.com/Mynacol)
* [nel50n](https://github.com/nel50n)
* [niawag](https://github.com/niawag)
* [Niehztog](https://github.com/Niehztog)
* [NikNikYkt](https://github.com/NikNikYkt)
* [Nono-m0le](https://github.com/Nono-m0le)
* [NotsoanoNimus](https://github.com/NotsoanoNimus)
* [obsiwitch](https://github.com/obsiwitch)
* [Ololbu](https://github.com/Ololbu)
* [ORelio](https://github.com/ORelio)
* [otakuf](https://github.com/otakuf)
* [Park0](https://github.com/Park0)
* [Paroleen](https://github.com/Paroleen)
* [Patricol](https://github.com/Patricol)
* [paulchen](https://github.com/paulchen)
* [PaulVayssiere](https://github.com/PaulVayssiere)
* [pellaeon](https://github.com/pellaeon)
* [PeterDaveHello](https://github.com/PeterDaveHello)
* [Peterr-K](https://github.com/Peterr-K)
* [Piranhaplant](https://github.com/Piranhaplant)
* [pirnz](https://github.com/pirnz)
* [pit-fgfjiudghdf](https://github.com/pit-fgfjiudghdf)
* [pitchoule](https://github.com/pitchoule)
* [pmaziere](https://github.com/pmaziere)
* [Pofilo](https://github.com/Pofilo)
* [prysme01](https://github.com/prysme01)
* [pubak42](https://github.com/pubak42)
* [Qluxzz](https://github.com/Qluxzz)
* [quentinus95](https://github.com/quentinus95)
* [quickwick](https://github.com/quickwick)
* [rakoo](https://github.com/rakoo)
* [RawkBob](https://github.com/RawkBob)
* [regisenguehard](https://github.com/regisenguehard)
* [Riduidel](https://github.com/Riduidel)
* [rogerdc](https://github.com/rogerdc)
* [Roliga](https://github.com/Roliga)
* [ronansalmon](https://github.com/ronansalmon)
* [rremizov](https://github.com/rremizov)
* [s0lesurviv0r](https://github.com/s0lesurviv0r)
* [sal0max](https://github.com/sal0max)
* [sebsauvage](https://github.com/sebsauvage)
* [shutosg](https://github.com/shutosg)
* [simon816](https://github.com/simon816)
* [Simounet](https://github.com/Simounet)
* [somini](https://github.com/somini)
* [SpangleLabs](https://github.com/SpangleLabs)
* [SqrtMinusOne](https://github.com/SqrtMinusOne)
* [squeek502](https://github.com/squeek502)
* [StelFux](https://github.com/StelFux)
* [stjohnjohnson](https://github.com/stjohnjohnson)
* [Stopka](https://github.com/Stopka)
* [Strubbl](https://github.com/Strubbl)
* [sublimz](https://github.com/sublimz)
* [sunchaserinfo](https://github.com/sunchaserinfo)
* [SuperSandro2000](https://github.com/SuperSandro2000)
* [sysadminstory](https://github.com/sysadminstory)
* [t0stiman](https://github.com/t0stiman)
* [tameroski](https://github.com/tameroski)
* [teromene](https://github.com/teromene)
* [tgkenney](https://github.com/tgkenney)
* [thefranke](https://github.com/thefranke)
* [TheRadialActive](https://github.com/TheRadialActive)
* [theScrabi](https://github.com/theScrabi)
* [thezeroalpha](https://github.com/thezeroalpha)
* [thibaultcouraud](https://github.com/thibaultcouraud)
* [timendum](https://github.com/timendum)
* [TitiTestScalingo](https://github.com/TitiTestScalingo)
* [tomaszkane](https://github.com/tomaszkane)
* [tomershvueli](https://github.com/tomershvueli)
* [TotalCaesar659](https://github.com/TotalCaesar659)
* [tpikonen](https://github.com/tpikonen)
* [TReKiE](https://github.com/TReKiE)
* [triatic](https://github.com/triatic)
* [User123698745](https://github.com/User123698745)
* [VerifiedJoseph](https://github.com/VerifiedJoseph)
* [vitkabele](https://github.com/vitkabele)
* [WalterBarrett](https://github.com/WalterBarrett)
* [wtuuju](https://github.com/wtuuju)
* [xurxof](https://github.com/xurxof)
* [yamanq](https://github.com/yamanq)
* [yardenac](https://github.com/yardenac)
* [ymeister](https://github.com/ymeister)
* [yue-dongchen](https://github.com/yue-dongchen)
* [ZeNairolf](https://github.com/ZeNairolf)


================================================
FILE: Dockerfile
================================================
FROM debian:12-slim AS rssbridge

LABEL description="RSS-Bridge is a PHP project capable of generating RSS and Atom feeds for websites that don't have one."
LABEL repository="https://github.com/RSS-Bridge/rss-bridge"
LABEL website="https://github.com/RSS-Bridge/rss-bridge"

ARG DEBIAN_FRONTEND=noninteractive
RUN set -xe && \
    apt-get update && \
    apt-get install --yes --no-install-recommends \
      ca-certificates \
      nginx \
      nss-plugin-pem \
      php-curl \
      php-fpm \
      php-intl \
      # php-json is enabled by default with PHP 8.2 in Debian 12
      php-mbstring \
      php-memcached \
      # php-opcache is enabled by default with PHP 8.2 in Debian 12
      # php-openssl is enabled by default with PHP 8.2 in Debian 12
      php-sqlite3 \
      php-xml \
      php-zip \
      # php-zlib is enabled by default with PHP 8.2 in Debian 12
      # for downloading libcurl-impersonate
      curl \
      # for patching libcurl-impersonate
      patchelf \
      && \
    # install curl-impersonate library
    curlimpersonate_version=1.2.5 && \
    { \
        { \
            [ $(arch) = 'aarch64' ] && \
            archive="libcurl-impersonate-v${curlimpersonate_version}.aarch64-linux-gnu.tar.gz" && \
            sha512sum="cd340819d27c03e6833e746c1de181aa828f5986f4152fe0d55d5ea1b0a7c5328db129f9146d6369d2c2e20facd7c0a67e32cc916dddc74d1557106f89636dd0" \
        ; } \
        || { \
            [ $(arch) = 'armv7l' ] && \
            archive="libcurl-impersonate-v${curlimpersonate_version}.arm-linux-gnueabihf.tar.gz" && \
            sha512sum="143e57779c4872557e8becfd91bf9c92d9085b1c964d103a39b6e85253e3f3257796d205de4b49f6bc25c8ad0a39e5d4ec4f51391037e27d32d6355e52c5d346" \
        ; } \
        || { \
            [ $(arch) = 'x86_64' ] && \
            archive="libcurl-impersonate-v${curlimpersonate_version}.x86_64-linux-gnu.tar.gz" && \
            sha512sum="816e7d08110f2f5a6e7e2364e7c1d9ec0cc371e9b5024e0239db937379f057bb40ec80e56d0c49cdaf80b7f560888511c1bda5516b850a6d54c46a2eccc94dc6" \
        ; } \
    } && \
    curl -LO "https://github.com/lexiforest/curl-impersonate/releases/download/v${curlimpersonate_version}/${archive}" && \
    echo "$sha512sum  $archive" | sha512sum -c - && \
    mkdir -p /usr/local/lib/curl-impersonate && \
    tar xaf "$archive" -C /usr/local/lib/curl-impersonate && \
    patchelf --set-soname libcurl.so.4 /usr/local/lib/curl-impersonate/libcurl-impersonate.so && \
    rm "$archive" && \
    apt-get purge --assume-yes curl patchelf && \
    rm -rf /var/lib/apt/lists/*

ENV LD_PRELOAD=/usr/local/lib/curl-impersonate/libcurl-impersonate.so
ENV CURL_IMPERSONATE=chrome142

# logs should go to stdout / stderr
RUN ln -sfT /dev/stderr /var/log/nginx/error.log; \
	ln -sfT /dev/stdout /var/log/nginx/access.log; \
	chown -R --no-dereference www-data:adm /var/log/nginx/

COPY ./config/nginx.conf /etc/nginx/sites-available/default
COPY ./config/php-fpm.conf /etc/php/8.2/fpm/pool.d/rss-bridge.conf
COPY ./config/php.ini /etc/php/8.2/fpm/conf.d/90-rss-bridge.ini

COPY --chown=www-data:www-data ./ /app/

EXPOSE 80

ENTRYPOINT ["/app/docker-entrypoint.sh"]


================================================
FILE: README.md
================================================
# RSS-Bridge

![RSS-Bridge](static/logo_600px.png)

RSS-Bridge is a PHP web application.

It generates web feeds for websites that don't have one.

Officially hosted instance: https://rss-bridge.org/bridge01/

IRC channel #rssbridge at https://libera.chat/

[Full documentation](https://rss-bridge.github.io/rss-bridge/index.html)

Alternatively find another
[public instance](https://rss-bridge.github.io/rss-bridge/General/Public_Hosts.html).

Requires minimum PHP 7.4.


[![LICENSE](https://img.shields.io/badge/license-UNLICENSE-blue.svg)](UNLICENSE)
[![GitHub release](https://img.shields.io/github/release/rss-bridge/rss-bridge.svg?logo=github)](https://github.com/rss-bridge/rss-bridge/releases/latest)
[![irc.libera.chat](https://img.shields.io/badge/irc.libera.chat-%23rssbridge-blue.svg)](https://web.libera.chat/#rssbridge)
[![Actions Status](https://img.shields.io/github/actions/workflow/status/RSS-Bridge/rss-bridge/tests.yml?branch=master&label=GitHub%20Actions&logo=github)](https://github.com/RSS-Bridge/rss-bridge/actions)

|||
|:-:|:-:|
|![Screenshot #1](/static/screenshot-1.png?raw=true)|![Screenshot #2](/static/screenshot-2.png?raw=true)|
|![Screenshot #3](/static/screenshot-3.png?raw=true)|![Screenshot #4](/static/screenshot-4.png?raw=true)|
|![Screenshot #5](/static/screenshot-5.png?raw=true)|![Screenshot #6](/static/screenshot-6.png?raw=true)|

## A subset of bridges (15/447)

* `CssSelectorBridge`: [Scrape out a feed using CSS selectors](https://rss-bridge.org/bridge01/#bridge-CssSelectorBridge)
* `FeedMergeBridge`: [Combine multiple feeds into one](https://rss-bridge.org/bridge01/#bridge-FeedMergeBridge)
* `FeedReducerBridge`: [Reduce a noisy feed by some percentage](https://rss-bridge.org/bridge01/#bridge-FeedReducerBridge)
* `FilterBridge`: [Filter a feed by excluding/including items by keyword](https://rss-bridge.org/bridge01/#bridge-FilterBridge)
* `GettrBridge`: [Fetches the latest posts from a GETTR user](https://rss-bridge.org/bridge01/#bridge-GettrBridge)
* `MastodonBridge`: [Fetches statuses from a Mastodon (ActivityPub) instance](https://rss-bridge.org/bridge01/#bridge-MastodonBridge)
* `RedditBridge`: [Fetches posts from a user/subredit (with filtering options)](https://rss-bridge.org/bridge01/#bridge-RedditBridge)
* `RumbleBridge`: [Fetches channel/user videos](https://rss-bridge.org/bridge01/#bridge-RumbleBridge)
* `SoundcloudBridge`: [Fetches music by username](https://rss-bridge.org/bridge01/#bridge-SoundcloudBridge)
* `TelegramBridge`: [Fetches posts from a public channel](https://rss-bridge.org/bridge01/#bridge-TelegramBridge)
* `ThePirateBayBridge:` [Fetches torrents by search/user/category](https://rss-bridge.org/bridge01/#bridge-ThePirateBayBridge)
* `TikTokBridge`: [Fetches posts by username](https://rss-bridge.org/bridge01/#bridge-TikTokBridge)
* `TwitchBridge`: [Fetches videos from channel](https://rss-bridge.org/bridge01/#bridge-TwitchBridge)
* `XPathBridge`: [Scrape out a feed using XPath expressions](https://rss-bridge.org/bridge01/#bridge-XPathBridge)
* `YoutubeBridge`: [Fetches videos by username/channel/playlist/search](https://rss-bridge.org/bridge01/#bridge-YoutubeBridge)
* `YouTubeCommunityTabBridge`: [Fetches posts from a channel's Posts tab](https://rss-bridge.org/bridge01/#bridge-YouTubeCommunityTabBridge)

## Tutorial

### How to install on traditional shared web hosting

RSS-Bridge can basically be unzipped into a web folder. Should be working instantly.

Latest zip:
https://github.com/RSS-Bridge/rss-bridge/archive/refs/heads/master.zip (2MB)

### How to install on Debian 12 (nginx + php-fpm)

These instructions have been tested on a fresh Debian 12 VM from Digital Ocean (1vcpu-512mb-10gb, 5 USD/month).

```shell
timedatectl set-timezone Europe/Oslo

apt install git nginx php8.2-fpm php-mbstring php-simplexml php-curl php-intl

# Create a user account
useradd --shell /bin/bash --create-home rss-bridge

cd /var/www

# Create folder and change its ownership to rss-bridge
mkdir rss-bridge && chown rss-bridge:rss-bridge rss-bridge/

# Become rss-bridge
su rss-bridge

# Clone master branch into existing folder
git clone https://github.com/RSS-Bridge/rss-bridge.git rss-bridge/
cd rss-bridge

# Copy over the default config (OPTIONAL)
cp -v config.default.ini.php config.ini.php

# Recursively give full permissions to user/owner
chmod 700 --recursive ./

# Give read and execute to others on folder ./static
chmod o+rx ./ ./static

# Recursively give give read to others on folder ./static
chmod o+r --recursive ./static
```

Nginx config:

```nginx
# /etc/nginx/sites-enabled/rss-bridge.conf

server {
    listen 80;

    # TODO: change to your own server name
    server_name example.com;

    access_log /var/log/nginx/rss-bridge.access.log;
    error_log /var/log/nginx/rss-bridge.error.log;
    log_not_found off;

    # Intentionally not setting a root folder

    # Static content only served here
    location /static/ {
        alias /var/www/rss-bridge/static/;
    }

    # Pass off to php-fpm only when location is EXACTLY == /
    location = / {
        root /var/www/rss-bridge/;
        include snippets/fastcgi-php.conf;
        fastcgi_read_timeout 45s;
        fastcgi_pass unix:/run/php/rss-bridge.sock;
    }

    # Reduce log noise
    location = /favicon.ico {
        access_log off;
    }

    # Reduce log noise
    location = /robots.txt {
        access_log off;
    }
}
```

PHP FPM pool config:
```ini
; /etc/php/8.2/fpm/pool.d/rss-bridge.conf

[rss-bridge]

user = rss-bridge
group = rss-bridge

listen = /run/php/rss-bridge.sock

listen.owner = www-data
listen.group = www-data

; Create 10 workers standing by to serve requests
pm = static
pm.max_children = 10

; Respawn worker after 500 requests (workaround for memory leaks etc.)
pm.max_requests = 500
```

PHP ini config:
```ini
; /etc/php/8.2/fpm/conf.d/30-rss-bridge.ini

max_execution_time = 15
memory_limit = 64M
```

Restart fpm and nginx:

```shell
# Lint and restart php-fpm
php-fpm8.2 -t && systemctl restart php8.2-fpm

# Lint and restart nginx
nginx -t && systemctl restart nginx
```

### How to install from Composer

Install the latest release.

```shell
cd /var/www
composer create-project -v --no-dev --no-scripts rss-bridge/rss-bridge
```

### How to install with Caddy

TODO. See https://github.com/RSS-Bridge/rss-bridge/issues/3785

### Install from Docker Hub:

Install by downloading the docker image from Docker Hub:

```bash
# Create container
docker create --name=rss-bridge --publish 3000:80 --volume $(pwd)/config:/config rssbridge/rss-bridge
```

You can put custom `config.ini.php` and bridges into `./config`.

**You must restart container for custom changes to take effect.**

See `docker-entrypoint.sh` for details.

```bash
# Start container
docker start rss-bridge
```

Browse http://localhost:3000/

### Install by locally building from Dockerfile

```bash
# Build image from Dockerfile
docker build -t rss-bridge .

# Create container
docker create --name rss-bridge --publish 3000:80 --volume $(pwd)/config:/config rss-bridge
```

You can put custom `config.ini.php` and bridges into `./config`.

**You must restart container for custom changes to take effect.**

See `docker-entrypoint.sh` for details.

```bash
# Start container
docker start rss-bridge
```

Browse http://localhost:3000/

### Install with docker-compose (using Docker Hub)

You can put custom `config.ini.php` and bridges into `./config`.

**You must restart container for custom changes to take effect.**

See `docker-entrypoint.sh` for details.

```bash
docker-compose up
```

Browse http://localhost:3000/

### Other installation methods

[![Deploy on Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/sebsauvage/rss-bridge)
[![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
[![Deploy to Cloudron](https://cloudron.io/img/button.svg)](https://www.cloudron.io/store/com.rssbridgeapp.cloudronapp.html)
[![Run on PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=rssbridge)

The Heroku quick deploy currently does not work. It might work if you fork this repo and
modify the `repository` in `scalingo.json`. See https://github.com/RSS-Bridge/rss-bridge/issues/2688

Learn more in
[Installation](https://rss-bridge.github.io/rss-bridge/For_Hosts/Installation.html).

## How-to

### How to fix "Access denied."

Output is from php-fpm. It is unable to read index.php.

    chown rss-bridge:rss-bridge /var/www/rss-bridge/index.php

### How to password-protect the instance (token)

Modify `config.ini.php`:

    [authentication]

    token = "hunter2"

### How to remove all cache items

As current user:

    bin/cache-clear

As user rss-bridge:

    sudo -u rss-bridge bin/cache-clear

As root:

    sudo bin/cache-clear

### How to remove all expired cache items

    bin/cache-prune

### How to fix "PHP Fatal error:  Uncaught Exception: The FileCache path is not writable"

```shell
# Give rss-bridge ownership
chown rss-bridge:rss-bridge -R /var/www/rss-bridge/cache

# Or, give www-data ownership
chown www-data:www-data -R /var/www/rss-bridge/cache

# Or, give everyone write permission
chmod 777 -R /var/www/rss-bridge/cache

# Or last ditch effort (CAREFUL)
rm -rf /var/www/rss-bridge/cache/ && mkdir /var/www/rss-bridge/cache/
```

### How to fix "attempt to write a readonly database"

The sqlite files (db, wal and shm) are not writeable.

    chown -v rss-bridge:rss-bridge cache/*

### How to fix "Unable to prepare statement: 1, no such table: storage"

    rm cache/*

### How to create a completely new bridge

New code files MUST have `declare(strict_types=1);` at the top of file:

```php
<?php

declare(strict_types=1);
```

Create the new bridge in e.g. `bridges/BearBlogBridge.php`:

```php
<?php

declare(strict_types=1);

class BearBlogBridge extends BridgeAbstract
{
    const NAME = 'BearBlog (bearblog.dev)';

    public function collectData()
    {
        $dom = getSimpleHTMLDOM('https://herman.bearblog.dev/blog/');
        foreach ($dom->find('.blog-posts li') as $li) {
            $a = $li->find('a', 0);
            $this->items[] = [
                'title' => $a->plaintext,
                'uri' => 'https://herman.bearblog.dev' . $a->href,
            ];
        }
    }
}
```

Learn more in [bridge api](https://rss-bridge.github.io/rss-bridge/Bridge_API/index.html).

### How to enable all bridges

    enabled_bridges[] = *

### How to enable some bridges

```
enabled_bridges[] = TwitchBridge
enabled_bridges[] = GettrBridge
```

### How to switch to memcached as cache backend

```
[cache]

; Cache backend: file (default), sqlite, memcached, null
type = "memcached"
```

### How to switch to sqlite3 as cache backend

    type = "sqlite"

### How to disable bridge errors (as feed items)

When a bridge fails, RSS-Bridge will produce a feed with a single item describing the error.

This way, feed readers pick it up and you are notified.

If you don't want this behaviour, switch the error output to `http`:

    [error]

    ; Defines how error messages are returned by RSS-Bridge
    ;
    ; "feed" = As part of the feed (default)
    ; "http" = As HTTP error message
    ; "none" = No errors are reported
    output = "http"

### How to accumulate errors before finally reporting it

Modify `report_limit` so that an error must occur 3 times before it is reported.

    ; Defines how often an error must occur before it is reported to the user
    report_limit = 3

The report count is reset to 0 each day.

### How to password-protect the instance (HTTP Basic Auth)

    [authentication]

    enable = true
    username = "alice"
    password = "cat"

Will typically require feed readers to be configured with the credentials.

It may also be possible to manually include the credentials in the URL:

https://alice:cat@rss-bridge.org/bridge01/?action=display&bridge=FabriceBellardBridge&format=Html

### How to create a new output format

See `formats/PlaintextFormat.php` for an example.

### How to run unit tests and linter

These commands require that you have installed the dev dependencies in `composer.json`.

Run all tests:

    ./vendor/bin/phpunit

Run a single test class:

    ./vendor/bin/phpunit --filter UrlTest

Run linter:

    ./vendor/bin/phpcs --standard=phpcs.xml --warning-severity=0 --extensions=php -p ./

https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki

### How to spawn a minimal development environment

    php -S 127.0.0.1:9001

http://127.0.0.1:9001/


## Explanation

We are RSS-Bridge community, a group of developers continuing the project initiated by sebsauvage,
webmaster of
[sebsauvage.net](https://sebsauvage.net), author of
[Shaarli](https://sebsauvage.net/wiki/doku.php?id=php:shaarli) and
[ZeroBin](https://sebsauvage.net/wiki/doku.php?id=php:zerobin).

See [CONTRIBUTORS.md](CONTRIBUTORS.md)

RSS-Bridge uses caching to prevent services from banning your server for repeatedly updating feeds.
The specific cache duration can be different between bridges.

RSS-Bridge allows you to take full control over which bridges are displayed to the user.
That way you can host your own RSS-Bridge service with your favorite collection of bridges!

Current maintainers (as of 2024): @dvikan and @Mynacol #2519

## Reference

### Feed item structure

This is the feed item structure that bridges are expected to produce.

```php
    $item = [
        'uri' => 'https://example.com/blog/hello',
        'title' => 'Hello world',
        // Publication date in unix timestamp
        'timestamp' => 1668706254,
        'author' => 'Alice',
        'content' => 'Here be item content',
        'enclosures' => [
            'https://example.com/foo.png',
            'https://example.com/bar.png'
        ],
        'categories' => [
            'news',
            'tech',
        ],
        // Globally unique id
        'uid' => 'e7147580c8747aad',
    ]
```

### Output formats

* `Atom`: Atom feed, for use in feed readers
* `Html`: Simple HTML page
* `Json`: JSON, for consumption by other applications
* `Mrss`: MRSS feed, for use in feed readers
* `Plaintext`: Raw text, for consumption by other applications
* `Sfeed`: Text, TAB separated

### Cache backends

* `File`
* `SQLite`
* `Memcached`
* `Array`
* `Null`

### Licenses

The source code for RSS-Bridge is [Public Domain](UNLICENSE).

RSS-Bridge uses third party libraries with their own license:

  * [`Parsedown`](https://github.com/erusev/parsedown) licensed under the [MIT License](https://opensource.org/licenses/MIT)
  * [`PHP Simple HTML DOM Parser`](https://simplehtmldom.sourceforge.io/docs/1.9/index.html) licensed under the [MIT License](https://opensource.org/licenses/MIT)
  * [`php-urljoin`](https://github.com/fluffy-critter/php-urljoin) licensed under the [MIT License](https://opensource.org/licenses/MIT)
  * [`Laravel framework`](https://github.com/laravel/framework/) licensed under the [MIT License](https://opensource.org/licenses/MIT)

## Rant

*Dear so-called "social" websites.*

Your catchword is "share", but you don't want us to share. You want to keep us within your walled gardens. That's why you've been removing RSS links from webpages, hiding them deep on your website, or removed feeds entirely, replacing it with crippled or demented proprietary API. **FUCK YOU.**

You're not social when you hamper sharing by removing feeds. You're happy to have customers creating content for your ecosystem, but you don't want this content out - a content you do not even own. Google Takeout is just a gimmick. We want our data to flow, we want RSS or Atom feeds.

We want to share with friends, using open protocols: RSS, Atom, XMPP, whatever. Because no one wants to have *your* service with *your* applications using *your* API force-feeding them. Friends must be free to choose whatever software and service they want.

We are rebuilding bridges you have willfully destroyed.

Get your shit together: Put RSS/Atom back in.


================================================
FILE: UNLICENSE
================================================
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org>



================================================
FILE: actions/ConnectivityAction.php
================================================
<?php

/**
 * Checks if the website for a given bridge is reachable.
 *
 * **Remarks**
 * - This action is only available in debug mode.
 * - Returns the bridge status as Json-formatted string.
 * - Returns an error if the bridge is not whitelisted.
 * - Returns a responsive web page that automatically checks all whitelisted
 * bridges (using JavaScript) if no bridge is specified.
 */
class ConnectivityAction implements ActionInterface
{
    private BridgeFactory $bridgeFactory;

    public function __construct(
        BridgeFactory $bridgeFactory
    ) {
        $this->bridgeFactory = $bridgeFactory;
    }

    public function __invoke(Request $request): Response
    {
        if (Configuration::getConfig('system', 'env') !== 'dev') {
            return new Response('This action is only available in dev environment!', 403);
        }

        $bridgeName = $request->get('bridge');
        if (!$bridgeName) {
            return new Response(render_template('connectivity.html.php'));
        }
        $bridgeClassName = $this->bridgeFactory->createBridgeClassName($bridgeName);
        if (!$bridgeClassName) {
            return new Response('Bridge not found', 404);
        }
        return $this->reportBridgeConnectivity($bridgeClassName);
    }

    private function reportBridgeConnectivity($bridgeClassName)
    {
        if (!$this->bridgeFactory->isEnabled($bridgeClassName)) {
            throw new \Exception('Bridge is not whitelisted!');
        }

        $bridge = $this->bridgeFactory->create($bridgeClassName);
        $curl_opts = [
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_FOLLOWLOCATION => true,
        ];
        $result = [
            'bridge'        => $bridgeClassName,
            'successful'    => false,
            'http_code'     => null,
        ];
        try {
            $response = getContents($bridge::URI, [], $curl_opts, true);
            $result['http_code'] = $response->getCode();
            if (in_array($result['http_code'], [200])) {
                $result['successful'] = true;
            }
        } catch (\Exception $e) {
        }

        return new Response(Json::encode($result), 200, ['content-type' => 'text/json']);
    }
}


================================================
FILE: actions/DetectAction.php
================================================
<?php

class DetectAction implements ActionInterface
{
    private BridgeFactory $bridgeFactory;

    public function __construct(
        BridgeFactory $bridgeFactory
    ) {
        $this->bridgeFactory = $bridgeFactory;
    }

    public function __invoke(Request $request): Response
    {
        $url = $request->get('url');
        $format = $request->get('format');

        if (!$url) {
            return new Response(render(__DIR__ . '/../templates/error.html.php', ['message' => 'You must specify a url']));
        }
        if (!$format) {
            return new Response(render(__DIR__ . '/../templates/error.html.php', ['message' => 'You must specify a format']));
        }

        foreach ($this->bridgeFactory->getBridgeClassNames() as $bridgeClassName) {
            if (!$this->bridgeFactory->isEnabled($bridgeClassName)) {
                continue;
            }

            $bridge = $this->bridgeFactory->create($bridgeClassName);

            $bridgeParams = $bridge->detectParameters($url);

            if (!$bridgeParams) {
                continue;
            }

            $query = [
                'action' => 'display',
                'bridge' => $bridgeClassName,
                'format' => $format,
            ];
            $query = array_merge($query, $bridgeParams);
            return new Response('', 301, ['location' => '?' . http_build_query($query)]);
        }

        return new Response(render(__DIR__ . '/../templates/error.html.php', [
            'message' => 'No bridge found for given URL: ' . $url,
        ]));
    }
}


================================================
FILE: actions/DisplayAction.php
================================================
<?php

class DisplayAction implements ActionInterface
{
    private CacheInterface $cache;
    private Logger $logger;
    private BridgeFactory $bridgeFactory;

    public function __construct(
        CacheInterface $cache,
        Logger $logger,
        BridgeFactory $bridgeFactory
    ) {
        $this->cache = $cache;
        $this->logger = $logger;
        $this->bridgeFactory = $bridgeFactory;
    }

    public function __invoke(Request $request): Response
    {
        $bridgeName = $request->get('bridge');
        $format = $request->get('format');
        $noproxy = $request->get('_noproxy');

        if (!$bridgeName) {
            return new Response(render(__DIR__ . '/../templates/error.html.php', ['message' => 'Missing bridge name parameter']), 400);
        }
        $bridgeClassName = $this->bridgeFactory->createBridgeClassName($bridgeName);
        if (!$bridgeClassName) {
            return new Response(render(__DIR__ . '/../templates/error.html.php', ['message' => 'Bridge not found']), 404);
        }

        if (!$format) {
            return new Response(render(__DIR__ . '/../templates/error.html.php', ['message' => 'You must specify a format']), 400);
        }
        if (!$this->bridgeFactory->isEnabled($bridgeClassName)) {
            return new Response(render(__DIR__ . '/../templates/error.html.php', ['message' => 'This bridge is not whitelisted']), 400);
        }

        // Disable proxy (if enabled and per user's request)
        if (
            Configuration::getConfig('proxy', 'url')
            && Configuration::getConfig('proxy', 'by_bridge')
            && $noproxy
        ) {
            // This const is only used once in getContents()
            define('NOPROXY', true);
        }

        $cacheKey = 'http_' . json_encode($request->toArray());

        $bridge = $this->bridgeFactory->create($bridgeClassName);

        $response = $this->createResponse($request, $bridge, $format);

        if ($response->getCode() === 200) {
            $ttl = $request->get('_cache_timeout');
            if (Configuration::getConfig('cache', 'custom_timeout') && isset($ttl)) {
                $ttl = (int) $ttl;
            } else {
                $ttl = $bridge->getCacheTimeout();
            }
            $this->cache->set($cacheKey, $response, $ttl);
        }

        return $response;
    }

    private function createResponse(Request $request, BridgeAbstract $bridge, string $format)
    {
        $items = [];

        try {
            $bridge->loadConfiguration();
            // Remove parameters that don't concern bridges
            $remove = [
                'token',
                'action',
                'bridge',
                'format',
                '_noproxy',
                '_cache_timeout',
                '_error_time',
                '_', // Some RSS readers add a cache-busting parameter (_=<timestamp>) to feed URLs, detect and ignore them.
            ];
            $requestArray = $request->toArray();
            $input = array_diff_key($requestArray, array_fill_keys($remove, ''));
            $bridge->setInput($input);
            $bridge->collectData();
            $items = $bridge->getItems();
        } catch (\Throwable $e) {
            if ($e instanceof ClientException) {
                $this->logger->debug(sprintf('Exception in DisplayAction(%s): %s', $bridge->getShortName(), create_sane_exception_message($e)));
            } elseif ($e instanceof RateLimitException) {
                $this->logger->debug(sprintf('Exception in DisplayAction(%s): %s', $bridge->getShortName(), create_sane_exception_message($e)));
                return new Response(render(__DIR__ . '/../templates/exception.html.php', ['e' => $e]), 429);
            } elseif ($e instanceof HttpException) {
                if (in_array($e->getCode(), [429, 503])) {
                    // Log with debug, immediately reproduce and return
                    $this->logger->debug(sprintf('Exception in DisplayAction(%s): %s', $bridge->getShortName(), create_sane_exception_message($e)));
                    return new Response(render(__DIR__ . '/../templates/exception.html.php', ['e' => $e]), $e->getCode());
                }
                // Some other status code which we let fail normally (but don't log it)
            } else {
                $this->logger->error(sprintf('Exception in DisplayAction(%s)', $bridge->getShortName()), ['e' => $e]);
            }
            $errorOutput = Configuration::getConfig('error', 'output');
            $reportLimit = Configuration::getConfig('error', 'report_limit');
            $errorCount = 1;
            if ($reportLimit > 1) {
                $errorCount = $this->logBridgeError($bridge->getName(), $e->getCode());
            }
            // Let clients know about the error if we are passed the report limit
            if ($errorCount >= $reportLimit) {
                if ($errorOutput === 'feed') {
                    // Render the exception as a feed item
                    $items = [$this->createFeedItemFromException($e, $bridge)];
                } elseif ($errorOutput === 'http') {
                    return new Response(render(__DIR__ . '/../templates/exception.html.php', ['e' => $e]), 500);
                } elseif ($errorOutput === 'none') {
                    // Do nothing (produces an empty feed)
                }
            }
        }

        $formatFactory = new FormatFactory();
        $format = $formatFactory->create($format);

        $format->setItems($items);
        $format->setFeed($bridge->getFeed());
        $now = time();
        $format->setLastModified($now);
        $headers = [
            'last-modified' => gmdate('D, d M Y H:i:s ', $now) . 'GMT',
            'content-type'  => $format->getMimeType() . '; charset=UTF-8',
        ];
        $body = $format->render();

        // This is supposed to remove non-utf8 byte sequences, but I'm unsure if it works
        ini_set('mbstring.substitute_character', 'none');
        $body = mb_convert_encoding($body, 'UTF-8', 'UTF-8');

        return new Response($body, 200, $headers);
    }

    private function createFeedItemFromException($e, BridgeAbstract $bridge): array
    {
        $item = [];

        // Create a unique identifier every 24 hours
        $uniqueIdentifier = urlencode((int)(time() / 86400));
        $title = sprintf('Bridge returned error %s! (%s)', $e->getCode(), $uniqueIdentifier);

        $item['title'] = $title;
        $item['uri'] = get_current_url();
        $item['timestamp'] = time();

        // Create an item identifier for feed readers e.g. "staysafetv twitch videos_19389"
        $item['uid'] = $bridge->getName() . '_' . $uniqueIdentifier;

        $content = render_template(__DIR__ . '/../templates/bridge-error.html.php', [
            'error' => render_template(__DIR__ . '/../templates/exception.html.php', ['e' => $e]),
            'searchUrl' => self::createGithubSearchUrl($bridge),
            'issueUrl' => self::createGithubIssueUrl($bridge, $e),
            'maintainer' => $bridge->getMaintainer(),
        ]);
        $item['content'] = $content;

        return $item;
    }

    private function logBridgeError($bridgeName, $code)
    {
        // todo: it's not really necessary to json encode $report
        $cacheKey = 'error_reporting_' . $bridgeName . '_' . $code;
        $report = $this->cache->get($cacheKey);
        if ($report) {
            $report = Json::decode($report);
            $report['time'] = time();
            $report['count']++;
        } else {
            $report = [
                'error' => $code,
                'time' => time(),
                'count' => 1,
            ];
        }
        $ttl = 86400 * 5;
        $this->cache->set($cacheKey, Json::encode($report), $ttl);
        return $report['count'];
    }

    private static function createGithubIssueUrl(BridgeAbstract $bridge, \Throwable $e): string
    {
        $maintainer = $bridge->getMaintainer();
        if (str_contains($maintainer, ',')) {
            $maintainers = explode(',', $maintainer);
        } else {
            $maintainers = [$maintainer];
        }
        $maintainers = array_map('trim', $maintainers);

        $queryString = $_SERVER['QUERY_STRING'] ?? '';
        $query = [
            'title' => $bridge->getName() . ' failed with: ' . $e->getMessage(),
            'body' => sprintf(
                "```\n%s\n\n%s\n\nQuery string: %s\nVersion: %s\nOs: %s\nPHP version: %s\n```\nMaintainer: @%s",
                create_sane_exception_message($e),
                implode("\n", trace_to_call_points(trace_from_exception($e))),
                $queryString,
                Configuration::getVersion(),
                PHP_OS_FAMILY,
                phpversion() ?: 'Unknown',
                implode(', @', $maintainers),
            ),
            'labels' => 'Bridge-Broken',
            'assignee' => $maintainer[0],
        ];

        return 'https://github.com/RSS-Bridge/rss-bridge/issues/new?' . http_build_query($query);
    }

    private static function createGithubSearchUrl($bridge): string
    {
        return sprintf(
            'https://github.com/RSS-Bridge/rss-bridge/issues?q=%s',
            urlencode('is:issue is:open ' . $bridge->getName())
        );
    }
}


================================================
FILE: actions/FindfeedAction.php
================================================
<?php

/**
 * This action is used by the frontpage form search.
 * It finds a bridge based off of a user input url.
 * It uses bridges' detectParameters implementation.
 */
class FindfeedAction implements ActionInterface
{
    private BridgeFactory $bridgeFactory;

    public function __construct(
        BridgeFactory $bridgeFactory
    ) {
        $this->bridgeFactory = $bridgeFactory;
    }

    public function __invoke(Request $request): Response
    {
        $url = $request->get('url');
        $format = $request->get('format');

        if (!$url) {
            return new Response('You must specify a url', 400);
        }
        if (!$format) {
            return new Response('You must specify a format', 400);
        }

        $results = [];
        foreach ($this->bridgeFactory->getBridgeClassNames() as $bridgeClassName) {
            if (!$this->bridgeFactory->isEnabled($bridgeClassName)) {
                continue;
            }

            $bridge = $this->bridgeFactory->create($bridgeClassName);

            $bridgeParams = $bridge->detectParameters($url);

            if ($bridgeParams === null) {
                continue;
            }

            // It's allowed to have no 'context' in a bridge (only a default context without any name)
            // In this case, the reference to the parameters are found in the first element of the PARAMETERS array

            $context = $bridgeParams['context'] ?? 0;

            $bridgeData = [];
            // Construct the array of parameters
            foreach ($bridgeParams as $key => $value) {
                // 'context' is a special case : it's a bridge parameters, there is no "name" for this parameter
                if ($key == 'context') {
                    $bridgeData[$key]['name'] = 'Context';
                    $bridgeData[$key]['value'] = $value;
                } else {
                    $bridgeData[$key]['name'] = $this->getParameterName($bridge, $context, $key);
                    $bridgeData[$key]['value'] = $value;
                }
            }

            $bridgeParams['bridge'] = $bridgeClassName;
            $bridgeParams['format'] = $format;
            $content = [
                'url' => './?action=display&' . http_build_query($bridgeParams),
                'bridgeParams' => $bridgeParams,
                'bridgeData' => $bridgeData,
                'bridgeMeta' => [
                        'name' => $bridge::NAME,
                        'description' => $bridge::DESCRIPTION,
                        'parameters' => $bridge::PARAMETERS,
                        'icon' => $bridge->getIcon(),
                    ],
            ];
            $results[] = $content;
        }
        if ($results === []) {
            return new Response(Json::encode(['message' => 'No bridge found for given url']), 404, ['content-type' => 'application/json']);
        }
        return new Response(Json::encode($results), 200, ['content-type' => 'application/json']);
    }

    // Get parameter name in the actual context, or in the global parameter
    private function getParameterName($bridge, $context, $key)
    {
        if (isset($bridge::PARAMETERS[$context][$key]['name'])) {
            $name = $bridge::PARAMETERS[$context][$key]['name'];
        } else if (isset($bridge::PARAMETERS['global'][$key]['name'])) {
            $name = $bridge::PARAMETERS['global'][$key]['name'];
        } else {
            $name = 'Variable "' . $key . '" (No name provided)';
        }
        return $name;
    }
}


================================================
FILE: actions/FrontpageAction.php
================================================
<?php

final class FrontpageAction implements ActionInterface
{
    private BridgeFactory $bridgeFactory;

    public function __construct(
        BridgeFactory $bridgeFactory
    ) {
        $this->bridgeFactory = $bridgeFactory;
    }

    public function __invoke(Request $request): Response
    {
        $token = $request->getAttribute('token');

        $messages = [];
        $activeBridges = 0;

        $bridgeClassNames = $this->bridgeFactory->getBridgeClassNames();

        foreach ($this->bridgeFactory->getMissingEnabledBridges() as $missingEnabledBridge) {
            $messages[] = [
                'body' => sprintf('Warning : Bridge "%s" not found', $missingEnabledBridge),
                'level' => 'warning'
            ];
        }

        $body = '';
        foreach ($bridgeClassNames as $bridgeClassName) {
            if ($this->bridgeFactory->isEnabled($bridgeClassName)) {
                $bridge = $this->bridgeFactory->create($bridgeClassName);
                $body .= self::render($bridge, $bridgeClassName, $token);
                $activeBridges++;
            }
        }

        $response = new Response(render(__DIR__ . '/../templates/frontpage.html.php', [
            'messages'          => $messages,
            'admin_email'       => Configuration::getConfig('admin', 'email'),
            'admin_telegram'    => Configuration::getConfig('admin', 'telegram'),
            'bridges'           => $body,
            'active_bridges'    => $activeBridges,
            'total_bridges'     => count($bridgeClassNames),
        ]));

        // TODO: The rendered template could be cached, but beware config changes that changes the html
        return $response;
    }

    public static function render(
        BridgeAbstract $bridge,
        string $bridgeClassName,
        ?string $token
    ): string {
        $uri = $bridge->getURI();
        $name = $bridge->getName();
        $icon = $bridge->getIcon();
        $description = $bridge->getDescription();
        $parameters = $bridge->getParameters();

        // Checkbox for disabling of proxy (if enabled)
        if (
            Configuration::getConfig('proxy', 'url')
            && Configuration::getConfig('proxy', 'by_bridge')
        ) {
            $proxyName = Configuration::getConfig('proxy', 'name') ?: Configuration::getConfig('proxy', 'url');
            $parameters['global']['_noproxy'] = [
                'name' => sprintf('Disable proxy (%s)', $proxyName),
                'type' => 'checkbox',
            ];
        }

        if (Configuration::getConfig('cache', 'custom_timeout')) {
            $parameters['global']['_cache_timeout'] = [
                'name' => 'Cache timeout in seconds',
                'type' => 'number',
                'defaultValue' => $bridge->getCacheTimeout()
            ];
        }

        $shortName = $bridge->getShortName();
        $card = <<<CARD
            <section
                class="bridge-card"
                id="bridge-{$bridgeClassName}"
                data-ref="{$name}"
                data-short-name="$shortName"
            >

            <a style="position: absolute; top: 10px; left: 10px" href="#bridge-{$bridgeClassName}">
                <h1>#</h1>
            </a>

            <h2><a href="{$uri}">{$name}</a></h2>
            <p class="description">{$description}</p>

            <input type="checkbox" class="showmore-box" id="showmore-{$bridgeClassName}" />
            <label class="showmore" for="showmore-{$bridgeClassName}">Show more</label>


        CARD;

        if (count($parameters) === 0) {
            // The bridge has zero parameters
            $card .= self::renderForm($bridgeClassName, '', [], $token);
        } elseif (count($parameters) === 1 && array_key_exists('global', $parameters)) {
            // The bridge has a single context with key 'global'
            $card .= self::renderForm($bridgeClassName, '', $parameters['global'], $token);
        } else {
            // The bridge has one or more contexts (named or unnamed)
            foreach ($parameters as $contextName => $contextParameters) {
                if ($contextName === 'global') {
                    continue;
                }

                if (array_key_exists('global', $parameters)) {
                    // Merge the global parameters into current context
                    $contextParameters = array_merge($contextParameters, $parameters['global']);
                }

                if (!is_numeric($contextName)) {
                    // This is a named context
                    $card .= '<h5>' . $contextName . "</h5>\n";
                }

                $card .= self::renderForm($bridgeClassName, $contextName, $contextParameters, $token);
            }
        }

        $card .= html_tag('label', 'Show less', [
                'class' => 'showless',
                'for'   => "showmore-$bridgeClassName",
            ]) . "\n";

        if (Configuration::getConfig('admin', 'donations') && $bridge->getDonationURI()) {
            $card .= sprintf(
                '<p class="maintainer">%s ~ <a href="%s">Donate</a></p>',
                $bridge->getMaintainer(),
                $bridge->getDonationURI()
            );
        } else {
            $card .= html_tag('p', $bridge->getMaintainer(), ['class' => 'maintainer']) . "\n";
        }
        $card .= "</section>\n\n";

        return $card;
    }

    private static function renderForm(
        string $bridgeClassName,
        string $contextName,
        array $parameters,
        ?string $token
    ): string {
        $form = <<<EOD
        <form method="GET" action="?" class="bridge-form">
            <input type="hidden" name="action" value="display" />
            <input type="hidden" name="bridge" value="{$bridgeClassName}" />

        EOD;

        if (Configuration::getConfig('authentication', 'token') && $token) {
            $form .= html_input([
                    'type'  => 'hidden',
                    'name'  => 'token',
                    'value' => $token,
                ]) . "\n";
        }

        if (!empty($contextName)) {
            $form .= html_input([
                    'type'  => 'hidden',
                    'name'  => 'context',
                    'value' => $contextName,
                ]) . "\n";
        }

        $form .= '<div class="parameters">' . "\n";

        foreach ($parameters as $id => $parameter) {
            if (!isset($parameter['exampleValue'])) {
                $parameter['exampleValue'] = '';
            }

            if (!isset($parameter['defaultValue'])) {
                $parameter['defaultValue'] = '';
            }

            $idArg = 'arg-' . urlencode($bridgeClassName) . '-' . urlencode($contextName) . '-' . urlencode($id);

            $form .= html_tag('label', $parameter['name'], ['for' => $idArg]) . "\n";

            if (
                !isset($parameter['type'])
                || $parameter['type'] === 'text'
            ) {
                $form .= self::getTextInput($parameter, $idArg, $id) . "\n";
            } elseif ($parameter['type'] === 'number') {
                $form .= self::getNumberInput($parameter, $idArg, $id) . "\n";
            } elseif ($parameter['type'] === 'list') {
                $form .= self::getListInput($parameter, $idArg, $id) . "\n";
            } elseif ($parameter['type'] === 'checkbox') {
                $form .= self::getCheckboxInput($parameter, $idArg, $id) . "\n";
            } else {
                $foo = 2;
                // oops?
            }

            $params = [];
            if (isset($parameter['title'])) {
                $params = [
                    'title' => $parameter['title'],
                    'class' => 'info',
                ];
            }
            if ($parameter['exampleValue'] !== '') {
                $params = [
                    'title'         => sprintf("Example (right click to use):\n%s", $parameter['exampleValue']),
                    'class'         => 'info',
                    'oncontextmenu' => 'rssbridge_use_placeholder_value(this);return false',
                    'data-for'      => $idArg,
                ];
            }

            if ($params) {
                $form .= html_tag('i', 'i', $params) . "\n";
            } else {
                $form .= html_tag('i', ' ', ['class' => 'no-info']) . "\n";
            }
        }

        $form .= "</div>\n\n";

        $form .= html_tag('button', 'Generate feed', [
                'type'          => 'submit',
                'name'          => 'format',
                'value'         => 'Html',
                'formtarget'    => '_blank',
            ]) . "\n";

        return $form . "</form>\n\n";
    }

    public static function getTextInput(array $parameter, string $id, string $name): string
    {
        $pattern = $parameter['pattern'] ?? null;
        $checked = $parameter['defaultValue'] === 'checked';
        $required = $parameter['required'] ?? false;

        return html_input([
            'id'            => $id,
            'type'          => 'text',
            'value'         => $parameter['defaultValue'],
            'placeholder'   => $parameter['exampleValue'],
            'name'          => $name,
            'pattern'       => $pattern,
            'checked'       => $checked,
            'required'      => $required,
        ]);
    }

    public static function getNumberInput(array $parameter, string $id, string $name): string
    {
        $pattern = $parameter['pattern'] ?? null;
        $checked = $parameter['defaultValue'] === 'checked';
        $required = $parameter['required'] ?? false;

        return html_input([
            'id'            => $id,
            'type'          => 'number',
            'value'         => $parameter['defaultValue'],
            'placeholder'   => $parameter['exampleValue'],
            'name'          => $name,
            'pattern'       => $pattern,
            'checked'       => $checked,
            'required'      => $required,
        ]);
    }

    public static function getCheckboxInput(array $parameter, string $id, string $name): string
    {
        return html_input([
            'id'        => $id,
            'type'      => 'checkbox',
            'name'      => $name,
            'checked'   => $parameter['defaultValue'] === 'checked',
        ]);
    }

    public static function getListInput(array $parameter, string $id, string $name): string
    {
        $list = sprintf('<select id="%s" name="%s">', $id, $name) . "\n";

        foreach ($parameter['values'] as $name => $value) {
            if (is_array($value)) {
                $list .= '<optgroup label="' . htmlentities($name) . '">';
                foreach ($value as $subname => $subvalue) {
                    if (
                        $parameter['defaultValue'] === $subname
                        || $parameter['defaultValue'] === $subvalue
                    ) {
                        $list .= html_option($subname, $subvalue, true) . "\n";
                    } else {
                        $list .= html_option($subname, $subvalue) . "\n";
                    }
                }
                $list .= '</optgroup>';
            } else {
                if (
                    $parameter['defaultValue'] === $name
                    || $parameter['defaultValue'] === $value
                ) {
                    $list .= html_option($name, $value, true) . "\n";
                } else {
                    $list .= html_option($name, $value) . "\n";
                }
            }
        }

        $list .= "</select>\n";

        return $list;
    }
}


================================================
FILE: actions/HealthAction.php
================================================
<?php

declare(strict_types=1);

class HealthAction implements ActionInterface
{
    public function __invoke(Request $request): Response
    {
        $response = [
            'code' => 200,
            'message' => 'all is good',
        ];
        return new Response(Json::encode($response), 200, ['content-type' => 'application/json']);
    }
}


================================================
FILE: actions/ListAction.php
================================================
<?php

class ListAction implements ActionInterface
{
    private BridgeFactory $bridgeFactory;

    public function __construct(
        BridgeFactory $bridgeFactory
    ) {
        $this->bridgeFactory = $bridgeFactory;
    }

    public function __invoke(Request $request): Response
    {
        $list = new \stdClass();
        $list->bridges = [];
        $list->total = 0;

        foreach ($this->bridgeFactory->getBridgeClassNames() as $bridgeClassName) {
            $bridge = $this->bridgeFactory->create($bridgeClassName);

            $list->bridges[$bridgeClassName] = [
                'status'        => $this->bridgeFactory->isEnabled($bridgeClassName) ? 'active' : 'inactive',
                'uri'           => $bridge->getURI(),
                'donationUri'   => $bridge->getDonationURI(),
                'name'          => $bridge->getName(),
                'icon'          => $bridge->getIcon(),
                'parameters'    => $bridge->getParameters(),
                'maintainer'    => $bridge->getMaintainer(),
                'description'   => $bridge->getDescription()
            ];
        }
        $list->total = count($list->bridges);
        return new Response(Json::encode($list), 200, ['content-type' => 'application/json']);
    }
}


================================================
FILE: app.json
================================================
{
  "service": "Heroku",
  "name": "rss-bridge-heroku",
  "description": "RSS-Bridge is a PHP project capable of generating RSS and Atom feeds for websites which don't have one.",
  "repository": "https://github.com/RSS-Bridge/rss-bridge?1651005770",
  "keywords": ["php", "rss-bridge", "rss"]
}



================================================
FILE: bridges/ABCNewsBridge.php
================================================
<?php

class ABCNewsBridge extends BridgeAbstract
{
    const NAME = 'ABC News';
    const URI = 'https://www.abc.net.au';
    const DESCRIPTION = 'Topics of the Australian Broadcasting Corporation';
    const MAINTAINER = 'yue-dongchen';

    const PARAMETERS = [
        [
            'topic' => [
                'type' => 'list',
                'name' => 'Region',
                'title' => 'Choose state',
                'values' => [
                    'ACT' => 'act',
                    'NSW' => 'nsw',
                    'NT' => 'nt',
                    'QLD' => 'qld',
                    'SA' => 'sa',
                    'TAS' => 'tas',
                    'VIC' => 'vic',
                    'WA' => 'wa'
                ],
            ]
        ]
    ];

    public function collectData()
    {
        $url = sprintf('https://www.abc.net.au/news/%s', $this->getInput('topic'));
        $dom = getSimpleHTMLDOM($url);
        $dom = $dom->find('div[data-component="PaginationList"]', 0);
        if (!$dom) {
            throw new \Exception(sprintf('Unable to find css selector on `%s`', $url));
        }
        $dom = defaultLinkTo($dom, $this->getURI());
        foreach ($dom->find('article[data-component="DetailCard"]') as $article) {
            $a = $article->find('a', 0);
            $this->items[] = [
                'title' => $a->plaintext,
                'uri' => $a->href,
                'content' => $article->find('p', 0)->plaintext,
                'timestamp' => strtotime($article->find('time', 0)->datetime),
            ];
        }
    }
}


================================================
FILE: bridges/ABolaBridge.php
================================================
<?php

class ABolaBridge extends BridgeAbstract
{
    const NAME = 'A Bola';
    const URI = 'https://abola.pt/';
    const DESCRIPTION = 'Returns news from the Portuguese sports newspaper A BOLA.PT';
    const MAINTAINER = 'rmscoelho';
    const CACHE_TIMEOUT = 3600;
    const PARAMETERS = [
        [
            'feed' => [
                'name' => 'News Feed',
                'type' => 'list',
                'title' => 'Feeds from the Portuguese sports newspaper A BOLA.PT',
                'values' => [
                    'Últimas' => 'Nnh/Noticias',
                    'Seleção Nacional' => 'Selecao/Noticias',
                    'Futebol Nacional' => [
                        'Notícias' => 'Nacional/Noticias',
                        'Primeira Liga' => 'Nacional/Liga/Noticias',
                        'Liga 2' => 'Nacional/Liga2/Noticias',
                        'Liga 3' => 'Nacional/Liga3/Noticias',
                        'Liga Revelação' => 'Nacional/Liga-Revelacao/Noticias',
                        'Campeonato de Portugal' => 'Nacional/Campeonato-Portugal/Noticias',
                        'Distritais' => 'Nacional/Distritais/Noticias',
                        'Taça de Portugal' => 'Nacional/TPortugal/Noticias',
                        'Futebol Feminino' => 'Nacional/FFeminino/Noticias',
                        'Futsal' => 'Nacional/Futsal/Noticias',
                    ],
                    'Futebol Internacional' => [
                        'Notícias' => 'Internacional/Noticias/Noticias',
                        'Liga dos Campeões' => 'Internacional/Liga-dos-campeoes/Noticias',
                        'Liga Europa' => 'Internacional/Liga-europa/Noticias',
                        'Liga Conferência' => 'Internacional/Liga-conferencia/Noticias',
                        'Liga das Nações' => 'Internacional/Liga-das-nacoes/Noticias',
                        'UEFA Youth League' => 'Internacional/Uefa-Youth-League/Noticias',
                    ],
                    'Mercado' => 'Mercado',
                    'Modalidades' => 'Modalidades/Noticias',
                    'Motores' => 'Motores/Noticias',
                ]
            ]
        ]
    ];

    public function getIcon()
    {
        return 'https://abola.pt/img/icons/favicon-96x96.png';
    }

    public function getName()
    {
        return !is_null($this->getKey('feed')) ? self::NAME . ' | ' . $this->getKey('feed') : self::NAME;
    }

    public function getURI()
    {
        return self::URI . $this->getInput('feed');
    }

    public function collectData()
    {
        $url = sprintf('https://abola.pt/%s', $this->getInput('feed'));
        $dom = getSimpleHTMLDOM($url);
        if ($this->getInput('feed') !== 'Mercado') {
            $dom = $dom->find('div#body_Todas1_upNoticiasTodas', 0);
        } else {
            $dom = $dom->find('div#body_NoticiasMercado_upNoticiasTodas', 0);
        }
        if (!$dom) {
            throw new \Exception(sprintf('Unable to find css selector on `%s`', $url));
        }
        $dom = defaultLinkTo($dom, $this->getURI());
        foreach ($dom->find('div.media') as $key => $article) {
            //Get thumbnail
            $image = $article->find('.media-img', 0)->style;
            $image = preg_replace('/background-image: url\(/i', '', $image);
            $image = substr_replace($image, '', -4);
            $image = preg_replace('/https:\/\//i', '', $image);
            $image = preg_replace('/www\./i', '', $image);
            $image = preg_replace('/\/\//', '/', $image);
            $image = preg_replace('/\/\/\//', '//', $image);
            $image = substr($image, 7);
            $image = 'https://' . $image;
            $image = preg_replace('/ptimg/', 'pt/img', $image);
            $image = preg_replace('/\/\/bola/', 'www.abola', $image);
            //Timestamp
            $date = date('Y/m/d');
            if (!is_null($article->find("span#body_Todas1_rptNoticiasTodas_lblData_$key", 0))) {
                $date = $article->find("span#body_Todas1_rptNoticiasTodas_lblData_$key", 0)->plaintext;
                $date = preg_replace('/\./', '/', $date);
            }
            $time = $article->find("span#body_Todas1_rptNoticiasTodas_lblHora_$key", 0)->plaintext;
            $date = explode('/', $date);
            $time = explode(':', $time);
            $year = $date[0];
            $month = $date[1];
            $day = $date[2];
            $hour = $time[0];
            $minute = $time[1];
            $timestamp = mktime($hour, $minute, 0, $month, $day, $year);
            //Content
            $image = '<img src="' . $image . '" alt="' . $article->find('h4 span', 0)->plaintext . '" />';
            $description = '<p>' . $article->find('.media-texto > span', 0)->plaintext . '</p>';
            $content = $image . '</br>' . $description;
            $a = $article->find('.media-body > a', 0);
            $this->items[] = [
                'title' => $a->find('h4 span', 0)->plaintext,
                'uri' => $a->href,
                'content' => $content,
                'timestamp' => $timestamp,
            ];
        }
    }
}


================================================
FILE: bridges/AO3Bridge.php
================================================
<?php

class AO3Bridge extends BridgeAbstract
{
    const NAME = 'AO3';
    const URI = 'https://archiveofourown.org/';
    const CACHE_TIMEOUT = 1800;
    const DESCRIPTION = 'Returns works or chapters from Archive of Our Own';
    const MAINTAINER = 'Obsidienne';
    const PARAMETERS = [
        'List' => [
            'url' => [
                'name' => 'url',
                'required' => true,
                // Example: F/F tag
                'exampleValue' => 'https://archiveofourown.org/tags/F*s*F/works',
            ],
            'range' => [
                'name' => 'Chapter Content',
                'title' => 'Chapter(s) to include in each work\'s feed entry',
                'defaultValue' => null,
                'type' => 'list',
                'values' => [
                    'None' => null,
                    'First' => 'first',
                    'Latest' => 'last',
                    'Entire work' => 'all',
                ],
            ],
            'unique' => [
                'name' => 'Make separate entries for new fic chapters',
                'type' => 'checkbox',
                'required' => false,
                'title' => 'Make separate entries for new fic chapters',
                'defaultValue' => 'checked',
            ],
            'limit' => self::LIMIT,
        ],
        'Bookmarks' => [
            'user' => [
                'name' => 'user',
                'required' => true,
                // Example: Nyaaru's bookmarks
                'exampleValue' => 'Nyaaru',
            ],
        ],
        'Work' => [
            'id' => [
                'name' => 'id',
                'required' => true,
                // Example: latest chapters from A Better Past by LysSerris
                'exampleValue' => '18181853',
            ],
        ]
    ];
    private $title;

    public function collectData()
    {
        switch ($this->queriedContext) {
            case 'Bookmarks':
                $this->collectList($this->getURI());
                break;
            case 'List':
                $this->collectList($this->getURI());
                break;
            case 'Work':
                $this->collectWork($this->getURI());
                break;
        }
    }

    /**
     * Feed for lists of works (e.g. recent works, search results, filtered tags,
     * bookmarks, series, collections).
     */
    private function collectList($url)
    {
        $version = 'v0.0.1';
        $headers = [
            "useragent: rss-bridge $version (https://github.com/RSS-Bridge/rss-bridge)"
        ];
        $response = getContents($url, $headers);

        $html = \str_get_html($response);
        $html = defaultLinkTo($html, self::URI);

        // Get list title. Will include page range + count in some cases
        $heading = ($html->find('#main h2', 0));
        if ($heading->find('a.tag')) {
            $heading = $heading->find('a.tag', 0);
        }
        $this->title = $heading->plaintext;

        $limit = $this->getInput('limit') ?? 3;
        $count = 0;
        foreach ($html->find('.index.group > li') as $element) {
            $item = [];

            $title = $element->find('div h4 a', 0);
            if (!isset($title)) {
                continue; // discard deleted works
            }
            $item['title'] = $title->plaintext;
            $item['uri'] = $title->href;

            $strdate = $element->find('div p.datetime', 0)->plaintext;
            $item['timestamp'] = strtotime($strdate);

            // detach from rest of page because remove() is buggy
            $element = str_get_html($element->outertext());
            $tags = $element->find('ul.required-tags', 0);
            foreach ($tags->childNodes() as $tag) {
                $item['categories'][] = html_entity_decode($tag->plaintext);
            }
            $tags->remove();
            $tags = $element->find('ul.tags', 0);
            foreach ($tags->childNodes() as $tag) {
                $item['categories'][] = html_entity_decode($tag->plaintext);
            }
            $tags->remove();

            $item['content'] = implode('', $element->childNodes());

            $chapters = $element->find('dl dd.chapters', 0);
            // bookmarked series and external works do not have a chapters count
            $chapters = (isset($chapters) ? $chapters->plaintext : 0);
            if ($this->getInput('unique')) {
                $item['uid'] = $item['uri'] . "/$strdate/$chapters";
            } else {
                $item['uid'] = $item['uri'];
            }


            // Fetch workskin of desired chapter(s) in list
            if ($this->getInput('range') && ($limit == 0 || $count++ < $limit)) {
                $url = $item['uri'];
                switch ($this->getInput('range')) {
                    case ('all'):
                        $url .= '?view_full_work=true';
                        break;
                    case ('first'):
                        break;
                    case ('last'):
                        // only way to get this is using the navigate page unfortunately
                        $url .= '/navigate';
                        $response = getContents($url, $headers);
                        $html = \str_get_html($response);
                        $html = defaultLinkTo($html, self::URI);
                        $url = $html->find('ol.index.group > li > a', -1)->href;
                        break;
                }
                $response = getContents($url, $headers);

                $html = \str_get_html($response);
                $html = defaultLinkTo($html, self::URI);
                // remove duplicate fic summary
                if ($ficsum = $html->find('#workskin > .preface > .summary', 0)) {
                    $ficsum->remove();
                }
                $item['content'] .= $html->find('#workskin', 0);
            }

            // Use predictability of download links to generate enclosures
            $wid = explode('/', $item['uri'])[4];
            foreach (['azw3', 'epub', 'mobi', 'pdf', 'html'] as $ext) {
                $item['enclosures'][] = 'https://archiveofourown.org/downloads/' . $wid . '/work.' . $ext;
            }

            $this->items[] = $item;
        }
    }

    /**
     * Feed for recent chapters of a specific work.
     */
    private function collectWork($url)
    {
        $version = 'v0.0.1';
        $headers = [
            "useragent: rss-bridge $version (https://github.com/RSS-Bridge/rss-bridge)"
        ];
        $response = getContents($url . '/navigate', $headers);

        $html = \str_get_html($response);
        $html = defaultLinkTo($html, self::URI);

        $response = getContents($url . '?view_full_work=true', $headers);

        $workhtml = \str_get_html($response);
        $workhtml = defaultLinkTo($workhtml, self::URI);

        $this->title = $html->find('h2 a', 0)->plaintext;

        $nav = $html->find('ol.index.group > li');
        for ($i = 0; $i < count($nav); $i++) {
            $item = [];

            $element = $nav[$i];
            $item['title'] = $element->find('a', 0)->plaintext;
            $item['content'] = $workhtml->find('#chapter-' . ($i + 1), 0);
            $item['uri'] = $element->find('a', 0)->href;

            $strdate = $element->find('span.datetime', 0)->plaintext;
            $strdate = str_replace('(', '', $strdate);
            $strdate = str_replace(')', '', $strdate);
            $item['timestamp'] = strtotime($strdate);

            $item['uid'] = $item['uri'] . "/$strdate";

            $this->items[] = $item;
        }

        $this->items = array_reverse($this->items);
    }

    public function getName()
    {
        $name = parent::getName() . " $this->queriedContext";
        if (isset($this->title)) {
            $name .= " - $this->title";
        }
        return $name;
    }

    public function getIcon()
    {
        return self::URI . '/favicon.ico';
    }

    public function getURI()
    {
        $url = parent::getURI();
        switch ($this->queriedContext) {
            case 'Bookmarks':
                $user = $this->getInput('user');
                $url = self::URI
                    . '/users/' . $user
                    . '/bookmarks?bookmark_search[sort_column]=bookmarkable_date';
                break;
            case 'List':
                $url = $this->getInput('url');
                break;
            case 'Work':
                $url = self::URI . '/works/' . $this->getInput('id');
                break;
        }
        return $url;
    }
}


================================================
FILE: bridges/ARDAudiothekBridge.php
================================================
<?php

class ARDAudiothekBridge extends BridgeAbstract
{
    const NAME = 'ARD-Audiothek';
    const URI = 'https://www.ardaudiothek.de';
    const DESCRIPTION = 'Feed of any show in the ARD-Audiothek, specified by its path';
    const MAINTAINER = 'Mar-Koeh';
    /*
     * The URL Prefix of the API
     * @const APIENDPOINT https-URL of the used endpoint, ending in `/`
     */
    const APIENDPOINT = 'https://api.ardaudiothek.de/';
    /*
     * The requested width of the preview image
     * 448 and 128 have been observed on the wild
     * @const IMAGEWIDTH width in px of the preview image
     */
    const IMAGEWIDTH = 448;
    /*
     * Placeholder that will be replace by IMAGEWIDTH in the preview image URL
     * @const IMAGEWIDTHPLACEHOLDER
     */
    const IMAGEWIDTHPLACEHOLDER = '{width}';
    /*
     * File extension appended to image link in $this->icon
     * @const IMAGEEXTENSION
     */
    const IMAGEEXTENSION = '.jpg';

    const PARAMETERS = [
        [
            'path' => [
                'name' => 'Show Link or ID',
                'required' => true,
                'title' => 'Link to the show page or just its numeric suffix',
                'defaultValue' => 'https://www.ardaudiothek.de/sendung/kalk-welk/10777871/'
            ],
            'limit' => self::LIMIT,
        ]
    ];


    /**
     * Holds the title of the current show
     *
     * @var string
     */
    private $title;

    /**
     * Holds the URI of the show
     *
     * @var string
     */
    private $uri;

    /**
     * Holds the icon of the feed
     *
     */
    private $icon;

    public function collectData()
    {
        $path = $this->getInput('path');
        $limit = $this->getInput('limit');

        $oldTz = date_default_timezone_get();
        date_default_timezone_set('Europe/Berlin');

        $pathComponents = explode('/', $path);
        if (empty($pathComponents)) {
            throwClientException('Path may not be empty');
        }
        if (count($pathComponents) < 2) {
            $showID = $pathComponents[0];
        } else {
            $lastKey = count($pathComponents) - 1;
            $showID = $pathComponents[$lastKey];
            if (strlen($showID) === 0) {
                $showID = $pathComponents[$lastKey - 1];
            }
        }

        $url = self::APIENDPOINT . 'programsets/' . $showID . '/';
        $json1 = getContents($url);
        $data1 = Json::decode($json1, false);
        $processedJSON = $data1->data->programSet;
        if (!$processedJSON) {
            throw new \Exception('Unable to find show id: ' . $showID);
        }

        $answerLength = 1;
        $offset = 0;
        $numberOfElements = 1;

        while ($answerLength != 0 && $offset < $numberOfElements && (is_null($limit) || $offset < $limit)) {
            $json2 = getContents($url . '?offset=' . $offset);
            $data2 = Json::decode($json2, false);
            $processedJSON = $data2->data->programSet;

            $answerLength = count($processedJSON->items->nodes);
            $offset = $offset + $answerLength;
            $numberOfElements = $processedJSON->numberOfElements;

            foreach ($processedJSON->items->nodes as $audio) {
                $item = [];
                $item['uri'] = $audio->sharingUrl;
                $item['title'] = $audio->title;
                $imageSquare = str_replace(self::IMAGEWIDTHPLACEHOLDER, self::IMAGEWIDTH, $audio->image->url1X1);
                $image = str_replace(self::IMAGEWIDTHPLACEHOLDER, self::IMAGEWIDTH, $audio->image->url);
                $item['enclosures'] = [
                    $audio->audios[0]->url,
                    $imageSquare
                ];
                // synopsis in list is shortened, full synopsis is available using one request per item
                $item['content'] = '<img src="' . $image . '" /><p>' . $audio->synopsis . '</p>';
                $item['timestamp'] = $audio->publicationStartDateAndTime;
                $item['uid'] = $audio->id;
                $item['author'] = $audio->programSet->publicationService->title;

                $category = $audio->programSet->editorialCategories->title ?? null;
                if ($category) {
                    $item['categories'] = [$category];
                }

                $item['itunes'] = [
                    'duration' => $audio->duration,
                ];

                $this->items[] = $item;
            }
        }
        $this->title = $processedJSON->title;
        $this->uri = $processedJSON->sharingUrl;
        $this->icon = str_replace(self::IMAGEWIDTHPLACEHOLDER, self::IMAGEWIDTH, $processedJSON->image->url1X1);
        // add image file extension to URL so icon is shown in generated RSS feeds, see
        // https://github.com/RSS-Bridge/rss-bridge/blob/4aed05c7b678b5673386d61374bba13637d15487/formats/MrssFormat.php#L76
        $this->icon = $this->icon . self::IMAGEEXTENSION;

        $this->items = array_slice($this->items, 0, $limit);

        date_default_timezone_set($oldTz);
    }

    /** {@inheritdoc} */
    public function getURI()
    {
        if (!empty($this->uri)) {
            return $this->uri;
        }
        return parent::getURI();
    }

    /** {@inheritdoc} */
    public function getName()
    {
        if (!empty($this->title)) {
            return $this->title;
        }
        return parent::getName();
    }

    /** {@inheritdoc} */
    public function getIcon()
    {
        if (!empty($this->icon)) {
            return $this->icon;
        }
        return parent::getIcon();
    }
}


================================================
FILE: bridges/ARDMediathekBridge.php
================================================
<?php

class ARDMediathekBridge extends BridgeAbstract
{
    const NAME = 'ARD-Mediathek';
    const URI = 'https://www.ardmediathek.de';
    const DESCRIPTION = 'Feed of any series in the ARD-Mediathek, specified by its path';
    const MAINTAINER = 'yue-dongchen';
    /*
     * Number of Items to be requested from ARDmediathek API
     * 12 has been observed on the wild
     * 29 is the highest successfully tested value
     * More Items could be fetched via pagination
     * The JSON-field pagination holds more information on that
     * @const PAGESIZE number of requested items
     */
    const PAGESIZE = 29;
    /*
     * The URL Prefix of the (Webapp-)API
     * @const APIENDPOINT https-URL of the used endpoint
     */
    const APIENDPOINT = 'https://api.ardmediathek.de/page-gateway/widgets/ard/asset/';
    /*
     * The URL prefix of the video link
     * URLs from the webapp include a slug containing titles of show, episode, and tv station.
     * It seems to work without that.
     * @const VIDEOLINKPREFIX https-URL prefix of video links
     */
    const VIDEOLINKPREFIX = 'https://www.ardmediathek.de/video/';
    /*
     * The requested width of the preview image
     * 432 has been observed on the wild
     * The webapp seems to also compute and add the height value
     * It seems to works without that.
     * @const IMAGEWIDTH width in px of the preview image
     */
    const IMAGEWIDTH = 432;
    /*
     * Placeholder that will be replace by IMAGEWIDTH in the preview image URL
     * @const IMAGEWIDTHPLACEHOLDER
     */
    const IMAGEWIDTHPLACEHOLDER = '{width}';
    /**
     * Title of the current show
     * @var string
     */
    private $title;

    const PARAMETERS = [
        [
            'path' => [
                'name' => 'Show Link or ID',
                'required' => true,
                'title' => 'Link to the show page or just its alphanumeric suffix',
                'defaultValue' => 'https://www.ardmediathek.de/sendung/45-min/Y3JpZDovL25kci5kZS8xMzkx/'
            ]
        ]
    ];

    public function collectData()
    {
        $oldTz = date_default_timezone_get();

        date_default_timezone_set('Europe/Berlin');

        $pathComponents = explode('/', $this->getInput('path'));
        if (empty($pathComponents)) {
            throwClientException('Path may not be empty');
        }
        if (count($pathComponents) < 2) {
            $showID = $pathComponents[0];
        } else {
            $lastKey = count($pathComponents) - 1;
            $showID = $pathComponents[$lastKey];
            if (strlen($showID) === 0) {
                $showID = $pathComponents[$lastKey - 1];
            }
        }

        $url = self::APIENDPOINT . $showID . '?pageSize=' . self::PAGESIZE;
        $rawJSON = getContents($url);
        $processedJSON = json_decode($rawJSON);

        foreach ($processedJSON->teasers as $video) {
            $item = [];
            // there is also ->links->self->id, ->links->self->urlId, ->links->target->id, ->links->target->urlId
            $item['uri'] = self::VIDEOLINKPREFIX . $video->id . '/';
            // there is also ->mediumTitle and ->shortTitle
            $item['title'] = $video->longTitle;
            // in the test, aspect16x9 was the only child of images, not sure whether that is always true
            $item['enclosures'] = [
                str_replace(self::IMAGEWIDTHPLACEHOLDER, self::IMAGEWIDTH, $video->images->aspect16x9->src)
            ];
            $item['content'] = '<img src="' . $item['enclosures'][0] . '" /><p>';
            $item['timestamp'] = $video->broadcastedOn;
            $item['uid'] = $video->id;
            $item['author'] = $video->publicationService->name;
            $this->items[] = $item;
        }

        $this->title = $processedJSON->title;

        date_default_timezone_set($oldTz);
    }

    /** {@inheritdoc} */
    public function getName()
    {
        if (!empty($this->title)) {
            return $this->title;
        }
        return parent::getName();
    }
}


================================================
FILE: bridges/ARMCommunityBridge.php
================================================
<?php

declare(strict_types=1);

class ARMCommunityBridge extends BridgeAbstract
{
    const MAINTAINER = 'thefranke';
    const NAME = 'ARM Community';
    const URI = 'https://developer.arm.com';
    const CACHE_TIMEOUT = 86400; // 24h
    const DESCRIPTION = 'A bridge for the ARM Community blog';

    const PARAMETERS = [
        'Blog' => [
            'community' => [
                'name' => 'Community',
                'type' => 'list',
                'values' => [
                    'AI' => 'ai-blog',
                    'Announcements' => 'announcements',
                    'Architectures and Processors' => 'architectures-and-processors-blog',
                    'Automotive' => 'automotive-blog',
                    'Embedded and Microcontrollers' => 'embedded-and-microcontrollers-blog',
                    'Internet of Things (IoT)' => 'internet-of-things-blog',
                    'Laptops and Desktops' => 'laptops-and-desktops-blog',
                    'Mobile, Graphics, and Gaming' => 'mobile-graphics-and-gaming-blog',
                    'Operating Systems' => 'operating-systems-blog',
                    'Server and Cloud Computing' => 'servers-and-cloud-computing-blog',
                    'SoC Design and Simulation' => 'soc-design-and-simulation-blog',
                    'Tools, Software and IDEs' => 'tools-software-ides-blog',
                ],
            ]
        ]
    ];

    public function collectData()
    {
        $category = '/community/arm-community-blogs/b/' . $this->getInput('community');

        $header = [
            'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:140.0) Gecko/20100101 Firefox/140.0',
        ];

        $html = getSimpleHTMLDOM(static::URI . $category, $header);
        $html = defaultLinkTo($html, static::URI);

        foreach ($html->find('ads-card') as $c) {
            $articleurl = static::URI . $c->link;
            $articlehtml = getSimpleHTMLDOMCached($articleurl, static::CACHE_TIMEOUT, $header);

            $date = strtotime($articlehtml->find('#blog-date', 0)->innertext);
            $title = $articlehtml->find('#blog-title', 0)->innertext;
            $author = $articlehtml->find('#blog-title', 0)->parent->find('p', 1)->find('a', 0)->innertext;
            $content = $articlehtml->find('#blog-body', 0)->innertext;

            $this->items[] = [
                'title'      => $title,
                'timestamp'  => $date,
                'author'     => $author,
                'uri'        => $articleurl,
                'content'    => $content,
            ];
        }
    }

    public function getName()
    {
        $categoryname = $this->getKey('community');

        if (empty($categoryname)) {
            return static::NAME;
        }

        return static::NAME . ' - ' . $categoryname;
    }
}


================================================
FILE: bridges/ASRockNewsBridge.php
================================================
<?php

class ASRockNewsBridge extends BridgeAbstract
{
    const NAME = 'ASRock News';
    const URI = 'https://www.asrock.com';
    const DESCRIPTION = 'Returns latest news articles';
    const MAINTAINER = 'VerifiedJoseph';
    const PARAMETERS = [];

    const CACHE_TIMEOUT = 3600; // 1 hour

    public function collectData()
    {
        $html = getSimpleHTMLDOM(self::URI . '/news/index.asp');

        $html = defaultLinkTo($html, self::URI . '/news/');

        foreach ($html->find('div.inner > a') as $index => $a) {
            $item = [];

            $articlePath = $a->href;

            $articlePageHtml = getSimpleHTMLDOMCached($articlePath, self::CACHE_TIMEOUT);

            $articlePageHtml = defaultLinkTo($articlePageHtml, self::URI);

            $contents = $articlePageHtml->find('div.Contents', 0);

            $item['uri'] = $articlePath;
            $item['title'] = $contents->find('h3', 0)->innertext;

            $contents->find('h3', 0)->outertext = '';

            $item['content'] = $contents->innertext;
            $item['timestamp'] = $this->extractDate($a->plaintext);

            $img = $a->find('img', 0);
            if ($img) {
                $item['enclosures'][] = $img->src;
            }

            $this->items[] = $item;

            if (count($this->items) >= 10) {
                break;
            }
        }
    }

    private function extractDate($text)
    {
        $dateRegex = '/^([0-9]{4}\/[0-9]{1,2}\/[0-9]{1,2})/';

        $text = trim($text);

        if (preg_match($dateRegex, $text, $matches)) {
            return $matches[1];
        }

        return '';
    }
}


================================================
FILE: bridges/AcademiaBridge.php
================================================
<?php

declare(strict_types=1);

class AcademiaBridge extends BridgeAbstract
{
    const NAME = 'Academia';
    const URI = 'https://www.academia.edu';
    const DESCRIPTION = 'Returns papers from Academia.edu topic pages';
    const MAINTAINER = 'tillcash';
    const CACHE_TIMEOUT = 3600; // seconds (1 hour)
    const PARAMETERS = [
        [
            'topic' => [
                'name' => 'Topic name',
                'required' => true,
                'exampleValue' => 'Deadlock_Avoidance',
            ],
            'sort' => [
                'name' => 'Sort by',
                'type' => 'list',
                'values' => [
                    'Newest' => 'Newest',
                    'Top papers' => 'TopPapers',
                    'Most cited' => 'MostCited',
                    'Most downloaded' => 'MostDownloaded',
                ],
            ],
        ],
    ];

    public function getName()
    {
        $topic = $this->getInput('topic');
        if ($topic) {
            return self::NAME . ' - ' . str_replace('_', ' ', $topic);
        }

        return self::NAME;
    }

    public function collectData()
    {
        $topic = $this->getInput('topic');
        $sort = $this->getInput('sort') ?? 'Newest';

        $url = self::URI . '/Documents/in/' . $topic;
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            throwServerException('Invalid topic name: ' . $topic);
        }

        if ($sort !== 'Newest') {
            $url .= '/' . $sort;
        }

        $dom = getSimpleHTMLDOM($url);

        $json = $dom->find('script[type="application/ld+json"]', 0);
        if (!$json) {
            throwServerException('Unable to parse content');
        }

        $data = Json::decode($json->innertext);

        $articles = $data['subjectOf'] ?? null;
        if (!is_array($articles) || empty($articles)) {
            throwServerException('Invalid or empty content');
        }

        $summaryByUrl = $this->extractSummaries($dom);

        foreach ($articles as $article) {
            if (($article['@type'] ?? '') !== 'ScholarlyArticle') {
                continue;
            }

            $articleUrl = $article['url'] ?? '';
            if (!filter_var($articleUrl, FILTER_VALIDATE_URL)) {
                continue;
            }

            $this->items[] = [
                'uri' => $articleUrl,
                'uid' => $articleUrl,
                'title' => $article['name'] ?? '',
                'author' => $article['author']['name'] ?? '',
                'timestamp' => $article['datePublished'] ?? '',
                'content' => $summaryByUrl[$articleUrl] ?? '',
            ];
        }
    }

    private function extractSummaries($dom): array
    {
        $summaryByUrl = [];

        foreach ($dom->find('.work-card-container') as $card) {
            $a = $card->find('.title a', 0);
            if (!$a) {
                continue;
            }

            $url = $a->href;
            $complete = $card->find('.complete.hidden', 0);
            $summary = $complete ? trim($complete->plaintext) : '';

            $summaryByUrl[$url] = $summary;
        }

        return $summaryByUrl;
    }
}


================================================
FILE: bridges/AcrimedBridge.php
================================================
<?php

class AcrimedBridge extends FeedExpander
{
    const MAINTAINER = 'qwertygc';
    const NAME = 'Acrimed';
    const URI = 'https://www.acrimed.org/';
    const CACHE_TIMEOUT = 4800; //2hours
    const DESCRIPTION = 'Returns the newest articles';

    const PARAMETERS = [
        [
            'limit' => [
                'name' => 'limit',
                'type' => 'number',
                'defaultValue' => -1,
            ]
        ]
    ];

    public function collectData()
    {
        $url = 'https://www.acrimed.org/spip.php?page=backend';
        $limit = $this->getInput('limit');
        $this->collectExpandableDatas($url, $limit);
    }

    protected function parseItem(array $item)
    {
        $articlePage = getSimpleHTMLDOM($item['uri']);
        $article = sanitize($articlePage->find('article.article1', 0)->innertext);
        $article = defaultLinkTo($article, static::URI);
        $item['content'] = $article;

        return $item;
    }
}


================================================
FILE: bridges/ActivisionResearchBridge.php
================================================
<?php

class ActivisionResearchBridge extends BridgeAbstract
{
    const NAME = 'Activision Research Blog';
    const URI = 'https://research.activision.com';
    const DESCRIPTION = 'Posts from the Activision Research blog';
    const MAINTAINER = 'thefranke';
    const CACHE_TIMEOUT = 86400; // 24h

    public function collectData()
    {
        $dom = getSimpleHTMLDOM(static::URI);
        $dom = $dom->find('div[id="home-blog-feed"]', 0);
        if (!$dom) {
            throw new \Exception(sprintf('Unable to find css selector on `%s`', $url));
        }
        $dom = defaultLinkTo($dom, $this->getURI());
        foreach ($dom->find('div[class="blog-entry"]') as $article) {
            $a = $article->find('a', 0);

            $blogimg = extractFromDelimiters($article->find('div[class="blog-img"]', 0)->style, 'url(', ')');

            $title = htmlspecialchars_decode($article->find('div[class="title"]', 0)->plaintext);
            $author = htmlspecialchars_decode($article->find('div[class="author]', 0)->plaintext);
            $date = $article->find('div[class="pubdate"]', 0)->plaintext;

            $entry = getSimpleHTMLDOMCached($a->href, static::CACHE_TIMEOUT * 7 * 4);
            $entry = defaultLinkTo($entry, $this->getURI());

            $content = $entry->find('div[class="blog-body"]', 0);
            $tagsremove = ['script', 'iframe', 'input', 'form'];
            $content = sanitize($content, $tagsremove);
            $content = '<img src="' . static::URI . $blogimg . '" alt="">' . $content;

            $this->items[] = [
                'title' => $title,
                'author' => $author,
                'uri' => $a->href,
                'content' => $content,
                'timestamp' => strtotime($date),
            ];
        }
    }
}


================================================
FILE: bridges/AirBreizhBridge.php
================================================
<?php

class AirBreizhBridge extends BridgeAbstract
{
    const MAINTAINER = 'fanch317';
    const NAME = 'Air Breizh';
    const URI = 'https://www.airbreizh.asso.fr/';
    const DESCRIPTION = 'Returns newests publications on Air Breizh';
    const PARAMETERS = [
        'Publications' => [
            'theme' => [
                'name' => 'Thematique',
                'type' => 'list',
                'values' => [
                    'Tout' => '',
                    'Rapport d\'activite' => 'rapport-dactivite',
                    'Etude' => 'etudes',
                    'Information' => 'information',
                    'Autres documents' => 'autres-documents',
                    'Plan Régional de Surveillance de la qualité de l’air' => 'prsqa',
                    'Transport' => 'transport'
                ]
            ]
        ]
    ];

    public function getIcon()
    {
        return 'https://www.airbreizh.asso.fr/voy_content/uploads/2017/11/favicon.png';
    }

    public function collectData()
    {
        $html = '';
        $html = getSimpleHTMLDOM(static::URI . 'publications/?fwp_publications_thematiques=' . $this->getInput('theme'));

        foreach ($html->find('article') as $article) {
            $item = [];
            // Title
            $item['title'] = $article->find('h2', 0)->plaintext;
            // Author
            $item['author'] = 'Air Breizh';
            // Image
            $imagelink = $article->find('.card__image', 0)->find('img', 0)->getAttribute('src');
            // Content preview
            $item['content'] = '<img src="' . $imagelink . '" />
			<br/>'
            . $article->find('.card__text', 0)->plaintext;
            // URL
            $item['uri'] = $article->find('.publi__buttons', 0)->find('a', 0)->getAttribute('href');
            // ID
            $item['id'] = $article->find('.publi__buttons', 0)->find('a', 0)->getAttribute('href');
            $this->items[] = $item;
        }
    }
}


================================================
FILE: bridges/AkamaiBridge.php
================================================
<?php

class AkamaiBridge extends FeedExpander
{
    const MAINTAINER = 'Mynacol';
    const NAME = 'Akamai Blog';
    const URI = 'https://www.akamai.com/blog';
    const DESCRIPTION = 'Akamai CDN Blog';
    const PARAMETERS = [[
        'limit' => [
            'name' => 'Limit',
            'type' => 'number',
            'required' => false,
            'title' => 'Specify number of full articles to return',
            'defaultValue' => 5
        ]
    ]];

    const FEED_URI = 'https://feeds.feedburner.com/akamai/blog';
    const HEADERS = [
        'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0',
        'Accept-Language: en',
    ];

    public function collectData()
    {
        $this->collectExpandableDatas(
            self::FEED_URI,
            $this->getInput('limit') ?? static::LIMIT
        );
    }

    protected function parseItem(array $item)
    {
        $page = getSimpleHTMLDOMCached($item['uri'], self::CACHE_TIMEOUT, self::HEADERS);
        $page = defaultLinkTo($page, $item['uri']);

        if (!$page) {
            return $item;
        }

        $article = $page->find('section.main-content', 0);
        if (!$article) {
            return $item;
        }

        // Extract categories/tags
        foreach ($article->find('.taglist .cmp-tag-list__list-item') as $tag) {
            $item['categories'][] = $tag->plaintext;
        }

        // Remove annoying elements
        foreach ($article->find('.socialshare, .blogauthor, .taglist, .cmp-prismjs__copy') as $elem) {
            $elem->remove();
        }
        foreach ($article->find('p') as $elem) {
            if ($elem->plaintext === 'Tags') {
                $elem->remove();
            }
        }

        // Replace content with full text
        $item['content'] = $article->innertext;

        return $item;
    }

    public function getIcon()
    {
        return 'https://www.akamai.com/site/favicon/android-chrome-192x192.png';
    }
}


================================================
FILE: bridges/AlbionOnlineBridge.php
================================================
<?php

class AlbionOnlineBridge extends BridgeAbstract
{
    const NAME = 'Albion Online Changelog';
    const MAINTAINER = 'otakuf';
    const URI = 'https://albiononline.com';
    const DESCRIPTION = 'Returns the changes made to the Albion Online';
    const CACHE_TIMEOUT = 3600; // 60min

    const PARAMETERS = [ [
        'postcount' => [
            'name' => 'Limit',
            'type' => 'number',
            'required' => true,
            'title' => 'Maximum number of items to return',
            'defaultValue' => 5,
        ],
        'language' => [
            'name' => 'Language',
            'type' => 'list',
            'values' => [
                'English' => 'en',
                'Deutsch' => 'de',
                'Polski' => 'pl',
                'Français' => 'fr',
                'Русский' => 'ru',
                'Português' => 'pt',
                'Español' => 'es',
             ],
            'title' => 'Language of changelog posts',
            'defaultValue' => 'en',
        ],
        'full' => [
            'name' => 'Full changelog',
            'type' => 'checkbox',
            'required' => false,
            'title' => 'Enable to receive the full changelog post for each item'
        ],
    ]];

    public function collectData()
    {
        $api = 'https://albiononline.com/';
        // Example: https://albiononline.com/en/changelog/1/5
        $url = $api . $this->getInput('language') . '/changelog/1/' . $this->getInput('postcount');

        $html = getSimpleHTMLDOM($url);

        foreach ($html->find('li') as $data) {
            $item = [];
            $item['uri'] = self::URI . $data->find('a', 0)->getAttribute('href');
            $item['title'] = trim(explode('|', $data->find('span', 0)->plaintext)[0]);
            // Time below work only with en lang. Need to think about solution. May be separate request like getFullChangelog, but to english list for all language
            //print_r( date_parse_from_format( 'M j, Y' , 'Sep 9, 2020') );
            //$item['timestamp'] = $this->extractDate($a->plaintext);
            $item['author'] = 'albiononline.com';
            if ($this->getInput('full')) {
                $item['content'] = $this->getFullChangelog($item['uri']);
            } else {
                //$item['content'] = trim(preg_replace('/\s+/', ' ', $data->find('span', 0)->plaintext));
                // Just use title, no info at all or use title and date, see above
                $item['content'] = $item['title'];
            }
            $item['uid'] = hash('sha256', $item['title']);
            $this->items[] = $item;
        }
    }

    private function getFullChangelog($url)
    {
        $html = getSimpleHTMLDOMCached($url);
        $html = defaultLinkTo($html, self::URI);
        return $html->find('div.small-12.columns', 1)->innertext;
    }
}


================================================
FILE: bridges/AlfaBankByBridge.php
================================================
<?php

class AlfaBankByBridge extends BridgeAbstract
{
    const MAINTAINER = 'lassana';
    const NAME = 'AlfaBank.by Новости';
    const URI = 'https://www.alfabank.by';
    const DESCRIPTION = 'Уведомления Alfa-Now — новости от Альфа-Банка';
    const CACHE_TIMEOUT = 3600; // 1 hour
    const PARAMETERS = [
        'News' => [
            'business' => [
                'name' => 'Альфа Бизнес',
                'type' => 'list',
                'title' => 'В зависимости от выбора, возращает уведомления для" .
					" клиентов физ. лиц либо для клиентов-юридических лиц и ИП',
                'values' => [
                    'Новости' => 'news',
                    'Новости бизнеса' => 'newsBusiness'
                ],
                'defaultValue' => 'news'
            ],
            'fullContent' => [
                'name' => 'Включать содержимое',
                'type' => 'checkbox',
                'title' => 'Если выбрано, содержимое уведомлений вставляется в поток (работает медленно)'
            ]
        ]
    ];

    public function collectData()
    {
        $business = $this->getInput('business') == 'newsBusiness';
        $fullContent = $this->getInput('fullContent') == 'on';

        $mainPageUrl = self::URI . '/about/articles/uvedomleniya/';
        if ($business) {
            $mainPageUrl .= '?business=true';
        }
        $html = getSimpleHTMLDOM($mainPageUrl);
        $limit = 0;

        foreach ($html->find('a.notifications__item') as $element) {
            if ($limit < 10) {
                $item = [];
                $item['uid'] = 'urn:sha1:' . hash('sha1', $element->getAttribute('data-notification-id'));
                $item['title'] = $element->find('div.item-title', 0)->innertext;
                $item['timestamp'] = DateTime::createFromFormat(
                    'd M Y',
                    $this->ruMonthsToEn($element->find('div.item-date', 0)->innertext)
                )->getTimestamp();

                $itemUrl = self::URI . $element->href;
                if ($business) {
                    $itemUrl = str_replace('?business=true', '', $itemUrl);
                }
                $item['uri'] = $itemUrl;

                if ($fullContent) {
                    $itemHtml = getSimpleHTMLDOM($itemUrl);
                    if ($itemHtml) {
                        $item['content'] = $itemHtml->find('div.now-p__content-text', 0)->innertext;
                    }
                }

                $this->items[] = $item;
                $limit++;
            }
        }
    }

    public function getIcon()
    {
        return static::URI . '/local/images/favicon.ico';
    }

    private function ruMonthsToEn($date)
    {
        $ruMonths = [
            'Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня',
            'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря' ];
        $enMonths = [
            'January', 'February', 'March', 'April', 'May', 'June',
            'July', 'August', 'September', 'October', 'November', 'December' ];
        return str_replace($ruMonths, $enMonths, $date);
    }
}


================================================
FILE: bridges/AllSidesBridge.php
================================================
<?php

class AllSidesBridge extends BridgeAbstract
{
    const NAME = 'AllSides';
    const URI = 'https://www.allsides.com';
    const DESCRIPTION = 'Balanced news and media bias ratings.';
    const MAINTAINER = 'Oliver Nutter';
    const PARAMETERS = [
        'global' => [
            'limit' => [
                'name' => 'Number of posts to return',
                'type' => 'number',
                'defaultValue' => 10,
                'required' => false,
                'title' => 'Zero or negative values return all posts (ignored if not fetching full article)',
            ],
            'fetch' => [
                'name' => 'Fetch full article content',
                'type' => 'checkbox',
                'defaultValue' => 'checked',
            ],
        ],
        'Headline Roundups' => [],
    ];

    private const ROUNDUPS_URI = self::URI . '/headline-roundups';

    public function collectData()
    {
        switch ($this->queriedContext) {
            case 'Headline Roundups':
                $index = getSimpleHTMLDOM(self::ROUNDUPS_URI);
                defaultLinkTo($index, self::ROUNDUPS_URI);
                $entries = $index->find('table.views-table > tbody > tr');

                $limit = (int) $this->getInput('limit');
                $fetch = (bool) $this->getInput('fetch');

                if ($limit > 0 && $fetch) {
                    $entries = array_slice($entries, 0, $limit);
                }

                foreach ($entries as $entry) {
                    $item = [
                        'title' => $entry->find('.views-field-name', 0)->text(),
                        'uri' => $entry->find('a', 0)->href,
                        'timestamp' => $entry->find('.date-display-single', 0)->content,
                        'author' => 'AllSides Staff',
                    ];

                    if ($fetch) {
                        $article = getSimpleHTMLDOMCached($item['uri']);
                        defaultLinkTo($article, $item['uri']);

                        $item['content'] = $article->find('.story-id-page-description', 0);

                        foreach ($article->find('.page-tags a') as $tag) {
                            $item['categories'][] = $tag->text();
                        }
                    }

                    $this->items[] = $item;
                }
                break;
        }
    }

    public function getName()
    {
        if ($this->queriedContext) {
            return self::NAME . " - {$this->queriedContext}";
        }
        return self::NAME;
    }

    public function getURI()
    {
        switch ($this->queriedContext) {
            case 'Headline Roundups':
                return self::ROUNDUPS_URI;
        }
        return self::URI;
    }
}


================================================
FILE: bridges/AllegroBridge.php
================================================
<?php

class AllegroBridge extends BridgeAbstract
{
    const NAME = 'Allegro';
    const URI = 'https://www.allegro.pl';
    const DESCRIPTION = 'Returns the search results from the Allegro.pl shopping and bidding portal';
    const MAINTAINER = 'wrobelda';
    const PARAMETERS = [[
        'url' => [
            'name' => 'Search URL',
            'title' => 'Copy the URL from your browser\'s address bar after searching for your items and paste it here',
            'exampleValue' => 'https://allegro.pl/kategoria/swieze-warzywa-cebula-318660',
            'required' => true,
        ],
        'cookie' => [
            'name' => 'The complete cookie value',
            'title' => 'Paste the cookie value from your browser, otherwise 403 gets returned',
            'required' => true,
        ],
        'includeSponsoredOffers' => [
            'type' => 'checkbox',
            'name' => 'Include Sponsored Offers',
            'defaultValue' => 'checked'
        ],
        'includePromotedOffers' => [
            'type' => 'checkbox',
            'name' => 'Include Promoted Offers',
            'defaultValue' => 'checked'
        ]
    ]];

    public function getName()
    {
        $url = $this->getInput('url');
        if (!$url) {
            return parent::getName();
        }
        $parsedUrl = parse_url($url, PHP_URL_QUERY);
        if (!$parsedUrl) {
            return parent::getName();
        }
        parse_str($parsedUrl, $fields);

        if (array_key_exists('string', $fields)) {
            $f = urldecode($fields['string']);
        } else {
            $f = false;
        }
        if ($f) {
            return $f;
        }

        return parent::getName();
    }

    public function getURI()
    {
        $url = $this->getInput('url');
        if (!$url) {
            return parent::getURI();
        }

        # make sure we order by the most recently listed offers
        $url = preg_replace('/([?&])order=[^&]+(&|$)/', '$1', $this->getInput('url'));
        $url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'order=n';

        # do not return related listings if no exact matches are found
        $url .= '&strategy=NO_FALLBACK';

        return $url;
    }

    public function collectData()
    {
        $html = getContents($this->getURI(), [], [CURLOPT_COOKIE => $this->getInput('cookie')]);

        $storeData = null;
        if (preg_match('/<script[^>]*>\s*(\{\s*?"__listing_StoreState".*\})\s*<\/script>/i', $html, $match)) {
            $data = json_decode($match[1], true);
            $storeData = $data['__listing_StoreState'] ?? null;
        }

        foreach ($storeData['items']['elements'] as $elements) {
            if (!array_key_exists('offerId', $elements)) {
                continue;
            }
            if (!$this->getInput('includeSponsoredOffers') && $elements['isSponsored']) {
                continue;
            }
            if (!$this->getInput('includePromotedOffers') && $elements['promoted']) {
                continue;
            }

            $item = [];
            $item['uid'] = $elements['offerId'];
            $item['uri'] = $elements['url'];
            $item['title'] = $elements['alt'];

            $image = $elements['photos'][0]['medium'];
            if ($image) {
                $item['enclosures'] = [$image . '#.image'];
            }

            $price = $elements['price']['mainPrice']['amount'];
            $currency = $elements['price']['mainPrice']['currency'];
            $sellerType = $elements['seller']['title'];

            $item['categories'] = [$sellerType];

            $description = '';
            foreach ($elements['parameters'] as $parameter) {
                $item['categories'] = array_merge($item['categories'], $parameter['values']);
                $description .= '<dt>' . $parameter['name'] . ': ' . implode(',', $parameter['values']) . '</dt>';
            }

            $item['content'] = '<div><strong>'
                . $price . ' ' . $currency
                . '</strong></div><dl><dt>'
                . $sellerType . '</dt>'
                . $description
                . '</dl><hr>';

            $this->items[] = $item;
        }
    }
}



================================================
FILE: bridges/AllocineFRBridge.php
================================================
<?php

class AllocineFRBridge extends BridgeAbstract
{
    const MAINTAINER = 'superbaillot.net';
    const NAME = 'Allo Cine';
    const CACHE_TIMEOUT = 25200; // 7h
    const URI = 'https://www.allocine.fr';
    const DESCRIPTION = 'Bridge for allocine.fr';
    const PARAMETERS = [ [
        'category' => [
            'name' => 'Emission',
            'type' => 'list',
            'title' => 'Sélectionner l\'emission',
            'values' => [
                'Faux Raccord' => 'faux-raccord',
                'Fanzone' => 'fanzone',
                'Game In Ciné' => 'game-in-cine',
                'Pour la faire courte' => 'pour-la-faire-courte',
                'Home Cinéma' => 'home-cinema',
                'PILS - Par Ici Les Sorties' => 'pils-par-ici-les-sorties',
                'AlloCiné : l\'émission, sur LeStream' => 'allocine-lemission-sur-lestream',
                'Give Me Five' => 'give-me-five',
                'Aviez-vous remarqué ?' => 'aviez-vous-remarque',
                'Et paf, il est mort' => 'et-paf-il-est-mort',
                'The Big Fan Theory' => 'the-big-fan-theory',
                'Clichés' => 'cliches',
                'Complètement...' => 'completement',
                '#Fun Facts' => 'fun-facts',
                'Origin Story' => 'origin-story',
            ]
        ]
    ]];

    public function getURI()
    {
        if (!is_null($this->getInput('category'))) {
            $categories = [
                'faux-raccord' => '/video/programme-12284/',
                'fanzone' => '/video/programme-12298/',
                'game-in-cine' => '/video/programme-12288/',
                'pour-la-faire-courte' => '/video/programme-20960/',
                'home-cinema' => '/video/programme-12287/',
                'pils-par-ici-les-sorties' => '/video/programme-25789/',
                'allocine-lemission-sur-lestream' => '/video/programme-25123/',
                'give-me-five' => '/video/programme-21919/saison-34518/',
                'aviez-vous-remarque' => '/video/programme-19518/',
                'et-paf-il-est-mort' => '/video/programme-25113/',
                'the-big-fan-theory' => '/video/programme-20403/',
                'cliches' => '/video/programme-24834/',
                'completement' => '/video/programme-23859/',
                'fun-facts' => '/video/programme-23040/',
                'origin-story' => '/video/programme-25667/'
            ];

            $category = $this->getInput('category');
            if (array_key_exists($category, $categories)) {
                return static::URI . $this->getLastSeasonURI($categories[$category]);
            } else {
                throwClientException('Emission inconnue');
            }
        }

        return parent::getURI();
    }

    private function getLastSeasonURI($category)
    {
        $html = getSimpleHTMLDOMCached(static::URI . $category, 86400);
        $seasonLink = $html->find('section[class=section-wrap section]', 0)->find('div[class=cf]', 0)->find('a', 0);
        $URI = $seasonLink->href;
        return $URI;
    }

    public function getName()
    {
        if (!is_null($this->getInput('category'))) {
            return self::NAME . ' : ' . $this->getKey('category');
        }

        return parent::getName();
    }

    public function collectData()
    {
        $html = getSimpleHTMLDOM($this->getURI());

        foreach ($html->find('div[class=gd-col-left]', 0)->find('div[class*=video-card]') as $element) {
            $item = [];

            $title = $element->find('a[class*=meta-title-link]', 0);
            $content = trim(defaultLinkTo($element->outertext, static::URI));

            // Replace image 'src' with the one in 'data-src'
            $content = preg_replace('@src="data:image/gif;base64,[A-Za-z0-9+\/]*"@', '', $content);
            $content = preg_replace('@data-src=@', 'src=', $content);

            // Remove date in the content to prevent content update while the video is getting older
            $content = preg_replace('@<div class="meta-sub light">.*<span>[^<]*</span>[^<]*</div>@', '', $content);

            $item['content'] = $content;
            $item['title'] = trim($title->innertext);
            $item['uri'] = static::URI . '/' . substr($title->href, 1);
            $this->items[] = $item;
        }
    }
}


================================================
FILE: bridges/AllocineFRSortiesBridge.php
================================================
<?php

class AllocineFRSortiesBridge extends BridgeAbstract
{
    const MAINTAINER = 'Simounet';
    const NAME = 'AlloCiné Sorties';
    const CACHE_TIMEOUT = 25200; // 7h
    const BASE_URI = 'https://www.allocine.fr';
    const URI = self::BASE_URI . '/film/sorties-semaine/';
    const DESCRIPTION = 'Bridge for AlloCiné - Sorties cinéma cette semaine';

    public function getName()
    {
        return self::NAME;
    }

    public function collectData()
    {
        $html = getSimpleHTMLDOM($this->getURI());

        foreach ($html->find('section.section.section-wrap', 0)->find('li.mdl') as $element) {
            $item = [];

            $thumb = $element->find('figure.thumbnail', 0);
            $meta = $element->find('div.meta-body', 0);
            $synopsis = $element->find('div.synopsis', 0);
            $date = $element->find('span.date', 0);

            $title = $element->find('a[class*=meta-title-link]', 0);
            $content = trim(defaultLinkTo($thumb->outertext . $meta->outertext . $synopsis->outertext, static::URI));

            // Replace image 'src' with the one in 'data-src'
            $content = preg_replace('@src="data:image/gif;base64,[A-Za-z0-9=+\/]*"@', '', $content);
            $content = preg_replace('@data-src=@', 'src=', $content);

            $item['content'] = $content;
            $item['title'] = trim($title->innertext);
            $item['timestamp'] = $this->frenchPubDateToTimestamp($date->plaintext);
            $item['uri'] = static::BASE_URI . '/' . substr($title->href, 1);
            $this->items[] = $item;
        }
    }

    private function frenchPubDateToTimestamp($date)
    {
        return strtotime(
            strtr(
                strtolower($date),
                [
                    'janvier' => 'jan',
                    'février' => 'feb',
                    'mars' => 'march',
                    'avril' => 'apr',
                    'mai' => 'may',
                    'juin' => 'jun',
                    'juillet' => 'jul',
                    'août' => 'aug',
                    'septembre' => 'sep',
                    'octobre' => 'oct',
                    'novembre' => 'nov',
                    'décembre' => 'dec'
                ]
            )
        );
    }
}


================================================
FILE: bridges/AlpinePackagesBridge.php
================================================
<?php

declare(strict_types=1);

class AlpinePackagesBridge extends BridgeAbstract
{
    const NAME = 'Alpine Packages';
    const MAINTAINER = 'rsd76';
    const URI = 'https://pkgs.alpinelinux.org';
    const DESCRIPTION = 'Get Alpine package versions';
    const CACHE_TIMEOUT = 3600;

    const PARAMETERS = [
        [
            'package' => [
                'type' => 'text',
                'name' => 'Package Name',
                'required' => true,
                'exampleValue' => 'curl',
                'title' => 'Name of the package. Use * and ? as wildcards. For example: curl-dev, curl-* or curl-???.'
            ],
            'branch' => [
                'type' => 'text',
                'name' => 'Package branch',
                'required' => true,
                'exampleValue' => 'v3.23',
                'title' => 'Name of the branch. For example: edge, v3.23, v3.22, etc.'
            ],
            'repository' => [
                'type' => 'list',
                'name' => 'Repository name',
                'values' => [
                    'All' => 'all',
                    'Community' => 'community',
                    'Main' => 'main',
                    'Testing' => 'testing'
                ],
                'defaultValue' => 'all'
            ],
            'architecture' => [
                'type' => 'list',
                'name' => 'Achitecture',
                'values' => [
                    'All' => 'all',
                    'aarch64' => 'aarch64',
                    'armhf' => 'armhf',
                    'armv7' => 'armv7',
                    'loongarch64' => 'loongarch64',
                    'ppc64le' => 'ppc64le',
                    'riscv64' => 'riscv64',
                    's390x' => 's390x',
                    'x86' => 'x86',
                    'x86_64' => 'x86_64'
                ],
                'defaultValue' => 'all'
            ]
        ]
    ];

    private function getADom($element)
    {
        return $element->find('a')[0];
    }

    private function getElementData($element)
    {
        $classes = [
            'package',
            'repo',
            'arch',
            'maintainer'
        ];
        $noAhrefClasses = [
            'branch',
            'bdate'
        ];
        $data = [];
        // Get data from element which contains <a href=...>.
        foreach ($classes as $class) {
            $td = $this->getTdClassDom($element, $class);
            $a = $this->getADom($td);
            $data[$class] = trim($a->plaintext);
            $data[$class . '-href'] = $a->href;
        }
        // Get data from element which only contains text.
        foreach ($noAhrefClasses as $class) {
            $td = $this->getTdClassDom($element, $class);
            $data[$class] = trim($td->plaintext);
        }
        // Get version data in a <strong> element.
        $td = $this->getTdClassDom($element, 'version');
        $strong = $td->find('strong[class=hint--right hint--rounded text-success]')[0];
        $data['version'] = trim($strong->plaintext);
        return $data;
    }

    private function getTdClassDom($element, $class)
    {
        return $element->find('td[class=' . $class . ']')[0];
    }

    public function collectData()
    {
        $dom = getSimpleHTMLDOM($this->getUri());
        $dom = defaultLinkTo($dom, self::URI);
        $table = $dom->find('table[class=pure-table pure-table-striped]')[0];
        $tbody = $table->find('tbody')[0];
        $trs = $tbody->find('tr');
        foreach ($trs as $tr) {
            $itemData = $this->getElementData($tr);
            $this->items[] = [
                'title' => $itemData['package'] . '-' . $itemData['version'],
                'uri' => $itemData['package-href'],
                'timestamp' => strtotime($itemData['bdate']),
                'uid' => trim($itemData['package']) . $itemData['version'] . $itemData['arch'] . $itemData['branch'] . $itemData['repo'],
                'author' => $itemData['maintainer'],
                'categories' => [
                    'arch: ' . $itemData['arch'],
                    'branch: ' . $itemData['branch'],
                    'repo: ' . $itemData['repo']
                ]
            ];
        }
    }

    public function getName()
    {
        $packageName = $this->getInput('package');
        $branchName = $this->getInput('branch');
        $repositoryName = $this->getInput('repository');
        $architecture = $this->getInput('architecture');

        $name = '';

        if ($packageName) {
            $packageName = strtolower($packageName);
            $name = $packageName . ' (';
            if ($branchName) {
                $branchName = strtolower($branchName);
                $name .= 'branch ' . $branchName;
            }
            if ($repositoryName) {
                $repositoryName = strtolower($repositoryName);
                if ($repositoryName !== 'all') {
                    $name .= ', repo ' . $repositoryName;
                }
            }
            if ($architecture) {
                $architecture = strtolower($architecture);
                if ($architecture !== 'all') {
                    $name .= ', arch ' . $architecture;
                }
            }
            $name .= ') - Alpine packages';
            return $name;
        }

        return parent::getName();
    }

    public function getUri()
    {
        $package = $this->getInput('package');
        $branch = $this->getInput('branch');
        $repository = $this->getInput('repository');
        $architecture = $this->getInput('architecture');

        if ($package) {
            $package = urlencode(strtolower(trim($package)));
        }
        if ($branch) {
            $branch = strtolower(trim($branch));
        }
        if ($repository) {
            $repository = strtolower($repository);
            if ($repository === 'all') {
                $repository = '';
            }
        }
        if ($architecture) {
            $architecture = strtolower(trim($architecture));
            if ($architecture === 'all') {
                $architecture = '';
            }
        }

        if ($package && $branch) {
            return self::URI . '/packages?name=' . $package . '&branch=' . $branch . '&repo=' . $repository . '&arch=' . $architecture . '&origin=&flagged=&maintainer=';
        }
        return self::URI;
    }
}


================================================
FILE: bridges/AmazonBridge.php
================================================
<?php

class AmazonBridge extends BridgeAbstract
{
    const MAINTAINER = 'Alexis CHEMEL';
    const NAME = 'Amazon';
    const URI = 'https://www.amazon.com/';
    const CACHE_TIMEOUT = 3600; // 1h
    const DESCRIPTION = 'Returns products from Amazon search';

    const PARAMETERS = [[
        'q' => [
            'name' => 'Keyword',
            'required' => true,
            'exampleValue' => 'watch',
        ],
        'sort' => [
            'name' => 'Sort by',
            'type' => 'list',
            'values' => [
                'Relevance' => 'relevanceblender',
                'Price: Low to High' => 'price-asc-rank',
                'Price: High to Low' => 'price-desc-rank',
                'Average Customer Review' => 'review-rank',
                'Newest Arrivals' => 'date-desc-rank',
            ],
            'defaultValue' => 'relevanceblender',
        ],
        'tld' => [
            'name' => 'Country',
            'type' => 'list',
            'values' => [
                'Australia' => 'com.au',
                'Brazil' => 'com.br',
                'Canada' => 'ca',
                'China' => 'cn',
                'France' => 'fr',
                'Germany' => 'de',
                'India' => 'in',
                'Italy' => 'it',
                'Japan' => 'co.jp',
                'Mexico' => 'com.mx',
                'Netherlands' => 'nl',
                'Poland' => 'pl',
                'Spain' => 'es',
                'Sweden' => 'se',
                'Turkey' => 'com.tr',
                'United Kingdom' => 'co.uk',
                'United States' => 'com',
            ],
            'defaultValue' => 'com',
        ],
    ]];

    public function collectData()
    {
        $baseUrl = sprintf('https://www.amazon.%s', $this->getInput('tld'));

        $url = sprintf(
            '%s/s/?field-keywords=%s&sort=%s',
            $baseUrl,
            urlencode($this->getInput('q')),
            $this->getInput('sort')
        );

        $dom = getSimpleHTMLDOM($url);

        $elements = $dom->find('div.s-result-item');

        foreach ($elements as $element) {
            $item = [];

            $title = $element->find('h2', 0);
            if (!$title) {
                continue;
            }

            $item['title'] = $title->innertext;

            $itemUrl = $element->find('a', 0)->href;
            $item['uri'] = urljoin($baseUrl, $itemUrl);

            $image = $element->find('img', 0);
            if ($image) {
                $item['content'] = '<img src="' . $image->getAttribute('src') . '" /><br />';
            }

            $price = $element->find('span.a-price > .a-offscreen', 0);
            if ($price) {
                $item['content'] .= $price->innertext;
            }

            $this->items[] = $item;
        }
    }

    public function getName()
    {
        if (!is_null($this->getInput('tld')) && !is_null($this->getInput('q'))) {
            return 'Amazon.' . $this->getInput('tld') . ': ' . $this->getInput('q');
        }

        return parent::getName();
    }
}


================================================
FILE: bridges/AmazonPriceTrackerBridge.php
================================================
<?php

class AmazonPriceTrackerBridge extends BridgeAbstract
{
    const MAINTAINER = 'captn3m0, sal0max, bagnacauda';
    const NAME = 'Amazon Price Tracker';
    const URI = 'https://www.amazon.com/';
    const CACHE_TIMEOUT = 3600; // 1h
    const DESCRIPTION = 'Tracks price for a single product on Amazon';

    const PARAMETERS = [
        [
        'asin' => [
            'name'          => 'ASIN',
            'required'      => true,
            'exampleValue'  => 'B0923XT6K7',
            // https://stackoverflow.com/a/12827734
            'pattern'       => 'B[\dA-Z]{9}|\d{9}(X|\d)',
        ],
        'tld' => [
            'name' => 'Country',
            'type' => 'list',
            'values' => [
                'Australia'         => 'com.au',
                'Brazil'        => 'com.br',
                'Canada'        => 'ca',
                'China'         => 'cn',
                'France'        => 'fr',
                'Germany'       => 'de',
                'India'         => 'in',
                'Italy'         => 'it',
                'Japan'         => 'co.jp',
                'Mexico'        => 'com.mx',
                'Netherlands'       => 'nl',
                'Poland'        => 'pl',
                'Spain'         => 'es',
                'Sweden'        => 'se',
                'Turkey'        => 'com.tr',
                'United Kingdom'    => 'co.uk',
                'United States'     => 'com',
            ],
            'defaultValue' => 'com',
        ],
        ]];

    const PRICE_SELECTORS = [
        '#priceblock_ourprice',
        '.priceBlockBuyingPriceString',
        '#newBuyBoxPrice',
        '#tp_price_block_total_price_ww',
        'span.offer-price',
        '.a-color-price',
    ];

    const WHITESPACE = " \t\n\r\0\x0B\xC2\xA0";

    protected $title;

    /**
     * Generates domain name given a amazon TLD
     */
    private function getDomainName()
    {
        return 'https://www.amazon.' . $this->getInput('tld');
    }

    /**
     * Generates URI for a Amazon product page
     */
    public function getURI()
    {
        if (!is_null($this->getInput('asin'))) {
            return $this->getDomainName() . '/dp/' . $this->getInput('asin');
        }
        return parent::getURI();
    }

    /**
     * Scrapes the product title from the html page
     * returns the default title if scraping fails
     */
    private function getTitle($html)
    {
        $titleTag = $html->find('#productTitle', 0);

        if (!$titleTag) {
            return $this->getDefaultTitle();
        } else {
            return trim(html_entity_decode($titleTag->innertext, ENT_QUOTES));
        }
    }

    /**
     * Title used by the feed if none could be found
     */
    private function getDefaultTitle()
    {
        return 'Amazon.' . $this->getInput('tld') . ': ' . $this->getInput('asin');
    }

    /**
     * Returns name for the feed
     * Uses title (already scraped) if it has one
     */
    public function getName()
    {
        if (isset($this->title)) {
            return $this->title;
        } else {
            return parent::getName();
        }
    }

    private function parseDynamicImage($attribute)
    {
        $json = json_decode(html_entity_decode($attribute), true);

        if ($json and count($json) > 0) {
            return array_keys($json)[0];
        }
    }

    /**
     * Returns a generated image tag for the product
     */
    private function getImage($html)
    {
        $image = 'https://placekitten.com/200/300';
        $imageSrc = $html->find('#main-image-container img', 0);
        if ($imageSrc) {
            $hiresImage = $imageSrc->getAttribute('data-old-hires');
            $dynamicImageAttribute = $imageSrc->getAttribute('data-a-dynamic-image');
            $image = $hiresImage ?: $this->parseDynamicImage($dynamicImageAttribute);
        }

        return <<<EOT
<img width="300" style="max-width:300;max-height:300" src="$image" alt="{$this->title}" />
EOT;
    }

    /**
     * Return \simple_html_dom object
     * for the entire html of the product page
     */
    private function getHtml()
    {
        $uri = $this->getURI();

        return getSimpleHTMLDOM($uri);
    }

    private function scrapePriceFromMetrics($html)
    {
        $asinData = $html->find('#cerberus-data-metrics', 0);

        // <div id="cerberus-data-metrics" style="display: none;"
        //  data-asin="B00WTHJ5SU" data-asin-price="14.99" data-asin-shipping="0"
        //  data-asin-currency-code="USD" data-substitute-count="-1" ... />
        if ($asinData) {
            return [
                'price'     => $asinData->getAttribute('data-asin-price'),
                'currency'  => $asinData->getAttribute('data-asin-currency-code'),
                'shipping'  => $asinData->getAttribute('data-asin-shipping')
            ];
        }

        return false;
    }

    private function scrapePriceTwister($html)
    {
        $json = $html->find('.twister-plus-buying-options-price-data', 0);
        if ($json == null) {
            return null;
        }

        $data = json_decode($json->innertext, true);
        foreach ($data as $key => $value) {
            $value = $value[0];
            return [
                'displayPrice' => $value['displayPrice'],
                'price' => $value['priceAmount'],
                'currency' => $value['currencySymbol'],
                'shipping' => null,
            ];
        }

        return null;
    }

    private function scrapePriceGeneric($html)
    {
        $default = [
            'price'         => null,
            'displayPrice'  => null,
            'currency'      => null,
            'shipping'      => null,
        ];
        $priceDiv = null;

        foreach (self::PRICE_SELECTORS as $sel) {
            $priceDiv = $html->find($sel, 0);
            if ($priceDiv) {
                break;
            }
        }

        if (!$priceDiv) {
            return $default;
        }

        $priceString = str_replace(str_split(self::WHITESPACE), '', $priceDiv->plaintext);
        $price = null;
        $priceFound = false;

    // find longest repeated string
        for ($offset = 0; $offset < strlen($priceString); $offset++) {
            for ($length = 1; substr_count($priceString, substr($priceString, $offset, $length + 1)) >= 2; $length++) {
                $priceFound = true;
            }

            if ($priceFound) {
                $price = substr($priceString, $offset, $length);
                break;
            }
        }

        $currency = str_replace($price, '', $priceString);

        if ($price != null && $currency != null) {
            return [
                'price'     => $price,
                'displayPrice'  => null,
                'currency'  => $currency,
                'shipping'  => null
            ];
        }
        return $default;
    }

    public function collectData()
    {
        $html = $this->getHtml();
        $this->title = $this->getTitle($html);
        $image = $this->getImage($html);
        $data = $this->scrapePriceTwister($html) ?? $this->scrapePriceGeneric($html);

        // render
        $content = '';
        $price = $data['displayPrice'];
        if (!$price) {
            $price = sprintf('%s %s', $data['price'], $data['currency']);
        }
        $content .= sprintf('%s<br>Price: %s', $image, $price);
        if ($data['shipping'] !== null) {
            $content .= sprintf('<br>Shipping: %s %s</br>', $data['shipping'], $data['currency']);
        }

        $item = [
            'title'     => $this->title,
            'uri'       => $this->getURI(),
            'content'   => $content,
            // This is to ensure that feed readers notice the price change
            'uid'       => md5($data['price'])
        ];

        $this->items[] = $item;
    }
}


================================================
FILE: bridges/AnfrBridge.php
================================================
<?php

class AnfrBridge extends BridgeAbstract
{
    const NAME = 'ANFR';
    const URI = 'https://data.anfr.fr/';
    const DESCRIPTION = 'Fetches data from the French administration "Agence Nationale des Fréquences".';
    const CACHE_TIMEOUT = 604800; // 7d
    const MAINTAINER = 'quent1';
    const PARAMETERS = [
        'Données sur les réseaux mobiles' => [
            'departement' => [
                'name' => 'Département',
                'type' => 'list',
                'values' => [
                    'Tous' => null,
                    'Ain' => '001',
                    'Aisne' => '002',
                    'Allier' => '003',
                    'Alpes-de-Haute-Provence' => '004',
                    'Hautes-Alpes' => '005',
                    'Alpes-Maritimes' => '006',
                    'Ardèche' => '007',
                    'Ardennes' => '008',
                    'Ariège' => '009',
                    'Aube' => '010',
                    'Aude' => '011',
                    'Aveyron' => '012',
                    'Bouches-du-Rhône' => '013',
                    'Calvados' => '014',
                    'Cantal' => '015',
                    'Charente' => '016',
                    'Charente-Maritime' => '017',
                    'Cher' => '018',
                    'Corrèze' => '019',
                    'Corse-du-Sud' => '02A',
                    'Haute-Corse' => '02B',
                    'Côte-d\'Or' => '021',
                    'Côtes-d\'Armor' => '022',
                    'Creuse' => '023',
                    'Dordogne' => '024',
                    'Doubs' => '025',
                    'Drôme' => '026',
                    'Eure' => '027',
                    'Eure-et-Loir' => '028',
                    'Finistère' => '029',
                    'Gard' => '030',
                    'Haute-Garonne' => '031',
                    'Gers' => '032',
                    'Gironde' => '033',
                    'Hérault' => '034',
                    'Ille-et-Vilaine' => '035',
                    'Indre' => '036',
                    'Indre-et-Loire' => '037',
                    'Isère' => '038',
                    'Jura' => '039',
                    'Landes' => '040',
                    'Loir-et-Cher' => '041',
                    'Loire' => '042',
                    'Haute-Loire' => '043',
                    'Loire-Atlantique' => '044',
                    'Loiret' => '045',
                    'Lot' => '046',
                    'Lot-et-Garonne' => '047',
                    'Lozère' => '048',
                    'Maine-et-Loire' => '049',
                    'Manche' => '050',
                    'Marne' => '051',
                    'Haute-Marne' => '052',
                    'Mayenne' => '053',
                    'Meurthe-et-Moselle' => '054',
                    'Meuse' => '055',
                    'Morbihan' => '056',
                    'Moselle' => '057',
                    'Nièvre' => '058',
                    'Nord' => '059',
                    'Oise' => '060',
                    'Orne' => '061',
                    'Pas-de-Calais' => '062',
                    'Puy-de-Dôme' => '063',
                    'Pyrénées-Atlantiques' => '064',
                    'Hautes-Pyrénées' => '065',
                    'Pyrénées-Orientales' => '066',
                    'Bas-Rhin' => '067',
                    'Haut-Rhin' => '068',
                    'Rhône' => '069',
                    'Haute-Saône' => '070',
                    'Saône-et-Loire' => '071',
                    'Sarthe' => '072',
                    'Savoie' => '073',
                    'Haute-Savoie' => '074',
                    'Paris' => '075',
                    'Seine-Maritime' => '076',
                    'Seine-et-Marne' => '077',
                    'Yvelines' => '078',
                    'Deux-Sèvres' => '079',
                    'Somme' => '080',
                    'Tarn' => '081',
                    'Tarn-et-Garonne' => '082',
                    'Var' => '083',
                    'Vaucluse' => '084',
                    'Vendée' => '085',
                    'Vienne' => '086',
                    'Haute-Vienne' => '087',
                    'Vosges' => '088',
                    'Yonne' => '089',
                    'Territoire de Belfort' => '090',
                    'Essonne' => '091',
                    'Hauts-de-Seine' => '092',
                    'Seine-Saint-Denis' => '093',
                    'Val-de-Marne' => '094',
                    'Val-d\'Oise' => '095',
                    'Guadeloupe' => '971',
                    'Martinique' => '972',
                    'Guyane' => '973',
                    'La Réunion' => '974',
                    'Saint-Pierre-et-Miquelon' => '975',
                    'Mayotte' => '976',
                    'Saint-Barthélemy' => '977',
                    'Saint-Martin' => '978',
                    'Terres australes et antarctiques françaises' => '984',
                    'Wallis-et-Futuna' => '986',
                    'Polynésie française' => '987',
                    'Nouvelle-Calédonie' => '988',
                    'Île de Clipperton' => '989'
                ]
            ],
            'generation' => [
                'name' => 'Génération',
                'type' => 'list',
                'values' => [
                    'Tous' => null,
                    '2G' => '2G',
                    '3G' => '3G',
                    '4G' => '4G',
                    '5G' => '5G',
                ]
            ],
            'operateur' => [
                'name' => 'Opérateur',
                'type' => 'list',
                'values' => [
                    'Tous' => null,
                    'Bouygues Télécom' => 'BOUYGUES TELECOM',
                    'Dauphin Télécom' => 'DAUPHIN TELECOM',
                    'Digiciel' => 'DIGICEL',
                    'Free Caraïbes' => 'FREE CARAIBES',
                    'Free Mobile' => 'FREE MOBILE',
                    'GLOBALTEL' => 'GLOBALTEL',
                    'Office des postes et télécommunications de Nouvelle Calédonie' => 'Gouv Nelle Calédonie (OPT)',
                    'Maore Mobile' => 'MAORE MOBILE',
                    'ONATi' => 'ONATI',
                    'Orange' => 'ORANGE',
                    'Outremer Telecom' => 'OUTREMER TELECOM',
                    'Vodafone polynésie' => 'PMT/VODAPHONE',
                    'SFR' => 'SFR',
                    'SPM Télécom' => 'SPM TELECOM',
                    'Service des Postes et Télécommunications de Polynésie Française' => 'Gouv Nelle Calédonie (OPT)',
                    'SRR' => 'SRR',
                    'Station étrangère' => 'Station étrangère',
                    'Telco OI' => 'TELCO IO',
                    'United Telecommunication Services Caraïbes' => 'UTS Caraibes',
                    'Ora Mobile' => 'VITI SAS',
                    'Zeop' => 'ZEOP'
                ]
            ],
            'statut' => [
                'name' => 'Statut',
                'type' => 'list',
                'values' => [
                    'Tous' => null,
                    'En service' => 'En service',
                    'Projet approuvé' => 'Projet approuvé',
                    'Techniquement opérationnel' => 'Techniquement opérationnel',
                ]
            ]
        ]
    ];

    public function collectData()
    {
        $urlParts = [
            'id' => 'observatoire_2g_3g_4g',
            'resource_id' => '88ef0887-6b0f-4d3f-8545-6d64c8f597da',
            'fields' => 'id,adm_lb_nom,sta_nm_dpt,emr_lb_systeme,generation,date_maj,sta_nm_anfr,adr_lb_lieu,adr_lb_add1,adr_lb_add2,adr_lb_add3,adr_nm_cp,statut',
            'rows' => 10000
        ];

        if (!empty($this->getInput('departement'))) {
            $urlParts['refine.sta_nm_dpt'] = urlencode($this->getInput('departement'));
        }

        if (!empty($this->getInput('generation'))) {
            $urlParts['refine.generation'] = $this->getInput('generation');
        }

        if (!empty($this->getInput('operateur'))) {
            // http_build_query() already does urlencoding so this call is redundant
            $urlParts['refine.adm_lb_nom'] = urlencode($this->getInput('operateur'));
        }

        if (!empty($this->getInput('statut'))) {
            $urlParts['refine.statut'] = urlencode($this->getInput('statut'));
        }

        // API seems to not play well with urlencoded data
        $url = urljoin(static::URI, '/d4c/api/records/1.0/download/?' . urldecode(http_build_query($urlParts)));

        $json = getContents($url);
        $data = Json::decode($json, false);
        $records = $data->records;
        $frequenciesByStation = [];
        foreach ($records as $record) {
            if (!isset($frequenciesByStation[$record->fields->sta_nm_anfr])) {
                $street = sprintf(
                    '%s %s %s',
                    $record->fields->adr_lb_add1 ?? '',
                    $record->fields->adr_lb_add2 ?? '',
                    $record->fields->adr_lb_add3 ?? ''
                );
                $frequenciesByStation[$record->fields->sta_nm_anfr] = [
                    'id' => $record->fields->sta_nm_anfr,
                    'operator' => $record->fields->adm_lb_nom,
                    'frequencies' => [],
                    'lastUpdate' => 0,
                    'address' => [
                        'street' => trim($street),
                        'postCode' => $record->fields->adr_nm_cp,
                        'city' => $record->fields->adr_lb_lieu
                    ]
                ];
            }

            $frequenciesByStation[$record->fields->sta_nm_anfr]['frequencies'][] = [
                'generation' => $record->fields->generation,
                'frequency' => $record->fields->emr_lb_systeme,
                'status' => $record->fields->statut,
                'updatedAt' => strtotime($record->fields->date_maj),
            ];

            $frequenciesByStation[$record->fields->sta_nm_anfr]['lastUpdate'] = max(
                $frequenciesByStation[$record->fields->sta_nm_anfr]['lastUpdate'],
                strtotime($record->fields->date_maj)
            );
        }

        usort($frequenciesByStation, static fn ($a, $b) => $b['lastUpdate'] <=> $a['lastUpdate']);

        foreach ($frequenciesByStation as $station) {
            $title = sprintf(
                '[%s] Mise à jour de la station n°%s à %s (%s)',
                $station['operator'],
                $station['id'],
                $station['address']['city'],
                $station['address']['postCode']
            );

            $array_reduce = array_reduce($station['frequencies'], static function ($carry, $frequency) {
                return sprintf('%s<li>%s : %s</li>', $carry, $frequency['frequency'], $frequency['status']);
            }, '');

            $content = sprintf(
                '<h1>Adresse complète</h1><p>%s<br>%s<br>%s</p><h1>Fréquences</h1><p><ul>%s</ul></p>',
                $station['address']['street'],
                $station['address']['postCode'],
                $station['address']['city'],
                $array_reduce
            );

            $this->items[] = [
                'uid'       => $station['id'],
                'timestamp' => $station['lastUpdate'],
                'title'     => $title,
                'content'   => $content,
            ];
        }
    }
}

================================================
FILE: bridges/AnidexBridge.php
================================================
<?php

class AnidexBridge extends BridgeAbstract
{
    const MAINTAINER = 'ORelio';
    const NAME = 'Anidex';
    const URI = 'http://anidex.info/'; // anidex.info has ddos-guard so we need to use anidex.moe
    const ALTERNATE_URI = 'https://anidex.moe/'; // anidex.moe returns 301 unless Host is set to anidex.info
    const ALTERNATE_HOST = 'anidex.info'; // Correct host for requesting anidex.moe without 301 redirect
    const DESCRIPTION = 'Returns the newest torrents, with optional search criteria.';
    const PARAMETERS = [
        [
            'id' => [
                'name' => 'Category',
                'type' => 'list',
                'values' => [
                    'All categories' => '0',
                    'Anime' => '1,2,3',
                    'Anime - Sub' => '1',
                    'Anime - Raw' => '2',
                    'Anime - Dub' => '3',
                    'Live Action' => '4,5',
                    'Live Action - Sub' => '4',
                    'Live Action - Raw' => '5',
                    'Light Novel' => '6',
                    'Manga' => '7,8',
                    'Manga - Translated' => '7',
                    'Manga - Raw' => '8',
                    'Music' => '9,10,11',
                    'Music - Lossy' => '9',
                    'Music - Lossless' => '10',
                    'Music - Video' => '11',
                    'Games' => '12',
                    'Applications' => '13',
                    'Pictures' => '14',
                    'Adult Video' => '15',
                    'Other' => '16'
                ]
            ],
            'lang_id' => [
                'name' => 'Language',
                'type' => 'list',
                'values' => [
                    'All languages' => '0',
                    'English' => '1',
                    'Japanese' => '2',
                    'Polish' => '3',
                    'Serbo-Croatian' => '4',
                    'Dutch' => '5',
                    'Italian' => '6',
                    'Russian' => '7',
                    'German' => '8',
                    'Hungarian' => '9',
                    'French' => '10',
                    'Finnish' => '11',
                    'Vietnamese' => '12',
                    'Greek' => '13',
                    'Bulgarian' => '14',
                    'Spanish (Spain)' => '15',
                    'Portuguese (Brazil)' => '16',
                    'Portuguese (Portugal)' => '17',
                    'Swedish' => '18',
                    'Arabic' => '19',
                    'Danish' => '20',
                    'Chinese (Simplified)' => '21',
                    'Bengali' => '22',
                    'Romanian' => '23',
                    'Czech' => '24',
                    'Mongolian' => '25',
                    'Turkish' => '26',
                    'Indonesian' => '27',
                    'Korean' => '28',
                    'Spanish (LATAM)' => '29',
                    'Persian' => '30',
                    'Malaysian' => '31'
                ]
            ],
            'group_id' => [
                'name' => 'Group ID',
                'type' => 'number'
            ],
            'r' => [
                'name' => 'Hide Remakes',
                'type' => 'checkbox'
            ],
            'b' => [
                'name' => 'Only Batches',
                'type' => 'checkbox'
            ],
            'a' => [
                'name' => 'Only Authorized',
                'type' => 'checkbox'
            ],
            'q' => [
                'name' => 'Keyword',
                'description' => 'Keyword(s)',
                'type' => 'text'
            ],
            'h' => [
                'name' => 'Adult content',
                'type' => 'list',
                'values' => [
                    'No filter' => '0',
                    'Hide +18' => '1',
                    'Only +18' => '2'
                ]
            ]
        ]
    ];

    public function collectData()
    {
        // Build Search URL from user-provided parameters
        $search_url = self::ALTERNATE_URI . '?s=upload_timestamp&o=desc';
        foreach (['id', 'lang_id', 'group_id'] as $param_name) {
            $param = $this->getInput($param_name);
            if (!empty($param) && intval($param) != 0 && ctype_digit(str_replace(',', '', $param))) {
                $search_url .= '&' . $param_name . '=' . $param;
            }
        }
        foreach (['r', 'b', 'a'] as $param_name) {
            $param = $this->getInput($param_name);
            if (!empty($param) && boolval($param)) {
                $search_url .= '&' . $param_name . '=1';
            }
        }
        $query = $this->getInput('q');
        if (!empty($query)) {
            $search_url .= '&q=' . urlencode($query);
        }
        $opt = [];
        $h = $this->getInput('h');
        if (!empty($h) && intval($h) != 0 && ctype_digit($h)) {
            $opt[CURLOPT_COOKIE] = 'anidex_h_toggle=' . $h;
        }

        // We need to use a different Host HTTP header to reach the correct page on ALTERNATE_URI
        $headers = ['Host: ' . self::ALTERNATE_HOST];

        // The HTTPS certificate presented by anidex.moe is for anidex.info. We need to ignore this.
        // As a consequence, the bridge is intentionally marked as insecure by setting self::URI to http://
        $opt[CURLOPT_SSL_VERIFYHOST] = 0;
        $opt[CURLOPT_SSL_VERIFYPEER] = 0;

        // Retrieve torrent listing from search results, which does not contain torrent description
        $html = getSimpleHTMLDOM($search_url, $headers, $opt);
        $links = $html->find('a');
        $results = [];
        foreach ($links as $link) {
            if (strpos($link->href, '/torrent/') === 0 && !in_array($link->href, $results)) {
                $results[] = $link->href;
            }
        }
        if (empty($results) && empty($this->getInput('q'))) {
            throwServerException('No results from Anidex: ' . $search_url);
        }

        //Process each item individually
        foreach ($results as $element) {
            //Limit total amount of requests
            if (count($this->items) >= 20) {
                break;
            }

            $torrent_id = str_replace('/torrent/', '', $element);

            //Ignore entries without valid torrent ID
            if ($torrent_id != 0 && ctype_digit($torrent_id)) {
                //Retrieve data for this torrent ID
                $item_browse_uri = self::URI . 'torrent/' . $torrent_id;
                $item_fetch_uri = self::ALTERNATE_URI . 'torrent/' . $torrent_id;

                //Retrieve full description from torrent page (cached for 24 hours: 86400 seconds)
                if ($item_html = getSimpleHTMLDOMCached($item_fetch_uri, 86400, $headers, $opt)) {
                    //Retrieve data from page contents
                    $item_title = str_replace(' (Torrent) - AniDex ', '', $item_html->find('title', 0)->plaintext);
                    $item_desc = $item_html->find('div.panel-body', 0);
                    $item_author = trim($item_html->find('span.fa-user', 0)->parent()->plaintext);
                    $item_date = strtotime(trim($item_html->find('span.fa-clock', 0)->parent()->plaintext));
                    $item_image = $this->getURI() . 'images/user_logos/default.png';

                    //Check for description-less torrent andn optionally extract image
                    $desc_title_found = false;
                    foreach ($item_html->find('h3.panel-title') as $h3) {
                        if (strpos($h3, 'Description') !== false) {
                            $desc_title_found = true;
                            break;
                        }
                    }
                    if ($desc_title_found) {
                        //Retrieve image for thumbnail or generic logo fallback
                        foreach ($item_desc->find('img') as $img) {
                            if (strpos($img->src, 'prez') === false) {
                                $item_image = $img->src;
                                break;
                            }
                        }
                        $item_desc = trim($item_desc->innertext);
                    } else {
                        $item_desc = '<em>No description.
Download .txt
gitextract_888ghlns/

├── .devcontainer/
│   ├── Dockerfile
│   ├── devcontainer.json
│   ├── launch.json
│   ├── nginx.conf
│   ├── post-create-command.sh
│   └── xdebug.ini
├── .dockerignore
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── .gitignore
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE/
│   │   ├── bridge-request.md
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── prtester-requirements.txt
│   ├── prtester.py
│   └── workflows/
│       ├── dockerbuild.yml
│       ├── documentation.yml
│       ├── lint.yml
│       ├── prhtmlgenerator.yml
│       └── tests.yml
├── .gitignore
├── CONTRIBUTORS.md
├── Dockerfile
├── README.md
├── UNLICENSE
├── actions/
│   ├── ConnectivityAction.php
│   ├── DetectAction.php
│   ├── DisplayAction.php
│   ├── FindfeedAction.php
│   ├── FrontpageAction.php
│   ├── HealthAction.php
│   └── ListAction.php
├── app.json
├── bridges/
│   ├── ABCNewsBridge.php
│   ├── ABolaBridge.php
│   ├── AO3Bridge.php
│   ├── ARDAudiothekBridge.php
│   ├── ARDMediathekBridge.php
│   ├── ARMCommunityBridge.php
│   ├── ASRockNewsBridge.php
│   ├── AcademiaBridge.php
│   ├── AcrimedBridge.php
│   ├── ActivisionResearchBridge.php
│   ├── AirBreizhBridge.php
│   ├── AkamaiBridge.php
│   ├── AlbionOnlineBridge.php
│   ├── AlfaBankByBridge.php
│   ├── AllSidesBridge.php
│   ├── AllegroBridge.php
│   ├── AllocineFRBridge.php
│   ├── AllocineFRSortiesBridge.php
│   ├── AlpinePackagesBridge.php
│   ├── AmazonBridge.php
│   ├── AmazonPriceTrackerBridge.php
│   ├── AnfrBridge.php
│   ├── AnidexBridge.php
│   ├── AnimeUltimeBridge.php
│   ├── AnisearchBridge.php
│   ├── AnnasArchiveBridge.php
│   ├── AppleAppStoreBridge.php
│   ├── AppleMusicBridge.php
│   ├── ArsTechnicaBridge.php
│   ├── ArtStationBridge.php
│   ├── Arte7Bridge.php
│   ├── AsahiShimbunAJWBridge.php
│   ├── AssociatedPressNewsBridge.php
│   ├── AstrophysicsDataSystemBridge.php
│   ├── AtmoNouvelleAquitaineBridge.php
│   ├── AtmoOccitanieBridge.php
│   ├── AuctionetBridge.php
│   ├── AutoJMBridge.php
│   ├── AwwwardsBridge.php
│   ├── BAEBridge.php
│   ├── BMDSystemhausBlogBridge.php
│   ├── BadDragonBridge.php
│   ├── BakaUpdatesMangaReleasesBridge.php
│   ├── BandcampBridge.php
│   ├── BandcampDailyBridge.php
│   ├── BarraqueiroBridgeAbstract.php
│   ├── BarraqueiroOesteBridge.php
│   ├── BastaBridge.php
│   ├── BazarakiBridge.php
│   ├── BinanceBridge.php
│   ├── BlaguesDeMerdeBridge.php
│   ├── BleepingComputerBridge.php
│   ├── BlizzardNewsBridge.php
│   ├── BlueskyBridge.php
│   ├── BoaViagemBridge.php
│   ├── BodaccBridge.php
│   ├── BookMyShowBridge.php
│   ├── BooruprojectBridge.php
│   ├── BrotFuerDieWeltBridge.php
│   ├── BruegelBridge.php
│   ├── BrutBridge.php
│   ├── BugzillaBridge.php
│   ├── BukowskisBridge.php
│   ├── BundesbankBridge.php
│   ├── BundestagParteispendenBridge.php
│   ├── BundesverbandFuerFreieKammernBridge.php
│   ├── CBCEditorsBlogBridge.php
│   ├── CMetropolitanaBridge.php
│   ├── CNETBridge.php
│   ├── CNETFranceBridge.php
│   ├── CVEDetailsBridge.php
│   ├── CachetBridge.php
│   ├── CarThrottleBridge.php
│   ├── CaschyBridge.php
│   ├── CastorusBridge.php
│   ├── CdactionBridge.php
│   ├── CentreFranceBridge.php
│   ├── CeskaTelevizeBridge.php
│   ├── CodebergBridge.php
│   ├── CollegeDeFranceBridge.php
│   ├── ComboiosDePortugalBridge.php
│   ├── ComickBridge.php
│   ├── ComicsKingdomBridge.php
│   ├── CommonDreamsBridge.php
│   ├── CopieDoubleBridge.php
│   ├── CorreioDaFeiraBridge.php
│   ├── CourrierInternationalBridge.php
│   ├── CraigslistBridge.php
│   ├── CrewbayBridge.php
│   ├── CryptomeBridge.php
│   ├── CssSelectorBridge.php
│   ├── CssSelectorComplexBridge.php
│   ├── CssSelectorFeedExpanderBridge.php
│   ├── CubariBridge.php
│   ├── CubariProxyBridge.php
│   ├── CybernewsBridge.php
│   ├── DRKBlutspendeBridge.php
│   ├── DacksnackBridge.php
│   ├── DagensNyheterDirektBridge.php
│   ├── DailymotionBridge.php
│   ├── DailythanthiBridge.php
│   ├── DanbooruBridge.php
│   ├── DarkReadingBridge.php
│   ├── DauphineLibereBridge.php
│   ├── DealabsBridge.php
│   ├── DemoBridge.php
│   ├── DemosBerlinBridge.php
│   ├── DerpibooruBridge.php
│   ├── DesoutterBridge.php
│   ├── DeutscheWelleBridge.php
│   ├── DeutscherAeroClubBridge.php
│   ├── DevToBridge.php
│   ├── DeveloppezDotComBridge.php
│   ├── DiarioDeNoticiasBridge.php
│   ├── DiarioDoAlentejoBridge.php
│   ├── DiceBridge.php
│   ├── DiscogsBridge.php
│   ├── DjMagDotComBridge.php
│   ├── DockerHubBridge.php
│   ├── DonnonsBridge.php
│   ├── DoujinStyleBridge.php
│   ├── DribbbleBridge.php
│   ├── Drive2ruBridge.php
│   ├── DuckDuckGoBridge.php
│   ├── DuvarOrgBridge.php
│   ├── EASeedBridge.php
│   ├── EBayBridge.php
│   ├── EDDHPiRepsBridge.php
│   ├── EDDHPresseschauBridge.php
│   ├── EZTVBridge.php
│   ├── EconomistBridge.php
│   ├── EconomistWorldInBriefBridge.php
│   ├── EdfPricesBridge.php
│   ├── ElektroARGOSBridge.php
│   ├── EliteDangerousGalnetBridge.php
│   ├── ElloBridge.php
│   ├── ElsevierBridge.php
│   ├── EngadgetBridge.php
│   ├── EpicGamesFreeBridge.php
│   ├── EpicgamesBridge.php
│   ├── ErowallBridge.php
│   ├── EsquerdaNetBridge.php
│   ├── EstCeQuonMetEnProdBridge.php
│   ├── EtsyBridge.php
│   ├── EuronewsBridge.php
│   ├── ExecuteProgramBridge.php
│   ├── ExplosmBridge.php
│   ├── FB2Bridge.php
│   ├── FDroidRepoBridge.php
│   ├── FFXIVLodestoneNewsBridge.php
│   ├── FM4Bridge.php
│   ├── FSecureBlogBridge.php
│   ├── FabBridge.php
│   ├── FabriceBellardBridge.php
│   ├── FacebookBridge.php
│   ├── FallGuysBridge.php
│   ├── FanaticalBridge.php
│   ├── FarsideNitterBridge.php
│   ├── FeedExpanderExampleBridge.php
│   ├── FeedExpanderTestBridge.php
│   ├── FeedMergeBridge.php
│   ├── FeedReducerBridge.php
│   ├── FiaBridge.php
│   ├── FicbookBridge.php
│   ├── FiderBridge.php
│   ├── FilterBridge.php
│   ├── FinanzflussBridge.php
│   ├── FindACrewBridge.php
│   ├── FirefoxAddonsBridge.php
│   ├── FirefoxReleaseNotesBridge.php
│   ├── FlaschenpostBridge.php
│   ├── FlashbackBridge.php
│   ├── FlickrBridge.php
│   ├── FliegermagazinBridge.php
│   ├── FolhaDeSaoPauloBridge.php
│   ├── ForGifsBridge.php
│   ├── ForensicArchitectureBridge.php
│   ├── Formula1Bridge.php
│   ├── FourchanBridge.php
│   ├── FreeCodeCampBridge.php
│   ├── FreeTelechargerBridge.php
│   ├── FunkBridge.php
│   ├── FurAffinityBridge.php
│   ├── FurAffinityUserBridge.php
│   ├── FuturaSciencesBridge.php
│   ├── GBAtempBridge.php
│   ├── GGDealsBridge.php
│   ├── GOGBridge.php
│   ├── GQMagazineBridge.php
│   ├── GULPProjekteBridge.php
│   ├── GabBridge.php
│   ├── GameBananaBridge.php
│   ├── GatesNotesBridge.php
│   ├── GelbooruBridge.php
│   ├── GenshinImpactBridge.php
│   ├── GettrBridge.php
│   ├── GiphyBridge.php
│   ├── GitHubGistBridge.php
│   ├── GiteaBridge.php
│   ├── GithubIssueBridge.php
│   ├── GithubPackagesBridge.php
│   ├── GithubPullRequestBridge.php
│   ├── GithubReleaseBridge.php
│   ├── GithubSearchBridge.php
│   ├── GithubTrendingBridge.php
│   ├── GitlabIssueBridge.php
│   ├── GizmodoBridge.php
│   ├── GlassdoorBridge.php
│   ├── GlowficBridge.php
│   ├── GoAccessBridge.php
│   ├── GoComicsBridge.php
│   ├── GogsBridge.php
│   ├── GolemBridge.php
│   ├── GoodreadsBridge.php
│   ├── GoogleGroupsBridge.php
│   ├── GooglePlayStoreBridge.php
│   ├── GoogleScholarBridge.php
│   ├── GoogleSearchBridge.php
│   ├── GovTrackBridge.php
│   ├── GrandComicsDatabaseBridge.php
│   ├── GroupBundNaturschutzBridge.php
│   ├── HDWallpapersBridge.php
│   ├── HackerNewsUserThreadsBridge.php
│   ├── HanimeBridge.php
│   ├── HarvardBusinessReviewBridge.php
│   ├── HarvardHealthBlogBridge.php
│   ├── HashnodeBridge.php
│   ├── HaveIBeenPwnedBridge.php
│   ├── HeiseBridge.php
│   ├── HinduTamilBridge.php
│   ├── HonkaiImpactSeaBridge.php
│   ├── HotUKDealsBridge.php
│   ├── HumbleBundleBridge.php
│   ├── HuntShowdownNewsBridge.php
│   ├── HytaleBridge.php
│   ├── I4wifiBridge.php
│   ├── IGNBridge.php
│   ├── IKWYDBridge.php
│   ├── IPBBridge.php
│   ├── IdealoBridge.php
│   ├── IdenticaBridge.php
│   ├── ImgsedBridge.php
│   ├── IndeedBridge.php
│   ├── IndiegogoBridge.php
│   ├── InstagramBridge.php
│   ├── InstituteForTheStudyOfWarBridge.php
│   ├── InstructablesBridge.php
│   ├── InternationalInstituteForStrategicStudiesBridge.php
│   ├── InternetArchiveBridge.php
│   ├── InvestorsObserverBridge.php
│   ├── ItakuBridge.php
│   ├── ItchioBridge.php
│   ├── IvooxBridge.php
│   ├── JapanExpoBridge.php
│   ├── JohannesBlickBridge.php
│   ├── JornalNBridge.php
│   ├── JustETFBridge.php
│   ├── JustWatchBridge.php
│   ├── Kanali6Bridge.php
│   ├── KemonoBridge.php
│   ├── KernelBugTrackerBridge.php
│   ├── KhinsiderBridge.php
│   ├── KilledbyGoogleBridge.php
│   ├── KilledbyMicrosoftBridge.php
│   ├── KitsuBridge.php
│   ├── KleinanzeigenBridge.php
│   ├── KoFiBridge.php
│   ├── KonachanBridge.php
│   ├── KoreusBridge.php
│   ├── KununuBridge.php
│   ├── LWNprevBridge.php
│   ├── LaCentraleBridge.php
│   ├── LaTeX3ProjectNewslettersBridge.php
│   ├── LeBonCoinBridge.php
│   ├── LeMondeInformatiqueBridge.php
│   ├── LeagueOfLegendsNewsBridge.php
│   ├── LegifranceJOBridge.php
│   ├── LegoIdeasBridge.php
│   ├── LesJoiesDuCodeBridge.php
│   ├── LfcPlBridge.php
│   ├── LinuxBlogBridge.php
│   ├── ListverseBridge.php
│   ├── LogicMastersBridge.php
│   ├── LolibooruBridge.php
│   ├── LuftfahrtBundesAmtBridge.php
│   ├── LuftsportSHBridge.php
│   ├── MaalaimalarBridge.php
│   ├── MagellantvBridge.php
│   ├── MagicTheGatheringBridge.php
│   ├── Mailman2Bridge.php
│   ├── MallTvBridge.php
│   ├── MangaDexBridge.php
│   ├── MangaReaderBridge.php
│   ├── ManyVidsBridge.php
│   ├── MarktplaatsBridge.php
│   ├── MastodonBridge.php
│   ├── MediapartBlogsBridge.php
│   ├── MediapartBridge.php
│   ├── MicrosoftOfficeUpdatesBridge.php
│   ├── MilbooruBridge.php
│   ├── MinecraftBridge.php
│   ├── MistralAIBridge.php
│   ├── MixCloudBridge.php
│   ├── MixologyBridge.php
│   ├── ModelKarteiBridge.php
│   ├── ModifyBridge.php
│   ├── ModrinthBridge.php
│   ├── MoebooruBridge.php
│   ├── MoinMoinBridge.php
│   ├── MondeDiploBridge.php
│   ├── MotatosBridge.php
│   ├── MozillaBugTrackerBridge.php
│   ├── MozillaSecurityBridge.php
│   ├── MsnMondeBridge.php
│   ├── MspabooruBridge.php
│   ├── MydealsBridge.php
│   ├── N26Bridge.php
│   ├── NACSouthGermanyMediaLibraryBridge.php
│   ├── NFLRUSBridge.php
│   ├── NHKWorldJapanShowBridge.php
│   ├── NOSBridge.php
│   ├── NPRBridge.php
│   ├── NYTBridge.php
│   ├── NasaApodBridge.php
│   ├── NasestrechaBridge.php
│   ├── NationalGeographicBridge.php
│   ├── NautiljonBridge.php
│   ├── NewOnNetflixBridge.php
│   ├── NewgroundsBridge.php
│   ├── NextInkBridge.php
│   ├── NextgovBridge.php
│   ├── NiceMatinBridge.php
│   ├── NikonDownloadCenterBridge.php
│   ├── NineGagBridge.php
│   ├── NintendoBridge.php
│   ├── NordbayernBridge.php
│   ├── NotAlwaysBridge.php
│   ├── NovayaGazetaEuropeBridge.php
│   ├── NovelUpdatesBridge.php
│   ├── NpciBridge.php
│   ├── NurembergerNachrichtenBridge.php
│   ├── NvidiaDriverBridge.php
│   ├── NyaaTorrentsBridge.php
│   ├── OLXBridge.php
│   ├── OMonlineBridge.php
│   ├── OglafBridge.php
│   ├── OllamaBridge.php
│   ├── OnVaSortirBridge.php
│   ├── OneFortuneADayBridge.php
│   ├── OpenCVEBridge.php
│   ├── OpenwhydBridge.php
│   ├── OpenwrtSecurityBridge.php
│   ├── OtrkeyFinderBridge.php
│   ├── OvertakeBridge.php
│   ├── PanneauPocketBridge.php
│   ├── ParksOnTheAirBridge.php
│   ├── ParlerBridge.php
│   ├── ParuVenduImmoBridge.php
│   ├── PatreonBridge.php
│   ├── PaulGrahamBridge.php
│   ├── PcGamerBridge.php
│   ├── PepperBridgeAbstract.php
│   ├── PhoronixBridge.php
│   ├── PicalaBridge.php
│   ├── PicartoBridge.php
│   ├── PickyWallpapersBridge.php
│   ├── PicnobBridge.php
│   ├── PicukiBridge.php
│   ├── PikabuBridge.php
│   ├── PillowfortBridge.php
│   ├── PinterestBridge.php
│   ├── PirateCommunityBridge.php
│   ├── PixivBridge.php
│   ├── PlantUMLReleasesBridge.php
│   ├── PokemonNewsBridge.php
│   ├── PornhubBridge.php
│   ├── PresidenciaPTBridge.php
│   ├── PriviblurBridge.php
│   ├── QnapBridge.php
│   ├── QwantzBridge.php
│   ├── QwenBlogBridge.php
│   ├── QwerteeBridge.php
│   ├── RadioFranceBridge.php
│   ├── RadioMelodieBridge.php
│   ├── RainLoopBridge.php
│   ├── RainbowSixSiegeBridge.php
│   ├── RedditBridge.php
│   ├── Releases3DSBridge.php
│   ├── ReleasesSwitchBridge.php
│   ├── RemixAudioBridge.php
│   ├── ReporterreBridge.php
│   ├── ReutersBridge.php
│   ├── RibatejanaBridge.php
│   ├── RiptApparelBridge.php
│   ├── RoadAndTrackBridge.php
│   ├── RobinhoodSnacksBridge.php
│   ├── RoosterTeethBridge.php
│   ├── RtsBridge.php
│   ├── Rue89Bridge.php
│   ├── Rule34Bridge.php
│   ├── Rule34pahealBridge.php
│   ├── RumbleBridge.php
│   ├── RutubeBridge.php
│   ├── SIMARBridge.php
│   ├── SafebooruBridge.php
│   ├── SamMobileUpdateBridge.php
│   ├── SamsungMobileChangelogBridge.php
│   ├── ScalableCapitalBlogBridge.php
│   ├── SchweinfurtBuergerinformationenBridge.php
│   ├── ScientificAmericanBridge.php
│   ├── ScmbBridge.php
│   ├── ScoopItBridge.php
│   ├── ScribbleHubBridge.php
│   ├── ScribdBridge.php
│   ├── SensCritiqueBridge.php
│   ├── SeznamZpravyBridge.php
│   ├── ShadertoyBridge.php
│   ├── ShanaprojectBridge.php
│   ├── Shimmie2Bridge.php
│   ├── SitemapBridge.php
│   ├── SkimfeedBridge.php
│   ├── SkyArteBridge.php
│   ├── SleeperFantasyFootballBridge.php
│   ├── SlusheBridge.php
│   ├── SongkickBridge.php
│   ├── SoundcloudBridge.php
│   ├── SplCenterBridge.php
│   ├── SpotifyBridge.php
│   ├── SpottschauBridge.php
│   ├── StanfordSIRbookreviewBridge.php
│   ├── SteamAppNewsBridge.php
│   ├── SteamBridge.php
│   ├── SteamCommunityBridge.php
│   ├── SteamGroupAnnouncementsBridge.php
│   ├── StockFilingsBridge.php
│   ├── StorytelBridge.php
│   ├── StravaBridge.php
│   ├── StreamCzBridge.php
│   ├── StripeAPIChangeLogBridge.php
│   ├── SubitoBridge.php
│   ├── SubstackBridge.php
│   ├── SubstackProfileBridge.php
│   ├── SummitsOnTheAirBridge.php
│   ├── SuperSmashBlogBridge.php
│   ├── SymfonyCastsBridge.php
│   ├── TCBScansBridge.php
│   ├── TagesspiegelBridge.php
│   ├── TapasBridge.php
│   ├── TarnkappeBridge.php
│   ├── TbibBridge.php
│   ├── TebeoBridge.php
│   ├── TeefuryBridge.php
│   ├── TelegramBridge.php
│   ├── TestFaktaBridge.php
│   ├── TheDriveBridge.php
│   ├── TheFarSideBridge.php
│   ├── TheGuardianBridge.php
│   ├── TheHackerNewsBridge.php
│   ├── TheOatmealBridge.php
│   ├── ThePirateBayBridge.php
│   ├── TheRedHandFilesBridge.php
│   ├── TheWhiteboardBridge.php
│   ├── TheYeteeBridge.php
│   ├── ThreadsBridge.php
│   ├── TicketioBridge.php
│   ├── TikTokBridge.php
│   ├── TinyLetterBridge.php
│   ├── TldrTechBridge.php
│   ├── TomsToucheBridge.php
│   ├── TorrentGalaxyBridge.php
│   ├── TraktBridge.php
│   ├── TrelloBridge.php
│   ├── TriabolosNewsBridge.php
│   ├── TwitScoopBridge.php
│   ├── TwitchBridge.php
│   ├── TwitterBridge.php
│   ├── TwitterEngineeringBridge.php
│   ├── TwitterV2Bridge.php
│   ├── UberNewsroomBridge.php
│   ├── UniverseTodayBridge.php
│   ├── UnogsBridge.php
│   ├── UnraidCommunityApplicationsBridge.php
│   ├── UnsplashBridge.php
│   ├── UrlebirdBridge.php
│   ├── UsbekEtRicaBridge.php
│   ├── UsenixBridge.php
│   ├── UsesTechBridge.php
│   ├── VarietyBridge.php
│   ├── ViadeoCompanyBridge.php
│   ├── ViceBridge.php
│   ├── VideoCardzBridge.php
│   ├── VieDeMerdeBridge.php
│   ├── VimeoBridge.php
│   ├── VixenBridge.php
│   ├── Vk2Bridge.php
│   ├── VkBridge.php
│   ├── VproTegenlichtBridge.php
│   ├── WKYTNewsBridge.php
│   ├── WYMTNewsBridge.php
│   ├── WaggaCouncilBridge.php
│   ├── WallmineNewsBridge.php
│   ├── WallpaperflareBridge.php
│   ├── WarhammerComBridge.php
│   ├── WeLiveSecurityBridge.php
│   ├── WebfailBridge.php
│   ├── WhatsAppBlogBridge.php
│   ├── WikiLeaksBridge.php
│   ├── WikipediaBridge.php
│   ├── WirecutterDealsBridge.php
│   ├── WiredBridge.php
│   ├── WordPressBridge.php
│   ├── WordPressMadaraBridge.php
│   ├── WordPressPluginUpdateBridge.php
│   ├── WorldOfTanksBridge.php
│   ├── WorldbankBridge.php
│   ├── XPathBridge.php
│   ├── XbooruBridge.php
│   ├── XenForoBridge.php
│   ├── YGGTorrentBridge.php
│   ├── YandereBridge.php
│   ├── YandexZenBridge.php
│   ├── YeggiBridge.php
│   ├── YorushikaBridge.php
│   ├── YouTubeCommunityTabBridge.php
│   ├── YouTubeFeedExpanderBridge.php
│   ├── YoutubeBridge.php
│   ├── ZDFMediathekBridge.php
│   ├── ZDNetBridge.php
│   ├── ZeitBridge.php
│   ├── ZenodoBridge.php
│   └── ZonebourseBridge.php
├── caches/
│   ├── ArrayCache.php
│   ├── FileCache.php
│   ├── MemcachedCache.php
│   ├── NullCache.php
│   └── SQLiteCache.php
├── composer.json
├── config/
│   ├── nginx.conf
│   ├── php-fpm.conf
│   └── php.ini
├── config.default.ini.php
├── contrib/
│   └── .gitkeep
├── docker-bake.hcl
├── docker-compose.yml
├── docker-entrypoint.sh
├── docs/
│   ├── 01_General/
│   │   ├── 01_Project-goals.md
│   │   ├── 02_Contribute.md
│   │   ├── 03_Requirements.md
│   │   ├── 04_Screenshots.md
│   │   ├── 05_FAQ.md
│   │   └── 06_Public_Hosts.md
│   ├── 02_CLI/
│   │   └── index.md
│   ├── 03_For_Hosts/
│   │   ├── 01_Installation.md
│   │   ├── 02_Updating.md
│   │   ├── 04_Heroku_Installation.md
│   │   ├── 05_Whitelisting.md
│   │   ├── 06_Authentication.md
│   │   ├── 07_Customizations.md
│   │   ├── 08_Custom_Configuration.md
│   │   └── index.md
│   ├── 04_For_Developers/
│   │   ├── 01_Coding_style_policy.md
│   │   ├── 02_Pull_Request_policy.md
│   │   ├── 03_Folder_structure.md
│   │   ├── 04_Actions.md
│   │   ├── 05_Debug_mode.md
│   │   ├── 06_Github_Codespaces_Tutorial.md
│   │   ├── 07_Development_Environment_Setup.md
│   │   └── index.md
│   ├── 05_Bridge_API/
│   │   ├── 01_How_to_create_a_new_bridge.md
│   │   ├── 02_BridgeAbstract.md
│   │   ├── 03_FeedExpander.md
│   │   ├── 04_WebDriverAbstract.md
│   │   ├── 05_XPathAbstract.md
│   │   └── index.md
│   ├── 06_Helper_functions/
│   │   └── index.md
│   ├── 07_Cache_API/
│   │   ├── 01_How_to_create_a_new_cache.md
│   │   ├── 02_CacheInterface.md
│   │   └── index.md
│   ├── 09_Technical_recommendations/
│   │   └── index.md
│   ├── 10_Bridge_Specific/
│   │   ├── ActivityPub_(Mastodon).md
│   │   ├── Economist.md
│   │   ├── FacebookBridge.md
│   │   ├── FurAffinityBridge.md
│   │   ├── Furaffinityuser.md
│   │   ├── Instagram.md
│   │   ├── PixivBridge.md
│   │   ├── Substack.md
│   │   ├── Telegram.md
│   │   ├── TwitterV2.md
│   │   └── Vk2.md
│   ├── 99_Theme/
│   │   └── rssbridge/
│   │       └── config.json
│   ├── config.json
│   ├── index.md
│   └── readme.md
├── formats/
│   ├── AtomFormat.php
│   ├── HtmlFormat.php
│   ├── JsonFormat.php
│   ├── MrssFormat.php
│   ├── PlaintextFormat.php
│   └── SfeedFormat.php
├── index.php
├── lib/
│   ├── ActionInterface.php
│   ├── BridgeAbstract.php
│   ├── BridgeFactory.php
│   ├── CacheFactory.php
│   ├── CacheInterface.php
│   ├── Configuration.php
│   ├── Container.php
│   ├── FeedExpander.php
│   ├── FeedItem.php
│   ├── FeedParser.php
│   ├── FormatAbstract.php
│   ├── FormatFactory.php
│   ├── ParameterValidator.php
│   ├── RssBridge.php
│   ├── TwitterClient.php
│   ├── WebDriverAbstract.php
│   ├── XPathAbstract.php
│   ├── bootstrap.php
│   ├── config.php
│   ├── contents.php
│   ├── dependencies.php
│   ├── html.php
│   ├── http.php
│   ├── logger.php
│   ├── parsedown/
│   │   ├── LICENSE.txt
│   │   └── Parsedown.php
│   ├── php-urljoin/
│   │   ├── LICENSE
│   │   └── src/
│   │       └── urljoin.php
│   ├── php8backports.php
│   ├── seotags.php
│   ├── simplehtmldom/
│   │   ├── LICENSE
│   │   └── simple_html_dom.php
│   ├── url.php
│   └── utils.php
├── middlewares/
│   ├── BasicAuthMiddleware.php
│   ├── CacheMiddleware.php
│   ├── ExceptionMiddleware.php
│   ├── MaintenanceMiddleware.php
│   ├── Middleware.php
│   ├── SecurityMiddleware.php
│   └── TokenAuthenticationMiddleware.php
├── phpcompatibility.xml
├── phpcs.xml
├── phpunit.xml
├── scalingo.json
├── static/
│   ├── connectivity.css
│   ├── connectivity.js
│   ├── rss-bridge.js
│   └── style.css
├── templates/
│   ├── base.html.php
│   ├── bridge-error.html.php
│   ├── connectivity.html.php
│   ├── error.html.php
│   ├── exception.html.php
│   ├── frontpage.html.php
│   ├── html-format.html.php
│   └── token.html.php
└── tests/
    ├── BridgeCardTest.php
    ├── BridgeFactoryTest.php
    ├── BridgeImplementationTest.php
    ├── CacheImplementationTest.php
    ├── CacheTest.php
    ├── ConfigurationTest.php
    ├── FeedItemTest.php
    ├── FeedParserTest.php
    ├── FormatTest.php
    ├── Formats/
    │   ├── AtomFormatTest.php
    │   ├── BaseFormatTest.php
    │   ├── FormatImplementationTest.php
    │   ├── JsonFormatTest.php
    │   ├── MrssFormatTest.php
    │   └── samples/
    │       ├── expectedAtomFormat/
    │       │   ├── feed.common.xml
    │       │   ├── feed.empty.xml
    │       │   ├── feed.emptyItems.xml
    │       │   └── feed.microblog.xml
    │       ├── expectedJsonFormat/
    │       │   ├── feed.common.json
    │       │   ├── feed.empty.json
    │       │   ├── feed.emptyItems.json
    │       │   └── feed.microblog.json
    │       ├── expectedMrssFormat/
    │       │   ├── feed.common.xml
    │       │   ├── feed.empty.xml
    │       │   ├── feed.emptyItems.xml
    │       │   └── feed.microblog.xml
    │       ├── feed.common.json
    │       ├── feed.empty.json
    │       ├── feed.emptyItems.json
    │       └── feed.microblog.json
    ├── ParameterValidatorTest.php
    ├── RedditBridgeTest.php
    ├── UrlTest.php
    └── UtilsTest.php
Download .txt
Showing preview only (262K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3209 symbols across 605 files)

FILE: .github/prtester.py
  class Instance (line 20) | class Instance:
  function main (line 24) | def main(instances: Iterable[Instance], with_artifacts: bool, with_reduc...
  function testBridges (line 53) | def testBridges(instance: Instance, bridge_cards: Iterable, with_artifac...
  function getFirstLine (line 165) | def getFirstLine(value: str) -> str:

FILE: actions/ConnectivityAction.php
  class ConnectivityAction (line 13) | class ConnectivityAction implements ActionInterface
    method __construct (line 17) | public function __construct(
    method __invoke (line 23) | public function __invoke(Request $request): Response
    method reportBridgeConnectivity (line 40) | private function reportBridgeConnectivity($bridgeClassName)

FILE: actions/DetectAction.php
  class DetectAction (line 3) | class DetectAction implements ActionInterface
    method __construct (line 7) | public function __construct(
    method __invoke (line 13) | public function __invoke(Request $request): Response

FILE: actions/DisplayAction.php
  class DisplayAction (line 3) | class DisplayAction implements ActionInterface
    method __construct (line 9) | public function __construct(
    method __invoke (line 19) | public function __invoke(Request $request): Response
    method createResponse (line 69) | private function createResponse(Request $request, BridgeAbstract $brid...
    method createFeedItemFromException (line 146) | private function createFeedItemFromException($e, BridgeAbstract $bridg...
    method logBridgeError (line 172) | private function logBridgeError($bridgeName, $code)
    method createGithubIssueUrl (line 193) | private static function createGithubIssueUrl(BridgeAbstract $bridge, \...
    method createGithubSearchUrl (line 223) | private static function createGithubSearchUrl($bridge): string

FILE: actions/FindfeedAction.php
  class FindfeedAction (line 8) | class FindfeedAction implements ActionInterface
    method __construct (line 12) | public function __construct(
    method __invoke (line 18) | public function __invoke(Request $request): Response
    method getParameterName (line 84) | private function getParameterName($bridge, $context, $key)

FILE: actions/FrontpageAction.php
  class FrontpageAction (line 3) | final class FrontpageAction implements ActionInterface
    method __construct (line 7) | public function __construct(
    method __invoke (line 13) | public function __invoke(Request $request): Response
    method render (line 51) | public static function render(
    method renderForm (line 150) | private static function renderForm(
    method getTextInput (line 245) | public static function getTextInput(array $parameter, string $id, stri...
    method getNumberInput (line 263) | public static function getNumberInput(array $parameter, string $id, st...
    method getCheckboxInput (line 281) | public static function getCheckboxInput(array $parameter, string $id, ...
    method getListInput (line 291) | public static function getListInput(array $parameter, string $id, stri...

FILE: actions/HealthAction.php
  class HealthAction (line 5) | class HealthAction implements ActionInterface
    method __invoke (line 7) | public function __invoke(Request $request): Response

FILE: actions/ListAction.php
  class ListAction (line 3) | class ListAction implements ActionInterface
    method __construct (line 7) | public function __construct(
    method __invoke (line 13) | public function __invoke(Request $request): Response

FILE: bridges/ABCNewsBridge.php
  class ABCNewsBridge (line 3) | class ABCNewsBridge extends BridgeAbstract
    method collectData (line 30) | public function collectData()

FILE: bridges/ABolaBridge.php
  class ABolaBridge (line 3) | class ABolaBridge extends BridgeAbstract
    method getIcon (line 47) | public function getIcon()
    method getName (line 52) | public function getName()
    method getURI (line 57) | public function getURI()
    method collectData (line 62) | public function collectData()

FILE: bridges/AO3Bridge.php
  class AO3Bridge (line 3) | class AO3Bridge extends BridgeAbstract
    method collectData (line 58) | public function collectData()
    method collectList (line 77) | private function collectList($url)
    method collectWork (line 177) | private function collectWork($url)
    method getName (line 217) | public function getName()
    method getIcon (line 226) | public function getIcon()
    method getURI (line 231) | public function getURI()

FILE: bridges/ARDAudiothekBridge.php
  class ARDAudiothekBridge (line 3) | class ARDAudiothekBridge extends BridgeAbstract
    method collectData (line 64) | public function collectData()
    method getURI (line 148) | public function getURI()
    method getName (line 157) | public function getName()
    method getIcon (line 166) | public function getIcon()

FILE: bridges/ARDMediathekBridge.php
  class ARDMediathekBridge (line 3) | class ARDMediathekBridge extends BridgeAbstract
    method collectData (line 60) | public function collectData()
    method getName (line 107) | public function getName()

FILE: bridges/ARMCommunityBridge.php
  class ARMCommunityBridge (line 5) | class ARMCommunityBridge extends BridgeAbstract
    method collectData (line 36) | public function collectData()
    method getName (line 66) | public function getName()

FILE: bridges/ASRockNewsBridge.php
  class ASRockNewsBridge (line 3) | class ASRockNewsBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()
    method extractDate (line 51) | private function extractDate($text)

FILE: bridges/AcademiaBridge.php
  class AcademiaBridge (line 5) | class AcademiaBridge extends BridgeAbstract
    method getName (line 32) | public function getName()
    method collectData (line 42) | public function collectData()
    method extractSummaries (line 93) | private function extractSummaries($dom): array

FILE: bridges/AcrimedBridge.php
  class AcrimedBridge (line 3) | class AcrimedBridge extends FeedExpander
    method collectData (line 21) | public function collectData()
    method parseItem (line 28) | protected function parseItem(array $item)

FILE: bridges/ActivisionResearchBridge.php
  class ActivisionResearchBridge (line 3) | class ActivisionResearchBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/AirBreizhBridge.php
  class AirBreizhBridge (line 3) | class AirBreizhBridge extends BridgeAbstract
    method getIcon (line 27) | public function getIcon()
    method collectData (line 32) | public function collectData()

FILE: bridges/AkamaiBridge.php
  class AkamaiBridge (line 3) | class AkamaiBridge extends FeedExpander
    method collectData (line 25) | public function collectData()
    method parseItem (line 33) | protected function parseItem(array $item)
    method getIcon (line 68) | public function getIcon()

FILE: bridges/AlbionOnlineBridge.php
  class AlbionOnlineBridge (line 3) | class AlbionOnlineBridge extends BridgeAbstract
    method collectData (line 42) | public function collectData()
    method getFullChangelog (line 70) | private function getFullChangelog($url)

FILE: bridges/AlfaBankByBridge.php
  class AlfaBankByBridge (line 3) | class AlfaBankByBridge extends BridgeAbstract
    method collectData (line 31) | public function collectData()
    method getIcon (line 72) | public function getIcon()
    method ruMonthsToEn (line 77) | private function ruMonthsToEn($date)

FILE: bridges/AllSidesBridge.php
  class AllSidesBridge (line 3) | class AllSidesBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method getName (line 69) | public function getName()
    method getURI (line 77) | public function getURI()

FILE: bridges/AllegroBridge.php
  class AllegroBridge (line 3) | class AllegroBridge extends BridgeAbstract
    method getName (line 33) | public function getName()
    method getURI (line 57) | public function getURI()
    method collectData (line 74) | public function collectData()

FILE: bridges/AllocineFRBridge.php
  class AllocineFRBridge (line 3) | class AllocineFRBridge extends BridgeAbstract
    method getURI (line 35) | public function getURI()
    method getLastSeasonURI (line 67) | private function getLastSeasonURI($category)
    method getName (line 75) | public function getName()
    method collectData (line 84) | public function collectData()

FILE: bridges/AllocineFRSortiesBridge.php
  class AllocineFRSortiesBridge (line 3) | class AllocineFRSortiesBridge extends BridgeAbstract
    method getName (line 12) | public function getName()
    method collectData (line 17) | public function collectData()
    method frenchPubDateToTimestamp (line 44) | private function frenchPubDateToTimestamp($date)

FILE: bridges/AlpinePackagesBridge.php
  class AlpinePackagesBridge (line 5) | class AlpinePackagesBridge extends BridgeAbstract
    method getADom (line 60) | private function getADom($element)
    method getElementData (line 65) | private function getElementData($element)
    method getTdClassDom (line 97) | private function getTdClassDom($element, $class)
    method collectData (line 102) | public function collectData()
    method getName (line 126) | public function getName()
    method getUri (line 161) | public function getUri()

FILE: bridges/AmazonBridge.php
  class AmazonBridge (line 3) | class AmazonBridge extends BridgeAbstract
    method collectData (line 55) | public function collectData()
    method getName (line 97) | public function getName()

FILE: bridges/AmazonPriceTrackerBridge.php
  class AmazonPriceTrackerBridge (line 3) | class AmazonPriceTrackerBridge extends BridgeAbstract
    method getDomainName (line 62) | private function getDomainName()
    method getURI (line 70) | public function getURI()
    method getTitle (line 82) | private function getTitle($html)
    method getDefaultTitle (line 96) | private function getDefaultTitle()
    method getName (line 105) | public function getName()
    method parseDynamicImage (line 114) | private function parseDynamicImage($attribute)
    method getImage (line 126) | private function getImage($html)
    method getHtml (line 145) | private function getHtml()
    method scrapePriceFromMetrics (line 152) | private function scrapePriceFromMetrics($html)
    method scrapePriceTwister (line 170) | private function scrapePriceTwister($html)
    method scrapePriceGeneric (line 191) | private function scrapePriceGeneric($html)
    method collectData (line 241) | public function collectData()

FILE: bridges/AnfrBridge.php
  class AnfrBridge (line 3) | class AnfrBridge extends BridgeAbstract
    method collectData (line 180) | public function collectData()

FILE: bridges/AnidexBridge.php
  class AnidexBridge (line 3) | class AnidexBridge extends BridgeAbstract
    method collectData (line 111) | public function collectData()

FILE: bridges/AnimeUltimeBridge.php
  class AnimeUltimeBridge (line 3) | class AnimeUltimeBridge extends BridgeAbstract
    method collectData (line 25) | public function collectData()
    method getName (line 125) | public function getName()

FILE: bridges/AnisearchBridge.php
  class AnisearchBridge (line 3) | class AnisearchBridge extends BridgeAbstract
    method collectData (line 31) | public function collectData()

FILE: bridges/AnnasArchiveBridge.php
  class AnnasArchiveBridge (line 3) | class AnnasArchiveBridge extends BridgeAbstract
    method collectData (line 118) | public function collectData()
    method getName (line 162) | public function getName()
    method getURI (line 171) | public function getURI()

FILE: bridges/AppleAppStoreBridge.php
  class AppleAppStoreBridge (line 3) | class AppleAppStoreBridge extends BridgeAbstract
    method makeHtmlUrl (line 70) | private function makeHtmlUrl()
    method makeJsonUrl (line 77) | private function makeJsonUrl()
    method getName (line 93) | public function getName()
    method debugLog (line 102) | private function debugLog($message)
    method getAppData (line 109) | private function getAppData()
    method extractAppDetails (line 170) | private function extractAppDetails($data)
    method getVersionHistory (line 185) | private function getVersionHistory($data)
    method collectData (line 202) | public function collectData()

FILE: bridges/AppleMusicBridge.php
  class AppleMusicBridge (line 3) | class AppleMusicBridge extends BridgeAbstract
    method collectData (line 25) | public function collectData()
    method getJson (line 59) | private function getJson()
    method getArtist (line 80) | private function getArtist($json)
    method getName (line 93) | public function getName()
    method getIcon (line 102) | public function getIcon()

FILE: bridges/ArsTechnicaBridge.php
  class ArsTechnicaBridge (line 3) | class ArsTechnicaBridge extends FeedExpander
    method collectData (line 30) | public function collectData()
    method parseItem (line 36) | protected function parseItem(array $item)

FILE: bridges/ArtStationBridge.php
  class ArtStationBridge (line 3) | class ArtStationBridge extends BridgeAbstract
    method getIcon (line 21) | public function getIcon()
    method getName (line 26) | public function getName()
    method fetchSearch (line 31) | private function fetchSearch($searchQuery)
    method fetchProject (line 52) | private function fetchProject($hashID)
    method collectData (line 59) | public function collectData()

FILE: bridges/Arte7Bridge.php
  class Arte7Bridge (line 3) | class Arte7Bridge extends BridgeAbstract
    method collectData (line 101) | public function collectData()

FILE: bridges/AsahiShimbunAJWBridge.php
  class AsahiShimbunAJWBridge (line 3) | class AsahiShimbunAJWBridge extends BridgeAbstract
    method getSectionURI (line 37) | private function getSectionURI($section)
    method collectData (line 42) | public function collectData()

FILE: bridges/AssociatedPressNewsBridge.php
  class AssociatedPressNewsBridge (line 3) | class AssociatedPressNewsBridge extends BridgeAbstract
    method detectParameters (line 52) | public function detectParameters($url)
    method collectData (line 65) | public function collectData()
    method getURI (line 79) | public function getURI()
    method getName (line 88) | public function getName()
    method getTagURI (line 97) | private function getTagURI()
    method collectCardData (line 106) | private function collectCardData()
    method processMediaPlaceholders (line 191) | private function processMediaPlaceholders($html, $id)
    method processHubLinks (line 226) | private function processHubLinks($html, $storyContent)
    method processVideo (line 244) | private function processVideo($storyContent)
    method processIframes (line 262) | private function processIframes($html)

FILE: bridges/AstrophysicsDataSystemBridge.php
  class AstrophysicsDataSystemBridge (line 3) | class AstrophysicsDataSystemBridge extends BridgeAbstract
    method getName (line 20) | public function getName()
    method getURI (line 28) | public function getURI()
    method collectData (line 36) | public function collectData()

FILE: bridges/AtmoNouvelleAquitaineBridge.php
  class AtmoNouvelleAquitaineBridge (line 3) | class AtmoNouvelleAquitaineBridge extends BridgeAbstract
    method getClosest (line 20) | private function getClosest($search, $arr)
    method collectData (line 31) | public function collectData()
    method getIndex (line 56) | private function getIndex()
    method getMaxIndexText (line 67) | private function getMaxIndexText()
    method getQualityText (line 73) | private function getQualityText($index, $indexes)
    method getLegendIndexes (line 86) | private function getLegendIndexes()
    method getTomorrowTrendIndex (line 99) | private function getTomorrowTrendIndex()
    method getTomorrowTrendQualityText (line 118) | private function getTomorrowTrendQualityText($trendIndex, $indexes)
    method getIndexMessage (line 131) | private function getIndexMessage()
    method getQualityMessage (line 143) | private function getQualityMessage()
    method getTomorrowTrendIndexMessage (line 156) | private function getTomorrowTrendIndexMessage()
    method getTomorrowTrendQualityMessage (line 168) | private function getTomorrowTrendQualityMessage()

FILE: bridges/AtmoOccitanieBridge.php
  class AtmoOccitanieBridge (line 3) | class AtmoOccitanieBridge extends BridgeAbstract
    method collectData (line 18) | public function collectData()

FILE: bridges/AuctionetBridge.php
  class AuctionetBridge (line 3) | class AuctionetBridge extends BridgeAbstract
    method collectData (line 230) | public function collectData()
    method getName (line 256) | public function getName()
    method getUrl (line 264) | private function getUrl($page)
    method getDocumentTitle (line 295) | private function getDocumentTitle($data)
    method parsePageData (line 312) | private function parsePageData($data)

FILE: bridges/AutoJMBridge.php
  class AutoJMBridge (line 3) | class AutoJMBridge extends BridgeAbstract
    method getIcon (line 30) | public function getIcon()
    method getName (line 35) | public function getName()
    method getURI (line 46) | public function getURI()
    method collectData (line 57) | public function collectData()
    method getResults (line 142) | private function getResults(int $page)
    method detectParameters (line 155) | public function detectParameters($url)

FILE: bridges/AwwwardsBridge.php
  class AwwwardsBridge (line 3) | class AwwwardsBridge extends BridgeAbstract
    method collectData (line 17) | public function collectData()
    method getIcon (line 41) | public function getIcon()
    method fetchSites (line 46) | private function fetchSites()

FILE: bridges/BAEBridge.php
  class BAEBridge (line 3) | class BAEBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method getURI (line 71) | public function getURI()
    method removeAccents (line 87) | private function removeAccents($string)

FILE: bridges/BMDSystemhausBlogBridge.php
  class BMDSystemhausBlogBridge (line 3) | class BMDSystemhausBlogBridge extends BridgeAbstract
    method collectData (line 54) | public function collectData()
    method detectParameters (line 144) | public function detectParameters($url)
    method getURI (line 208) | public function getURI()
    method getIcon (line 216) | public function getIcon()
    method getMetaItemPropContent (line 222) | private function getMetaItemPropContent($elem, $key)
    method getURIbyCountry (line 235) | private function getURIbyCountry($country)

FILE: bridges/BadDragonBridge.php
  class BadDragonBridge (line 3) | class BadDragonBridge extends BridgeAbstract
    method setParam (line 127) | private function setParam($inArr, &$outArr, $param, $strFrom, $strTo =...
    method detectParameters (line 134) | public function detectParameters($url)
    method getName (line 204) | public function getName()
    method getURI (line 216) | public function getURI()
    method collectData (line 228) | public function collectData()
    method inputToURL (line 377) | private function inputToURL($api = false)

FILE: bridges/BakaUpdatesMangaReleasesBridge.php
  class BakaUpdatesMangaReleasesBridge (line 3) | class BakaUpdatesMangaReleasesBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()
    method getURI (line 42) | public function getURI()
    method getName (line 56) | public function getName()
    method getSanitizedHash (line 64) | private function getSanitizedHash($string)
    method filterText (line 69) | private function filterText($text)
    method filterHTML (line 74) | private function filterHTML($text)
    method findID (line 79) | private function findID($manga)
    method collectDataBySeries (line 90) | private function collectDataBySeries()
    method collectDataByList (line 155) | private function collectDataByList()

FILE: bridges/BandcampBridge.php
  class BandcampBridge (line 3) | class BandcampBridge extends BridgeAbstract
    method getIcon (line 102) | public function getIcon()
    method collectData (line 107) | public function collectData()
    method buildTralbumItem (line 233) | private function buildTralbumItem($tralbum_data)
    method buildRequestJson (line 298) | private function buildRequestJson()
    method getImageUrl (line 308) | private function getImageUrl($id, $size)
    method apiGet (line 313) | private function apiGet($endpoint, $query_data)
    method getURI (line 322) | public function getURI()
    method getName (line 360) | public function getName()
    method detectParameters (line 394) | public function detectParameters($url)

FILE: bridges/BandcampDailyBridge.php
  class BandcampDailyBridge (line 3) | class BandcampDailyBridge extends BridgeAbstract
    method collectData (line 94) | public function collectData()
    method getURI (line 130) | public function getURI()
    method getName (line 146) | public function getName()

FILE: bridges/BarraqueiroBridgeAbstract.php
  class BarraqueiroBridgeAbstract (line 3) | abstract class BarraqueiroBridgeAbstract extends BridgeAbstract
    method collectDataBarraqueiro (line 7) | public function collectDataBarraqueiro($base_uri, $full_uri)

FILE: bridges/BarraqueiroOesteBridge.php
  class BarraqueiroOesteBridge (line 3) | class BarraqueiroOesteBridge extends BarraqueiroBridgeAbstract
    method collectData (line 9) | public function collectData()

FILE: bridges/BastaBridge.php
  class BastaBridge (line 3) | class BastaBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/BazarakiBridge.php
  class BazarakiBridge (line 3) | class BazarakiBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method processAdvertContent (line 76) | private function processAdvertContent($advert)
    method convertRelativeTime (line 124) | private function convertRelativeTime($timeString)

FILE: bridges/BinanceBridge.php
  class BinanceBridge (line 3) | class BinanceBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()
    method getIcon (line 30) | public function getIcon()

FILE: bridges/BlaguesDeMerdeBridge.php
  class BlaguesDeMerdeBridge (line 3) | class BlaguesDeMerdeBridge extends BridgeAbstract
    method getIcon (line 11) | public function getIcon()
    method collectData (line 16) | public function collectData()

FILE: bridges/BleepingComputerBridge.php
  class BleepingComputerBridge (line 3) | class BleepingComputerBridge extends FeedExpander
    method collectData (line 10) | public function collectData()
    method parseItem (line 16) | protected function parseItem(array $item)

FILE: bridges/BlizzardNewsBridge.php
  class BlizzardNewsBridge (line 3) | class BlizzardNewsBridge extends BridgeAbstract
    method getSourceUrl (line 62) | private function getSourceUrl(): string
    method collectData (line 75) | public function collectData()
    method filterChars (line 96) | private function filterChars($content)
    method getIcon (line 101) | public function getIcon()

FILE: bridges/BlueskyBridge.php
  class BlueskyBridge (line 3) | class BlueskyBridge extends BridgeAbstract
    method getName (line 61) | public function getName()
    method getURI (line 73) | public function getURI()
    method getIcon (line 85) | public function getIcon()
    method getDescription (line 93) | public function getDescription()
    method parseExternal (line 101) | private function parseExternal($external, $did)
    method textToDescription (line 124) | private function textToDescription($record)
    method collectData (line 144) | public function collectData()
    method getPostVideoDescription (line 496) | private function getPostVideoDescription(array $video, $authorDID)
    method getPostImageDescription (line 506) | private function getPostImageDescription(array $image)
    method getPostDescription (line 514) | private function getPostDescription(
    method fallbackAuthor (line 540) | private function fallbackAuthor($author, $reason)
    method generateVerboseTitle (line 554) | private function generateVerboseTitle($post)
    method resolveHandle (line 607) | private function resolveHandle($handle)
    method getProfile (line 617) | private function getProfile($did)
    method getAuthorFeed (line 627) | private function getAuthorFeed($did, $filter)
    method getListFeedDescription (line 638) | private function getListFeedDescription(array $record): string
    method getStarterPackDescription (line 671) | private function getStarterPackDescription(array $record): string

FILE: bridges/BoaViagemBridge.php
  class BoaViagemBridge (line 3) | class BoaViagemBridge extends BarraqueiroBridgeAbstract
    method collectData (line 9) | public function collectData()

FILE: bridges/BodaccBridge.php
  class BodaccBridge (line 3) | class BodaccBridge extends BridgeAbstract
    method collectData (line 158) | public function collectData()

FILE: bridges/BookMyShowBridge.php
  class BookMyShowBridge (line 3) | class BookMyShowBridge extends BridgeAbstract
    method collectData (line 1095) | public function collectData()
    method makeUrl (line 1125) | private function makeUrl($category)
    method getDatesHtml (line 1130) | private function getDatesHtml($dates)
    method generateEventHtml (line 1149) | private function generateEventHtml($event, $category)
    method generateVenueHtml (line 1168) | private function generateVenueHtml($venues)
    method generateEventDetailsTable (line 1189) | private function generateEventDetailsTable($event, $headers = self::TA...
    method generateStandardHtml (line 1216) | private function generateStandardHtml($event)
    method generateInnerMovieDetails (line 1236) | private function generateInnerMovieDetails($data)
    method generateMovieHtml (line 1283) | private function generateMovieHtml($eventGroup)
    method generateMovieUrl (line 1310) | private function generateMovieUrl($eventGroup)
    method generateMoviesData (line 1315) | private function generateMoviesData($eventGroup)
    method generateEventData (line 1339) | private function generateEventData($event, $category)
    method generateGenericEventData (line 1351) | private function generateGenericEventData($event, $category)
    method isEventOnline (line 1380) | private function isEventOnline($event)
    method matchesLanguage (line 1391) | private function matchesLanguage()
    method matchesOnline (line 1400) | private function matchesOnline($event)
    method matchesFilters (line 1411) | private function matchesFilters($category, $event)
    method getName (line 1419) | public function getName()
    method makeHeaders (line 1443) | private function makeHeaders($city)
    method generateDirectionsHtml (line 1456) | private function generateDirectionsHtml($lat, $long, $address = '')

FILE: bridges/BooruprojectBridge.php
  class BooruprojectBridge (line 3) | class BooruprojectBridge extends DanbooruBridge
    method getFullURI (line 37) | protected function getFullURI()
    method getTags (line 45) | protected function getTags($element)
    method getURI (line 60) | public function getURI()
    method getName (line 69) | public function getName()

FILE: bridges/BrotFuerDieWeltBridge.php
  class BrotFuerDieWeltBridge (line 5) | class BrotFuerDieWeltBridge extends BridgeAbstract
    method collectData (line 24) | public function collectData()

FILE: bridges/BruegelBridge.php
  class BruegelBridge (line 3) | class BruegelBridge extends BridgeAbstract
    method getIcon (line 23) | public function getIcon()
    method collectData (line 28) | public function collectData()
    method getAuthor (line 53) | private function getAuthor($article)

FILE: bridges/BrutBridge.php
  class BrutBridge (line 3) | class BrutBridge extends BridgeAbstract
    method collectData (line 41) | public function collectData()
    method getURI (line 58) | public function getURI()
    method getName (line 66) | public function getName()

FILE: bridges/BugzillaBridge.php
  class BugzillaBridge (line 3) | class BugzillaBridge extends BridgeAbstract
    method getName (line 52) | public function getName()
    method getURI (line 60) | public function getURI()
    method collectData (line 65) | public function collectData()
    method getTitle (line 85) | protected function getTitle($url)
    method collectComments (line 95) | protected function collectComments($url)
    method collectUpdates (line 128) | protected function collectUpdates($url)
    method getUser (line 159) | protected function getUser($user)
    method getJSON (line 191) | protected static function getJSON($url)

FILE: bridges/BukowskisBridge.php
  class BukowskisBridge (line 3) | class BukowskisBridge extends BridgeAbstract
    method collectData (line 174) | public function collectData()
    method getName (line 216) | public function getName()

FILE: bridges/BundesbankBridge.php
  class BundesbankBridge (line 3) | class BundesbankBridge extends BridgeAbstract
    method getIcon (line 30) | public function getIcon()
    method getURI (line 35) | public function getURI()
    method collectData (line 47) | public function collectData()

FILE: bridges/BundestagParteispendenBridge.php
  class BundestagParteispendenBridge (line 3) | class BundestagParteispendenBridge extends BridgeAbstract
    method getIcon (line 18) | public function getIcon()
    method collectData (line 23) | public function collectData()
    method generateItemFromRow (line 56) | private function generateItemFromRow(simple_html_dom_node $row)

FILE: bridges/BundesverbandFuerFreieKammernBridge.php
  class BundesverbandFuerFreieKammernBridge (line 3) | class BundesverbandFuerFreieKammernBridge extends XPathAbstract
    method formatItemTimestamp (line 21) | protected function formatItemTimestamp($value)

FILE: bridges/CBCEditorsBlogBridge.php
  class CBCEditorsBlogBridge (line 3) | class CBCEditorsBlogBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/CMetropolitanaBridge.php
  class CMetropolitanaBridge (line 5) | class CMetropolitanaBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/CNETBridge.php
  class CNETBridge (line 3) | class CNETBridge extends SitemapBridge
    method collectData (line 33) | public function collectData()

FILE: bridges/CNETFranceBridge.php
  class CNETFranceBridge (line 3) | class CNETFranceBridge extends FeedExpander
    method collectData (line 30) | public function collectData()
    method parseItem (line 46) | protected function parseItem(array $item)

FILE: bridges/CVEDetailsBridge.php
  class CVEDetailsBridge (line 10) | class CVEDetailsBridge extends BridgeAbstract
    method collectData (line 39) | public function collectData()
    method fetchContent (line 69) | private function fetchContent()
    method getName (line 100) | public function getName()

FILE: bridges/CachetBridge.php
  class CachetBridge (line 3) | class CachetBridge extends BridgeAbstract
    method getURI (line 28) | public function getURI()
    method validatePing (line 39) | private function validatePing($ping)
    method getComponentName (line 54) | private function getComponentName($id)
    method collectData (line 71) | public function collectData()

FILE: bridges/CarThrottleBridge.php
  class CarThrottleBridge (line 3) | class CarThrottleBridge extends BridgeAbstract
    method collectData (line 36) | public function collectData()
    method handleCategory (line 47) | private function handleCategory($category)
    method handleCategory2 (line 54) | private function handleCategory2($categoryParameter, $categoryURLname)
    method getArticles (line 61) | private function getArticles($category)
    method parseAuthor (line 104) | private function parseAuthor($articlePage)

FILE: bridges/CaschyBridge.php
  class CaschyBridge (line 3) | class CaschyBridge extends FeedExpander
    method collectData (line 29) | public function collectData()
    method parseItem (line 37) | protected function parseItem(array $item)
    method addArticleToItem (line 53) | private function addArticleToItem($item, $article)

FILE: bridges/CastorusBridge.php
  class CastorusBridge (line 3) | class CastorusBridge extends BridgeAbstract
    method extractActivityTitle (line 34) | private function extractActivityTitle($activity)
    method extractActivityUrl (line 46) | private function extractActivityUrl($activity)
    method extractActivityTime (line 58) | private function extractActivityTime($activity)
    method extractActivityPrice (line 76) | private function extractActivityPrice($activity)
    method collectData (line 87) | public function collectData()

FILE: bridges/CdactionBridge.php
  class CdactionBridge (line 3) | class CdactionBridge extends BridgeAbstract
    method collectData (line 36) | public function collectData()
    method processArticles (line 46) | private function processArticles(array $articles): void

FILE: bridges/CentreFranceBridge.php
  class CentreFranceBridge (line 3) | class CentreFranceBridge extends BridgeAbstract
    method collectData (line 56) | public function collectData()
    method collectArticleData (line 129) | private function collectArticleData($uri): array
    method getName (line 220) | public function getName()
    method getIcon (line 242) | public function getIcon()
    method detectParameters (line 251) | public function detectParameters($url)

FILE: bridges/CeskaTelevizeBridge.php
  class CeskaTelevizeBridge (line 3) | class CeskaTelevizeBridge extends BridgeAbstract
    method collectData (line 21) | public function collectData()
    method getUploadTimeFromString (line 59) | private function getUploadTimeFromString($string)
    method fixChars (line 73) | private function fixChars($text)
    method getURI (line 78) | public function getURI()
    method getName (line 83) | public function getName()

FILE: bridges/CodebergBridge.php
  class CodebergBridge (line 3) | class CodebergBridge extends BridgeAbstract
    method collectData (line 80) | public function collectData()
    method getName (line 110) | public function getName()
    method getURI (line 134) | public function getURI()
    method getBranch (line 154) | private function getBranch()
    method getRepo (line 163) | private function getRepo()
    method extractCommits (line 171) | private function extractCommits($html)
    method extractIssues (line 206) | private function extractIssues($html)
    method extractIssueComments (line 242) | private function extractIssueComments($html)
    method extractPulls (line 276) | private function extractPulls($html)
    method extractReleases (line 320) | private function extractReleases($html)
    method extractTags (line 353) | private function extractTags($html)
    method extractDownloads (line 371) | private function extractDownloads($html, $skipFirst = false)
    method ellipsisTitle (line 394) | private function ellipsisTitle($text)
    method stripSvg (line 408) | private function stripSvg($html)
    method detectParameters (line 420) | public function detectParameters($url)

FILE: bridges/CollegeDeFranceBridge.php
  class CollegeDeFranceBridge (line 3) | class CollegeDeFranceBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/ComboiosDePortugalBridge.php
  class ComboiosDePortugalBridge (line 5) | class ComboiosDePortugalBridge extends BridgeAbstract
    method collectData (line 42) | public function collectData()

FILE: bridges/ComickBridge.php
  class ComickBridge (line 3) | class ComickBridge extends BridgeAbstract
    method getComick (line 110) | private function getComick($url)
    method collectData (line 122) | public function collectData()
    method getName (line 171) | public function getName()
    method getURI (line 179) | public function getURI()

FILE: bridges/ComicsKingdomBridge.php
  class ComicsKingdomBridge (line 3) | class ComicsKingdomBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method getURI (line 51) | public function getURI()
    method getName (line 69) | public function getName()

FILE: bridges/CommonDreamsBridge.php
  class CommonDreamsBridge (line 3) | class CommonDreamsBridge extends FeedExpander
    method collectData (line 10) | public function collectData()
    method parseItem (line 15) | protected function parseItem(array $item)
    method extractContent (line 21) | private function extractContent($url)

FILE: bridges/CopieDoubleBridge.php
  class CopieDoubleBridge (line 3) | class CopieDoubleBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/CorreioDaFeiraBridge.php
  class CorreioDaFeiraBridge (line 3) | class CorreioDaFeiraBridge extends BridgeAbstract
    method getIcon (line 33) | public function getIcon()
    method getName (line 38) | public function getName()
    method getURI (line 43) | public function getURI()
    method collectData (line 48) | public function collectData()

FILE: bridges/CourrierInternationalBridge.php
  class CourrierInternationalBridge (line 3) | class CourrierInternationalBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 16) | protected function parseItem(array $item)

FILE: bridges/CraigslistBridge.php
  class CraigslistBridge (line 3) | class CraigslistBridge extends BridgeAbstract
    method detectParameters (line 45) | public function detectParameters($url)
    method getURI (line 55) | public function getURI()
    method collectData (line 64) | public function collectData()
    method getQueryResultsImages (line 105) | private function getQueryResultsImages($html): array

FILE: bridges/CrewbayBridge.php
  class CrewbayBridge (line 3) | class CrewbayBridge extends BridgeAbstract
    method collectData (line 109) | public function collectData()
    method getURI (line 215) | public function getURI()

FILE: bridges/CryptomeBridge.php
  class CryptomeBridge (line 3) | class CryptomeBridge extends BridgeAbstract
    method getIcon (line 19) | public function getIcon()
    method collectData (line 24) | public function collectData()

FILE: bridges/CssSelectorBridge.php
  class CssSelectorBridge (line 3) | class CssSelectorBridge extends BridgeAbstract
    method getURI (line 71) | public function getURI()
    method getName (line 80) | public function getName()
    method collectData (line 88) | public function collectData()
    method filterUrlList (line 133) | protected function filterUrlList($links, $url_pattern, $limit = 0)
    method getPageTitle (line 154) | protected function getPageTitle($page)
    method titleCleanup (line 169) | protected function titleCleanup($title, $title_cleanup)
    method cleanArticleContent (line 182) | protected function cleanArticleContent($content, $cleanup_selector)
    method htmlFindEntries (line 211) | protected function htmlFindEntries($page, $url_selector, $url_pattern ...
    method expandEntryWithSelector (line 274) | protected function expandEntryWithSelector($entry_url, $content_select...

FILE: bridges/CssSelectorComplexBridge.php
  class CssSelectorComplexBridge (line 3) | class CssSelectorComplexBridge extends BridgeAbstract
    method getURI (line 129) | public function getURI()
    method getName (line 138) | public function getName()
    method getHeaders (line 146) | protected function getHeaders()
    method collectData (line 157) | public function collectData()
    method filterUrlList (line 223) | protected function filterUrlList($links, $url_pattern, $limit = 0)
    method getTitle (line 245) | protected function getTitle($page, $title_cleanup)
    method cleanArticleContent (line 263) | protected function cleanArticleContent($content, $cleanup_selector, $r...
    method htmlFindEntryElements (line 302) | protected function htmlFindEntryElements($page, $entry_selector, $url_...
    method fetchArticleElementFromPage (line 356) | protected function fetchArticleElementFromPage($entry_url, $content_se...
    method parseTimeStrAsTimestamp (line 369) | protected function parseTimeStrAsTimestamp($timeStr, $format)
    method parseEntryElement (line 405) | protected function parseEntryElement(

FILE: bridges/CssSelectorFeedExpanderBridge.php
  class CssSelectorFeedExpanderBridge (line 3) | class CssSelectorFeedExpanderBridge extends CssSelectorBridge
    method collectData (line 49) | public function collectData()

FILE: bridges/CubariBridge.php
  class CubariBridge (line 3) | class CubariBridge extends BridgeAbstract
    method getName (line 20) | public function getName()
    method getURI (line 29) | public function getURI()
    method collectData (line 48) | public function collectData()
    method getEncodedGist (line 67) | protected function getEncodedGist()
    method getSanitizedHash (line 81) | private function getSanitizedHash($string)
    method getItemFromChapter (line 86) | protected function getItemFromChapter($chapnum, $chapter)

FILE: bridges/CubariProxyBridge.php
  class CubariProxyBridge (line 3) | class CubariProxyBridge extends BridgeAbstract
    method collectData (line 42) | public function collectData()
    method getName (line 107) | public function getName()
    method getURI (line 116) | public function getURI()
    method getIcon (line 125) | public function getIcon()

FILE: bridges/CybernewsBridge.php
  class CybernewsBridge (line 5) | class CybernewsBridge extends BridgeAbstract
    method collectData (line 14) | public function collectData()
    method fetchFullArticle (line 62) | private function fetchFullArticle(string $url): string

FILE: bridges/DRKBlutspendeBridge.php
  class DRKBlutspendeBridge (line 3) | class DRKBlutspendeBridge extends FeedExpander
    method collectData (line 60) | public function collectData()
    method parseItem (line 66) | protected function parseItem(array $item)
    method getURI (line 182) | public function getURI()
    method buildAppointmentsURI (line 190) | private function buildAppointmentsURI()
    method parseImages (line 199) | private function parseImages($parentElement): array
    method parseOffers (line 224) | private function parseOffers($offerElements): array
    method getCleanPlainText (line 255) | private function getCleanPlainText($htmlElement): string
    method explodeLines (line 263) | private function explodeLines(string $text): array

FILE: bridges/DacksnackBridge.php
  class DacksnackBridge (line 3) | class DacksnackBridge extends BridgeAbstract
    method getIcon (line 10) | public function getIcon()
    method parseSwedishDates (line 15) | private function parseSwedishDates($dateString)
    method collectData (line 53) | public function collectData()

FILE: bridges/DagensNyheterDirektBridge.php
  class DagensNyheterDirektBridge (line 3) | class DagensNyheterDirektBridge extends BridgeAbstract
    method getIcon (line 12) | public function getIcon()
    method collectData (line 17) | public function collectData()

FILE: bridges/DailymotionBridge.php
  class DailymotionBridge (line 3) | class DailymotionBridge extends BridgeAbstract
    method getIcon (line 45) | public function getIcon()
    method collectData (line 50) | public function collectData()
    method getName (line 76) | public function getName()
    method getURI (line 100) | public function getURI()
    method getPlaylistTitle (line 130) | private function getPlaylistTitle($id)
    method getApiUrl (line 137) | private function getApiUrl()

FILE: bridges/DailythanthiBridge.php
  class DailythanthiBridge (line 3) | class DailythanthiBridge extends BridgeAbstract
    method getName (line 41) | public function getName()
    method collectData (line 47) | public function collectData()
    method constructContent (line 72) | private function constructContent($url)

FILE: bridges/DanbooruBridge.php
  class DanbooruBridge (line 3) | class DanbooruBridge extends BridgeAbstract
    method getFullURI (line 31) | protected function getFullURI()
    method getTags (line 38) | protected function getTags($element)
    method getItemFromElement (line 43) | protected function getItemFromElement($element)
    method collectData (line 65) | public function collectData()

FILE: bridges/DarkReadingBridge.php
  class DarkReadingBridge (line 3) | class DarkReadingBridge extends FeedExpander
    method collectData (line 42) | public function collectData()
    method parseItem (line 49) | protected function parseItem(array $item)
    method extractArticleContent (line 62) | private function extractArticleContent($article)

FILE: bridges/DauphineLibereBridge.php
  class DauphineLibereBridge (line 3) | class DauphineLibereBridge extends FeedExpander
    method collectData (line 35) | public function collectData()
    method parseItem (line 46) | protected function parseItem(array $item)
    method extractContent (line 52) | private function extractContent($url)

FILE: bridges/DealabsBridge.php
  class DealabsBridge (line 3) | class DealabsBridge extends PepperBridgeAbstract

FILE: bridges/DemoBridge.php
  class DemoBridge (line 3) | class DemoBridge extends BridgeAbstract
    method collectData (line 37) | public function collectData()

FILE: bridges/DemosBerlinBridge.php
  class DemosBerlinBridge (line 3) | class DemosBerlinBridge extends BridgeAbstract
    method getIcon (line 20) | public function getIcon()
    method collectData (line 25) | public function collectData()
    method getSanitizedHash (line 59) | private function getSanitizedHash($string)

FILE: bridges/DerpibooruBridge.php
  class DerpibooruBridge (line 3) | class DerpibooruBridge extends BridgeAbstract
    method detectParameters (line 35) | public function detectParameters($url)
    method getName (line 56) | public function getName()
    method getURI (line 66) | public function getURI()
    method collectData (line 79) | public function collectData()

FILE: bridges/DesoutterBridge.php
  class DesoutterBridge (line 3) | class DesoutterBridge extends BridgeAbstract
    method getURI (line 133) | public function getURI()
    method getName (line 145) | public function getName()
    method collectData (line 150) | public function collectData()
    method getFullNewsArticle (line 190) | private function getFullNewsArticle($uri)
    method extractNewsLanguages (line 205) | private function extractNewsLanguages()
    method extractIndustryLanguages (line 231) | private function extractIndustryLanguages()

FILE: bridges/DeutscheWelleBridge.php
  class DeutscheWelleBridge (line 3) | class DeutscheWelleBridge extends FeedExpander
    method collectData (line 69) | public function collectData()
    method parseItem (line 74) | protected function parseItem(array $item)
    method unparseUrl (line 133) | private function unparseUrl($parsed_url)

FILE: bridges/DeutscherAeroClubBridge.php
  class DeutscherAeroClubBridge (line 3) | class DeutscherAeroClubBridge extends XPathAbstract
    method formatItemTimestamp (line 21) | protected function formatItemTimestamp($value)

FILE: bridges/DevToBridge.php
  class DevToBridge (line 3) | class DevToBridge extends BridgeAbstract
    method getURI (line 47) | public function getURI()
    method getIcon (line 65) | public function getIcon()
    method collectData (line 71) | public function collectData()
    method getName (line 113) | public function getName()
    method getFullArticle (line 122) | private function getFullArticle($url)

FILE: bridges/DeveloppezDotComBridge.php
  class DeveloppezDotComBridge (line 3) | class DeveloppezDotComBridge extends FeedExpander
    method collectData (line 169) | public function collectData()
    method parseItem (line 179) | protected function parseItem(array $item)
    method getRssUrl (line 219) | private function getRssUrl()
    method fixComaInTitle (line 232) | private function fixComaInTitle($txt)
    method extractFullText (line 242) | private function extractFullText($articleHTMLContent)
    method decodeParagraph (line 288) | private function decodeParagraph($p)
    method isHtmlTagNotTxt (line 332) | private function isHtmlTagNotTxt($txt)
    method formatParagraph (line 344) | private function formatParagraph($txt)
    method getAllVideoUrl (line 363) | private function getAllVideoUrl($item)
    method getVideoUrl (line 387) | private function getVideoUrl($p)

FILE: bridges/DiarioDeNoticiasBridge.php
  class DiarioDeNoticiasBridge (line 3) | class DiarioDeNoticiasBridge extends BridgeAbstract
    method getIcon (line 34) | public function getIcon()
    method getName (line 39) | public function getName()
    method getURI (line 51) | public function getURI()
    method collectData (line 63) | public function collectData()

FILE: bridges/DiarioDoAlentejoBridge.php
  class DiarioDoAlentejoBridge (line 3) | class DiarioDoAlentejoBridge extends BridgeAbstract
    method getIcon (line 26) | public function getIcon()
    method collectData (line 31) | public function collectData()

FILE: bridges/DiceBridge.php
  class DiceBridge (line 3) | class DiceBridge extends BridgeAbstract
    method getIcon (line 79) | public function getIcon()
    method collectData (line 84) | public function collectData()

FILE: bridges/DiscogsBridge.php
  class DiscogsBridge (line 3) | class DiscogsBridge extends BridgeAbstract
    method collectData (line 83) | public function collectData()
    method getURI (line 169) | public function getURI()
    method getName (line 174) | public function getName()

FILE: bridges/DjMagDotComBridge.php
  class DjMagDotComBridge (line 5) | class DjMagDotComBridge extends BridgeAbstract
    method getIcon (line 22) | public function getIcon()
    method getURI (line 27) | public function getURI()
    method parseDateString (line 32) | private function parseDateString($dateString)
    method fetchArticleDetails (line 58) | private function fetchArticleDetails($uri, $image, $title)
    method collectData (line 76) | public function collectData()

FILE: bridges/DockerHubBridge.php
  class DockerHubBridge (line 3) | class DockerHubBridge extends BridgeAbstract
    method detectParameters (line 52) | public function detectParameters($url)
    method collectData (line 74) | public function collectData()
    method getURI (line 103) | public function getURI()
    method getName (line 122) | public function getName()
    method getRepo (line 137) | private function getRepo()
    method getApiUrl (line 146) | private function getApiUrl()
    method getLayerUrl (line 165) | private function getLayerUrl($name, $digest)
    method getTagUrl (line 175) | private function getTagUrl($name)
    method getImagesTable (line 190) | private function getImagesTable($result)
    method getShortDigestId (line 223) | private function getShortDigestId($digest)

FILE: bridges/DonnonsBridge.php
  class DonnonsBridge (line 9) | class DonnonsBridge extends BridgeAbstract
    method collectData (line 36) | public function collectData()
    method collectDataByPage (line 45) | private function collectDataByPage($page)
    method getPageURI (line 106) | private function getPageURI($page)
    method getURI (line 118) | public function getURI()
    method getName (line 127) | public function getName()

FILE: bridges/DoujinStyleBridge.php
  class DoujinStyleBridge (line 3) | class DoujinStyleBridge extends BridgeAbstract
    method collectData (line 49) | public function collectData()
    method getURI (line 116) | public function getURI()

FILE: bridges/DribbbleBridge.php
  class DribbbleBridge (line 3) | class DribbbleBridge extends BridgeAbstract
    method getIcon (line 11) | public function getIcon()
    method collectData (line 17) | public function collectData()
    method fetchData (line 49) | private function fetchData($html)
    method findJsonForShot (line 84) | private function findJsonForShot($shot, $json)
    method getImageTag (line 95) | private function getImageTag($preview_path, $title)
    method getFullSizeImagePath (line 105) | private function getFullSizeImagePath($preview_path)

FILE: bridges/Drive2ruBridge.php
  class Drive2ruBridge (line 3) | class Drive2ruBridge extends BridgeAbstract
    method getUserContent (line 81) | private function getUserContent($url)
    method getLogbooksContent (line 106) | private function getLogbooksContent($url)
    method getNews (line 131) | private function getNews()
    method adjustContent (line 156) | private function adjustContent($content)
    method addCommentsLink (line 181) | private function addCommentsLink($content, $url)
    method addReadMoreLink (line 186) | private function addReadMoreLink($content, $url)
    method collectData (line 196) | public function collectData()
    method getName (line 221) | public function getName()
    method getIcon (line 226) | public function getIcon()

FILE: bridges/DuckDuckGoBridge.php
  class DuckDuckGoBridge (line 3) | class DuckDuckGoBridge extends BridgeAbstract
    method collectData (line 32) | public function collectData()

FILE: bridges/DuvarOrgBridge.php
  class DuvarOrgBridge (line 3) | class DuvarOrgBridge extends BridgeAbstract
    method collectData (line 35) | public function collectData()

FILE: bridges/EASeedBridge.php
  class EASeedBridge (line 3) | class EASeedBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/EBayBridge.php
  class EBayBridge (line 3) | class EBayBridge extends BridgeAbstract
    method getURI (line 25) | public function getURI()
    method getName (line 42) | public function getName()
    method collectData (line 65) | public function collectData()

FILE: bridges/EDDHPiRepsBridge.php
  class EDDHPiRepsBridge (line 3) | class EDDHPiRepsBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()
    method getIcon (line 29) | public function getIcon()
    method extractTexts (line 34) | private function extractTexts($nodes)
    method formatItemAuthor (line 51) | protected function formatItemAuthor($texts)
    method formatItemContent (line 57) | protected function formatItemContent($texts)
    method formatItemTitle (line 68) | protected function formatItemTitle($texts)
    method formatItemTimestamp (line 74) | protected function formatItemTimestamp($value)
    method formatItemUri (line 81) | protected function formatItemUri($value)

FILE: bridges/EDDHPresseschauBridge.php
  class EDDHPresseschauBridge (line 3) | class EDDHPresseschauBridge extends XPathAbstract
    method getIcon (line 21) | public function getIcon()
    method formatItemAuthor (line 26) | protected function formatItemAuthor($value)
    method formatItemTimestamp (line 33) | protected function formatItemTimestamp($value)

FILE: bridges/EZTVBridge.php
  class EZTVBridge (line 5) | class EZTVBridge extends BridgeAbstract
    method collectData (line 48) | public function collectData()
    method getEztvUri (line 85) | protected function getEztvUri()
    method getItemFromTorrent (line 98) | protected function getItemFromTorrent($torrent)

FILE: bridges/EconomistBridge.php
  class EconomistBridge (line 3) | class EconomistBridge extends FeedExpander
    method collectData (line 82) | public function collectData()
    method parseItem (line 106) | protected function parseItem(array $item)
    method processContent (line 142) | private function processContent($html, $elem)

FILE: bridges/EconomistWorldInBriefBridge.php
  class EconomistWorldInBriefBridge (line 3) | class EconomistWorldInBriefBridge extends BridgeAbstract
    method collectData (line 54) | public function collectData()
    method splitGobbets (line 91) | private function splitGobbets($gobbets)
    method mergeGobbets (line 117) | private function mergeGobbets($gobbets)
    method collectArticles (line 134) | private function collectArticles($articles)
    method addQuote (line 168) | private function addQuote($quote)
    method mergeEverything (line 181) | private function mergeEverything()

FILE: bridges/EdfPricesBridge.php
  class EdfPricesBridge (line 3) | class EdfPricesBridge extends BridgeAbstract
    method removeEmojisAndSpecialSpaces (line 42) | private function removeEmojisAndSpecialSpaces(string $text): string
    method tempo (line 66) | private function tempo(simple_html_dom $html, string $contractUri, int...
    method base (line 112) | private function base(simple_html_dom $html, string $contractUri, int ...
    method hphc (line 143) | private function hphc(simple_html_dom $html, string $contractUri, int ...
    method ejp (line 178) | private function ejp(simple_html_dom $html, string $contractUri, int $...
    method addSubscriptionPowerInfo (line 211) | private function addSubscriptionPowerInfo(simple_html_dom_node $tableP...
    method collectData (line 261) | public function collectData()

FILE: bridges/ElektroARGOSBridge.php
  class ElektroARGOSBridge (line 10) | class ElektroARGOSBridge extends BridgeAbstract
    method collectData (line 32) | public function collectData()
    method getURI (line 57) | public function getURI()
    method getKeywordUrlMap (line 82) | public function getKeywordUrlMap()
    method getName (line 96) | public function getName()
    method fixDate (line 124) | private function fixDate($date)
    method extractImages (line 137) | private function extractImages($article)
    method collectNews (line 159) | private function collectNews($html)
    method collectEvents (line 188) | private function collectEvents($html)
    method collectTopic (line 224) | private function collectTopic($html)
    method extractEventUri (line 260) | private function extractEventUri($article)
    method extractNewsUri (line 272) | private function extractNewsUri($article)
    method extractLetterUri (line 287) | private function extractLetterUri($article)
    method extractDate (line 306) | private function extractDate($article)
    method extractNewsDescription (line 321) | private function extractNewsDescription($article)
    method extractNewsDescription1 (line 336) | private function extractNewsDescription1($article)
    method extractNewsDescription2 (line 351) | private function extractNewsDescription2($article)
    method extractNewsDescription3 (line 366) | private function extractNewsDescription3($article)
    method extractNewsDescription4 (line 389) | private function extractNewsDescription4($article)
    method extractNewsDescription5 (line 403) | private function extractNewsDescription5($article)
    method extractNewsDescription6 (line 417) | private function extractNewsDescription6($article)
    method extractEventDescription (line 439) | private function extractEventDescription($article)
    method extractNewsTitle (line 453) | private function extractNewsTitle($article)
    method extractEventTitle (line 468) | private function extractEventTitle($article)
    method extractLetterDescription (line 483) | private function extractLetterDescription($article)
    method parseDateTimeFromString (line 500) | private function parseDateTimeFromString(string $dateString): ?DateTime
    method findValuesByKeySubstring (line 580) | private function findValuesByKeySubstring(string $text, array $map): a...
    method removeCzechDiacritics (line 612) | private function removeCzechDiacritics(string $text): string
    method formatTitleFromURI (line 634) | private function formatTitleFromURI(string $uri): string

FILE: bridges/EliteDangerousGalnetBridge.php
  class EliteDangerousGalnetBridge (line 3) | class EliteDangerousGalnetBridge extends BridgeAbstract
    method collectData (line 27) | public function collectData()

FILE: bridges/ElloBridge.php
  class ElloBridge (line 3) | class ElloBridge extends BridgeAbstract
    method collectData (line 30) | public function collectData()
    method findText (line 59) | private function findText($path)
    method getPostContent (line 70) | private function getPostContent($path)
    method getEnclosures (line 88) | private function getEnclosures($post, $postData)
    method getUsername (line 103) | private function getUsername($post, $postData)
    method getAPIKey (line 112) | private function getAPIKey()
    method getName (line 127) | public function getName()

FILE: bridges/ElsevierBridge.php
  class ElsevierBridge (line 3) | class ElsevierBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method getIcon (line 40) | public function getIcon(): string

FILE: bridges/EngadgetBridge.php
  class EngadgetBridge (line 3) | class EngadgetBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 18) | protected function parseItem(array $item)

FILE: bridges/EpicGamesFreeBridge.php
  class EpicGamesFreeBridge (line 3) | class EpicGamesFreeBridge extends BridgeAbstract
    method collectData (line 41) | public function collectData()
    method getURI (line 81) | public function getURI()

FILE: bridges/EpicgamesBridge.php
  class EpicgamesBridge (line 3) | class EpicgamesBridge extends BridgeAbstract
    method collectData (line 45) | public function collectData()

FILE: bridges/ErowallBridge.php
  class ErowallBridge (line 3) | class ErowallBridge extends BridgeAbstract
    method collectData (line 32) | public function collectData()
    method getPagedURI (line 82) | private function getPagedURI($pgnum)
    method getURI (line 87) | public function getURI()
    method getName (line 108) | public function getName()

FILE: bridges/EsquerdaNetBridge.php
  class EsquerdaNetBridge (line 6) | class EsquerdaNetBridge extends FeedExpander
    method collectData (line 29) | public function collectData()
    method parseItem (line 34) | protected function parseItem(array $item)
    method getURI (line 61) | public function getURI()
    method getIcon (line 67) | public function getIcon()

FILE: bridges/EstCeQuonMetEnProdBridge.php
  class EstCeQuonMetEnProdBridge (line 3) | class EstCeQuonMetEnProdBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/EtsyBridge.php
  class EtsyBridge (line 3) | class EtsyBridge extends BridgeAbstract
    method collectData (line 34) | public function collectData()
    method getURI (line 71) | public function getURI()

FILE: bridges/EuronewsBridge.php
  class EuronewsBridge (line 3) | class EuronewsBridge extends BridgeAbstract
    method collectData (line 48) | public function collectData()
    method getItemContent (line 88) | private function getItemContent($url)

FILE: bridges/ExecuteProgramBridge.php
  class ExecuteProgramBridge (line 3) | class ExecuteProgramBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()
    method getIcon (line 34) | public function getIcon()

FILE: bridges/ExplosmBridge.php
  class ExplosmBridge (line 3) | class ExplosmBridge extends BridgeAbstract
    method getIcon (line 20) | public function getIcon()
    method getURI (line 25) | public function getURI()
    method collectData (line 30) | public function collectData()

FILE: bridges/FB2Bridge.php
  class FB2Bridge (line 3) | class FB2Bridge extends BridgeAbstract
    method getIcon (line 24) | public function getIcon()
    method collectData (line 29) | public function collectData()
    method buildContent (line 231) | private function buildContent($pageContent)
    method getCookies (line 247) | private function getCookies($pageURL)
    method getPageInfos (line 271) | private function getPageInfos($page, $cookies)
    method getName (line 314) | public function getName()
    method getURI (line 324) | public function getURI()

FILE: bridges/FDroidRepoBridge.php
  class FDroidRepoBridge (line 3) | class FDroidRepoBridge extends BridgeAbstract
    method collectData (line 46) | public function collectData()
    method fetchData (line 61) | private function fetchData()
    method getAllUpdates (line 69) | private function getAllUpdates()
    method getPackage (line 130) | private function getPackage($package)
    method getURI (line 159) | public function getURI()
    method getName (line 173) | public function getName()
    method createAnchor (line 190) | private function createAnchor($url)

FILE: bridges/FFXIVLodestoneNewsBridge.php
  class FFXIVLodestoneNewsBridge (line 5) | class FFXIVLodestoneNewsBridge extends BridgeAbstract
    method getIcon (line 44) | public function getIcon()
    method collectData (line 49) | public function collectData()

FILE: bridges/FM4Bridge.php
  class FM4Bridge (line 3) | class FM4Bridge extends BridgeAbstract
    method getPageData (line 31) | private function getPageData($tag, $page)
    method collectData (line 62) | public function collectData()

FILE: bridges/FSecureBlogBridge.php
  class FSecureBlogBridge (line 3) | class FSecureBlogBridge extends BridgeAbstract
    method getURI (line 27) | public function getURI()
    method collectData (line 36) | public function collectData()
    method collectCategory (line 64) | private function collectCategory($category)
    method collectListing (line 77) | private function collectListing($url)
    method collectArticle (line 99) | private function collectArticle($url)

FILE: bridges/FabBridge.php
  class FabBridge (line 3) | class FabBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/FabriceBellardBridge.php
  class FabriceBellardBridge (line 3) | class FabriceBellardBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/FacebookBridge.php
  class FacebookBridge (line 3) | class FacebookBridge extends BridgeAbstract
    method getIcon (line 60) | public function getIcon()
    method getName (line 65) | public function getName()
    method detectParameters (line 84) | public function detectParameters($url)
    method getURI (line 116) | public function getURI()
    method collectData (line 146) | public function collectData()
    method collectGroupData (line 170) | private function collectGroupData()
    method sanitizeGroup (line 210) | private function sanitizeGroup($group)
    method validateHost (line 233) | private function validateHost($provided_host)
    method isPublicGroup (line 261) | private function isPublicGroup($html)
    method extractGroupName (line 268) | private function extractGroupName($html)
    method extractGroupPostURI (line 276) | private function extractGroupPostURI($post)
    method extractGroupPostContent (line 292) | private function extractGroupPostContent($post)
    method extractGroupPostAuthor (line 304) | private function extractGroupPostAuthor($post)
    method extractGroupPostEnclosures (line 312) | private function extractGroupPostEnclosures($post)
    method extractGroupPostTitle (line 334) | private function extractGroupPostTitle($post)
    method sanitizeUser (line 362) | private function sanitizeUser($user)
    method unescapeFacebookLink (line 390) | private function unescapeFacebookLink($content)
    method removeTrackingCodes (line 408) | private function removeTrackingCodes($content)
    method unescapeFacebookEmote (line 428) | private function unescapeFacebookEmote($content)
    method returnCaptchaMessage (line 473) | private function returnCaptchaMessage($captcha)
    method handleCaptchaResponse (line 512) | private function handleCaptchaResponse()
    method collectUserData (line 547) | private function collectUserData()

FILE: bridges/FallGuysBridge.php
  class FallGuysBridge (line 3) | class FallGuysBridge extends BridgeAbstract
    method collectData (line 38) | public function collectData()
    method getURI (line 132) | public function getURI()
    method getIcon (line 138) | public function getIcon()
    method requestJsonData (line 143) | private function requestJsonData(string $url, bool $useCache)

FILE: bridges/FanaticalBridge.php
  class FanaticalBridge (line 3) | class FanaticalBridge extends BridgeAbstract
    method collectData (line 26) | public function collectData()
    method getName (line 71) | public function getName()
    method getURI (line 78) | public function getURI()
    method getIcon (line 91) | public function getIcon()

FILE: bridges/FarsideNitterBridge.php
  class FarsideNitterBridge (line 3) | class FarsideNitterBridge extends FeedExpander
    method detectParameters (line 37) | public function detectParameters($url)
    method collectData (line 50) | public function collectData()
    method getRSS (line 55) | private function getRSS($attempt = 0)
    method parseItem (line 68) | protected function parseItem(array $item)
    method getName (line 87) | public function getName()
    method getURI (line 95) | public function getURI()

FILE: bridges/FeedExpanderExampleBridge.php
  class FeedExpanderExampleBridge (line 3) | class FeedExpanderExampleBridge extends FeedExpander
    method collectData (line 27) | public function collectData()

FILE: bridges/FeedExpanderTestBridge.php
  class FeedExpanderTestBridge (line 5) | class FeedExpanderTestBridge extends FeedExpander
    method collectData (line 14) | public function collectData()

FILE: bridges/FeedMergeBridge.php
  class FeedMergeBridge (line 3) | class FeedMergeBridge extends FeedExpander
    method collectData (line 43) | public function collectData()
    method getIcon (line 129) | public function getIcon()
    method getName (line 134) | public function getName()

FILE: bridges/FeedReducerBridge.php
  class FeedReducerBridge (line 3) | class FeedReducerBridge extends FeedExpander
    method collectData (line 24) | public function collectData()
    method getItems (line 34) | public function getItems()
    method getName (line 60) | public function getName()

FILE: bridges/FiaBridge.php
  class FiaBridge (line 3) | class FiaBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/FicbookBridge.php
  class FicbookBridge (line 3) | class FicbookBridge extends BridgeAbstract
    method getURI (line 41) | public function getURI()
    method getName (line 64) | public function getName()
    method collectData (line 81) | public function collectData()
    method collectSiteNews (line 103) | private function collectSiteNews($html)
    method collectCommentsData (line 114) | private function collectCommentsData($html)
    method collectUpdatesData (line 128) | private function collectUpdatesData($html)
    method fixDate (line 151) | private function fixDate($date)

FILE: bridges/FiderBridge.php
  class FiderBridge (line 3) | class FiderBridge extends BridgeAbstract
    method getName (line 36) | public function getName()
    method getURI (line 41) | public function getURI()
    method setTitle (line 46) | protected function setTitle($title)
    method getItem (line 54) | protected function getItem($post, $response = false, $first = false)
    method collectData (line 92) | public function collectData()

FILE: bridges/FilterBridge.php
  class FilterBridge (line 3) | class FilterBridge extends FeedExpander
    method collectData (line 82) | public function collectData()
    method parseItem (line 91) | protected function parseItem(array $item)
    method getURI (line 164) | public function getURI()
    method getName (line 173) | public function getName()

FILE: bridges/FinanzflussBridge.php
  class FinanzflussBridge (line 3) | class FinanzflussBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/FindACrewBridge.php
  class FindACrewBridge (line 3) | class FindACrewBridge extends BridgeAbstract
    method collectData (line 36) | public function collectData()
    method getURI (line 86) | public function getURI()

FILE: bridges/FirefoxAddonsBridge.php
  class FirefoxAddonsBridge (line 3) | class FirefoxAddonsBridge extends BridgeAbstract
    method collectData (line 23) | public function collectData()
    method getURI (line 75) | public function getURI()
    method getName (line 84) | public function getName()
    method removeLinkRedirects (line 96) | private function removeLinkRedirects($html)
    method detectParameters (line 106) | public function detectParameters($url)

FILE: bridges/FirefoxReleaseNotesBridge.php
  class FirefoxReleaseNotesBridge (line 3) | class FirefoxReleaseNotesBridge extends BridgeAbstract
    method getName (line 25) | public function getName()
    method collectData (line 31) | public function collectData()

FILE: bridges/FlaschenpostBridge.php
  class FlaschenpostBridge (line 3) | class FlaschenpostBridge extends BridgeAbstract
    method collectData (line 55) | public function collectData()
    method getName (line 202) | public function getName(): string
    method jsToJson (line 236) | private function jsToJson(string $js): string
    method addArticle (line 251) | private function addArticle($article, $product)
    method getIcon (line 314) | public function getIcon()
    method recursiveFind (line 320) | private function recursiveFind(array $haystack, $needle)
    method splitJsonObjects (line 348) | private function splitJsonObjects(string $json): array

FILE: bridges/FlashbackBridge.php
  class FlashbackBridge (line 3) | class FlashbackBridge extends BridgeAbstract
    method getName (line 63) | public function getName()
    method collectData (line 85) | public function collectData()

FILE: bridges/FlickrBridge.php
  class FlickrBridge (line 6) | class FlickrBridge extends BridgeAbstract
    method collectData (line 89) | public function collectData()
    method getURI (line 152) | public function getURI()
    method getName (line 178) | public function getName()
    method extractJsonModel (line 202) | private function extractJsonModel($html)
    method getPhotoModels (line 219) | private function getPhotoModels($json, $filter)
    method extractEnclosures (line 241) | private function extractEnclosures($model)
    method extractContentImage (line 253) | private function extractContentImage($model)
    method fixURL (line 275) | private function fixURL($url)

FILE: bridges/FliegermagazinBridge.php
  class FliegermagazinBridge (line 3) | class FliegermagazinBridge extends XPathAbstract

FILE: bridges/FolhaDeSaoPauloBridge.php
  class FolhaDeSaoPauloBridge (line 3) | class FolhaDeSaoPauloBridge extends FeedExpander
    method parseItem (line 32) | protected function parseItem(array $item)
    method collectData (line 55) | public function collectData()

FILE: bridges/ForGifsBridge.php
  class ForGifsBridge (line 3) | class ForGifsBridge extends FeedExpander
    method collectData (line 10) | public function collectData()
    method parseItem (line 15) | protected function parseItem(array $item)

FILE: bridges/ForensicArchitectureBridge.php
  class ForensicArchitectureBridge (line 3) | class ForensicArchitectureBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/Formula1Bridge.php
  class Formula1Bridge (line 3) | class Formula1Bridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()

FILE: bridges/FourchanBridge.php
  class FourchanBridge (line 3) | class FourchanBridge extends BridgeAbstract
    method getURI (line 25) | public function getURI()
    method collectData (line 34) | public function collectData()

FILE: bridges/FreeCodeCampBridge.php
  class FreeCodeCampBridge (line 3) | class FreeCodeCampBridge extends FeedExpander
    method collectData (line 12) | public function collectData()
    method parseItem (line 17) | protected function parseItem(array $item)

FILE: bridges/FreeTelechargerBridge.php
  class FreeTelechargerBridge (line 3) | class FreeTelechargerBridge extends BridgeAbstract
    method collectData (line 26) | public function collectData()
    method getName (line 59) | public function getName()
    method getURI (line 70) | public function getURI()
    method detectParameters (line 81) | public function detectParameters($url)

FILE: bridges/FunkBridge.php
  class FunkBridge (line 3) | class FunkBridge extends BridgeAbstract
    method collectData (line 26) | public function collectData()
    method collectArticle (line 47) | private function collectArticle($element)
    method detectParameters (line 62) | public function detectParameters($url)
    method getIcon (line 75) | public function getIcon()
    method getName (line 80) | public function getName()

FILE: bridges/FurAffinityBridge.php
  class FurAffinityBridge (line 3) | class FurAffinityBridge extends BridgeAbstract
    method detectParameters (line 610) | public function detectParameters($url)
    method getName (line 652) | public function getName()
    method getDescription (line 687) | public function getDescription()
    method getURI (line 720) | public function getURI()
    method collectData (line 760) | public function collectData()
    method postFASimpleHTMLDOM (line 819) | private function postFASimpleHTMLDOM($data)
    method getFASimpleHTMLDOM (line 837) | private function getFASimpleHTMLDOM($url, $cache = false)
    method saveLoggedInUser (line 854) | private function saveLoggedInUser($html)
    method itemsFromJournalList (line 866) | private function itemsFromJournalList($html, $limit)
    method itemsFromJournal (line 892) | private function itemsFromJournal($html)
    method itemsFromSubmissionList (line 913) | private function itemsFromSubmissionList($html, $limit)
    method setReferrerPolicy (line 979) | private function setReferrerPolicy(&$html)
    method isHiddenSubmission (line 992) | private function isHiddenSubmission($html)

FILE: bridges/FurAffinityUserBridge.php
  class FurAffinityUserBridge (line 3) | class FurAffinityUserBridge extends BridgeAbstract
    method collectData (line 31) | public function collectData()
    method getName (line 53) | public function getName()
    method getURI (line 58) | public function getURI()

FILE: bridges/FuturaSciencesBridge.php
  class FuturaSciencesBridge (line 3) | class FuturaSciencesBridge extends FeedExpander
    method collectData (line 82) | public function collectData()
    method parseItem (line 88) | protected function parseItem(array $item)
    method extractArticleContent (line 100) | private function extractArticleContent($article)
    method extractAuthor (line 161) | private function extractAuthor($article)

FILE: bridges/GBAtempBridge.php
  class GBAtempBridge (line 3) | class GBAtempBridge extends BridgeAbstract
    method collectData (line 23) | public function collectData()
    method fetchPostContent (line 80) | private function fetchPostContent($uri, $site_url)
    method buildItem (line 93) | private function buildItem($uri, $title, $author, $timestamp, $thumbna...
    method decodeHtmlEntities (line 107) | private function decodeHtmlEntities($text)
    method cleanupPostContent (line 114) | private function cleanupPostContent($content, $site_url)
    method findItemDate (line 123) | private function findItemDate($item)
    method findItemImage (line 133) | private function findItemImage($item, $selector)
    method getName (line 146) | public function getName()

FILE: bridges/GGDealsBridge.php
  class GGDealsBridge (line 5) | class GGDealsBridge extends BridgeAbstract
    method collectData (line 61) | public function collectData()
    method getName (line 105) | public function getName()
    method getURI (line 115) | public function getURI()

FILE: bridges/GOGBridge.php
  class GOGBridge (line 3) | class GOGBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()
    method buildGameContentPage (line 37) | private function buildGameContentPage($game)

FILE: bridges/GQMagazineBridge.php
  class GQMagazineBridge (line 10) | class GQMagazineBridge extends BridgeAbstract
    method getDomain (line 49) | private function getDomain()
    method getURI (line 61) | public function getURI()
    method findTitleOf (line 66) | private function findTitleOf($link)
    method collectData (line 78) | public function collectData()
    method loadFullArticle (line 126) | private function loadFullArticle($uri)
    method replaceUriInHtmlElement (line 137) | private function replaceUriInHtmlElement($element)

FILE: bridges/GULPProjekteBridge.php
  class GULPProjekteBridge (line 8) | class GULPProjekteBridge extends WebDriverAbstract
    method getBrowserOptions (line 22) | protected function getBrowserOptions()
    method clickAwayCookieBanner (line 33) | protected function clickAwayCookieBanner()
    method clickNextPage (line 45) | protected function clickNextPage()
    method getLogo (line 63) | protected function getLogo(RemoteWebElement $item)
    method getTimestamp (line 87) | protected function getTimestamp(string $timeAgo): int
    method collectData (line 121) | public function collectData()

FILE: bridges/GabBridge.php
  class GabBridge (line 3) | final class GabBridge extends BridgeAbstract
    method collectData (line 19) | public function collectData()
    method getName (line 39) | public function getName()
    method getURI (line 44) | public function getURI()
    method getUsername (line 49) | private function getUsername(): string

FILE: bridges/GameBananaBridge.php
  class GameBananaBridge (line 3) | class GameBananaBridge extends BridgeAbstract
    method getIcon (line 26) | public function getIcon()
    method collectData (line 33) | public function collectData()
    method getName (line 107) | public function getName()
    method getURI (line 116) | public function getURI()

FILE: bridges/GatesNotesBridge.php
  class GatesNotesBridge (line 3) | class GatesNotesBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()
    method getItemContent (line 50) | protected function getItemContent($articleUri)

FILE: bridges/GelbooruBridge.php
  class GelbooruBridge (line 3) | class GelbooruBridge extends BridgeAbstract
    method getFullURI (line 45) | protected function getFullURI()
    method buildThumbnailURI (line 59) | protected function buildThumbnailURI($element)
    method getItemFromElement (line 65) | protected function getItemFromElement($element)
    method collectData (line 93) | public function collectData()

FILE: bridges/GenshinImpactBridge.php
  class GenshinImpactBridge (line 3) | class GenshinImpactBridge extends BridgeAbstract
    method collectData (line 64) | public function collectData()
    method getIcon (line 100) | public function getIcon()

FILE: bridges/GettrBridge.php
  class GettrBridge (line 3) | class GettrBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method createContent (line 64) | private function createContent(\stdClass $post): string
    method getIcon (line 126) | public function getIcon()
    method processMetadata (line 134) | private function processMetadata(stdClass $post): void

FILE: bridges/GiphyBridge.php
  class GiphyBridge (line 3) | class GiphyBridge extends BridgeAbstract
    method getName (line 34) | public function getName()
    method getGiphyItems (line 43) | protected function getGiphyItems($entries)
    method collectData (line 67) | public function collectData()

FILE: bridges/GitHubGistBridge.php
  class GitHubGistBridge (line 3) | class GitHubGistBridge extends BridgeAbstract
    method getURI (line 23) | public function getURI()
    method getName (line 37) | public function getName()
    method collectData (line 42) | public function collectData()
    method fixContent (line 99) | private function fixContent($content)

FILE: bridges/GiteaBridge.php
  class GiteaBridge (line 8) | class GiteaBridge extends BridgeAbstract
    method getIcon (line 83) | public function getIcon()
    method getName (line 88) | public function getName()
    method getURI (line 106) | public function getURI()
    method collectData (line 156) | public function collectData()
    method collectReleasesData (line 188) | protected function collectReleasesData($html)
    method collectTagsData (line 203) | protected function collectTagsData($html)
    method collectCommitsData (line 216) | protected function collectCommitsData($html)
    method collectIssuesData (line 232) | protected function collectIssuesData($html)
    method collectSingleIssueOrPrData (line 259) | protected function collectSingleIssueOrPrData($html)
    method collectPullRequestsData (line 293) | protected function collectPullRequestsData($html)

FILE: bridges/GithubIssueBridge.php
  class GithubIssueBridge (line 3) | class GithubIssueBridge extends BridgeAbstract
    method getName (line 50) | public function getName()
    method getURI (line 70) | public function getURI()
    method buildGitHubIssueCommentUri (line 86) | private function buildGitHubIssueCommentUri($issue_number, $comment_id)
    method extractIssueEvent (line 99) | private function extractIssueEvent($issueNbr, $title, $comment)
    method extractIssueComment (line 136) | private function extractIssueComment($issueNbr, $title, $comment)
    method extractIssueComments (line 162) | private function extractIssueComments($issue)
    method collectData (line 201) | public function collectData()
    method detectParameters (line 289) | public function detectParameters($url)

FILE: bridges/GithubPackagesBridge.php
  class GithubPackagesBridge (line 5) | class GithubPackagesBridge extends BridgeAbstract
    method getPackageUri (line 54) | private function getPackageUri()
    method collectData (line 68) | public function collectData()
    method getName (line 139) | public function getName()
    method getUri (line 163) | public function getUri()

FILE: bridges/GithubPullRequestBridge.php
  class GitHubPullRequestBridge (line 3) | class GitHubPullRequestBridge extends GithubIssueBridge

FILE: bridges/GithubReleaseBridge.php
  class GitHubReleaseBridge (line 5) | class GitHubReleaseBridge extends BridgeAbstract
    method collectData (line 41) | public function collectData()
    method getName (line 105) | public function getName()
    method getURI (line 115) | public function getURI()
    method detectParameters (line 125) | public function detectParameters($url)

FILE: bridges/GithubSearchBridge.php
  class GithubSearchBridge (line 3) | class GithubSearchBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method getURI (line 77) | public function getURI()

FILE: bridges/GithubTrendingBridge.php
  class GithubTrendingBridge (line 3) | class GithubTrendingBridge extends BridgeAbstract
    method collectData (line 598) | public function collectData()
    method getName (line 627) | public function getName()
    method constructUrl (line 636) | private function constructUrl()

FILE: bridges/GitlabIssueBridge.php
  class GitlabIssueBridge (line 3) | class GitlabIssueBridge extends BridgeAbstract
    method getName (line 57) | public function getName()
    method getURI (line 76) | public function getURI()
    method getIcon (line 98) | public function getIcon()
    method collectData (line 103) | public function collectData()
    method parseIssueDescription (line 169) | private function parseIssueDescription()
    method parseMergeRequestDescription (line 193) | private function parseMergeRequestDescription()
    method fixImgSrc (line 217) | private function fixImgSrc($html)
    method parseAuthor (line 229) | private function parseAuthor($description_html)

FILE: bridges/GizmodoBridge.php
  class GizmodoBridge (line 3) | class GizmodoBridge extends FeedExpander
    method parseItem (line 11) | protected function parseItem(array $item)
    method collectData (line 34) | public function collectData()
    method stripTags (line 39) | private function stripTags($html)
    method handleFigureTags (line 54) | private function handleFigureTags($html)
    method handleIframeTags (line 75) | private function handleIframeTags($html)

FILE: bridges/GlassdoorBridge.php
  class GlassdoorBridge (line 3) | class GlassdoorBridge extends BridgeAbstract
    method getURI (line 69) | public function getURI()
    method collectData (line 81) | public function collectData()
    method collectBlogData (line 98) | private function collectBlogData($html, $limit)
    method collectReviewData (line 121) | private function collectReviewData($html, $limit)
    method filterCompanyURI (line 153) | private function filterCompanyURI($uri)

FILE: bridges/GlowficBridge.php
  class GlowficBridge (line 3) | class GlowficBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method getAPIURI (line 62) | private function getAPIURI()
    method getURI (line 68) | public function getURI()
    method getPost (line 74) | private function getPost()
    method getName (line 83) | public function getName()
    method getDescription (line 92) | public function getDescription()

FILE: bridges/GoAccessBridge.php
  class GoAccessBridge (line 3) | class GoAccessBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/GoComicsBridge.php
  class GoComicsBridge (line 5) | class GoComicsBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()
    method getURI (line 91) | public function getURI()
    method getName (line 100) | public function getName()

FILE: bridges/GogsBridge.php
  class GogsBridge (line 3) | class GogsBridge extends BridgeAbstract
    method getURI (line 66) | public function getURI()
    method getName (line 98) | public function getName()
    method getIcon (line 112) | public function getIcon()
    method collectData (line 117) | public function collectData()
    method collectCommitsData (line 141) | protected function collectCommitsData($html)
    method collectIssuesData (line 157) | protected function collectIssuesData($html)
    method collectSingleIssueData (line 185) | protected function collectSingleIssueData($html)
    method collectReleasesData (line 203) | protected function collectReleasesData($html)

FILE: bridges/GolemBridge.php
  class GolemBridge (line 3) | class GolemBridge extends FeedExpander
    method collectData (line 58) | public function collectData()
    method parseItem (line 66) | protected function parseItem(array $item)
    method extractContent (line 112) | private function extractContent($page, $prevcontent)

FILE: bridges/GoodreadsBridge.php
  class GoodreadsBridge (line 3) | class GoodreadsBridge extends BridgeAbstract
    method collectAuthorBooks (line 34) | private function collectAuthorBooks($url)
    method collectData (line 83) | public function collectData()

FILE: bridges/GoogleGroupsBridge.php
  class GoogleGroupsBridge (line 3) | class GoogleGroupsBridge extends XPathAbstract
    method getSourceUrl (line 43) | protected function getSourceUrl()
    method provideWebsiteContent (line 54) | protected function provideWebsiteContent()
    method detectParameters (line 61) | public function detectParameters($url)

FILE: bridges/GooglePlayStoreBridge.php
  class GooglePlayStoreBridge (line 3) | class GooglePlayStoreBridge extends BridgeAbstract
    method collectData (line 24) | public function collectData()
    method detectParameters (line 43) | public function detectParameters($url)

FILE: bridges/GoogleScholarBridge.php
  class GoogleScholarBridge (line 3) | class GoogleScholarBridge extends BridgeAbstract
    method getIcon (line 101) | public function getIcon()
    method collectData (line 106) | public function collectData()

FILE: bridges/GoogleSearchBridge.php
  class GoogleSearchBridge (line 3) | class GoogleSearchBridge extends BridgeAbstract
    method collectData (line 24) | public function collectData()
    method getURI (line 81) | public function getURI()
    method getName (line 98) | public function getName()

FILE: bridges/GovTrackBridge.php
  class GovTrackBridge (line 3) | class GovTrackBridge extends FeedExpander
    method collectData (line 27) | public function collectData()
    method parseItem (line 37) | protected function parseItem(array $item)
    method collectEvent (line 51) | private function collectEvent($uri, $limit)
    method getName (line 93) | public function getName()
    method getURI (line 102) | public function getURI()

FILE: bridges/GrandComicsDatabaseBridge.php
  class GrandComicsDatabaseBridge (line 3) | class GrandComicsDatabaseBridge extends BridgeAbstract
    method collectData (line 18) | public function collectData()

FILE: bridges/GroupBundNaturschutzBridge.php
  class GroupBundNaturschutzBridge (line 3) | class GroupBundNaturschutzBridge extends XPathAbstract
    method getSourceUrl (line 104) | protected function getSourceUrl()

FILE: bridges/HDWallpapersBridge.php
  class HDWallpapersBridge (line 3) | class HDWallpapersBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method getName (line 79) | public function getName()

FILE: bridges/HackerNewsUserThreadsBridge.php
  class HackerNewsUserThreadsBridge (line 3) | class HackerNewsUserThreadsBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()

FILE: bridges/HanimeBridge.php
  class HanimeBridge (line 3) | class HanimeBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/HarvardBusinessReviewBridge.php
  class HarvardBusinessReviewBridge (line 3) | class HarvardBusinessReviewBridge extends BridgeAbstract
    method collectData (line 21) | public function collectData()

FILE: bridges/HarvardHealthBlogBridge.php
  class HarvardHealthBlogBridge (line 3) | class HarvardHealthBlogBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method constructContent (line 49) | private function constructContent($url)

FILE: bridges/HashnodeBridge.php
  class HashnodeBridge (line 3) | class HashnodeBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()
    method getName (line 44) | public function getName()

FILE: bridges/HaveIBeenPwnedBridge.php
  class HaveIBeenPwnedBridge (line 10) | class HaveIBeenPwnedBridge extends BridgeAbstract
    method collectData (line 39) | public function collectData()
    method breachType (line 99) | private function breachType($breach)
    method orderBreaches (line 115) | private function orderBreaches()
    method createItems (line 130) | private function createItems()

FILE: bridges/HeiseBridge.php
  class HeiseBridge (line 3) | class HeiseBridge extends FeedExpander
    method collectData (line 123) | public function collectData()
    method parseItem (line 131) | protected function parseItem(array $item)
    method addArticleToItem (line 177) | private function addArticleToItem($item, $article)

FILE: bridges/HinduTamilBridge.php
  class HinduTamilBridge (line 3) | class HinduTamilBridge extends FeedExpander
    method getName (line 49) | public function getName()
    method collectData (line 55) | public function collectData()
    method parseItem (line 62) | protected function parseItem($item)
    method cleanContent (line 77) | private function cleanContent($content): string
    method getTimestamp (line 86) | private function getTimestamp($dom): ?string
    method getImage (line 92) | private function getImage($dom): string

FILE: bridges/HonkaiImpactSeaBridge.php
  class HonkaiImpactSeaBridge (line 3) | class HonkaiImpactSeaBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method getIcon (line 66) | public function getIcon()
    method getArticleUri (line 71) | private function getArticleUri($json_item)

FILE: bridges/HotUKDealsBridge.php
  class HotUKDealsBridge (line 3) | class HotUKDealsBridge extends PepperBridgeAbstract

FILE: bridges/HumbleBundleBridge.php
  class HumbleBundleBridge (line 3) | class HumbleBundleBridge extends BridgeAbstract
    method collectData (line 23) | public function collectData()
    method createChild (line 61) | private function createChild($dom, $body, $name = null, $val = null, $...
    method processBundle (line 75) | private function processBundle($item, $dom, $body)
    method getName (line 121) | public function getName()
    method getURI (line 128) | public function getURI()

FILE: bridges/HuntShowdownNewsBridge.php
  class HuntShowdownNewsBridge (line 3) | class HuntShowdownNewsBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/HytaleBridge.php
  class HytaleBridge (line 3) | class HytaleBridge extends BridgeAbstract
    method collectData (line 16) | public function collectData()
    method addBlogPost (line 46) | private function addBlogPost($blogPost)

FILE: bridges/I4wifiBridge.php
  class I4wifiBridge (line 8) | class I4wifiBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method getURI (line 48) | public function getURI()
    method getName (line 67) | public function getName()
    method fixDate (line 91) | private function fixDate($date)
    method extractImages (line 104) | private function extractImages($article)
    method collectNews (line 126) | private function collectNews($html)
    method extractNewsUri (line 156) | private function extractNewsUri($article)
    method extractNewsDate (line 171) | private function extractNewsDate($article)
    method extractNewsDescription (line 187) | private function extractNewsDescription($article)
    method extractNewsTitle (line 202) | private function extractNewsTitle($article)
    method parseDateTimeFromString (line 220) | private function parseDateTimeFromString(string $dateString): ?DateTime

FILE: bridges/IGNBridge.php
  class IGNBridge (line 3) | class IGNBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 18) | protected function parseItem(array $item)

FILE: bridges/IKWYDBridge.php
  class IKWYDBridge (line 3) | class IKWYDBridge extends BridgeAbstract
    method detectParameters (line 27) | public function detectParameters($url)
    method getName (line 48) | public function getName()
    method getURI (line 57) | public function getURI()
    method collectData (line 66) | public function collectData()

FILE: bridges/IPBBridge.php
  class IPBBridge (line 3) | class IPBBridge extends FeedExpander
    method getURI (line 36) | public function getURI()
    method collectData (line 41) | public function collectData()
    method isForum (line 83) | private function isForum($html)
    method isTopic (line 89) | private function isTopic($html)
    method collectForum (line 95) | private function collectForum($html)
    method collectForumList (line 114) | private function collectForumList($html)
    method collectForumTable (line 129) | private function collectForumTable($html)
    method collectTopic (line 148) | private function collectTopic($html, $limit)
    method collectTopicHistory (line 167) | private function collectTopicHistory($html, $limit, $callback)
    method collectTopicArticle (line 190) | private function collectTopicArticle($html, $firstrun = true)
    method collectTopicDiv (line 232) | private function collectTopicDiv($html, $firstrun = true)
    method findImages (line 282) | private function findImages($html)
    method scaleImages (line 294) | private function scaleImages($html, $width = 400, $height = 400)
    method fixContent (line 304) | private function fixContent($html)

FILE: bridges/IdealoBridge.php
  class IdealoBridge (line 3) | class IdealoBridge extends BridgeAbstract
    method getIcon (line 49) | public function getIcon()
    method getFeedTitle (line 58) | private function getFeedTitle()
    method convertPriceToFloat (line 96) | private function convertPriceToFloat($price)
    method getPriceTrend (line 116) | private function getPriceTrend($NewPrice, $OldPrice)
    method collectData (line 132) | public function collectData()
    method getName (line 279) | public function getName()
    method getURI (line 293) | public function getURI()

FILE: bridges/IdenticaBridge.php
  class IdenticaBridge (line 3) | class IdenticaBridge extends BridgeAbstract
    method collectData (line 19) | public function collectData()
    method getName (line 39) | public function getName()
    method getURI (line 48) | public function getURI()

FILE: bridges/ImgsedBridge.php
  class ImgsedBridge (line 3) | class ImgsedBridge extends BridgeAbstract
    method collectData (line 46) | public function collectData()
    method collectPosts (line 66) | private function collectPosts()
    method collectStories (line 116) | private function collectStories()
    method collectTaggeds (line 151) | private function collectTaggeds()
    method parseDate (line 205) | private function parseDate($content)
    method getURI (line 227) | public function getURI()
    method convertURLToInstagram (line 236) | private function convertURLToInstagram($url)
    method descriptionToTitle (line 240) | private function descriptionToTitle($description)
    method getName (line 245) | public function getName()
    method detectParameters (line 277) | public function detectParameters($url)

FILE: bridges/IndeedBridge.php
  class IndeedBridge (line 3) | class IndeedBridge extends BridgeAbstract
    method collectData (line 135) | public function collectData()
    method getURI (line 168) | public function getURI()
    method getName (line 183) | public function getName()
    method detectParameters (line 188) | public function detectParameters($url)

FILE: bridges/IndiegogoBridge.php
  class IndiegogoBridge (line 3) | class IndiegogoBridge extends BridgeAbstract
    method collectData (line 82) | public function collectData()
    method getCategories (line 106) | protected function getCategories()

FILE: bridges/InstagramBridge.php
  class InstagramBridge (line 3) | class InstagramBridge extends BridgeAbstract
    method getCacheTimeout (line 75) | public function getCacheTimeout()
    method getContents (line 84) | protected function getContents($uri)
    method getInstagramUserId (line 100) | protected function getInstagramUserId($username)
    method collectData (line 122) | public function collectData()
    method getInstagramSidecarData (line 229) | protected function getInstagramSidecarData($uri, $postTitle, $mediaInf...
    method getInstagramVideoData (line 257) | protected function getInstagramVideoData($uri, $mediaURI, $mediaInfo, ...
    method getTextContent (line 268) | protected function getTextContent($media)
    method getInstagramJSON (line 278) | protected function getInstagramJSON($uri)
    method getInstagramJSONFallback (line 324) | protected function getInstagramJSONFallback()
    method getName (line 349) | public function getName()
    method getURI (line 358) | public function getURI()
    method detectParameters (line 370) | public function detectParameters($url)

FILE: bridges/InstituteForTheStudyOfWarBridge.php
  class InstituteForTheStudyOfWarBridge (line 3) | class InstituteForTheStudyOfWarBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method processEntry (line 43) | private function processEntry($entry)

FILE: bridges/InstructablesBridge.php
  class InstructablesBridge (line 14) | class InstructablesBridge extends BridgeAbstract
    method collectData (line 238) | public function collectData()

FILE: bridges/InternationalInstituteForStrategicStudiesBridge.php
  class InternationalInstituteForStrategicStudiesBridge (line 3) | class InternationalInstituteForStrategicStudiesBridge extends BridgeAbst...
    method collectData (line 15) | public function collectData()
    method getContents (line 54) | private function getContents($uri)
    method getRenderArguments (line 92) | private function getRenderArguments($script_text)

FILE: bridges/InternetArchiveBridge.php
  class InternetArchiveBridge (line 3) | class InternetArchiveBridge extends BridgeAbstract
    method detectParameters (line 51) | public function detectParameters($url)
    method collectData (line 70) | public function collectData()
    method getURI (line 129) | public function getURI()
    method getName (line 138) | public function getName()
    method processUsername (line 148) | private function processUsername()
    method processUpload (line 157) | private function processUpload($result)
    method processReview (line 183) | private function processReview($result)
    method processWebArchives (line 205) | private function processWebArchives($result)
    method processCollection (line 222) | private function processCollection($result)
    method processHiddenDetails (line 242) | private function processHiddenDetails($html, $detailsDivNumber, $item)
    method processPosts (line 270) | private function processPosts($html)

FILE: bridges/InvestorsObserverBridge.php
  class InvestorsObserverBridge (line 5) | class InvestorsObserverBridge extends BridgeAbstract
    method collectData (line 14) | public function collectData()
    method fetchFullArticle (line 58) | private function fetchFullArticle(string $url): string

FILE: bridges/ItakuBridge.php
  class ItakuBridge (line 3) | class ItakuBridge extends BridgeAbstract
    method collectData (line 188) | public function collectData()
    method getName (line 335) | public function getName()
    method getURI (line 340) | public function getURI()
    method getImagesSearch (line 345) | private function getImagesSearch(array $opt)
    method getPostsSearch (line 379) | private function getPostsSearch(array $opt)
    method getFeedData (line 412) | private function getFeedData(array $opt, $ownerID = null)
    method getOwnerID (line 438) | private function getOwnerID($username)
    method getPost (line 446) | private function getPost($id, ?array $metadata = null)
    method getCommission (line 518) | private function getCommission($id, ?array $metadata = null)
    method getImage (line 590) | private function getImage($id /* array $metadata = null */) //$metadat...
    method getData (line 659) | private function getData(string $url, bool $cache = false, bool $getJS...
    method addItem (line 683) | private function addItem($item)

FILE: bridges/ItchioBridge.php
  class ItchioBridge (line 3) | class ItchioBridge extends BridgeAbstract
    method collectData (line 18) | public function collectData()

FILE: bridges/IvooxBridge.php
  class IvooxBridge (line 8) | class IvooxBridge extends BridgeAbstract
    method ivBridgeAddItem (line 25) | private function ivBridgeAddItem(
    method ivBridgeParseHtmlListing (line 45) | private function ivBridgeParseHtmlListing($html)
    method collectData (line 100) | public function collectData()

FILE: bridges/JapanExpoBridge.php
  class JapanExpoBridge (line 3) | class JapanExpoBridge extends BridgeAbstract
    method getIcon (line 17) | public function getIcon()
    method collectData (line 22) | public function collectData()
    method frenchPubDateToTimestamp (line 86) | private function frenchPubDateToTimestamp($date_to_parse)

FILE: bridges/JohannesBlickBridge.php
  class JohannesBlickBridge (line 3) | class JohannesBlickBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/JornalNBridge.php
  class JornalNBridge (line 3) | class JornalNBridge extends BridgeAbstract
    method getIcon (line 48) | public function getIcon()
    method getName (line 53) | public function getName()
    method getURI (line 61) | public function getURI()
    method collectData (line 66) | public function collectData()

FILE: bridges/JustETFBridge.php
  class JustETFBridge (line 3) | class JustETFBridge extends BridgeAbstract
    method collectData (line 51) | public function collectData()
    method getURI (line 67) | public function getURI()
    method getName (line 89) | public function getName()
    method fixDate (line 127) | private function fixDate($date)
    method extractImages (line 144) | private function extractImages($article)
    method collectNews (line 167) | private function collectNews($html)
    method extractNewsUri (line 203) | private function extractNewsUri($article)
    method extractNewsDate (line 211) | private function extractNewsDate($article)
    method extractNewsDescription (line 221) | private function extractNewsDescription($article)
    method extractNewsTitle (line 231) | private function extractNewsTitle($article)
    method extractFullArticleContent (line 239) | private function extractFullArticleContent($article)
    method extractFullArticleAuthor (line 266) | private function extractFullArticleAuthor($article)
    method collectProfile (line 278) | private function collectProfile($html)
    method extractProfileDate (line 291) | private function extractProfileDate($html)
    method extractProfileTitle (line 301) | private function extractProfileTitle($html)
    method extractProfileContent (line 309) | private function extractProfileContent($html)
    method extractProfileAuthor (line 348) | private function extractProfileAuthor($html)

FILE: bridges/JustWatchBridge.php
  class JustWatchBridge (line 3) | class JustWatchBridge extends BridgeAbstract
    method collectData (line 156) | public function collectData()
    method getURI (line 208) | public function getURI()
    method getName (line 213) | public function getName()
    method getIcon (line 221) | public function getIcon()

FILE: bridges/Kanali6Bridge.php
  class Kanali6Bridge (line 3) | class Kanali6Bridge extends XPathAbstract
    method getURI (line 18) | public function getURI()

FILE: bridges/KemonoBridge.php
  class KemonoBridge (line 3) | class KemonoBridge extends BridgeAbstract
    method isCoomer (line 43) | private function isCoomer()
    method baseURI (line 49) | private function baseURI()
    method getJson (line 57) | private function getJson(string $endpoint)
    method collectData (line 67) | public function collectData()
    method getName (line 105) | public function getName()
    method getURI (line 114) | public function getURI()

FILE: bridges/KernelBugTrackerBridge.php
  class KernelBugTrackerBridge (line 3) | class KernelBugTrackerBridge extends BridgeAbstract
    method getIcon (line 43) | public function getIcon()
    method collectData (line 48) | public function collectData()
    method getURI (line 110) | public function getURI()
    method getName (line 123) | public function getName()
    method inlineStyles (line 146) | private function inlineStyles($html)

FILE: bridges/KhinsiderBridge.php
  class KhinsiderBridge (line 3) | class KhinsiderBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/KilledbyGoogleBridge.php
  class KilledbyGoogleBridge (line 3) | class KilledbyGoogleBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()
    method handleJson (line 25) | private function handleJson($json)
    method orderItems (line 61) | private function orderItems()
    method limitItems (line 76) | private function limitItems()

FILE: bridges/KilledbyMicrosoftBridge.php
  class KilledbyMicrosoftBridge (line 3) | class KilledbyMicrosoftBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()
    method formatTitle (line 52) | private function formatTitle($name, $dateOpen, $dateClose)

FILE: bridges/KitsuBridge.php
  class KitsuBridge (line 3) | class KitsuBridge extends BridgeAbstract
    method collectData (line 48) | public function collectData()

FILE: bridges/KleinanzeigenBridge.php
  class KleinanzeigenBridge (line 3) | class KleinanzeigenBridge extends BridgeAbstract
    method getIcon (line 72) | public function getIcon()
    method getName (line 77) | public function getName()
    method collectData (line 89) | public function collectData()
    method addItem (line 137) | private function addItem($element)
    method findCategoryId (line 161) | private function findCategoryId()

FILE: bridges/KoFiBridge.php
  class KoFiBridge (line 3) | class KoFiBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method getFullContent (line 56) | private function getFullContent($html)
    method getPageId (line 75) | private function getPageId()

FILE: bridges/KonachanBridge.php
  class KonachanBridge (line 3) | class KonachanBridge extends MoebooruBridge

FILE: bridges/KoreusBridge.php
  class KoreusBridge (line 3) | class KoreusBridge extends FeedExpander
    method parseItem (line 10) | protected function parseItem(array $item)
    method collectData (line 19) | public function collectData()

FILE: bridges/KununuBridge.php
  class KununuBridge (line 3) | class KununuBridge extends BridgeAbstract
    method getURI (line 48) | public function getURI()
    method getName (line 60) | public function getName()
    method getIcon (line 70) | public function getIcon()
    method collectData (line 75) | public function collectData()
    method getAPI (line 105) | private function getAPI()
    method fixCompanyName (line 118) | private function fixCompanyName($company)
    method extractArticleDescription (line 133) | private function extractArticleDescription($json)

FILE: bridges/LWNprevBridge.php
  class LWNprevBridge (line 3) | class LWNprevBridge extends BridgeAbstract
    method getURI (line 13) | public function getURI()
    method jumpToNextTag (line 18) | private function jumpToNextTag(&$node)
    method jumpToPreviousTag (line 29) | private function jumpToPreviousTag(&$node)
    method collectData (line 40) | public function collectData()
    method getArticleContent (line 83) | private function getArticleContent(&$title)
    method getFeatureContents (line 118) | private function getFeatureContents(&$html)
    method getItemPrefix (line 143) | private function getItemPrefix(&$cat, &$cats)
    method getAnnouncements (line 191) | private function getAnnouncements(&$html)
    method getBriefItems (line 256) | private function getBriefItems(&$html)

FILE: bridges/LaCentraleBridge.php
  class LaCentraleBridge (line 3) | class LaCentraleBridge extends BridgeAbstract
    method collectData (line 417) | public function collectData()

FILE: bridges/LaTeX3ProjectNewslettersBridge.php
  class LaTeX3ProjectNewslettersBridge (line 3) | class LaTeX3ProjectNewslettersBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()
    method collectArticle (line 22) | private function collectArticle($element)
    method getIcon (line 33) | public function getIcon()

FILE: bridges/LeBonCoinBridge.php
  class LeBonCoinBridge (line 3) | class LeBonCoinBridge extends BridgeAbstract
    method getRange (line 335) | private function getRange($field, $range_min, $range_max)
    method collectData (line 358) | public function collectData()
    method buildRequestJson (line 422) | private function buildRequestJson()

FILE: bridges/LeMondeInformatiqueBridge.php
  class LeMondeInformatiqueBridge (line 3) | class LeMondeInformatiqueBridge extends FeedExpander
    method collectData (line 10) | public function collectData()
    method parseItem (line 15) | protected function parseItem(array $item)
    method cleanArticle (line 36) | private function cleanArticle($article_html)

FILE: bridges/LeagueOfLegendsNewsBridge.php
  class LeagueOfLegendsNewsBridge (line 3) | class LeagueOfLegendsNewsBridge extends BridgeAbstract
    method collectData (line 67) | public function collectData()
    method getSiteUrl (line 91) | private function getSiteUrl()
    method getArticleUri (line 108) | private function getArticleUri($href)

FILE: bridges/LegifranceJOBridge.php
  class LegifranceJOBridge (line 3) | class LegifranceJOBridge extends BridgeAbstract
    method collectData (line 17) | public function collectData()
    method extractItem (line 48) | private function extractItem($section, $subsection = null, $origin = n...
    method getIcon (line 77) | public function getIcon()

FILE: bridges/LegoIdeasBridge.php
  class LegoIdeasBridge (line 3) | class LegoIdeasBridge extends BridgeAbstract
    method getURI (line 35) | public function getURI()
    method collectData (line 45) | public function collectData()
    method getHttpPostURI (line 84) | private function getHttpPostURI()
    method getHttpPostData (line 92) | private function getHttpPostData()

FILE: bridges/LesJoiesDuCodeBridge.php
  class LesJoiesDuCodeBridge (line 3) | class LesJoiesDuCodeBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/LfcPlBridge.php
  class LfcPlBridge (line 3) | class LfcPlBridge extends BridgeAbstract
    method collectData (line 23) | public function collectData()
    method getContent (line 65) | private function getContent($article)
    method getImage (line 90) | private function getImage($article): ?string
    method withComment (line 106) | private function withComment(): bool

FILE: bridges/LinuxBlogBridge.php
  class LinuxBlogBridge (line 3) | class LinuxBlogBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()
    method constructContent (line 53) | private function constructContent($url)

FILE: bridges/ListverseBridge.php
  class ListverseBridge (line 3) | class ListverseBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 16) | protected function parseItem(array $item)

FILE: bridges/LogicMastersBridge.php
  class LogicMastersBridge (line 3) | class LogicMastersBridge extends XPathAbstract
    method formatItemTimestamp (line 21) | protected function formatItemTimestamp($value)

FILE: bridges/LolibooruBridge.php
  class LolibooruBridge (line 3) | class LolibooruBridge extends MoebooruBridge

FILE: bridges/LuftfahrtBundesAmtBridge.php
  class LuftfahrtBundesAmtBridge (line 3) | class LuftfahrtBundesAmtBridge extends XPathAbstract
    method provideFeedIcon (line 21) | protected function provideFeedIcon(\DOMXPath $xpath)
    method formatItemTimestamp (line 26) | protected function formatItemTimestamp($value)
    method formatItemUri (line 40) | protected function formatItemUri($value)

FILE: bridges/LuftsportSHBridge.php
  class LuftsportSHBridge (line 3) | class LuftsportSHBridge extends XPathAbstract
    method formatItemTimestamp (line 21) | protected function formatItemTimestamp($value)

FILE: bridges/MaalaimalarBridge.php
  class MaalaimalarBridge (line 3) | class MaalaimalarBridge extends BridgeAbstract
    method getName (line 71) | public function getName()
    method collectData (line 77) | public function collectData()
    method constructContent (line 103) | private function constructContent($article)

FILE: bridges/MagellantvBridge.php
  class MagellantvBridge (line 3) | class MagellantvBridge extends BridgeAbstract
    method getIcon (line 36) | public function getIcon()
    method retrieveTags (line 41) | private function retrieveTags($article)
    method collectData (line 53) | public function collectData()

FILE: bridges/MagicTheGatheringBridge.php
  class MagicTheGatheringBridge (line 5) | class MagicTheGatheringBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()

FILE: bridges/Mailman2Bridge.php
  class Mailman2Bridge (line 3) | class Mailman2Bridge extends BridgeAbstract
    method collectData (line 31) | public function collectData()
    method render (line 113) | private static function render($text)

FILE: bridges/MallTvBridge.php
  class MallTvBridge (line 3) | class MallTvBridge extends BridgeAbstract
    method fixChars (line 21) | private function fixChars($text)
    method getUploadTimeFromUrl (line 26) | private function getUploadTimeFromUrl($url)
    method collectData (line 38) | public function collectData()
    method getURI (line 67) | public function getURI()
    method getName (line 72) | public function getName()

FILE: bridges/MangaDexBridge.php
  class MangaDexBridge (line 3) | class MangaDexBridge extends BridgeAbstract
    method buildArrayQuery (line 88) | protected function buildArrayQuery($name, $array)
    method getAPI (line 97) | protected function getAPI()
    method getName (line 151) | public function getName()
    method getURI (line 163) | public function getURI()
    method collectData (line 173) | public function collectData()
    method getChapters (line 198) | protected function getChapters($content)

FILE: bridges/MangaReaderBridge.php
  class MangaReaderBridge (line 3) | class MangaReaderBridge extends BridgeAbstract
    method getName (line 32) | public function getName()
    method collectData (line 41) | public function collectData()

FILE: bridges/ManyVidsBridge.php
  class ManyVidsBridge (line 3) | class ManyVidsBridge extends BridgeAbstract
    method collectData (line 25) | public function collectData()
    method getName (line 95) | public function getName()
    method getUri (line 113) | public function getUri()

FILE: bridges/MarktplaatsBridge.php
  class MarktplaatsBridge (line 3) | class MarktplaatsBridge extends BridgeAbstract
    method collectData (line 118) | public function collectData()
    method getName (line 185) | public function getName()
    method scrapeSubCategories (line 196) | private static function scrapeSubCategories()
    method printArrayAsCode (line 241) | private static function printArrayAsCode($array, $indent = 0)
    method printScrapeArray (line 256) | private static function printScrapeArray()

FILE: bridges/MastodonBridge.php
  class MastodonBridge (line 3) | class MastodonBridge extends BridgeAbstract
    method collectData (line 67) | public function collectData()
    method parseStatus (line 92) | protected function parseStatus($content)
    method parseObject (line 165) | protected function parseObject($object, $item)
    method getName (line 213) | public function getName()
    method getInstance (line 221) | private function getInstance()
    method getUsername (line 227) | private function getUsername()
    method getURI (line 233) | public function getURI()
    method fetchAP (line 255) | protected function fetchAP($url)

FILE: bridges/MediapartBlogsBridge.php
  class MediapartBlogsBridge (line 3) | class MediapartBlogsBridge extends BridgeAbstract
    method getIcon (line 21) | public function getIcon()
    method collectData (line 26) | public function collectData()
    method getName (line 51) | public function getName()

FILE: bridges/MediapartBridge.php
  class MediapartBridge (line 3) | class MediapartBridge extends FeedExpander
    method collectData (line 26) | public function collectData()
    method parseItem (line 32) | protected function parseItem(array $item)

FILE: bridges/MicrosoftOfficeUpdatesBridge.php
  class MicrosoftOfficeUpdatesBridge (line 5) | class MicrosoftOfficeUpdatesBridge extends BridgeAbstract
    method getIcon (line 27) | public function getIcon()
    method getName (line 32) | public function getName()
    method collectData (line 38) | public function collectData(): void
    method collectContent (line 61) | private function collectContent($version): string

FILE: bridges/MilbooruBridge.php
  class MilbooruBridge (line 3) | class MilbooruBridge extends Shimmie2Bridge

FILE: bridges/MinecraftBridge.php
  class MinecraftBridge (line 5) | class MinecraftBridge extends BridgeAbstract
    method getIcon (line 28) | public function getIcon()
    method collectData (line 33) | public function collectData()
    method normalizeTags (line 73) | private function normalizeTags($tag)

FILE: bridges/MistralAIBridge.php
  class MistralAIBridge (line 3) | class MistralAIBridge extends BridgeAbstract
    method collectData (line 23) | public function collectData()
    method parsePage (line 36) | private function parsePage($url)

FILE: bridges/MixCloudBridge.php
  class MixCloudBridge (line 3) | class MixCloudBridge extends BridgeAbstract
    method getName (line 20) | public function getName()
    method compareDate (line 29) | private static function compareDate($stream1, $stream2)
    method collectData (line 34) | public function collectData()

FILE: bridges/MixologyBridge.php
  class MixologyBridge (line 3) | class MixologyBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()
    method parseTeaser (line 32) | protected function parseTeaser($teaser)
    method parseItem (line 54) | protected function parseItem(array $item)

FILE: bridges/ModelKarteiBridge.php
  class ModelKarteiBridge (line 3) | class ModelKarteiBridge extends BridgeAbstract
    method collectData (line 21) | public function collectData()
    method getName (line 111) | public function getName()

FILE: bridges/ModifyBridge.php
  class ModifyBridge (line 3) | class ModifyBridge extends FeedExpander
    method collectData (line 85) | public function collectData()
    method parseItem (line 94) | protected function parseItem(array $item)
    method buildPattern (line 151) | private function buildPattern($pattern)
    method getURI (line 168) | public function getURI()
    method getName (line 177) | public function getName()

FILE: bridges/ModrinthBridge.php
  class ModrinthBridge (line 7) | class ModrinthBridge extends BridgeAbstract
    method getURI (line 58) | public function getURI()
    method getName (line 69) | public function getName()
    method collectData (line 78) | public function collectData()
    method parseInputList (line 118) | protected function parseInputList($input): ?string

FILE: bridges/MoebooruBridge.php
  class MoebooruBridge (line 3) | class MoebooruBridge extends BridgeAbstract
    method getFullURI (line 22) | protected function getFullURI()
    method collectData (line 31) | public function collectData()

FILE: bridges/MoinMoinBridge.php
  class MoinMoinBridge (line 3) | class MoinMoinBridge extends BridgeAbstract
    method collectData (line 56) | public function collectData()
    method getName (line 148) | public function getName()
    method getURI (line 153) | public function getURI()
    method splitSections (line 166) | private function splitSections($html)
    method findSectionAnchor (line 207) | private function findSectionAnchor($section)
    method findAuthor (line 232) | private function findAuthor($html)
    method findTimestamp (line 258) | private function findTimestamp($html)
    method fixAnchors (line 277) | private function fixAnchors($html, $source = null)
    method followAnchor (line 304) | private function followAnchor($anchor)
    method findDomain (line 321) | private function findDomain($uri)
    method stripWithDelimiters (line 329) | private function stripWithDelimiters($string, $start, $end)
    method cleanArticle (line 341) | private function cleanArticle($article_html)

FILE: bridges/MondeDiploBridge.php
  class MondeDiploBridge (line 3) | class MondeDiploBridge extends BridgeAbstract
    method cleanText (line 11) | private function cleanText($text)
    method collectData (line 16) | public function collectData()
    method getItemTitle (line 38) | private function getItemTitle($title, $datesAuteurs)

FILE: bridges/MotatosBridge.php
  class MotatosBridge (line 3) | class MotatosBridge extends BridgeAbstract
    method getName (line 25) | public function getName()
    method getURI (line 43) | public function getURI()
    method getIcon (line 61) | public function getIcon()
    method getApiUrl (line 66) | private function getApiUrl()
    method collectData (line 82) | public function collectData()

FILE: bridges/MozillaBugTrackerBridge.php
  class MozillaBugTrackerBridge (line 3) | class MozillaBugTrackerBridge extends BridgeAbstract
    method getIcon (line 43) | public function getIcon()
    method collectData (line 48) | public function collectData()
    method getURI (line 107) | public function getURI()
    method getName (line 120) | public function getName()
    method inlineStyles (line 142) | private function inlineStyles($html)

FILE: bridges/MozillaSecurityBridge.php
  class MozillaSecurityBridge (line 3) | class MozillaSecurityBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/MsnMondeBridge.php
  class MsnMondeBridge (line 3) | class MsnMondeBridge extends FeedExpander
    method getName (line 13) | public function getName()
    method getURI (line 18) | public function getURI()
    method collectData (line 23) | public function collectData()
    method parseItem (line 28) | protected function parseItem(array $item)

FILE: bridges/MspabooruBridge.php
  class MspabooruBridge (line 3) | class MspabooruBridge extends GelbooruBridge
    method buildThumbnailURI (line 10) | protected function buildThumbnailURI($element)

FILE: bridges/MydealsBridge.php
  class MydealsBridge (line 3) | class MydealsBridge extends PepperBridgeAbstract

FILE: bridges/N26Bridge.php
  class N26Bridge (line 3) | class N26Bridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()
    method getIcon (line 39) | public function getIcon()

FILE: bridges/NACSouthGermanyMediaLibraryBridge.php
  class NACSouthGermanyMediaLibraryBridge (line 3) | class NACSouthGermanyMediaLibraryBridge extends BridgeAbstract
    method getIcon (line 32) | public function getIcon()
    method parseTimestamp (line 37) | private static function parseTimestamp($title)
    method collectDataForSWR1 (line 49) | private static function collectDataForSWR1($parent, $item)
    method collectDataForBayern2 (line 66) | private static function collectDataForBayern2($parent, $item)
    method collectDataInList (line 82) | private function collectDataInList($pageURI, $customizeItemCall)
    method collectDataFromAllPages (line 106) | private function collectDataFromAllPages($rootURI, $customizeItemCall)
    method collectData (line 115) | public function collectData()

FILE: bridges/NFLRUSBridge.php
  class NFLRUSBridge (line 3) | class NFLRUSBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/NHKWorldJapanShowBridge.php
  class NHKWorldJapanShowBridge (line 5) | class NHKWorldJapanShowBridge extends BridgeAbstract
    method getURI (line 181) | public function getURI()
    method getName (line 190) | public function getName()
    method getIcon (line 200) | public function getIcon()
    method collectData (line 205) | public function collectData()
    method detectParameters (line 266) | public function detectParameters($url)
    method getLocaleString (line 280) | protected function getLocaleString($string)

FILE: bridges/NOSBridge.php
  class NOSBridge (line 3) | class NOSBridge extends BridgeAbstract
    method collectData (line 37) | public function collectData()

FILE: bridges/NPRBridge.php
  class NPRBridge (line 3) | class NPRBridge extends FeedExpander
    method getIcon (line 164) | public function getIcon()
    method collectData (line 169) | public function collectData()
    method parseItem (line 175) | protected function parseItem(array $item)

FILE: bridges/NYTBridge.php
  class NYTBridge (line 3) | class NYTBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 17) | protected function parseItem(array $item)

FILE: bridges/NasaApodBridge.php
  class NasaApodBridge (line 3) | class NasaApodBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/NasestrechaBridge.php
  class NasestrechaBridge (line 9) | class NasestrechaBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method getURI (line 48) | public function getURI()
    method getName (line 67) | public function getName()
    method fixDate (line 91) | private function fixDate($date)
    method extractImages (line 104) | private function extractImages($article)
    method collectNews (line 126) | private function collectNews($html)
    method extractNewsUri (line 152) | private function extractNewsUri($article)
    method extractNewsDate (line 167) | private function extractNewsDate($article)
    method extractNewsDescription (line 185) | private function extractNewsDescription($article)
    method extractNewsTitle (line 200) | private function extractNewsTitle($article)
    method parseDateTimeFromString (line 218) | private function parseDateTimeFromString(string $dateString): ?DateTime

FILE: bridges/NationalGeographicBridge.php
  class NationalGeographicBridge (line 3) | class NationalGeographicBridge extends BridgeAbstract
    method getURI (line 50) | public function getURI()
    method getAPIURL (line 60) | private function getAPIURL($id)
    method collectData (line 69) | public function collectData()
    method getName (line 82) | public function getName()
    method getTopicName (line 92) | private function getTopicName($topic)
    method collectMagazine (line 97) | private function collectMagazine()
    method collectLatestStories (line 115) | private function collectLatestStories()
    method addStory (line 133) | private function addStory($story)
    method filterArticleData (line 180) | private function filterArticleData($data)
    method handleImages (line 211) | private function handleImages($image_module, $image_type)
    method getFullArticle (line 262) | private function getFullArticle($uri)

FILE: bridges/NautiljonBridge.php
  class NautiljonBridge (line 3) | class NautiljonBridge extends BridgeAbstract
    method formatDate (line 24) | private function formatDate($fright)
    method collectData (line 37) | public function collectData()

FILE: bridges/NewOnNetflixBridge.php
  class NewOnNetflixBridge (line 3) | class NewOnNetflixBridge extends BridgeAbstract
    method collectData (line 24) | public function collectData()

FILE: bridges/NewgroundsBridge.php
  class NewgroundsBridge (line 5) | class NewgroundsBridge extends BridgeAbstract
    method collectData (line 22) | public function collectData()
    method getName (line 66) | public function getName()
    method getURI (line 74) | public function getURI()

FILE: bridges/NextInkBridge.php
  class NextInkBridge (line 3) | class NextInkBridge extends FeedExpander
    method collectData (line 64) | public function collectData()
    method collectArticlesFromHtmlListing (line 89) | protected function collectArticlesFromHtmlListing($url, $limit)
    method parseItem (line 113) | protected function parseItem(array $item)

FILE: bridges/NextgovBridge.php
  class NextgovBridge (line 3) | class NextgovBridge extends FeedExpander
    method collectData (line 27) | public function collectData()
    method parseItem (line 34) | protected function parseItem(array $item)
    method extractContent (line 58) | private function extractContent($url)

FILE: bridges/NiceMatinBridge.php
  class NiceMatinBridge (line 3) | class NiceMatinBridge extends FeedExpander
    method collectData (line 10) | public function collectData()
    method parseItem (line 15) | protected function parseItem(array $item)
    method extractContent (line 21) | private function extractContent($url)

FILE: bridges/NikonDownloadCenterBridge.php
  class NikonDownloadCenterBridge (line 3) | class NikonDownloadCenterBridge extends BridgeAbstract
    method getURI (line 11) | public function getURI()
    method getIcon (line 17) | public function getIcon()
    method collectData (line 22) | public function collectData()

FILE: bridges/NineGagBridge.php
  class NineGagBridge (line 3) | class NineGagBridge extends BridgeAbstract
    method collectData (line 133) | public function collectData()
    method getName (line 181) | public function getName()
    method getURI (line 198) | public function getURI()
    method getGroup (line 208) | protected function getGroup()
    method getType (line 217) | protected function getType()
    method getPages (line 226) | protected function getPages()
    method getContent (line 239) | protected static function getContent($post)
    method getPhoto (line 252) | protected static function getPhoto($post)
    method getAnimated (line 271) | protected static function getAnimated($post)
    method getArticle (line 297) | protected static function getArticle($post)
    method getRichText (line 321) | protected static function getRichText($text = '')
    method getCategories (line 342) | protected static function getCategories($post)
    method getTimestamp (line 362) | protected static function getTimestamp($post)

FILE: bridges/NintendoBridge.php
  class NintendoBridge (line 3) | class NintendoBridge extends XPathAbstract
    method getCurrentCategory (line 350) | private function getCurrentCategory()
    method getIcon (line 359) | public function getIcon()
    method getURI (line 364) | public function getURI()
    method provideFeedTitle (line 374) | protected function provideFeedTitle(\DOMXPath $xpath)
    method getSourceUrl (line 381) | protected function getSourceUrl()
    method getExpressionItem (line 388) | protected function getExpressionItem()
    method getExpressionItemTimestamp (line 394) | protected function getExpressionItemTimestamp()
    method getExpressionItemCategories (line 409) | protected function getExpressionItemCategories()
    method collectData (line 416) | public function collectData()
    method formatItemTitle (line 437) | protected function formatItemTitle($value)
    method formatItemContent (line 450) | protected function formatItemContent($value)
    method formatItemTimestamp (line 460) | protected function formatItemTimestamp($value)
    method generateItemId (line 480) | protected function generateItemId(array $item)
    method getLanguageFromCountry (line 485) | private function getLanguageFromCountry($country)

FILE: bridges/NordbayernBridge.php
  class NordbayernBridge (line 3) | class NordbayernBridge extends BridgeAbstract
    method collectData (line 56) | public function collectData()
    method getValidImage (line 69) | private function getValidImage($picture)
    method getUseFullContent (line 81) | private function getUseFullContent($rawContent)
    method getTeaser (line 115) | private function getTeaser($content)
    method getArticle (line 127) | private function getArticle($link)
    method handleNewsblock (line 178) | private function handleNewsblock($listSite)

FILE: bridges/NotAlwaysBridge.php
  class NotAlwaysBridge (line 3) | class NotAlwaysBridge extends BridgeAbstract
    method getIcon (line 31) | public function getIcon()
    method collectData (line 36) | public function collectData()
    method getName (line 51) | public function getName()
    method getURI (line 60) | public function getURI()

FILE: bridges/NovayaGazetaEuropeBridge.php
  class NovayaGazetaEuropeBridge (line 3) | class NovayaGazetaEuropeBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()
    method convertBody (line 89) | private static function convertBody($data)
    method convertElement (line 110) | private static function convertElement($datum)

FILE: bridges/NovelUpdatesBridge.php
  class NovelUpdatesBridge (line 3) | class NovelUpdatesBridge extends BridgeAbstract
    method getURI (line 20) | public function getURI()
    method collectData (line 29) | public function collectData()
    method getName (line 52) | public function getName()

FILE: bridges/NpciBridge.php
  class NpciBridge (line 3) | class NpciBridge extends BridgeAbstract
    method getName (line 48) | public function getName()
    method getURI (line 56) | public function getURI()
    method collectData (line 62) | public function collectData()

FILE: bridges/NurembergerNachrichtenBridge.php
  class NurembergerNachrichtenBridge (line 3) | class NurembergerNachrichtenBridge extends BridgeAbstract
    method collectData (line 41) | public function collectData()
    method handleNewsblock (line 57) | private function handleNewsblock($listSite)
    method parseArticle (line 81) | private function parseArticle($article, $link)
    method getTeaser (line 121) | private function getTeaser($content)
    method getUseFullContent (line 133) | private function getUseFullContent($rawContent)
    method getValidImage (line 167) | private function getValidImage($picture)

FILE: bridges/NvidiaDriverBridge.php
  class NvidiaDriverBridge (line 3) | class NvidiaDriverBridge extends FeedExpander
    method collectData (line 53) | public function collectData()
    method getIcon (line 97) | public function getIcon()
    method getName (line 102) | public function getName()

FILE: bridges/NyaaTorrentsBridge.php
  class NyaaTorrentsBridge (line 3) | class NyaaTorrentsBridge extends BridgeAbstract
    method collectData (line 63) | public function collectData()
    method getName (line 91) | public function getName()
    method getIcon (line 100) | public function getIcon()
    method getURI (line 105) | public function getURI()

FILE: bridges/OLXBridge.php
  class OLXBridge (line 3) | class OLXBridge extends BridgeAbstract
    method getHostname (line 35) | private function getHostname()
    method getURI (line 43) | public function getURI()
    method getName (line 57) | public function getName()
    method collectData (line 82) | public function collectData()

FILE: bridges/OMonlineBridge.php
  class OMonlineBridge (line 3) | class OMonlineBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method extractDate2 (line 58) | private function extractDate2($text)

FILE: bridges/OglafBridge.php
  class OglafBridge (line 3) | class OglafBridge extends FeedExpander
    method collectData (line 20) | public function collectData()
    method parseItem (line 27) | protected function parseItem($item)

FILE: bridges/OllamaBridge.php
  class OllamaBridge (line 3) | class OllamaBridge extends BridgeAbstract
    method collectData (line 23) | public function collectData()
    method parsePage (line 45) | private function parsePage($uri)

FILE: bridges/OnVaSortirBridge.php
  class OnVaSortirBridge (line 3) | class OnVaSortirBridge extends FeedExpander
    method collectData (line 120) | public function collectData()
    method parseItem (line 126) | protected function parseItem(array $item)

FILE: bridges/OneFortuneADayBridge.php
  class OneFortuneADayBridge (line 3) | class OneFortuneADayBridge extends BridgeAbstract
    method getDescription (line 50) | public function getDescription()
    method collectData (line 55) | public function collectData()
    method getQuote (line 77) | private function getQuote($seed)

FILE: bridges/OpenCVEBridge.php
  class OpenCVEBridge (line 3) | class OpenCVEBridge extends BridgeAbstract
    method collectData (line 115) | public function collectData()
    method getTitle (line 194) | private function getTitle($titlePrefix, $cveItem)
    method fetchContents (line 204) | private function fetchContents($cveItem, $titlePrefix, $instance, $aut...
    method getTitleFromDatum (line 249) | private function getTitleFromDatum($datum, $titlePrefix)
    method getCVSSLabels (line 274) | private function getCVSSLabels($datum)
    method formatCVSSLabel (line 296) | private function formatCVSSLabel($score, $version, $critical_thr, $hig...
    method getLinks (line 321) | private function getLinks($id)
    method cvssV3VectorToTable (line 335) | private function cvssV3VectorToTable($cvssVector)
    method cvssV2VectorToTable (line 397) | private function cvssV2VectorToTable($cvssVector)
    method cvssV4VectorToTable (line 479) | private function cvssV4VectorToTable($cvssVector)
    method getVendors (line 556) | private function getVendors($datum)

FILE: bridges/OpenwhydBridge.php
  class OpenwhydBridge (line 3) | class OpenwhydBridge extends BridgeAbstract
    method getIcon (line 21) | public function getIcon()
    method collectData (line 26) | public function collectData()
    method getName (line 62) | public function getName()

FILE: bridges/OpenwrtSecurityBridge.php
  class OpenwrtSecurityBridge (line 3) | class OpenwrtSecurityBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()
    method getDate (line 35) | private function getDate($href)

FILE: bridges/OtrkeyFinderBridge.php
  class OtrkeyFinderBridge (line 3) | class OtrkeyFinderBridge extends BridgeAbstract
    method collectData (line 68) | public function collectData()
    method buildUri (line 92) | private function buildUri($page)
    method buildItem (line 106) | private function buildItem(simple_html_dom_node $node)
    method getFilename (line 165) | private function getFilename(simple_html_dom_node $node)
    method buildContent (line 184) | private function buildContent(simple_html_dom_node $node)

FILE: bridges/OvertakeBridge.php
  class OvertakeBridge (line 3) | class OvertakeBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 16) | protected function parseItem(array $item)

FILE: bridges/PanneauPocketBridge.php
  class PanneauPocketBridge (line 5) | class PanneauPocketBridge extends BridgeAbstract
    method getName (line 24) | public function getName()
    method collectData (line 29) | public function collectData()
    method extractCityName (line 69) | private function extractCityName($dom)
    method extractDate (line 92) | private function extractDate($text)

FILE: bridges/ParksOnTheAirBridge.php
  class ParksOnTheAirBridge (line 3) | class ParksOnTheAirBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/ParlerBridge.php
  class ParlerBridge (line 3) | final class ParlerBridge extends BridgeAbstract
    method collectData (line 22) | public function collectData()

FILE: bridges/ParuVenduImmoBridge.php
  class ParuVenduImmoBridge (line 3) | class ParuVenduImmoBridge extends BridgeAbstract
    method collectData (line 29) | public function collectData()
    method getURI (line 71) | public function getURI()
    method getName (line 98) | public function getName()

FILE: bridges/PatreonBridge.php
  class PatreonBridge (line 3) | class PatreonBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method findInclude (line 256) | private function findInclude($data, $type, $id)
    method apiGet (line 265) | private function apiGet($endpoint, $query_data = [])
    method getName (line 300) | public function getName()
    method getURI (line 315) | public function getURI()
    method detectParameters (line 324) | public function detectParameters($url)

FILE: bridges/PaulGrahamBridge.php
  class PaulGrahamBridge (line 3) | class PaulGrahamBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/PcGamerBridge.php
  class PcGamerBridge (line 3) | class PcGamerBridge extends BridgeAbstract
    method collectData (line 17) | public function collectData()

FILE: bridges/PepperBridgeAbstract.php
  class PepperBridgeAbstract (line 3) | class PepperBridgeAbstract extends BridgeAbstract
    method collectData (line 7) | public function collectData()
    method collectDataGroup (line 25) | protected function collectDataGroup()
    method collectDataKeywords (line 34) | protected function collectDataKeywords()
    method collectDeals (line 44) | protected function collectDeals($url)
    method collectDataTalk (line 102) | protected function collectDataTalk()
    method getCookiesHeaderValue (line 198) | private function getCookiesHeaderValue($url)
    method contains (line 211) | private function contains($str, array $arr)
    method getPrice (line 225) | private function getPrice($jsonDealData)
    method getPublishedDate (line 240) | private function getPublishedDate($jsonDealData)
    method getDealAuthor (line 249) | private function getDealAuthor($jsonDealData)
    method getTitle (line 258) | private function getTitle($jsonDealData)
    method getTalkTitle (line 268) | private function getTalkTitle()
    method getGroupTitle (line 286) | private function getGroupTitle()
    method getHTMLTitle (line 308) | private function getHTMLTitle($jsonDealData)
    method getDealURI (line 320) | private function getDealURI($jsonDealData)
    method getShippingCost (line 332) | private function getShippingCost($jsonDealData)
    method getTemperature (line 349) | private function getTemperature($data)
    method getDealJsonData (line 359) | private function getDealJsonData($deal)
    method getSource (line 369) | private function getSource($jsonData)
    method getDiscount (line 384) | private function getDiscount($jsonDealData)
    method getDealLocation (line 409) | private function getDealLocation($jsonDealData)
    method getImage (line 423) | private function getImage($deal)
    method getShipsFrom (line 438) | private function getShipsFrom($dealMeta)
    method getName (line 457) | public function getName()
    method getURI (line 478) | public function getURI()
    method getSearchURI (line 499) | private function getSearchURI()
    method getGroupURI (line 526) | private function getGroupURI()
    method getTalkURI (line 548) | private function getTalkURI()
    method i8n (line 559) | protected function i8n($key)

FILE: bridges/PhoronixBridge.php
  class PhoronixBridge (line 3) | class PhoronixBridge extends FeedExpander
    method collectData (line 27) | public function collectData()
    method parseItem (line 32) | protected function parseItem(array $item)
    method extractContent (line 55) | private function extractContent($page)

FILE: bridges/PicalaBridge.php
  class PicalaBridge (line 3) | class PicalaBridge extends BridgeAbstract
    method getURI (line 25) | public function getURI()
    method getIcon (line 34) | public function getIcon()
    method getDescription (line 39) | public function getDescription()
    method getName (line 48) | public function getName()
    method collectData (line 57) | public function collectData()

FILE: bridges/PicartoBridge.php
  class PicartoBridge (line 3) | class PicartoBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()
    method getName (line 37) | public function getName()

FILE: bridges/PickyWallpapersBridge.php
  class PickyWallpapersBridge (line 3) | class PickyWallpapersBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()
    method getURI (line 75) | public function getURI()
    method getName (line 92) | public function getName()

FILE: bridges/PicnobBridge.php
  class PicnobBridge (line 3) | class PicnobBridge extends BridgeAbstract
    method getURI (line 32) | public function getURI()
    method collectData (line 45) | public function collectData()
    method getName (line 94) | public function getName()

FILE: bridges/PicukiBridge.php
  class PicukiBridge (line 3) | class PicukiBridge extends BridgeAbstract
    method getURI (line 36) | public function getURI()
    method collectData (line 49) | public function collectData()
    method getName (line 117) | public function getName()

FILE: bridges/PikabuBridge.php
  class PikabuBridge (line 3) | class PikabuBridge extends BridgeAbstract
    method getURI (line 48) | public function getURI()
    method getIcon (line 65) | public function getIcon()
    method getName (line 70) | public function getName()
    method collectData (line 79) | public function collectData()

FILE: bridges/PillowfortBridge.php
  class PillowfortBridge (line 3) | class PillowfortBridge extends BridgeAbstract
    method collectData (line 52) | public function collectData()
    method getName (line 69) | public function getName()
    method getURI (line 79) | public function getURI()
    method getJSONURI (line 89) | protected function getJSONURI()
    method getUsername (line 94) | protected function getUsername()
    method genAvatarText (line 99) | protected function genAvatarText($author, $avatar_url, $title)
    method genImagesText (line 118) | protected function genImagesText($media)
    method getItemFromPost (line 172) | protected function getItemFromPost($post)

FILE: bridges/PinterestBridge.php
  class PinterestBridge (line 3) | class PinterestBridge extends FeedExpander
    method getIcon (line 25) | public function getIcon()
    method collectData (line 30) | public function collectData()
    method fixLowRes (line 36) | private function fixLowRes()
    method getURI (line 50) | public function getURI()
    method getName (line 59) | public function getName()

FILE: bridges/PirateCommunityBridge.php
  class PirateCommunityBridge (line 3) | class PirateCommunityBridge extends BridgeAbstract
    method detectParameters (line 21) | public function detectParameters($url)
    method getName (line 43) | public function getName()
    method getURI (line 52) | public function getURI()
    method collectData (line 64) | public function collectData()

FILE: bridges/PixivBridge.php
  class PixivBridge (line 7) | class PixivBridge extends BridgeAbstract
    method getName (line 87) | public function getName()
    method getURI (line 104) | public function getURI()
    method getSearchURI (line 122) | private function getSearchURI($mode)
    method getDataFromJSON (line 139) | private function getDataFromJSON($json, $json_key)
    method collectWorksArray (line 180) | private function collectWorksArray()
    method collectData (line 197) | public function collectData()
    method checkOptions (line 275) | private function checkOptions()
    method checkCookie (line 298) | private function checkCookie(array $headers)
    method getCookie (line 313) | private function getCookie()
    method getData (line 327) | private function getData(string $url, bool $cache = true, bool $getJSO...

FILE: bridges/PlantUMLReleasesBridge.php
  class PlantUMLReleasesBridge (line 8) | class PlantUMLReleasesBridge extends BridgeAbstract
    method getURI (line 19) | public function getURI()
    method collectData (line 24) | public function collectData()

FILE: bridges/PokemonNewsBridge.php
  class PokemonNewsBridge (line 5) | final class PokemonNewsBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/PornhubBridge.php
  class PornhubBridge (line 3) | class PornhubBridge extends BridgeAbstract
    method getName (line 44) | public function getName()
    method collectData (line 53) | public function collectData()

FILE: bridges/PresidenciaPTBridge.php
  class PresidenciaPTBridge (line 3) | class PresidenciaPTBridge extends BridgeAbstract
    method getIcon (line 48) | public function getIcon()
    method collectData (line 53) | public function collectData()

FILE: bridges/PriviblurBridge.php
  class PriviblurBridge (line 3) | class PriviblurBridge extends BridgeAbstract
    method collectData (line 22) | public function collectData()
    method getName (line 62) | public function getName()
    method getURI (line 71) | public function getURI()
    method getIcon (line 76) | public function getIcon()

FILE: bridges/QnapBridge.php
  class QnapBridge (line 5) | final class QnapBridge extends BridgeAbstract
    method collectData (line 16) | public function collectData()

FILE: bridges/QwantzBridge.php
  class QwantzBridge (line 3) | class QwantzBridge extends FeedExpander
    method collectData (line 9) | public function collectData()
    method parseItem (line 14) | protected function parseItem(array $item)
    method getIcon (line 32) | public function getIcon()

FILE: bridges/QwenBlogBridge.php
  class QwenBlogBridge (line 3) | class QwenBlogBridge extends FeedExpander
    method collectData (line 22) | public function collectData()
    method parseItem (line 27) | protected function parseItem(array $item)

FILE: bridges/QwerteeBridge.php
  class QwerteeBridge (line 3) | class QwerteeBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()

FILE: bridges/RadioFranceBridge.php
  class RadioFranceBridge (line 11) | class RadioFranceBridge extends BridgeAbstract
    method getDomain (line 38) | private function getDomain()
    method getURI (line 50) | public function getURI()
    method collectData (line 55) | public function collectData()
    method readAuthorsNamesFrom (line 127) | private function readAuthorsNamesFrom($persons_array)
    method convertJsonElementToHTML (line 140) | private function convertJsonElementToHTML($jsonElement)
    method convertJsonChildrenToHTML (line 177) | private function convertJsonChildrenToHTML($children)
    method removeAds (line 185) | private function removeAds($element)
    method replaceUriInHtmlElement (line 199) | private function replaceUriInHtmlElement($element)

FILE: bridges/RadioMelodieBridge.php
  class RadioMelodieBridge (line 3) | class RadioMelodieBridge extends BridgeAbstract
    method getIcon (line 10) | public function getIcon()
    method collectData (line 15) | public function collectData()
    method rewriteImage (line 103) | private function rewriteImage($url)
    method rewriteAudioPlayers (line 113) | private function rewriteAudioPlayers($html)
    method parseDate (line 138) | private function parseDate($date_fr)

FILE: bridges/RainLoopBridge.php
  class RainLoopBridge (line 3) | class RainLoopBridge extends BridgeAbstract
    method collectData (line 12) | public function collectData()

FILE: bridges/RainbowSixSiegeBridge.php
  class RainbowSixSiegeBridge (line 3) | class RainbowSixSiegeBridge extends BridgeAbstract
    method getIcon (line 14) | public function getIcon()
    method collectData (line 19) | public function collectData()

FILE: bridges/RedditBridge.php
  class RedditBridge (line 8) | class RedditBridge extends BridgeAbstract
    method collectData (line 115) | public function collectData()
    method collectDataInternal (line 143) | private function collectDataInternal(): void
    method createUrl (line 302) | public static function createUrl($search, $flareInput, $subreddit, boo...
    method getIcon (line 328) | public function getIcon()
    method getName (line 333) | public function getName()
    method urlEncodePathParts (line 344) | private function urlEncodePathParts($link)
    method createFigureLink (line 349) | private function createFigureLink($href, $src, $caption)
    method createLink (line 354) | private function createLink($href, $text)
    method createVideoContent (line 359) | private function createVideoContent(\stdClass $video): string
    method detectParameters (line 369) | public function detectParameters($url)

FILE: bridges/Releases3DSBridge.php
  class Releases3DSBridge (line 3) | class Releases3DSBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()
    method collectDataUrl (line 16) | protected function collectDataUrl($dataUrl)
    method typeToString (line 94) | private function typeToString($type)
    method cardToString (line 106) | private function cardToString($card)

FILE: bridges/ReleasesSwitchBridge.php
  class ReleasesSwitchBridge (line 8) | class ReleasesSwitchBridge extends Releases3DSBridge
    method collectData (line 14) | public function collectData()

FILE: bridges/RemixAudioBridge.php
  class RemixAudioBridge (line 3) | class RemixAudioBridge extends BridgeAbstract
    method collectData (line 27) | public function collectData()
    method getIcon (line 57) | public function getIcon()
    method getName (line 66) | public function getName()
    method getURI (line 75) | public function getURI()
    method getUser (line 85) | private function getUser($html)
    method getProfile (line 93) | private function getProfile()

FILE: bridges/ReporterreBridge.php
  class ReporterreBridge (line 6) | class ReporterreBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()
    method extractContent (line 34) | private function extractContent($url)

FILE: bridges/ReutersBridge.php
  class ReutersBridge (line 3) | class ReutersBridge extends BridgeAbstract
    method collectData (line 146) | public function collectData()
    method processData (line 244) | private function processData($data)
    method getSectionEndpoint (line 287) | private function getSectionEndpoint()
    method getAPIURL (line 304) | private function getAPIURL($endpoint, $fetch_type, $is_article_uid = f...
    method addStories (line 362) | private function addStories($title, $content, $timestamp, $author, $ur...
    method getArticle (line 374) | private function getArticle($feed_uri, $is_article_uid = false)
    method handleImage (line 440) | private function handleImage($images)
    method handleAuthorName (line 459) | private function handleAuthorName($authors)
    method handleArticleContent (line 476) | private function handleArticleContent($contents)
    method getName (line 583) | public function getName()

FILE: bridges/RibatejanaBridge.php
  class RibatejanaBridge (line 3) | class RibatejanaBridge extends BarraqueiroBridgeAbstract
    method collectData (line 9) | public function collectData()

FILE: bridges/RiptApparelBridge.php
  class RiptApparelBridge (line 3) | class RiptApparelBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()

FILE: bridges/RoadAndTrackBridge.php
  class RoadAndTrackBridge (line 3) | class RoadAndTrackBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()
    method fixImages (line 26) | private function fixImages($content)
    method fetchArticle (line 41) | private function fetchArticle($articleLink)

FILE: bridges/RobinhoodSnacksBridge.php
  class RobinhoodSnacksBridge (line 3) | class RobinhoodSnacksBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method getArticleContent (line 61) | private function getArticleContent($uri)

FILE: bridges/RoosterTeethBridge.php
  class RoosterTeethBridge (line 3) | class RoosterTeethBridge extends BridgeAbstract
    method collectData (line 71) | public function collectData()
    method getItemContent (line 120) | protected function getItemContent(array $value): string

FILE: bridges/RtsBridge.php
  class RtsBridge (line 3) | class RtsBridge extends BridgeAbstract
    method collectData (line 31) | public function collectData()

FILE: bridges/Rue89Bridge.php
  class Rue89Bridge (line 3) | class Rue89Bridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()
    method getArticle (line 19) | private function getArticle($articleInfo)

FILE: bridges/Rule34Bridge.php
  class Rule34Bridge (line 3) | class Rule34Bridge extends GelbooruBridge

FILE: bridges/Rule34pahealBridge.php
  class Rule34pahealBridge (line 3) | class Rule34pahealBridge extends Shimmie2Bridge
    method getItemFromElement (line 12) | protected function getItemFromElement($element)

FILE: bridges/RumbleBridge.php
  class RumbleBridge (line 3) | class RumbleBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()
    method getName (line 86) | public function getName()

FILE: bridges/RutubeBridge.php
  class RutubeBridge (line 3) | class RutubeBridge extends BridgeAbstract
    method getURI (line 38) | public function getURI()
    method getIcon (line 51) | public function getIcon()
    method getName (line 56) | public function getName()
    method getJSONData (line 65) | private function getJSONData($html)
    method getVideosFromReduxState (line 80) | private function getVideosFromReduxState()
    method getVideosFromSearchAPI (line 112) | private function getVideosFromSearchAPI()
    method collectData (line 119) | public function collectData()

FILE: bridges/SIMARBridge.php
  class SIMARBridge (line 3) | class SIMARBridge extends BridgeAbstract
    method collectData (line 19) | public function collectData()

FILE: bridges/SafebooruBridge.php
  class SafebooruBridge (line 3) | class SafebooruBridge extends GelbooruBridge
    method buildThumbnailURI (line 10) | protected function buildThumbnailURI($element)

FILE: bridges/SamMobileUpdateBridge.php
  class SamMobileUpdateBridge (line 5) | class SamMobileUpdateBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()

FILE: bridges/SamsungMobileChangelogBridge.php
  class SamsungMobileChangelogBridge (line 3) | class SamsungMobileChangelogBridge extends BridgeAbstract
    method collectData (line 33) | public function collectData()
    method getBaseURL (line 96) | private function getBaseURL()
    method getURI (line 101) | public function getURI()
    method getName (line 110) | public function getName()

FILE: bridges/ScalableCapitalBlogBridge.php
  class ScalableCapitalBlogBridge (line 6) | class ScalableCapitalBlogBridge extends WebDriverAbstract
    method getBrowserOptions (line 18) | protected function getBrowserOptions()
    method collectData (line 31) | public function collectData()
    method formatItemTimestamp (line 72) | protected function formatItemTimestamp($value)

FILE: bridges/SchweinfurtBuergerinformationenBridge.php
  class SchweinfurtBuergerinformationenBridge (line 3) | class SchweinfurtBuergerinformationenBridge extends BridgeAbstract
    method getIcon (line 24) | public function getIcon()
    method collectData (line 29) | public function collectData()
    method getArticleIDsFromPage (line 49) | private function getArticleIDsFromPage($page)
    method generateItemFromArticle (line 69) | private function generateItemFromArticle($id)

FILE: bridges/ScientificAmericanBridge.php
  class ScientificAmericanBridge (line 3) | class ScientificAmericanBridge extends FeedExpander
    method collectData (line 30) | public function collectData()
    method collectFeed (line 58) | private function collectFeed()
    method collectIssues (line 66) | private function collectIssues()
    method parseIssue (line 89) | private function parseIssue($issue_link)
    method updateItem (line 113) | private function updateItem($item)

FILE: bridges/ScmbBridge.php
  class ScmbBridge (line 3) | class ScmbBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/ScoopItBridge.php
  class ScoopItBridge (line 3) | class ScoopItBridge extends BridgeAbstract
    method collectData (line 19) | public function collectData()

FILE: bridges/ScribbleHubBridge.php
  class ScribbleHubBridge (line 3) | class ScribbleHubBridge extends FeedExpander
    method getIcon (line 37) | public function getIcon()
    method collectData (line 42) | public function collectData()
    method collectList (line 57) | private function collectList($url)
    method parseItem (line 123) | protected function parseItem(array $item)
    method getName (line 170) | public function getName()
    method getURI (line 201) | public function getURI()

FILE: bridges/ScribdBridge.php
  class ScribdBridge (line 3) | class ScribdBridge extends BridgeAbstract
    method collectData (line 24) | public function collectData()
    method getName (line 61) | public function getName()
    method getURI (line 70) | public function getURI()

FILE: bridges/SensCritiqueBridge.php
  class SensCritiqueBridge (line 3) | class SensCritiqueBridge extends BridgeAbstract
    method collectData (line 35) | public function collectData()
    method extractDataFromList (line 67) | private function extractDataFromList($list)

FILE: bridges/SeznamZpravyBridge.php
  class SeznamZpravyBridge (line 3) | class SeznamZpravyBridge extends BridgeAbstract
    method getName (line 24) | public function getName()
    method collectData (line 32) | public function collectData()

FILE: bridges/ShadertoyBridge.php
  class ShadertoyBridge (line 3) | class ShadertoyBridge extends BridgeAbstract
    method postprocessDescription (line 27) | public function postprocessDescription($content)
    method collectData (line 42) | public function collectData()

FILE: bridges/ShanaprojectBridge.php
  class ShanaprojectBridge (line 3) | class ShanaprojectBridge extends BridgeAbstract
    method getURI (line 34) | public function getURI()
    method collectData (line 39) | public function collectData()
    method loadSeasonAnimeList (line 85) | private function loadSeasonAnimeList()
    method extractAnimeTitle (line 104) | private function extractAnimeTitle($anime)
    method extractAnimeUri (line 112) | private function extractAnimeUri($anime)
    method extractAnimeTimestamp (line 120) | private function extractAnimeTimestamp($anime)
    method extractAnimeAuthor (line 132) | private function extractAnimeAuthor($anime)
    method extractAnimeEpisodeInformation (line 144) | private function extractAnimeEpisodeInformation($anime)
    method extractAnimeBackgroundImage (line 156) | private function extractAnimeBackgroundImage($anime)
    method buildAnimeSearchUri (line 169) | private function buildAnimeSearchUri($anime)
    method buildAnimeContent (line 178) | private function buildAnimeContent($anime)

FILE: bridges/Shimmie2Bridge.php
  class Shimmie2Bridge (line 3) | class Shimmie2Bridge extends DanbooruBridge
    method getFullURI (line 12) | protected function getFullURI()
    method getItemFromElement (line 21) | protected function getItemFromElement($element)

FILE: bridges/SitemapBridge.php
  class SitemapBridge (line 3) | class SitemapBridge extends CssSelectorBridge
    method collectData (line 70) | public function collectData()
    method getSitemapXml (line 109) | protected function getSitemapXml(&$url, $is_site_map = false)
    method sitemapXmlToList (line 136) | protected function sitemapXmlToList($sitemap, $url_pattern = '', $limi...

FILE: bridges/SkimfeedBridge.php
  class SkimfeedBridge (line 3) | class SkimfeedBridge extends BridgeAbstract
    method getURI (line 419) | public function getURI()
    method detectParameters (line 452) | public function detectParameters($url)
    method getName (line 474) | public function getName()
    method collectData (line 510) | public function collectData()
    method extractFeed (line 562) | private function extractFeed($html, $author)
    method extractHotTopics (line 600) | private function extractHotTopics($html)
    method extractCustomFeed (line 624) | private function extractCustomFeed($html)
    method getTarget (line 642) | private function getTarget($anchor)
    method exportBoxChannels (line 665) | private function exportBoxChannels()
    method exportTechChannels (line 721) | private function exportTechChannels()
    method isCompatible (line 797) | private function isCompatible($html)

FILE: bridges/SkyArteBridge.php
  class SkyArteBridge (line 5) | class SkyArteBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()
    method getJson (line 48) | private function getJson(string $url): ?array
    method parseEventData (line 65) | private function parseEventData(array $json): array

FILE: bridges/SleeperFantasyFootballBridge.php
  class SleeperFantasyFootballBridge (line 3) | class SleeperFantasyFootballBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()
    method processString (line 32) | protected function processString($inputString)

FILE: bridges/SlusheBridge.php
  class SlusheBridge (line 3) | class SlusheBridge extends BridgeAbstract
    method getName (line 67) | public function getName()
    method collectData (line 84) | public function collectData()

FILE: bridges/SongkickBridge.php
  class SongkickBridge (line 3) | class SongkickBridge extends BridgeAbstract
    method getURI (line 24) | public function getURI()
    method getName (line 29) | public function getName()
    method getIcon (line 37) | public function getIcon()
    method collectData (line 42) | public function collectData()

FILE: bridges/SoundcloudBridge.php
  class SoundCloudBridge (line 3) | class SoundCloudBridge extends BridgeAbstract
    method collectData (line 43) | public function collectData()
    method getIcon (line 90) | public function getIcon()
    method getURI (line 99) | public function getURI()
    method getName (line 108) | public function getName()
    method getClientID (line 117) | private function getClientID()
    method refreshClientID (line 128) | private function refreshClientID()
    method buildApiUrl (line 157) | private function buildApiUrl($endpoint, $parameters)
    method getUser (line 165) | private function getUser($username)
    method getUserItems (line 172) | private function getUserItems($userId, $type)
    method getApi (line 192) | private function getApi($endpoint, $parameters)
    method getTrackList (line 208) | private function getTrackList($tracks)

FILE: bridges/SplCenterBridge.php
  class SplCenterBridge (line 3) | class SplCenterBridge extends FeedExpander
    method collectData (line 24) | public function collectData()
    method parseItem (line 30) | protected function parseItem(array $item)
    method getURI (line 44) | public function getURI()
    method getName (line 53) | public function getName()

FILE: bridges/SpotifyBridge.php
  class SpotifyBridge (line 3) | class SpotifyBridge extends BridgeAbstract
    method collectData (line 98) | public function collectData()
    method collectDataInternal (line 117) | private function collectDataInternal()
    method fetchAccessToken (line 150) | private function fetchAccessToken()
    method getEntriesFromQuery (line 171) | private function getEntriesFromQuery()
    method getEntriesFromURIs (line 210) | private function getEntriesFromURIs()
    method getAlbumData (line 256) | private function getAlbumData($album)
    method getTrackData (line 271) | private function getTrackData($track)
    method getEpisodeData (line 283) | private function getEpisodeData($episode)
    method getDate (line 299) | private function getDate($entry)
    method getURI (line 322) | public function getURI()
    method getName (line 331) | public function getName()
    method getFirstEntry (line 340) | private function getFirstEntry()
    method getIcon (line 367) | public function getIcon()

FILE: bridges/SpottschauBridge.php
  class SpottschauBridge (line 3) | class SpottschauBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()

FILE: bridges/StanfordSIRbookreviewBridge.php
  class StanfordSIRbookreviewBridge (line 3) | class StanfordSIRbookreviewBridge extends BridgeAbstract
    method collectData (line 22) | public function collectData()

FILE: bridges/SteamAppNewsBridge.php
  class SteamAppNewsBridge (line 3) | class SteamAppNewsBridge extends BridgeAbstract
    method collectData (line 39) | public function collectData()
    method collectArticle (line 59) | private function collectArticle($json_item)
    method replaceBBcodes (line 77) | private function replaceBBcodes($text)

FILE: bridges/SteamBridge.php
  class SteamBridge (line 3) | class SteamBridge extends BridgeAbstract
    method collectData (line 26) | public function collectData()

FILE: bridges/SteamCommunityBridge.php
  class SteamCommunityBridge (line 3) | class SteamCommunityBridge extends BridgeAbstract
    method getIcon (line 33) | public function getIcon()
    method getMainPage (line 38) | protected function getMainPage()
    method getName (line 46) | public function getName()
    method getURI (line 65) | public function getURI()
    method collectMedia (line 78) | private function collectMedia()
    method collectWorkshop (line 150) | private function collectWorkshop()
    method collectData (line 204) | public function collectData()

FILE: bridges/SteamGroupAnnouncementsBridge.php
  class SteamGroupAnnouncementsBridge (line 3) | class SteamGroupAnnouncementsBridge extends FeedExpander
    method collectData (line 20) | public function collectData()

FILE: bridges/StockFilingsBridge.php
  class StockFilingsBridge (line 3) | class StockFilingsBridge extends FeedExpander
    method getIcon (line 24) | public function getIcon()
    method getSearchUrl (line 32) | private function getSearchUrl()
    method getRssFeed (line 40) | private function getRssFeed($html)
    method getHtml (line 64) | private function getHtml()
    method collectData (line 75) | public function collectData()

FILE: bridges/StorytelBridge.php
  class StorytelBridge (line 3) | class StorytelBridge extends BridgeAbstract
    method collectData (line 19) | public function collectData()

FILE: bridges/StravaBridge.php
  class StravaBridge (line 3) | class StravaBridge extends BridgeAbstract
    method detectParameters (line 17) | public function detectParameters($url)
    method collectData (line 27) | public function collectData()
    method getName (line 64) | public function getName()
    method getIcon (line 73) | public function getIcon()

FILE: bridges/StreamCzBridge.php
  class StreamCzBridge (line 3) | class StreamCzBridge extends BridgeAbstract
    method collectData (line 21) | public function collectData()
    method getURI (line 75) | public function getURI()
    method getName (line 80) | public function getName()

FILE: bridges/StripeAPIChangeLogBridge.php
  class StripeAPIChangeLogBridge (line 3) | class StripeAPIChangeLogBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/SubitoBridge.php
  class SubitoBridge (line 5) | class SubitoBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()

FILE: bridges/SubstackBridge.php
  class SubstackBridge (line 3) | class SubstackBridge extends FeedExpander
    method collectData (line 29) | public function collectData()

FILE: bridges/SubstackProfileBridge.php
  class SubstackProfileBridge (line 3) | class SubstackProfileBridge extends BridgeAbstract
    method collectData (line 18) | public function collectData()
    method processAttachment (line 35) | private function processAttachment(array $element)
    method fetchPost (line 98) | private function fetchPost(string $id)
    method quoteAttachment (line 111) | private function quoteAttachment(array $attachment)
    method processBodyJson (line 127) | private function processBodyJson(array $json)
    method getName (line 185) | public function getName()
    method getIcon (line 194) | public function getIcon()
    method getURI (line 202) | public function getURI()

FILE: bridges/SummitsOnTheAirBridge.php
  class SummitsOnTheAirBridge (line 3) | class SummitsOnTheAirBridge extends BridgeAbstract
    method collectData (line 21) | public function collectData()

FILE: bridges/SuperSmashBlogBridge.php
  class SuperSmashBlogBridge (line 3) | class SuperSmashBlogBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/SymfonyCastsBridge.php
  class SymfonyCastsBridge (line 3) | class SymfonyCastsBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/TCBScansBridge.php
  class TCBScansBridge (line 3) | class TCBScansBridge extends BridgeAbstract
    method collectData (line 49) | public function collectData()
    method getFullChapter (line 75) | private function getFullChapter($uri)
    method getName (line 89) | public function getName()
    method getIcon (line 98) | public function getIcon()

FILE: bridges/TagesspiegelBridge.php
  class TagesspiegelBridge (line 3) | class TagesspiegelBridge extends FeedExpander
    method collectData (line 110) | public function collectData()
    method parseItem (line 118) | protected function parseItem(array $item)
    method parseArticle (line 128) | private function parseArticle($item, $article)

FILE: bridges/TapasBridge.php
  class TapasBridge (line 3) | class TapasBridge extends FeedExpander
    method collectData (line 33) | public function collectData()
    method parseItem (line 46) | protected function parseItem(array $item)
    method getURI (line 76) | public function getURI()

FILE: bridges/TarnkappeBridge.php
  class TarnkappeBridge (line 3) | class TarnkappeBridge extends FeedExpander
    method collectData (line 30) | public function collectData()
    method parseItem (line 44) | protected function parseItem(array $item)
    method addArticleToItem (line 60) | private function addArticleToItem($item, $article)

FILE: bridges/TbibBridge.php
  class TbibBridge (line 3) | class TbibBridge extends GelbooruBridge
    method buildThumbnailURI (line 10) | protected function buildThumbnailURI($element)

FILE: bridges/TebeoBridge.php
  class TebeoBridge (line 3) | class TebeoBridge extends FeedExpander
    method getIcon (line 26) | public function getIcon()
    method collectData (line 31) | public function collectData()

FILE: bridges/TeefuryBridge.php
  class TeefuryBridge (line 3) | class TeefuryBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()

FILE: bridges/TelegramBridge.php
  class TelegramBridge (line 3) | class TelegramBridge extends BridgeAbstract
    method collectData (line 46) | public function collectData()
    method processContent (line 110) | private function processContent($messageDiv)
    method getURI (line 171) | public function getURI()
    method getName (line 180) | public function getName()
    method getIcon (line 188) | public function getIcon()
    method processReply (line 196) | private function processReply($messageDiv)
    method processSticker (line 217) | private function processSticker($messageDiv)
    method processPoll (line 245) | private function processPoll($messageDiv)
    method processLinkPreview (line 269) | private function processLinkPreview($messageDiv)
    method processVideo (line 307) | private function processVideo($messageDiv)
    method processPhoto (line 334) | private function processPhoto($messageDiv)
    method processNotSupported (line 352) | private function processNotSupported($messageDiv)
    method processAttachment (line 375) | private function processAttachment($messageDiv)
    method processLocation (line 393) | private function processLocation($messageDiv)
    method ellipsisTitle (line 409) | private function ellipsisTitle($text)
    method normalizeUsername (line 419) | private function normalizeUsername()
    method detectParameters (line 426) | public function detectParameters($url)

FILE: bridges/TestFaktaBridge.php
  class TestFaktaBridge (line 3) | class TestFaktaBridge extends BridgeAbstract
    method getIcon (line 10) | public function getIcon()
    method parseSwedishDates (line 15) | private function parseSwedishDates($dateString)
    method collectData (line 56) | public function collectData()

FILE: bridges/TheDriveBridge.php
  class TheDriveBridge (line 3) | class TheDriveBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 16) | protected function parseItem($feedItem)

FILE: bridges/TheFarSideBridge.php
  class TheFarSideBridge (line 3) | class TheFarSideBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()

FILE: bridges/TheGuardianBridge.php
  class TheGuardianBridge (line 3) | class TheGuardianBridge extends FeedExpander
    method collectData (line 52) | public function collectData()
    method parseItem (line 59) | protected function parseItem(array $item)

FILE: bridges/TheHackerNewsBridge.php
  class TheHackerNewsBridge (line 3) | class TheHackerNewsBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/TheOatmealBridge.php
  class TheOatmealBridge (line 3) | class TheOatmealBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 17) | protected function parseItem(array $item)

FILE: bridges/ThePirateBayBridge.php
  class ThePirateBayBridge (line 6) | class ThePirateBayBridge extends BridgeAbstract
    method collectData (line 104) | public function collectData()
    method processKeyword (line 113) | private function processKeyword($keyword)
    method processTorrent (line 158) | private function processTorrent($torrent)
    method renderSize (line 225) | private function renderSize($size)
    method renderUploadDate (line 243) | private function renderUploadDate($added)
    method renderCategory (line 248) | private function renderCategory($category)
    method renderUser (line 267) | private function renderUser($torrent)
    method renderStatusImage (line 281) | private function renderStatusImage($status)
    method renderImdbLink (line 323) | private function renderImdbLink($imdb)

FILE: bridges/TheRedHandFilesBridge.php
  class TheRedHandFilesBridge (line 3) | class TheRedHandFilesBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/TheWhiteboardBridge.php
  class TheWhiteboardBridge (line 3) | class TheWhiteboardBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/TheYeteeBridge.php
  class TheYeteeBridge (line 3) | class TheYeteeBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/ThreadsBridge.php
  class ThreadsBridge (line 3) | class ThreadsBridge extends BridgeAbstract
    method getName (line 30) | public function getName()
    method detectParameters (line 35) | public function detectParameters($url)
    method getURI (line 47) | public function getURI()
    method recursiveFind (line 54) | private function recursiveFind($haystack, $needle)
    method collectData (line 70) | public function collectData()

FILE: bridges/TicketioBridge.php
  class TicketioBridge (line 5) | class TicketioBridge extends BridgeAbstract
    method collectData (line 22) | public function collectData()

FILE: bridges/TikTokBridge.php
  class TikTokBridge (line 3) | class TikTokBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method getURI (line 90) | public function getURI()
    method getName (line 100) | public function getName()
    method processUsername (line 110) | private function processUsername()
    method detectParameters (line 122) | public function detectParameters($url)

FILE: bridges/TinyLetterBridge.php
  class TinyLetterBridge (line 3) | class TinyLetterBridge extends BridgeAbstract
    method getName (line 19) | public function getName()
    method getURI (line 29) | public function getURI()
    method collectData (line 39) | public function collectData()

FILE: bridges/TldrTechBridge.php
  class TldrTechBridge (line 5) | class TldrTechBridge extends BridgeAbstract
    method collectData (line 44) | public function collectData()
    method extractItem (line 74) | private function extractItem(Url $url)
    method extractContent (line 93) | private function extractContent($url)

FILE: bridges/TomsToucheBridge.php
  class TomsToucheBridge (line 3) | class TomsToucheBridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/TorrentGalaxyBridge.php
  class TorrentGalaxyBridge (line 3) | class TorrentGalaxyBridge extends BridgeAbstract
    method collectData (line 54) | public function collectData()
    method getName (line 98) | public function getName()
    method getURI (line 106) | public function getURI()
    method getDescription (line 116) | public function getDescription()
    method getIcon (line 124) | public function getIcon()

FILE: bridges/TraktBridge.php
  class TraktBridge (line 3) | class TraktBridge extends BridgeAbstract
    method detectParameters (line 24) | public function detectParameters($url)
    method collectData (line 34) | public function collectData()
    method getName (line 54) | public function getName()
    method getIcon (line 62) | public function getIcon()

FILE: bridges/TrelloBridge.php
  class TrelloBridge (line 3) | class TrelloBridge extends BridgeAbstract
    method queryAPI (line 554) | private function queryAPI($path, $params = [])
    method renderAction (line 561) | private function renderAction($action, $textOnly = false)
    method collectData (line 603) | public function collectData()
    method detectParameters (line 655) | public function detectParameters($url)
    method getURI (line 673) | public function getURI()
    method getName (line 684) | public function getName()

FILE: bridges/TriabolosNewsBridge.php
  class TriabolosNewsBridge (line 5) | class TriabolosNewsBridge extends BridgeAbstract
    method getURI (line 36) | public function getURI()
    method getDescription (line 45) | public function getDescription()
    method getName (line 54) | public function getName()
    method collectData (line 63) | public function collectData()

FILE: bridges/TwitScoopBridge.php
  class TwitScoopBridge (line 3) | class TwitScoopBridge extends BridgeAbstract
    method collectData (line 91) | public function collectData()
    method getURI (line 138) | public function getURI()
    method getName (line 147) | public function getName()

FILE: bridges/TwitchBridge.php
  class TwitchBridge (line 3) | class TwitchBridge extends BridgeAbstract
    method collectData (line 48) | public function collectData()
    method formatTimestampTime (line 197) | private function formatTimestampTime($seconds)
    method formatQueryTime (line 207) | private function formatQueryTime($seconds)
    method apiRequest (line 223) | private function apiRequest($query, $variables)
    method getName (line 241) | public function getName()
    method getURI (line 250) | public function getURI()
    method detectParameters (line 259) | public function detectParameters($url)

FILE: bridges/TwitterBridge.php
  class TwitterBridge (line 3) | class TwitterBridge extends BridgeAbstract
    method detectParameters (line 129) | public function detectParameters($url)
    method getName (line 169) | public function getName()
    method getURI (line 190) | public function getURI()
    method getFullText (line 217) | private function getFullText($id)
    method collectData (line 227) | public function collectData()
    method getIcon (line 587) | public function getIcon()
    method compareTweetId (line 592) | private static function compareTweetId($tweet1, $tweet2)

FILE: bridges/TwitterEngineeringBridge.php
  class TwitterEngineeringBridge (line 3) | class TwitterEngineeringBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 17) | protected function parseItem(array $item)
    method getCategoriesFromTags (line 46) | private static function getCategoriesFromTags($article_html)
    method getName (line 60) | public function getName()

FILE: bridges/TwitterV2Bridge.php
  class TwitterV2Bridge (line 8) | class TwitterV2Bridge extends BridgeAbstract
    method getName (line 137) | public function getName()
    method collectData (line 156) | public function collectData()
    method compareTweetDate (line 571) | private static function compareTweetDate($tweet1, $tweet2)
    method makeApiCall (line 582) | private function makeApiCall($api, $authHeaders, $params)
    method replaceTweetURLs (line 596) | private function replaceTweetURLs($tweetObject, $tweetText)
    method getTweetUser (line 636) | private function getTweetUser($tweetObject, $retweetedUsers, $includes...
    method createTweetMediaHTML (line 666) | private function createTweetMediaHTML($tweetObject, $includesMedia, $r...

FILE: bridges/UberNewsroomBridge.php
  class UberNewsroomBridge (line 3) | class UberNewsroomBridge extends BridgeAbstract
    method collectData (line 130) | public function collectData()
    method getURI (line 152) | public function getURI()
    method getName (line 161) | public function getName()
    method formatContent (line 170) | private function formatContent($html)

FILE: bridges/UniverseTodayBridge.php
  class UniverseTodayBridge (line 3) | class UniverseTodayBridge extends FeedExpander
    method collectData (line 22) | public function collectData()
    method parseItem (line 27) | protected function parseItem(array $item)

FILE: bridges/UnogsBridge.php
  class UnogsBridge (line 3) | class UnogsBridge extends BridgeAbstract
    method getName (line 73) | public function getName()
    method getJSON (line 91) | private function getJSON($url)
    method getImage (line 102) | private function getImage($nfid)
    method handleData (line 118) | private function handleData($data)
    method collectData (line 143) | public function collectData()

FILE: bridges/UnraidCommunityApplicationsBridge.php
  class UnraidCommunityApplicationsBridge (line 3) | class UnraidCommunityApplicationsBridge extends BridgeAbstract
    method fetchApps (line 15) | private function fetchApps()
    method sortApps (line 21) | private function sortApps()
    method collectData (line 28) | public function collectData()

FILE: bridges/UnsplashBridge.php
  class UnsplashBridge (line 3) | class UnsplashBridge extends BridgeAbstract
    method collectData (line 48) | public function collectData()
    method getName (line 110) | public function getName()

FILE: bridges/UrlebirdBridge.php
  class UrlebirdBridge (line 3) | class UrlebirdBridge extends BridgeAbstract
    method collectData (line 24) | public function collectData()
    method encodePathSegments (line 78) | private function encodePathSegments($url)
    method getName (line 88) | public function getName()
    method getIcon (line 93) | public function getIcon()

FILE: bridges/UsbekEtRicaBridge.php
  class UsbekEtRicaBridge (line 3) | class UsbekEtRicaBridge extends BridgeAbstract
    method collectData (line 28) | public function collectData()
    method loadFullArticle (line 98) | private function loadFullArticle($uri)
    method replaceUriInHtmlElement (line 115) | private function replaceUriInHtmlElement($element)

FILE: bridges/UsenixBridge.php
  class UsenixBridge (line 5) | final class UsenixBridge extends BridgeAbstract
    method collectData (line 16) | public function collectData()
    method collectLoginOnlineItems (line 25) | private function collectLoginOnlineItems(): void
    method getItemContent (line 50) | private function getItemContent(string $uri): array

FILE: bridges/UsesTechBridge.php
  class UsesTechbridge (line 3) | class UsesTechbridge extends BridgeAbstract
    method collectData (line 11) | public function collectData()

FILE: bridges/VarietyBridge.php
  class VarietyBridge (line 3) | class VarietyBridge extends FeedExpander
    method collectData (line 11) | public function collectData()
    method parseItem (line 16) | protected function parseItem(array $item)

FILE: bridges/ViadeoCompanyBridge.php
  class ViadeoCompanyBridge (line 3) | class ViadeoCompanyBridge extends BridgeAbstract
    method collectData (line 20) | public function collectData()

FILE: bridges/ViceBridge.php
  class ViceBridge (line 3) | class ViceBridge extends FeedExpander
    method collectData (line 24) | public function collectData()
    method parseItem (line 35) | protected function parseItem(array $item)

FILE: bridges/VideoCardzBridge.php
  class VideoCardzBridge (line 3) | class VideoCardzBridge extends BridgeAbstract
    method getIcon (line 28) | public function getIcon()
    method getName (line 33) | public function getName()
    method getURI (line 38) | public function getURI()
    method collectData (line 43) | public function collectData()

FILE: bridges/VieDeMerdeBridge.php
  class VieDeMerdeBridge (line 3) | class VieDeMerdeBridge extends BridgeAbstract
    method collectData (line 19) | public function collectData()

FILE: bridges/VimeoBridge.php
  class VimeoBridge (line 3) | class VimeoBridge extends BridgeAbstract
    method getURI (line 33) | public function getURI()
    method collectData (line 45) | public function collectData()
    method addClip (line 111) | private function addClip($element)
    method addOnDemand (line 129) | private function addOnDemand($element)
    method addPeople (line 150) | private function addPeople($element)
    method addChannel (line 166) | private function addChannel($element)
    method addGroup (line 182) | private function addGroup($element)

FILE: bridges/VixenBridge.php
  class VixenBridge (line 3) | class VixenBridge extends BridgeAbstract
    method collectData (line 36) | public function collectData()
    method getURI (line 77) | public function getURI()
    method getName (line 86) | public function getName()
    method makeLink (line 92) | private static function makeLink($URI, $text)
    method generateContent (line 97) | private function generateContent($imageURI, $description, $models)

FILE: bridges/Vk2Bridge.php
  class Vk2Bridge (line 3) | class Vk2Bridge extends BridgeAbstract
    method getURI (line 45) | public function getURI()
    method getName (line 54) | public function getName()
    method detectParameters (line 63) | public function detectParameters($url)
    method getPostURI (line 72) | protected function getPostURI($post)
    method generateContentFromPost (line 85) | protected function generateContentFromPost($post)
    method getImageURLWithLargestWidth (line 186) | protected function getImageURLWithLargestWidth($items)
    method collectData (line 194) | public function collectData()
    method generateFeed (line 250) | protected function generateFeed($r)
    method getTitle (line 292) | protected function getTitle($content)
    method api (line 303) | protected function api($method, array $params, $expected_error_codes =...

FILE: bridges/VkBridge.php
  class VkBridge (line 3) | class VkBridge extends BridgeAbstract
    method getURI (line 39) | public function getURI()
    method getName (line 48) | public function getName()
    method detectParameters (line 57) | public function detectParameters($url)
    method collectData (line 66) | public function collectData()
    method getPhoto (line 426) | private function getPhoto($a)
    method getTitle (line 464) | private function getTitle($content)
    method getTime (line 475) | private function getTime($post)
    method getContents (line 509) | private function getContents()
    method appendVideo (line 542) | protected function appendVideo($video_title, $video_link, $previewImg,...

FILE: bridges/VproTegenlichtBridge.php
  class VproTegenlichtBridge (line 3) | class VproTegenlichtBridge extends BridgeAbstract
    method getIcon (line 11) | public function getIcon()
    method collectData (line 16) | public function collectData()

FILE: bridges/WKYTNewsBridge.php
  class WKYTNewsBridge (line 3) | class WKYTNewsBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/WYMTNewsBridge.php
  class WYMTNewsBridge (line 3) | class WYMTNewsBridge extends BridgeAbstract
    method collectData (line 10) | public function collectData()

FILE: bridges/WaggaCouncilBridge.php
  class WaggaCouncilBridge (line 3) | class WaggaCouncilBridge extends BridgeAbstract
    method getURI (line 29) | public function getURI(): string
    method collectData (line 35) | public function collectData(): void

FILE: bridges/WallmineNewsBridge.php
  class WallmineNewsBridge (line 3) | class WallmineNewsBridge extends BridgeAbstract
    method collectData (line 13) | public function collectData()

FILE: bridges/WallpaperflareBridge.php
  class WallpaperflareBridge (line 3) | class WallpaperflareBridge extends XPathAbstract
    method getSourceUrl (line 28) | protected function getSourceUrl()
    method getIcon (line 33) | public function getIcon()
    method getName (line 38) | public function getName()

FILE: bridges/WarhammerComBridge.php
  class WarhammerComBridge (line 3) | class WarhammerComBridge extends BridgeAbstract
    method collectData (line 11) |
Condensed preview — 726 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,646K chars).
[
  {
    "path": ".devcontainer/Dockerfile",
    "chars": 762,
    "preview": "FROM rssbridge/rss-bridge:latest\n\nCOPY --chmod=755 post-create-command.sh /usr/local/bin/post-create-command\n\nADD https:"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 923,
    "preview": "{\n\t\"name\": \"rss-bridge dev\",\n\t\"build\": { \"dockerfile\": \"Dockerfile\" },\n\t\"customizations\": {\n\t\t// Configure properties sp"
  },
  {
    "path": ".devcontainer/launch.json",
    "chars": 1556,
    "preview": "{\n    // Use IntelliSense to learn about possible attributes.\n    // Hover to view descriptions of existing attributes.\n"
  },
  {
    "path": ".devcontainer/nginx.conf",
    "chars": 422,
    "preview": "server {\n    listen 3100 default_server;\n    root /workspaces/rss-bridge;\n    access_log /var/log/nginx/rssbridge.access"
  },
  {
    "path": ".devcontainer/post-create-command.sh",
    "chars": 833,
    "preview": "#/bin/sh\n\ncp .devcontainer/nginx.conf /etc/nginx/conf.d/default.conf\ncp .devcontainer/xdebug.ini /etc/php/8.2/fpm/conf.d"
  },
  {
    "path": ".devcontainer/xdebug.ini",
    "chars": 189,
    "preview": "[xdebug]\nxdebug.mode=develop,debug\nxdebug.client_host=localhost\nxdebug.client_port=9003\nxdebug.start_with_request=yes\nxd"
  },
  {
    "path": ".dockerignore",
    "chars": 189,
    "preview": ".git\n!.git/HEAD\n!.git/refs/heads/*\n.gitattributes\n.github/*\n.travis.yml\ncache/*\nCONTRIBUTING.md\nDEBUG\nDockerfile\nphpcomp"
  },
  {
    "path": ".git-blame-ignore-revs",
    "chars": 148,
    "preview": "# Reformat code base to PSR12\n4f75591060d95208a301bc6bf460d875631b29cc\n# Fix coding style missed by phpbcf\n951092eef374d"
  },
  {
    "path": ".gitattributes",
    "chars": 1869,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n*.sh text eol=lf\n\n# Custom for Visual Studio\n*.cs     "
  },
  {
    "path": ".github/.gitignore",
    "chars": 82,
    "preview": "# Visual Studio Code\n.vscode/*\n\n# Generated files\ncomment*.md\ncomment*.txt\n*.html\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 424,
    "preview": "### Pull request policy\n\nSee the [Pull request policy page on the documentation](https://rss-bridge.github.io/rss-bridge"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bridge-request.md",
    "chars": 2318,
    "preview": "---\nname: Bridge request\nabout: Use this template for requesting a new bridge\ntitle: Bridge request for ...\nlabels: Brid"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 842,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: Bug-Report\nassignees: ''\n\n---\n\n**Descri"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 608,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: Feature-Request\nassignees: ''\n\n---\n\n"
  },
  {
    "path": ".github/prtester-requirements.txt",
    "chars": 39,
    "preview": "beautifulsoup4>=4.10.0\nrequests>=2.26.0"
  },
  {
    "path": ".github/prtester.py",
    "chars": 10961,
    "preview": "import argparse\nimport requests\nimport re\nfrom bs4 import BeautifulSoup\nfrom datetime import datetime\nfrom typing impor"
  },
  {
    "path": ".github/workflows/dockerbuild.yml",
    "chars": 1820,
    "preview": "name: Build Container Image\n\non:\n  push:\n    branches:\n      - 'master'\n    tags:\n      - '20*'\n  pull_request:\n    bran"
  },
  {
    "path": ".github/workflows/documentation.yml",
    "chars": 783,
    "preview": "name: Documentation\n\non:\n  push:\n    paths:\n    - 'docs/**'\n  pull_request:\n    branches:\n      - 'master'\n    paths:\n  "
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 1474,
    "preview": "name: Lint\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\npermissions:\n  contents: read"
  },
  {
    "path": ".github/workflows/prhtmlgenerator.yml",
    "chars": 5940,
    "preview": "name: 'PR Testing'\n\non:\n  pull_request_target:\n    branches: [ master ]\n\npermissions:\n  contents: read\n\njobs:\n  checks:\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 509,
    "preview": "name: Tests\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\npermissions:\n  contents: rea"
  },
  {
    "path": ".gitignore",
    "chars": 3074,
    "preview": "#################\n## Eclipse\n#################\nvendor/*\ndata/\n*.pydevproject\n.project\n.metadata\ntmp/\n*.tmp\n*.bak\n*.swp\n*"
  },
  {
    "path": "CONTRIBUTORS.md",
    "chars": 9624,
    "preview": "# Contributors\n\n* [16mhz](https://github.com/16mhz)\n* [adamchainz](https://github.com/adamchainz)\n* [Ahiles3005](https:/"
  },
  {
    "path": "Dockerfile",
    "chars": 3147,
    "preview": "FROM debian:12-slim AS rssbridge\n\nLABEL description=\"RSS-Bridge is a PHP project capable of generating RSS and Atom feed"
  },
  {
    "path": "README.md",
    "chars": 16053,
    "preview": "# RSS-Bridge\n\n![RSS-Bridge](static/logo_600px.png)\n\nRSS-Bridge is a PHP web application.\n\nIt generates web feeds for web"
  },
  {
    "path": "UNLICENSE",
    "chars": 1211,
    "preview": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, c"
  },
  {
    "path": "actions/ConnectivityAction.php",
    "chars": 2223,
    "preview": "<?php\n\n/**\n * Checks if the website for a given bridge is reachable.\n *\n * **Remarks**\n * - This action is only availabl"
  },
  {
    "path": "actions/DetectAction.php",
    "chars": 1579,
    "preview": "<?php\n\nclass DetectAction implements ActionInterface\n{\n    private BridgeFactory $bridgeFactory;\n\n    public function __"
  },
  {
    "path": "actions/DisplayAction.php",
    "chars": 9332,
    "preview": "<?php\n\nclass DisplayAction implements ActionInterface\n{\n    private CacheInterface $cache;\n    private Logger $logger;\n "
  },
  {
    "path": "actions/FindfeedAction.php",
    "chars": 3536,
    "preview": "<?php\n\n/**\n * This action is used by the frontpage form search.\n * It finds a bridge based off of a user input url.\n * I"
  },
  {
    "path": "actions/FrontpageAction.php",
    "chars": 11723,
    "preview": "<?php\n\nfinal class FrontpageAction implements ActionInterface\n{\n    private BridgeFactory $bridgeFactory;\n\n    public fu"
  },
  {
    "path": "actions/HealthAction.php",
    "chars": 351,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass HealthAction implements ActionInterface\n{\n    public function __invoke(Request $r"
  },
  {
    "path": "actions/ListAction.php",
    "chars": 1277,
    "preview": "<?php\n\nclass ListAction implements ActionInterface\n{\n    private BridgeFactory $bridgeFactory;\n\n    public function __co"
  },
  {
    "path": "app.json",
    "chars": 297,
    "preview": "{\n  \"service\": \"Heroku\",\n  \"name\": \"rss-bridge-heroku\",\n  \"description\": \"RSS-Bridge is a PHP project capable of generat"
  },
  {
    "path": "bridges/ABCNewsBridge.php",
    "chars": 1588,
    "preview": "<?php\n\nclass ABCNewsBridge extends BridgeAbstract\n{\n    const NAME = 'ABC News';\n    const URI = 'https://www.abc.net.au"
  },
  {
    "path": "bridges/ABolaBridge.php",
    "chars": 5158,
    "preview": "<?php\n\nclass ABolaBridge extends BridgeAbstract\n{\n    const NAME = 'A Bola';\n    const URI = 'https://abola.pt/';\n    co"
  },
  {
    "path": "bridges/AO3Bridge.php",
    "chars": 8621,
    "preview": "<?php\n\nclass AO3Bridge extends BridgeAbstract\n{\n    const NAME = 'AO3';\n    const URI = 'https://archiveofourown.org/';\n"
  },
  {
    "path": "bridges/ARDAudiothekBridge.php",
    "chars": 5599,
    "preview": "<?php\n\nclass ARDAudiothekBridge extends BridgeAbstract\n{\n    const NAME = 'ARD-Audiothek';\n    const URI = 'https://www."
  },
  {
    "path": "bridges/ARDMediathekBridge.php",
    "chars": 4058,
    "preview": "<?php\n\nclass ARDMediathekBridge extends BridgeAbstract\n{\n    const NAME = 'ARD-Mediathek';\n    const URI = 'https://www."
  },
  {
    "path": "bridges/ARMCommunityBridge.php",
    "chars": 2843,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass ARMCommunityBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'thefranke';\n "
  },
  {
    "path": "bridges/ASRockNewsBridge.php",
    "chars": 1641,
    "preview": "<?php\n\nclass ASRockNewsBridge extends BridgeAbstract\n{\n    const NAME = 'ASRock News';\n    const URI = 'https://www.asro"
  },
  {
    "path": "bridges/AcademiaBridge.php",
    "chars": 3193,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass AcademiaBridge extends BridgeAbstract\n{\n    const NAME = 'Academia';\n    const UR"
  },
  {
    "path": "bridges/AcrimedBridge.php",
    "chars": 977,
    "preview": "<?php\n\nclass AcrimedBridge extends FeedExpander\n{\n    const MAINTAINER = 'qwertygc';\n    const NAME = 'Acrimed';\n    con"
  },
  {
    "path": "bridges/ActivisionResearchBridge.php",
    "chars": 1796,
    "preview": "<?php\n\nclass ActivisionResearchBridge extends BridgeAbstract\n{\n    const NAME = 'Activision Research Blog';\n    const UR"
  },
  {
    "path": "bridges/AirBreizhBridge.php",
    "chars": 1981,
    "preview": "<?php\n\nclass AirBreizhBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'fanch317';\n    const NAME = 'Air Breizh';\n"
  },
  {
    "path": "bridges/AkamaiBridge.php",
    "chars": 1997,
    "preview": "<?php\n\nclass AkamaiBridge extends FeedExpander\n{\n    const MAINTAINER = 'Mynacol';\n    const NAME = 'Akamai Blog';\n    c"
  },
  {
    "path": "bridges/AlbionOnlineBridge.php",
    "chars": 2861,
    "preview": "<?php\n\nclass AlbionOnlineBridge extends BridgeAbstract\n{\n    const NAME = 'Albion Online Changelog';\n    const MAINTAINE"
  },
  {
    "path": "bridges/AlfaBankByBridge.php",
    "chars": 3109,
    "preview": "<?php\n\nclass AlfaBankByBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'lassana';\n    const NAME = 'AlfaBank.by Н"
  },
  {
    "path": "bridges/AllSidesBridge.php",
    "chars": 2778,
    "preview": "<?php\n\nclass AllSidesBridge extends BridgeAbstract\n{\n    const NAME = 'AllSides';\n    const URI = 'https://www.allsides."
  },
  {
    "path": "bridges/AllegroBridge.php",
    "chars": 4217,
    "preview": "<?php\n\nclass AllegroBridge extends BridgeAbstract\n{\n    const NAME = 'Allegro';\n    const URI = 'https://www.allegro.pl'"
  },
  {
    "path": "bridges/AllocineFRBridge.php",
    "chars": 4340,
    "preview": "<?php\n\nclass AllocineFRBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'superbaillot.net';\n    const NAME = 'Allo"
  },
  {
    "path": "bridges/AllocineFRSortiesBridge.php",
    "chars": 2278,
    "preview": "<?php\n\nclass AllocineFRSortiesBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'Simounet';\n    const NAME = 'AlloC"
  },
  {
    "path": "bridges/AlpinePackagesBridge.php",
    "chars": 6438,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass AlpinePackagesBridge extends BridgeAbstract\n{\n    const NAME = 'Alpine Packages';"
  },
  {
    "path": "bridges/AmazonBridge.php",
    "chars": 3085,
    "preview": "<?php\n\nclass AmazonBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'Alexis CHEMEL';\n    const NAME = 'Amazon';\n  "
  },
  {
    "path": "bridges/AmazonPriceTrackerBridge.php",
    "chars": 7896,
    "preview": "<?php\n\nclass AmazonPriceTrackerBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'captn3m0, sal0max, bagnacauda';\n "
  },
  {
    "path": "bridges/AnfrBridge.php",
    "chars": 11521,
    "preview": "<?php\n\nclass AnfrBridge extends BridgeAbstract\n{\n    const NAME = 'ANFR';\n    const URI = 'https://data.anfr.fr/';\n    c"
  },
  {
    "path": "bridges/AnidexBridge.php",
    "chars": 8929,
    "preview": "<?php\n\nclass AnidexBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'ORelio';\n    const NAME = 'Anidex';\n    const"
  },
  {
    "path": "bridges/AnimeUltimeBridge.php",
    "chars": 5601,
    "preview": "<?php\n\nclass AnimeUltimeBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'ORelio';\n    const NAME = 'Anime-Ultime'"
  },
  {
    "path": "bridges/AnisearchBridge.php",
    "chars": 3107,
    "preview": "<?php\n\nclass AnisearchBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'Tone866';\n    const NAME = 'Anisearch';\n  "
  },
  {
    "path": "bridges/AnnasArchiveBridge.php",
    "chars": 6983,
    "preview": "<?php\n\nclass AnnasArchiveBridge extends BridgeAbstract\n{\n    const NAME = 'Anna\\'s Archive';\n    const MAINTAINER = 'pha"
  },
  {
    "path": "bridges/AppleAppStoreBridge.php",
    "chars": 8143,
    "preview": "<?php\n\nclass AppleAppStoreBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'NohamR';\n    const NAME = 'Apple App S"
  },
  {
    "path": "bridges/AppleMusicBridge.php",
    "chars": 3661,
    "preview": "<?php\n\nclass AppleMusicBridge extends BridgeAbstract\n{\n    const NAME = 'Apple Music';\n    const URI = 'https://www.appl"
  },
  {
    "path": "bridges/ArsTechnicaBridge.php",
    "chars": 4625,
    "preview": "<?php\n\nclass ArsTechnicaBridge extends FeedExpander\n{\n    const MAINTAINER = 'phantop';\n    const NAME = 'Ars Technica';"
  },
  {
    "path": "bridges/ArtStationBridge.php",
    "chars": 3032,
    "preview": "<?php\n\nclass ArtStationBridge extends BridgeAbstract\n{\n    const NAME = 'ArtStation';\n    const URI = 'https://www.artst"
  },
  {
    "path": "bridges/Arte7Bridge.php",
    "chars": 5631,
    "preview": "<?php\n\nclass Arte7Bridge extends BridgeAbstract\n{\n    const NAME = 'Arte +7';\n    const URI = 'https://www.arte.tv/';\n  "
  },
  {
    "path": "bridges/AsahiShimbunAJWBridge.php",
    "chars": 2917,
    "preview": "<?php\n\nclass AsahiShimbunAJWBridge extends BridgeAbstract\n{\n    const NAME = 'Asahi Shimbun AJW';\n    const BASE_URI = '"
  },
  {
    "path": "bridges/AssociatedPressNewsBridge.php",
    "chars": 9144,
    "preview": "<?php\n\nclass AssociatedPressNewsBridge extends BridgeAbstract\n{\n    const NAME = 'Associated Press News';\n    const URI "
  },
  {
    "path": "bridges/AstrophysicsDataSystemBridge.php",
    "chars": 1808,
    "preview": "<?php\n\nclass AstrophysicsDataSystemBridge extends BridgeAbstract\n{\n    const NAME = 'SAO/NASA Astrophysics Data System';"
  },
  {
    "path": "bridges/AtmoNouvelleAquitaineBridge.php",
    "chars": 196893,
    "preview": "<?php\n\nclass AtmoNouvelleAquitaineBridge extends BridgeAbstract\n{\n    const NAME = 'Atmo Nouvelle Aquitaine';\n    const "
  },
  {
    "path": "bridges/AtmoOccitanieBridge.php",
    "chars": 2226,
    "preview": "<?php\n\nclass AtmoOccitanieBridge extends BridgeAbstract\n{\n    const NAME = 'Atmo Occitanie';\n    const URI = 'https://ww"
  },
  {
    "path": "bridges/AuctionetBridge.php",
    "chars": 13170,
    "preview": "<?php\n\nclass AuctionetBridge extends BridgeAbstract\n{\n    const NAME = 'Auctionet';\n    const URI = 'https://www.auction"
  },
  {
    "path": "bridges/AutoJMBridge.php",
    "chars": 7469,
    "preview": "<?php\n\nclass AutoJMBridge extends BridgeAbstract\n{\n    const NAME = 'AutoJM';\n    const URI = 'https://www.autojm.fr/';\n"
  },
  {
    "path": "bridges/AwwwardsBridge.php",
    "chars": 1717,
    "preview": "<?php\n\nclass AwwwardsBridge extends BridgeAbstract\n{\n    const NAME = 'Awwwards';\n    const URI = 'https://www.awwwards."
  },
  {
    "path": "bridges/BAEBridge.php",
    "chars": 9212,
    "preview": "<?php\n\nclass BAEBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'couraudt';\n    const NAME = 'Bourse Aux Equipier"
  },
  {
    "path": "bridges/BMDSystemhausBlogBridge.php",
    "chars": 8876,
    "preview": "<?php\n\nclass BMDSystemhausBlogBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'cn-tools';\n    const NAME = 'BMD S"
  },
  {
    "path": "bridges/BadDragonBridge.php",
    "chars": 16295,
    "preview": "<?php\n\nclass BadDragonBridge extends BridgeAbstract\n{\n    const NAME = 'Bad Dragon';\n    const URI = 'https://bad-dragon"
  },
  {
    "path": "bridges/BakaUpdatesMangaReleasesBridge.php",
    "chars": 6658,
    "preview": "<?php\n\nclass BakaUpdatesMangaReleasesBridge extends BridgeAbstract\n{\n    const NAME = 'Baka Updates Manga Releases';\n   "
  },
  {
    "path": "bridges/BandcampBridge.php",
    "chars": 15676,
    "preview": "<?php\n\nclass BandcampBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'sebsauvage, Roliga';\n    const NAME = 'Band"
  },
  {
    "path": "bridges/BandcampDailyBridge.php",
    "chars": 6490,
    "preview": "<?php\n\nclass BandcampDailyBridge extends BridgeAbstract\n{\n    const NAME = 'Bandcamp Daily';\n    const URI = 'https://da"
  },
  {
    "path": "bridges/BarraqueiroBridgeAbstract.php",
    "chars": 726,
    "preview": "<?php\n\nabstract class BarraqueiroBridgeAbstract extends BridgeAbstract\n{\n    const MAINTAINER = 'FJSFerreira';\n\n    publ"
  },
  {
    "path": "bridges/BarraqueiroOesteBridge.php",
    "chars": 379,
    "preview": "<?php\n\nclass BarraqueiroOesteBridge extends BarraqueiroBridgeAbstract\n{\n    const NAME = 'Barraqueiro Oeste';\n    const "
  },
  {
    "path": "bridges/BastaBridge.php",
    "chars": 1016,
    "preview": "<?php\n\nclass BastaBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'qwertygc';\n    const NAME = 'Bastamag';\n    co"
  },
  {
    "path": "bridges/BazarakiBridge.php",
    "chars": 5010,
    "preview": "<?php\n\nclass BazarakiBridge extends BridgeAbstract\n{\n    const NAME = 'Bazaraki';\n    const URI = 'https://bazaraki.com'"
  },
  {
    "path": "bridges/BinanceBridge.php",
    "chars": 1100,
    "preview": "<?php\n\nclass BinanceBridge extends BridgeAbstract\n{\n    const NAME = 'Binance Blog';\n    const URI = 'https://www.binanc"
  },
  {
    "path": "bridges/BlaguesDeMerdeBridge.php",
    "chars": 1369,
    "preview": "<?php\n\nclass BlaguesDeMerdeBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'superbaillot.net, logmanoriginal';\n  "
  },
  {
    "path": "bridges/BleepingComputerBridge.php",
    "chars": 952,
    "preview": "<?php\n\nclass BleepingComputerBridge extends FeedExpander\n{\n    const MAINTAINER = 'csisoap';\n    const NAME = 'Bleeping "
  },
  {
    "path": "bridges/BlizzardNewsBridge.php",
    "chars": 3437,
    "preview": "<?php\n\nclass BlizzardNewsBridge extends BridgeAbstract\n{\n    const NAME = 'Blizzard News';\n    const URI = 'https://news"
  },
  {
    "path": "bridges/BlueskyBridge.php",
    "chars": 34230,
    "preview": "<?php\n\nclass BlueskyBridge extends BridgeAbstract\n{\n    //Initial PR by [RSSBridge contributors](https://github.com/RSS-"
  },
  {
    "path": "bridges/BoaViagemBridge.php",
    "chars": 337,
    "preview": "<?php\n\nclass BoaViagemBridge extends BarraqueiroBridgeAbstract\n{\n    const NAME = 'Boa Viagem';\n    const URI = 'https:/"
  },
  {
    "path": "bridges/BodaccBridge.php",
    "chars": 8243,
    "preview": "<?php\n\nclass BodaccBridge extends BridgeAbstract\n{\n    const NAME = 'BODACC';\n    const URI = 'https://bodacc-datadila.o"
  },
  {
    "path": "bridges/BookMyShowBridge.php",
    "chars": 45781,
    "preview": "<?php\n\nclass BookMyShowBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'captn3m0';\n    const NAME = 'BookMyShow';"
  },
  {
    "path": "bridges/BooruprojectBridge.php",
    "chars": 2046,
    "preview": "<?php\n\nclass BooruprojectBridge extends DanbooruBridge\n{\n    const MAINTAINER = 'mitsukarenai';\n    const NAME = 'Boorup"
  },
  {
    "path": "bridges/BrotFuerDieWeltBridge.php",
    "chars": 4144,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass BrotFuerDieWeltBridge extends BridgeAbstract\n{\n    const NAME = 'Brot für die Wel"
  },
  {
    "path": "bridges/BruegelBridge.php",
    "chars": 1923,
    "preview": "<?php\n\nclass BruegelBridge extends BridgeAbstract\n{\n    const NAME = 'Bruegel';\n    const URI = 'https://www.bruegel.org"
  },
  {
    "path": "bridges/BrutBridge.php",
    "chars": 2478,
    "preview": "<?php\n\nclass BrutBridge extends BridgeAbstract\n{\n    const NAME = 'Brut';\n    const URI = 'https://www.brut.media';\n    "
  },
  {
    "path": "bridges/BugzillaBridge.php",
    "chars": 6532,
    "preview": "<?php\n\nclass BugzillaBridge extends BridgeAbstract\n{\n    const NAME = 'Bugzilla';\n    const URI = 'https://www.bugzilla."
  },
  {
    "path": "bridges/BukowskisBridge.php",
    "chars": 9359,
    "preview": "<?php\n\nclass BukowskisBridge extends BridgeAbstract\n{\n    const NAME = 'Bukowskis';\n    const URI = 'https://www.bukowsk"
  },
  {
    "path": "bridges/BundesbankBridge.php",
    "chars": 2711,
    "preview": "<?php\n\nclass BundesbankBridge extends BridgeAbstract\n{\n    const PARAM_LANG = 'lang';\n\n    const LANG_EN = 'en';\n    con"
  },
  {
    "path": "bridges/BundestagParteispendenBridge.php",
    "chars": 3218,
    "preview": "<?php\n\nclass BundestagParteispendenBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'mibe';\n    const NAME = 'Deut"
  },
  {
    "path": "bridges/BundesverbandFuerFreieKammernBridge.php",
    "chars": 1141,
    "preview": "<?php\n\nclass BundesverbandFuerFreieKammernBridge extends XPathAbstract\n{\n    const NAME = 'Bundesverband für freie Kamme"
  },
  {
    "path": "bridges/CBCEditorsBlogBridge.php",
    "chars": 1379,
    "preview": "<?php\n\nclass CBCEditorsBlogBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'quickwick';\n    const NAME = 'CBC Edi"
  },
  {
    "path": "bridges/CMetropolitanaBridge.php",
    "chars": 838,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass CMetropolitanaBridge extends BridgeAbstract\n{\n    const NAME = 'CMetropolitana';\n"
  },
  {
    "path": "bridges/CNETBridge.php",
    "chars": 4167,
    "preview": "<?php\n\nclass CNETBridge extends SitemapBridge\n{\n    const MAINTAINER = 'ORelio';\n    const NAME = 'CNET News';\n    const"
  },
  {
    "path": "bridges/CNETFranceBridge.php",
    "chars": 1778,
    "preview": "<?php\n\nclass CNETFranceBridge extends FeedExpander\n{\n    const MAINTAINER = 'leomaradan';\n    const NAME = 'CNET France'"
  },
  {
    "path": "bridges/CVEDetailsBridge.php",
    "chars": 4190,
    "preview": "<?php\n\n// CVE Details is a collection of CVEs, taken from the National Vulnerability\n// Database (NVD) and other sources"
  },
  {
    "path": "bridges/CachetBridge.php",
    "chars": 4500,
    "preview": "<?php\n\nclass CachetBridge extends BridgeAbstract\n{\n    const NAME = 'Cachet';\n    const URI = 'https://cachethq.io/';\n  "
  },
  {
    "path": "bridges/CarThrottleBridge.php",
    "chars": 3264,
    "preview": "<?php\n\nclass CarThrottleBridge extends BridgeAbstract\n{\n    const NAME = 'Car Throttle';\n    const URI = 'https://www.ca"
  },
  {
    "path": "bridges/CaschyBridge.php",
    "chars": 2111,
    "preview": "<?php\n\nclass CaschyBridge extends FeedExpander\n{\n    const MAINTAINER = 'Tone866';\n    const NAME = 'Caschys Blog';\n    "
  },
  {
    "path": "bridges/CastorusBridge.php",
    "chars": 3782,
    "preview": "<?php\n\nclass CastorusBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'logmanoriginal';\n    const NAME = 'Castorus"
  },
  {
    "path": "bridges/CdactionBridge.php",
    "chars": 1906,
    "preview": "<?php\n\nclass CdactionBridge extends BridgeAbstract\n{\n    const NAME = 'CD-ACTION';\n    const URI = 'https://cdaction.pl'"
  },
  {
    "path": "bridges/CentreFranceBridge.php",
    "chars": 10194,
    "preview": "<?php\n\nclass CentreFranceBridge extends BridgeAbstract\n{\n    const NAME = 'Centre France Newspapers';\n    const URI = 'h"
  },
  {
    "path": "bridges/CeskaTelevizeBridge.php",
    "chars": 2932,
    "preview": "<?php\n\nclass CeskaTelevizeBridge extends BridgeAbstract\n{\n    const NAME = 'Česká televize';\n    const URI = 'https://ww"
  },
  {
    "path": "bridges/CodebergBridge.php",
    "chars": 14934,
    "preview": "<?php\n\nclass CodebergBridge extends BridgeAbstract\n{\n    const NAME = 'Codeberg';\n    const URI = 'https://codeberg.org/"
  },
  {
    "path": "bridges/CollegeDeFranceBridge.php",
    "chars": 3263,
    "preview": "<?php\n\nclass CollegeDeFranceBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'pit-fgfjiudghdf';\n    const NAME = '"
  },
  {
    "path": "bridges/ComboiosDePortugalBridge.php",
    "chars": 2029,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass ComboiosDePortugalBridge extends BridgeAbstract\n{\n    const NAME = 'CP | Avisos';"
  },
  {
    "path": "bridges/ComickBridge.php",
    "chars": 6352,
    "preview": "<?php\n\nclass ComickBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'phantop';\n    const NAME = 'Comick';\n    cons"
  },
  {
    "path": "bridges/ComicsKingdomBridge.php",
    "chars": 2416,
    "preview": "<?php\n\nclass ComicsKingdomBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'TReKiE';\n    // const MAINTAINER = 'st"
  },
  {
    "path": "bridges/CommonDreamsBridge.php",
    "chars": 757,
    "preview": "<?php\n\nclass CommonDreamsBridge extends FeedExpander\n{\n    const MAINTAINER = 'nyutag';\n    const NAME = 'CommonDreams';"
  },
  {
    "path": "bridges/CopieDoubleBridge.php",
    "chars": 1231,
    "preview": "<?php\n\nclass CopieDoubleBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'superbaillot.net';\n    const NAME = 'Cop"
  },
  {
    "path": "bridges/CorreioDaFeiraBridge.php",
    "chars": 2716,
    "preview": "<?php\n\nclass CorreioDaFeiraBridge extends BridgeAbstract\n{\n    const NAME = 'Correio da Feira';\n    const URI = 'https:/"
  },
  {
    "path": "bridges/CourrierInternationalBridge.php",
    "chars": 745,
    "preview": "<?php\n\nclass CourrierInternationalBridge extends FeedExpander\n{\n    const MAINTAINER = 'teromene';\n    const NAME = 'Cou"
  },
  {
    "path": "bridges/CraigslistBridge.php",
    "chars": 4439,
    "preview": "<?php\n\nclass CraigslistBridge extends BridgeAbstract\n{\n    const NAME = 'Craigslist';\n    const URI = 'https://craigslis"
  },
  {
    "path": "bridges/CrewbayBridge.php",
    "chars": 9334,
    "preview": "<?php\n\nclass CrewbayBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'couraudt';\n    const NAME = 'Crewbay';\n    c"
  },
  {
    "path": "bridges/CryptomeBridge.php",
    "chars": 1197,
    "preview": "<?php\n\nclass CryptomeBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'BoboTiG';\n    const NAME = 'Cryptome';\n    "
  },
  {
    "path": "bridges/CssSelectorBridge.php",
    "chars": 12495,
    "preview": "<?php\n\nclass CssSelectorBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'ORelio';\n    const NAME = 'CSS Selector'"
  },
  {
    "path": "bridges/CssSelectorComplexBridge.php",
    "chars": 17665,
    "preview": "<?php\n\nclass CssSelectorComplexBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'Lars Stegman';\n    const NAME = '"
  },
  {
    "path": "bridges/CssSelectorFeedExpanderBridge.php",
    "chars": 4796,
    "preview": "<?php\n\nclass CssSelectorFeedExpanderBridge extends CssSelectorBridge\n{\n    const MAINTAINER = 'ORelio';\n    const NAME ="
  },
  {
    "path": "bridges/CubariBridge.php",
    "chars": 3279,
    "preview": "<?php\n\nclass CubariBridge extends BridgeAbstract\n{\n    const NAME = 'Cubari';\n    const URI = 'https://cubari.moe';\n    "
  },
  {
    "path": "bridges/CubariProxyBridge.php",
    "chars": 3995,
    "preview": "<?php\n\nclass CubariProxyBridge extends BridgeAbstract\n{\n    const NAME = 'Cubari Proxy';\n    const MAINTAINER = 'phantop"
  },
  {
    "path": "bridges/CybernewsBridge.php",
    "chars": 2753,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass CybernewsBridge extends BridgeAbstract\n{\n    const NAME          = 'Cybernews';\n "
  },
  {
    "path": "bridges/DRKBlutspendeBridge.php",
    "chars": 8821,
    "preview": "<?php\n\nclass DRKBlutspendeBridge extends FeedExpander\n{\n    const MAINTAINER = 'User123698745';\n    const NAME = 'DRK-Bl"
  },
  {
    "path": "bridges/DacksnackBridge.php",
    "chars": 3610,
    "preview": "<?PHP\n\nclass DacksnackBridge extends BridgeAbstract\n{\n    const NAME = 'Däcksnack';\n    const URI = 'https://www.tidning"
  },
  {
    "path": "bridges/DagensNyheterDirektBridge.php",
    "chars": 1815,
    "preview": "<?PHP\n\nclass DagensNyheterDirektBridge extends BridgeAbstract\n{\n    const NAME          = 'Dagens Nyheter Direkt';\n    c"
  },
  {
    "path": "bridges/DailymotionBridge.php",
    "chars": 4862,
    "preview": "<?php\n\nclass DailymotionBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'mitsukarenai';\n    const NAME = 'Dailymo"
  },
  {
    "path": "bridges/DailythanthiBridge.php",
    "chars": 3132,
    "preview": "<?php\n\nclass DailythanthiBridge extends BridgeAbstract\n{\n    const NAME = 'Dailythanthi';\n    const URI = 'https://www.d"
  },
  {
    "path": "bridges/DanbooruBridge.php",
    "chars": 2103,
    "preview": "<?php\n\nclass DanbooruBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'mitsukarenai, logmanoriginal';\n    const NA"
  },
  {
    "path": "bridges/DarkReadingBridge.php",
    "chars": 2983,
    "preview": "<?php\n\nclass DarkReadingBridge extends FeedExpander\n{\n    const MAINTAINER = 'ORelio';\n    const NAME = 'Dark Reading';\n"
  },
  {
    "path": "bridges/DauphineLibereBridge.php",
    "chars": 1821,
    "preview": "<?php\n\nclass DauphineLibereBridge extends FeedExpander\n{\n    const MAINTAINER = 'qwertygc';\n    const NAME = 'Dauphine';"
  },
  {
    "path": "bridges/DealabsBridge.php",
    "chars": 4499,
    "preview": "<?php\n\nclass DealabsBridge extends PepperBridgeAbstract\n{\n    const NAME = 'Dealabs';\n    const URI = 'https://www.deala"
  },
  {
    "path": "bridges/DemoBridge.php",
    "chars": 1242,
    "preview": "<?php\n\nclass DemoBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'teromene';\n    const NAME = 'DemoBridge';\n    c"
  },
  {
    "path": "bridges/DemosBerlinBridge.php",
    "chars": 2615,
    "preview": "<?php\n\nclass DemosBerlinBridge extends BridgeAbstract\n{\n    const NAME = 'Demos Berlin';\n    const URI = 'https://www.be"
  },
  {
    "path": "bridges/DerpibooruBridge.php",
    "chars": 3635,
    "preview": "<?php\n\nclass DerpibooruBridge extends BridgeAbstract\n{\n    const NAME = 'Derpibooru';\n    const URI = 'https://derpiboor"
  },
  {
    "path": "bridges/DesoutterBridge.php",
    "chars": 9712,
    "preview": "<?php\n\nclass DesoutterBridge extends BridgeAbstract\n{\n    const CATEGORY_NEWS = 'News & Events';\n    const CATEGORY_INDU"
  },
  {
    "path": "bridges/DeutscheWelleBridge.php",
    "chars": 5504,
    "preview": "<?php\n\nclass DeutscheWelleBridge extends FeedExpander\n{\n    const MAINTAINER = 'No maintainer';\n    const NAME = 'Deutsc"
  },
  {
    "path": "bridges/DeutscherAeroClubBridge.php",
    "chars": 1157,
    "preview": "<?php\n\nclass DeutscherAeroClubBridge extends XPathAbstract\n{\n    const NAME = 'Deutscher Aero Club';\n    const URI = 'ht"
  },
  {
    "path": "bridges/DevToBridge.php",
    "chars": 4035,
    "preview": "<?php\n\nclass DevToBridge extends BridgeAbstract\n{\n    const CONTEXT_BY_TAG = 'By tag';\n    const CONTEXT_BY_USER = 'By u"
  },
  {
    "path": "bridges/DeveloppezDotComBridge.php",
    "chars": 15326,
    "preview": "<?php\n\nclass DeveloppezDotComBridge extends FeedExpander\n{\n    const MAINTAINER = 'Binnette';\n    const NAME = 'Developp"
  },
  {
    "path": "bridges/DiarioDeNoticiasBridge.php",
    "chars": 2283,
    "preview": "<?php\n\nclass DiarioDeNoticiasBridge extends BridgeAbstract\n{\n    const NAME = 'Diário de Notícias (PT)';\n    const URI ="
  },
  {
    "path": "bridges/DiarioDoAlentejoBridge.php",
    "chars": 2344,
    "preview": "<?php\n\nclass DiarioDoAlentejoBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'somini';\n    const NAME = 'Diário d"
  },
  {
    "path": "bridges/DiceBridge.php",
    "chars": 4494,
    "preview": "<?php\n\nclass DiceBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'rogerdc';\n    const NAME = 'Dice Unofficial RSS"
  },
  {
    "path": "bridges/DiscogsBridge.php",
    "chars": 6901,
    "preview": "<?php\n\nclass DiscogsBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'teromene';\n    const NAME = 'DiscogsBridge';"
  },
  {
    "path": "bridges/DjMagDotComBridge.php",
    "chars": 4462,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass DjMagDotComBridge extends BridgeAbstract\n{\n    const NAME = 'DJMag.com News';\n   "
  },
  {
    "path": "bridges/DockerHubBridge.php",
    "chars": 6274,
    "preview": "<?php\n\nclass DockerHubBridge extends BridgeAbstract\n{\n    const NAME = 'Docker Hub';\n    const URI = 'https://hub.docker"
  },
  {
    "path": "bridges/DonnonsBridge.php",
    "chars": 4062,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\n/**\n * Retourne les dons d'une recherche filtrée sur le site Donnons.org\n * Example: ht"
  },
  {
    "path": "bridges/DoujinStyleBridge.php",
    "chars": 4759,
    "preview": "<?php\n\nclass DoujinStyleBridge extends BridgeAbstract\n{\n    const NAME = 'DoujinStyle';\n    const URI = 'https://doujins"
  },
  {
    "path": "bridges/DribbbleBridge.php",
    "chars": 3884,
    "preview": "<?php\n\nclass DribbbleBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'quentinus95';\n    const NAME = 'Dribbble po"
  },
  {
    "path": "bridges/Drive2ruBridge.php",
    "chars": 9053,
    "preview": "<?php\n\nclass Drive2ruBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'dotter-ak';\n    const NAME = 'Drive2.ru';\n "
  },
  {
    "path": "bridges/DuckDuckGoBridge.php",
    "chars": 1533,
    "preview": "<?php\n\nclass DuckDuckGoBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'Astalaseven';\n    const NAME = 'DuckDuckG"
  },
  {
    "path": "bridges/DuvarOrgBridge.php",
    "chars": 2828,
    "preview": "<?php\n\nclass DuvarOrgBridge extends BridgeAbstract\n{\n    const NAME = 'Duvar.org - Haberler';\n    const MAINTAINER = 'yo"
  },
  {
    "path": "bridges/EASeedBridge.php",
    "chars": 1399,
    "preview": "<?php\n\nclass EASeedBridge extends BridgeAbstract\n{\n    const NAME = 'EA Seed Blog';\n    const URI = 'https://www.ea.com/"
  },
  {
    "path": "bridges/EBayBridge.php",
    "chars": 7235,
    "preview": "<?php\n\nclass EBayBridge extends BridgeAbstract\n{\n    const NAME = 'eBay';\n    const DESCRIPTION = 'Returns the search re"
  },
  {
    "path": "bridges/EDDHPiRepsBridge.php",
    "chars": 2610,
    "preview": "<?php\n\nclass EDDHPiRepsBridge extends BridgeAbstract\n{\n    const NAME = 'EDDH.de PIREPs';\n    const URI = 'https://eddh."
  },
  {
    "path": "bridges/EDDHPresseschauBridge.php",
    "chars": 1515,
    "preview": "<?php\n\nclass EDDHPresseschauBridge extends XPathAbstract\n{\n    const NAME = 'EDDH.de Presseschau';\n    const URI = 'http"
  },
  {
    "path": "bridges/EZTVBridge.php",
    "chars": 4254,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass EZTVBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'alexAubin';\n    const"
  },
  {
    "path": "bridges/EconomistBridge.php",
    "chars": 10223,
    "preview": "<?php\n\nclass EconomistBridge extends FeedExpander\n{\n    const MAINTAINER = 'bockiii, sqrtminusone';\n    const NAME = 'Ec"
  },
  {
    "path": "bridges/EconomistWorldInBriefBridge.php",
    "chars": 7376,
    "preview": "<?php\n\nclass EconomistWorldInBriefBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'sqrtminusone';\n    const NAME "
  },
  {
    "path": "bridges/EdfPricesBridge.php",
    "chars": 10372,
    "preview": "<?php\n\nclass EdfPricesBridge extends BridgeAbstract\n{\n    const NAME = 'EDF tarifs';\n    // pull info from this site for"
  },
  {
    "path": "bridges/ElektroARGOSBridge.php",
    "chars": 21962,
    "preview": "<?php\n\n/**\n *\n * this code downloads the HTML page with product news from ARGOS website (https://www.i4wifi.cz), parses "
  },
  {
    "path": "bridges/EliteDangerousGalnetBridge.php",
    "chars": 2024,
    "preview": "<?php\n\nclass EliteDangerousGalnetBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'corenting';\n    const NAME = 'E"
  },
  {
    "path": "bridges/ElloBridge.php",
    "chars": 3934,
    "preview": "<?php\n\nclass ElloBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'teromene';\n    const NAME = 'Ello';\n    const U"
  },
  {
    "path": "bridges/ElsevierBridge.php",
    "chars": 1624,
    "preview": "<?php\n\nclass ElsevierBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'dvikan';\n    const NAME = 'Elsevier journal"
  },
  {
    "path": "bridges/EngadgetBridge.php",
    "chars": 988,
    "preview": "<?php\n\nclass EngadgetBridge extends FeedExpander\n{\n    const MAINTAINER = 'IceWreck';\n    const NAME = 'Engadget';\n    c"
  },
  {
    "path": "bridges/EpicGamesFreeBridge.php",
    "chars": 3132,
    "preview": "<?php\n\nclass EpicGamesFreeBridge extends BridgeAbstract\n{\n    const NAME = 'Epic Games Free Games';\n    const MAINTAINER"
  },
  {
    "path": "bridges/EpicgamesBridge.php",
    "chars": 3222,
    "preview": "<?php\n\nclass EpicgamesBridge extends BridgeAbstract\n{\n    const NAME = 'Epic Games Store News';\n    const MAINTAINER = '"
  },
  {
    "path": "bridges/ErowallBridge.php",
    "chars": 3587,
    "preview": "<?php\n\nclass ErowallBridge extends BridgeAbstract\n{\n    const NAME = 'Erowall.com';\n    const URI = 'https://www.erowall"
  },
  {
    "path": "bridges/EsquerdaNetBridge.php",
    "chars": 1983,
    "preview": "<?php\n\n/**\n * Appears to be protected by cloudflare now\n */\nclass EsquerdaNetBridge extends FeedExpander\n{\n    const MAI"
  },
  {
    "path": "bridges/EstCeQuonMetEnProdBridge.php",
    "chars": 908,
    "preview": "<?php\n\nclass EstCeQuonMetEnProdBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'ORelio';\n    const NAME = 'Est-ce"
  },
  {
    "path": "bridges/EtsyBridge.php",
    "chars": 2580,
    "preview": "<?php\n\nclass EtsyBridge extends BridgeAbstract\n{\n    const NAME = 'Etsy search';\n    const URI = 'https://www.etsy.com';"
  },
  {
    "path": "bridges/EuronewsBridge.php",
    "chars": 9275,
    "preview": "<?php\n\nclass EuronewsBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'sqrtminusone';\n    const NAME = 'Euronews';"
  },
  {
    "path": "bridges/ExecuteProgramBridge.php",
    "chars": 1190,
    "preview": "<?php\n\nclass ExecuteProgramBridge extends BridgeAbstract\n{\n    const NAME = 'Execute Program Blog';\n    const URI = 'htt"
  },
  {
    "path": "bridges/ExplosmBridge.php",
    "chars": 1933,
    "preview": "<?php\n\nclass ExplosmBridge extends BridgeAbstract\n{\n    const NAME = 'Explosm: Cyanide & Happiness';\n    const URI = 'ht"
  },
  {
    "path": "bridges/FB2Bridge.php",
    "chars": 12141,
    "preview": "<?php\n\nclass FB2Bridge extends BridgeAbstract\n{\n    const MAINTAINER = 'teromene';\n    const NAME = 'Facebook Bridge | T"
  },
  {
    "path": "bridges/FDroidRepoBridge.php",
    "chars": 6421,
    "preview": "<?php\n\nclass FDroidRepoBridge extends BridgeAbstract\n{\n    const NAME = 'F-Droid Repository';\n    const URI = 'https://f"
  },
  {
    "path": "bridges/FFXIVLodestoneNewsBridge.php",
    "chars": 2420,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass FFXIVLodestoneNewsBridge extends BridgeAbstract\n{\n    const NAME = 'FFXIV Lodesto"
  },
  {
    "path": "bridges/FM4Bridge.php",
    "chars": 2079,
    "preview": "<?php\n\nclass FM4Bridge extends BridgeAbstract\n{\n    const MAINTAINER = 'joni1993';\n    const NAME = 'FM4';\n    const URI"
  },
  {
    "path": "bridges/FSecureBlogBridge.php",
    "chars": 4113,
    "preview": "<?php\n\nclass FSecureBlogBridge extends BridgeAbstract\n{\n    const NAME = 'F-Secure Blog';\n    const URI = 'https://blog."
  },
  {
    "path": "bridges/FabBridge.php",
    "chars": 1363,
    "preview": "<?php\n\nclass FabBridge extends BridgeAbstract\n{\n    const NAME = 'Epic Games Fab.com';\n    const URI = 'https://www.fab."
  },
  {
    "path": "bridges/FabriceBellardBridge.php",
    "chars": 1030,
    "preview": "<?php\n\nclass FabriceBellardBridge extends BridgeAbstract\n{\n    const NAME = 'Fabrice Bellard';\n    const URI = 'https://"
  },
  {
    "path": "bridges/FacebookBridge.php",
    "chars": 25890,
    "preview": "<?php\n\nclass FacebookBridge extends BridgeAbstract\n{\n    // const MAINTAINER = 'teromene, logmanoriginal';\n    const NAM"
  },
  {
    "path": "bridges/FallGuysBridge.php",
    "chars": 5862,
    "preview": "<?php\n\nclass FallGuysBridge extends BridgeAbstract\n{\n    const MAINTAINER = 'User123698745';\n    const NAME = 'Fall Guys"
  },
  {
    "path": "bridges/FanaticalBridge.php",
    "chars": 2977,
    "preview": "<?php\n\nclass FanaticalBridge extends BridgeAbstract\n{\n    const NAME = 'Fanatical';\n    const MAINTAINER = 'phantop';\n  "
  },
  {
    "path": "bridges/FarsideNitterBridge.php",
    "chars": 3080,
    "preview": "<?php\n\nclass FarsideNitterBridge extends FeedExpander\n{\n    const NAME = 'Farside Nitter';\n    const DESCRIPTION = \"Retu"
  },
  {
    "path": "bridges/FeedExpanderExampleBridge.php",
    "chars": 1602,
    "preview": "<?php\n\nclass FeedExpanderExampleBridge extends FeedExpander\n{\n    const MAINTAINER = 'logmanoriginal';\n    const NAME = "
  },
  {
    "path": "bridges/FeedExpanderTestBridge.php",
    "chars": 701,
    "preview": "<?php\n\ndeclare(strict_types=1);\n\nclass FeedExpanderTestBridge extends FeedExpander\n{\n    const MAINTAINER = 'No maintain"
  },
  {
    "path": "bridges/FeedMergeBridge.php",
    "chars": 5027,
    "preview": "<?php\n\nclass FeedMergeBridge extends FeedExpander\n{\n    const MAINTAINER = 'dvikan';\n    const NAME = 'FeedMerge';\n    c"
  },
  {
    "path": "bridges/FeedReducerBridge.php",
    "chars": 2113,
    "preview": "<?php\n\nclass FeedReducerBridge extends FeedExpander\n{\n    const MAINTAINER = 'mdemoss';\n    const NAME = 'Feed Reducer';"
  },
  {
    "path": "bridges/FiaBridge.php",
    "chars": 1514,
    "preview": "<?php\n\nclass FiaBridge extends BridgeAbstract\n{\n    const NAME = 'Federation Internationale de l\\'Automobile site feed';"
  },
  {
    "path": "bridges/FicbookBridge.php",
    "chars": 6066,
    "preview": "<?php\n\nclass FicbookBridge extends BridgeAbstract\n{\n    const NAME = 'Ficbook';\n    const URI = 'https://ficbook.net/';\n"
  },
  {
    "path": "bridges/FiderBridge.php",
    "chars": 3911,
    "preview": "<?php\n\nclass FiderBridge extends BridgeAbstract\n{\n    const NAME = 'Fider';\n    const URI = 'https://fider.io/';\n    con"
  },
  {
    "path": "bridges/FilterBridge.php",
    "chars": 5880,
    "preview": "<?php\n\nclass FilterBridge extends FeedExpander\n{\n    const MAINTAINER = 'Frenzie, ORelio';\n    const NAME = 'Filter';\n  "
  }
]

// ... and 526 more files (download for full content)

About this extraction

This page contains the full source code of the RSS-Bridge/rss-bridge GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 726 files (3.3 MB), approximately 904.6k tokens, and a symbol index with 3209 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!