gitextract_dc9d8v7i/ ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .swift-version ├── .swiftformat ├── .swiftlint.yml ├── .swiftpm/ │ └── xcode/ │ └── xcshareddata/ │ └── xcschemes/ │ ├── AllTargetsTests.xcscheme │ ├── AnnotationsService.xcscheme │ ├── AppStructureFeature.xcscheme │ ├── BatchDownloader.xcscheme │ ├── BookmarksFeature.xcscheme │ ├── Caching.xcscheme │ ├── Crashing.xcscheme │ ├── HomeFeature.xcscheme │ ├── LastPagePersistence.xcscheme │ ├── Localization.xcscheme │ ├── MoreMenuFeature.xcscheme │ ├── NetworkSupport.xcscheme │ ├── NoorUI.xcscheme │ ├── NotePersistence.xcscheme │ ├── NotesFeature.xcscheme │ ├── OAuthServiceAppAuthImpl.xcscheme │ ├── PageBookmarkPersistence.xcscheme │ ├── Preferences.xcscheme │ ├── QuranAudioKit.xcscheme │ ├── QuranEngine-Package.xcscheme │ ├── QuranImageFeature.xcscheme │ ├── QuranKit.xcscheme │ ├── QuranPagesFeature.xcscheme │ ├── QuranTextKit.xcscheme │ ├── QuranTextKitTests.xcscheme │ ├── QuranTranslationFeature.xcscheme │ ├── ReadingSelectorFeature.xcscheme │ ├── ReadingService.xcscheme │ ├── ReciterListFeature.xcscheme │ ├── SQLitePersistence.xcscheme │ ├── SearchFeature.xcscheme │ ├── SettingsFeature.xcscheme │ ├── SystemDependencies.xcscheme │ ├── SystemDependenciesFake.xcscheme │ ├── Timing.xcscheme │ ├── TranslationService.xcscheme │ ├── TranslationsFeature.xcscheme │ ├── UIx.xcscheme │ ├── Utilities.xcscheme │ ├── UtilitiesTests.xcscheme │ ├── VLogging.xcscheme │ └── VersionUpdater.xcscheme ├── AllTargetsTests/ │ └── Empty.swift ├── Core/ │ ├── Analytics/ │ │ └── AnalyticsLibrary.swift │ ├── AppMigrator/ │ │ ├── Sources/ │ │ │ ├── AppMigrator.swift │ │ │ └── AppVersionUpdater.swift │ │ └── Tests/ │ │ └── AppMigratorTests.swift │ ├── AsyncUtilitiesForTesting/ │ │ ├── AsyncAlgorithms++.swift │ │ ├── AsyncAsserts.swift │ │ ├── PublisherCollector.swift │ │ ├── XCTestCase+PromiseKit.swift │ │ └── XCTestCase+Publisher.swift │ ├── Caching/ │ │ ├── Sources/ │ │ │ ├── Cache.swift │ │ │ ├── OperationCacheableService.swift │ │ │ └── PagesCacheableService.swift │ │ └── Tests/ │ │ ├── CacheTests.swift │ │ ├── OperationCacheableServiceTests.swift │ │ └── PagesCacheableServiceTests.swift │ ├── Crashing/ │ │ ├── Crasher.swift │ │ └── Global.swift │ ├── Localization/ │ │ ├── Localizations.swift │ │ ├── NumberFormatter+Extension.swift │ │ ├── Resources/ │ │ │ ├── ar.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── de.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── en.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── es.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── fa.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── fr.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── kk.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── ms.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ └── Readers.strings │ │ │ ├── nl.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── pt.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ └── Readers.strings │ │ │ ├── ru.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── tr.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ └── Suras.strings │ │ │ ├── ug.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── uz.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ ├── vi.lproj/ │ │ │ │ ├── Android.strings │ │ │ │ ├── Android.stringsdict │ │ │ │ ├── Localizable.strings │ │ │ │ ├── Readers.strings │ │ │ │ └── Suras.strings │ │ │ └── zh.lproj/ │ │ │ ├── Android.strings │ │ │ ├── Android.stringsdict │ │ │ └── Localizable.strings │ │ └── resource_bundle.swift │ ├── Locking/ │ │ ├── NSLocking+Extension.swift │ │ └── Protected.swift │ ├── OAuthService/ │ │ └── OAuthService.swift │ ├── OAuthServiceAppAuthImpl/ │ │ └── OAuthServiceAppAuthImpl.swift │ ├── OAuthServiceFake/ │ │ └── OAuthServiceFake.swift │ ├── Preferences/ │ │ ├── Preference.swift │ │ ├── PreferenceKey.swift │ │ ├── PreferenceTransformer.swift │ │ └── Preferences.swift │ ├── QueuePlayer/ │ │ ├── AudioInterruptionMonitor.swift │ │ ├── AudioPlayer.swift │ │ ├── AudioPlaying.swift │ │ ├── AudioRequest.swift │ │ ├── NowPlayingUpdater.swift │ │ ├── Player.swift │ │ ├── PlayerItemInfo.swift │ │ ├── QueuePlayer.swift │ │ └── Runs.swift │ ├── SecurePersistence/ │ │ └── SecurePersistence.swift │ ├── SystemDependencies/ │ │ ├── EventObserver.swift │ │ ├── FileSystem.swift │ │ ├── KeychainAccess.swift │ │ ├── PersistentHistoryTransaction.swift │ │ ├── SystemBundle.swift │ │ ├── SystemTime.swift │ │ └── Zipper.swift │ ├── SystemDependenciesFake/ │ │ ├── AsyncChannelEventObserver.swift │ │ ├── FileSystemFake.swift │ │ ├── KeychainAccessFake.swift │ │ ├── PersistentHistoryTransactionFake.swift │ │ ├── SystemBundleFake.swift │ │ ├── SystemTimeFake.swift │ │ └── ZipperFake.swift │ ├── Timing/ │ │ └── Timer.swift │ ├── Utilities/ │ │ ├── Sources/ │ │ │ ├── Extensions/ │ │ │ │ ├── Array+Extension.swift │ │ │ │ ├── Error+Extension.swift │ │ │ │ ├── FileManager+Extension.swift │ │ │ │ ├── Int+Extension.swift │ │ │ │ ├── Result+Extension.swift │ │ │ │ ├── Sequence+Extension.swift │ │ │ │ ├── String+Chunking.swift │ │ │ │ ├── String+Extension.swift │ │ │ │ ├── Task+Extension.swift │ │ │ │ └── URL+Extension.swift │ │ │ └── Features/ │ │ │ ├── Address.swift │ │ │ ├── AsyncInitializer.swift │ │ │ ├── AsyncPublisher.swift │ │ │ ├── AsyncThrowingPublisher.swift │ │ │ ├── Attempt.swift │ │ │ ├── Locking.swift │ │ │ ├── MultiPredicateComparer.swift │ │ │ ├── MulticastContinuation.swift │ │ │ ├── Pair.swift │ │ │ └── RelativeFilePath.swift │ │ └── Tests/ │ │ ├── AsyncPublisherTests.swift │ │ ├── AsyncThrowingPublisherTests.swift │ │ ├── String+ChunkingTests.swift │ │ └── String+ExtensionTests.swift │ ├── VLogging/ │ │ └── Logger.swift │ └── WeakSet/ │ ├── UnsafeWeakSet.swift │ └── WeakSet.swift ├── Data/ │ ├── AudioTimingPersistence/ │ │ ├── AyahTimingPersistence.swift │ │ └── GRDBAyahTimingPersistence.swift │ ├── AuthenticationClient/ │ │ ├── Sources/ │ │ │ ├── AuthenticationClient.swift │ │ │ ├── AuthenticationClientMobileSyncImpl.swift │ │ │ └── AuthentincationClientImpl.swift │ │ └── Tests/ │ │ └── AuthenticationClientTests.swift │ ├── BatchDownloader/ │ │ ├── Sources/ │ │ │ ├── DownloadProgress.swift │ │ │ ├── Downloader/ │ │ │ │ ├── DownloadBatchDataController.swift │ │ │ │ ├── DownloadBatchResponse.swift │ │ │ │ ├── DownloadManager.swift │ │ │ │ ├── DownloadSessionDelegate.swift │ │ │ │ ├── DownloadsObserver.swift │ │ │ │ ├── DownloadsPersistence.swift │ │ │ │ └── GRDBDownloadsPersistence.swift │ │ │ ├── Entities/ │ │ │ │ ├── Download.swift │ │ │ │ └── DownloadRequest.swift │ │ │ └── Errors/ │ │ │ └── FileSystemError.swift │ │ └── Tests/ │ │ ├── DownloadManagerTests.swift │ │ └── HistoryProgressListener.swift │ ├── BatchDownloaderFake/ │ │ └── BatchDownloaderFake.swift │ ├── CoreDataModel/ │ │ ├── Quran.xcdatamodeld/ │ │ │ └── Quran.xcdatamodel/ │ │ │ └── contents │ │ ├── Resources.swift │ │ └── Schema.swift │ ├── CoreDataPersistence/ │ │ ├── Sources/ │ │ │ ├── CoreDataPersistentHistoryProcessor.swift │ │ │ ├── CoreDataPublisher.swift │ │ │ ├── CoreDataStack.swift │ │ │ ├── CoreDataTypes.swift │ │ │ ├── NSManagedObjectContext+Extensions.swift │ │ │ └── merging/ │ │ │ ├── CoreDataEntityUniquifier.swift │ │ │ ├── CoreDataInsertedEntitiesRetriever.swift │ │ │ ├── CoreDataPersistentHistoryTransactionsMerger.swift │ │ │ └── SimpleCoreDataEntityUniquifier.swift │ │ └── Tests/ │ │ ├── CoreDataInsertedEntitiesRetrieverTests.swift │ │ ├── CoreDataPublisherTests.swift │ │ ├── CoreDataStackTests.swift │ │ └── SimpleCoreDataEntityUniquifierTests.swift │ ├── CoreDataPersistenceTestSupport/ │ │ ├── CoreDataStack+Extensions.swift │ │ ├── LastPage+++.swift │ │ ├── Note+++.swift │ │ └── PageBookmark+++.swift │ ├── LastPagePersistence/ │ │ ├── Sources/ │ │ │ ├── CoreDataLastPageOverflowHandler.swift │ │ │ ├── CoreDataLastPagePersistence.swift │ │ │ ├── CoreDataLastPageUniquifier.swift │ │ │ ├── LastPagePersistence.swift │ │ │ └── LastPagePersistenceModel.swift │ │ └── Tests/ │ │ ├── CoreDataLastPagePersistenceTests.swift │ │ └── CoreDataLastPageUniquifierTests.swift │ ├── LinePagePersistence/ │ │ ├── Sources/ │ │ │ ├── GRDBLinePagePersistence.swift │ │ │ ├── LinePageModels.swift │ │ │ └── LinePagePersistence.swift │ │ └── Tests/ │ │ └── LinePagePersistenceTests.swift │ ├── NetworkSupport/ │ │ ├── Sources/ │ │ │ ├── NetworkError.swift │ │ │ ├── NetworkManager.swift │ │ │ └── NetworkSession.swift │ │ └── Tests/ │ │ └── NetworkManagerTests.swift │ ├── NetworkSupportFake/ │ │ └── NetworkSessionFake.swift │ ├── NotePersistence/ │ │ ├── Sources/ │ │ │ ├── CoreDataNotePersistence.swift │ │ │ ├── CoreDataNoteUniquifier.swift │ │ │ ├── NotePersistence.swift │ │ │ └── NotePersistenceModel.swift │ │ └── Tests/ │ │ ├── CoreDataNotePersistenceTests.swift │ │ └── CoreDataNoteUniquifierTests.swift │ ├── PageBookmarkPersistence/ │ │ ├── Sources/ │ │ │ ├── CoreDataPageBookmarkPersistence.swift │ │ │ ├── CoreDataPageBookmarkUniquifier.swift │ │ │ ├── MobileSyncPageBookmarkPersistence.swift │ │ │ ├── PageBookmarkPersistence.swift │ │ │ └── PageBookmarkPersistenceModel.swift │ │ └── Tests/ │ │ └── CoreDataPageBookmarkPersistenceTests.swift │ ├── SQLitePersistence/ │ │ ├── Sources/ │ │ │ ├── DatabaseConnection.swift │ │ │ └── PersistenceError.swift │ │ └── Tests/ │ │ └── DatabaseConnectionTests.swift │ ├── SyncedPageBookmarkPersistence/ │ │ ├── Sources/ │ │ │ ├── GRDBSyncedPageBookmarkPersistence.swift │ │ │ ├── SyncedPageBookmarkPersistence.swift │ │ │ └── SyncedPageBookmarkPersistenceModel.swift │ │ └── Tests/ │ │ └── GRDBSyncedPageBookmarkPersistenceTests.swift │ ├── TranslationPersistence/ │ │ ├── ActiveTranslationsPersistence.swift │ │ └── GRDBActiveTranslationsPersistence.swift │ ├── VerseTextPersistence/ │ │ ├── DatabaseVersionPersistence.swift │ │ ├── GRDBDatabaseVersionPersistence.swift │ │ ├── GRDBVerseTextPersistence.swift │ │ └── VerseTextPersistence.swift │ ├── WordFramePersistence/ │ │ ├── GRDBWordFramePersistence.swift │ │ └── WordFramePersistence.swift │ └── WordTextPersistence/ │ ├── GRDBWordTextPersistence.swift │ └── WordTextPersistence.swift ├── Documentation/ │ └── MobileSyncLocalDevelopment.md ├── Domain/ │ ├── AnnotationsService/ │ │ ├── Sources/ │ │ │ ├── AnalyticsLibrary+Events.swift │ │ │ ├── LastPageService.swift │ │ │ ├── LastPageUpdater.swift │ │ │ ├── NoteService.swift │ │ │ ├── PageBookmarkService.swift │ │ │ └── QuranHighlightsService.swift │ │ └── Tests/ │ │ └── EmptyTests.swift │ ├── AudioTimingService/ │ │ └── ReciterTimingRetriever.swift │ ├── AudioUpdater/ │ │ ├── Sources/ │ │ │ ├── AudioUpdate.swift │ │ │ ├── AudioUpdatePreferences.swift │ │ │ ├── AudioUpdater.swift │ │ │ ├── AudioUpdatesNetworkManager.swift │ │ │ └── MD5Calculator.swift │ │ └── Tests/ │ │ └── AudioUpdaterTests.swift │ ├── ImageService/ │ │ ├── Sources/ │ │ │ ├── ImageDataService.swift │ │ │ ├── LinePageAssetService.swift │ │ │ ├── LinePageGeometry.swift │ │ │ └── LinePageWordFrameAdapter.swift │ │ └── Tests/ │ │ ├── ImageDataServiceTests.swift │ │ ├── LinePageAssetServiceTests.swift │ │ ├── LinePageGeometryTests.swift │ │ ├── LinePageWordFrameAdapterTests.swift │ │ ├── WordFrameTests.swift │ │ └── __Snapshots__/ │ │ └── ImageDataServiceTests/ │ │ ├── testGettingImageAtPage1.2.json │ │ ├── testGettingImageAtPage3.2.json │ │ └── testGettingImageAtPage604.2.json │ ├── QuranAudioKit/ │ │ ├── Sources/ │ │ │ ├── AudioPlayer/ │ │ │ │ ├── GaplessAudioRequestBuilder.swift │ │ │ │ ├── GappedAudioRequestBuilder.swift │ │ │ │ ├── QuranAudioPlayer.swift │ │ │ │ └── QuranAudioRequestBuilder.swift │ │ │ ├── Dependencies/ │ │ │ │ └── QueuingPlayer.swift │ │ │ ├── Downloads/ │ │ │ │ ├── Download+Types.swift │ │ │ │ └── QuranAudioDownloader.swift │ │ │ └── Preferences/ │ │ │ ├── AudioEnd+Localization.swift │ │ │ ├── AudioPreferences.swift │ │ │ └── PreferencesLastAyahFinder.swift │ │ └── Tests/ │ │ ├── AudioRequest+Extension.swift │ │ ├── GaplessAudioRequestBuilderTests.swift │ │ ├── GappedAudioRequestBuilderTests.swift │ │ ├── QueuePlayerFake.swift │ │ ├── QuranAudioDownloaderTests.swift │ │ ├── QuranAudioPlayerDelegateClosures.swift │ │ ├── QuranAudioPlayerTests.swift │ │ └── __Snapshots__/ │ │ └── QuranAudioPlayerTests/ │ │ ├── testPlayingDownloadedGaplessReciter1FullSura.1.json │ │ ├── testPlayingDownloadedGaplessReciter1SuraEndsEarly.1.json │ │ ├── testPlayingDownloadedGaplessReciter1SurasHasEndTimestamp.1.json │ │ ├── testPlayingDownloadedGaplessReciter1SurasHasEndTimestampStopBeforeEnd.1.json │ │ ├── testPlayingDownloadedGaplessReciter2Suras1stSuraHasEndTimestamp.1.json │ │ ├── testPlayingDownloadedGaplessReciter3FullSura.1.json │ │ ├── testPlayingDownloadedGappedReciter1FullSura.1.json │ │ ├── testPlayingDownloadedGappedReciter1SuraEndsEarly.1.json │ │ ├── testPlayingDownloadedGappedReciter3FullSura.1.json │ │ └── testPlayingDownloadedGappedReciterAtTawbah.1.json │ ├── QuranResources/ │ │ └── QuranResources.swift │ ├── QuranTextKit/ │ │ ├── Sources/ │ │ │ ├── Localization/ │ │ │ │ └── QuranKit+Localization.swift │ │ │ ├── Preferences/ │ │ │ │ ├── FontSizePreferences.swift │ │ │ │ └── QuranContentStatePreferences.swift │ │ │ ├── Search/ │ │ │ │ ├── Recents/ │ │ │ │ │ └── SearchRecentsService.swift │ │ │ │ └── Searchers/ │ │ │ │ ├── CompositeSearcher.swift │ │ │ │ ├── NumberSearcher.swift │ │ │ │ ├── PersistenceSearcher.swift │ │ │ │ ├── SearchTerm.swift │ │ │ │ ├── Searcher.swift │ │ │ │ ├── SuraSearcher.swift │ │ │ │ └── TranslationSearcher.swift │ │ │ ├── ShareableText/ │ │ │ │ └── ShareableVerseTextRetriever.swift │ │ │ ├── TranslationText/ │ │ │ │ └── QuranTextDataService.swift │ │ │ └── TwoPages/ │ │ │ └── TwoPagesUtils.swift │ │ └── Tests/ │ │ ├── CompositeSearcherTests.swift │ │ ├── Encoding.swift │ │ ├── QuartersDataRetrieverTests.swift │ │ ├── QuranTextDataServiceTests.swift │ │ ├── SearchRecentsServiceTests.swift │ │ ├── ShareableVerseTextRetrieverTests.swift │ │ ├── TestData.swift │ │ ├── TwoPagesUtilsTests.swift │ │ └── __Snapshots__/ │ │ ├── CompositeSearcherTests/ │ │ │ ├── testMatchArabicQuran.1.json │ │ │ ├── testMatchArabicQuran.2.json │ │ │ ├── testMatchArabicSuraName.1.json │ │ │ ├── testMatchArabicSuraName.2.json │ │ │ ├── testMatchMultipleSuras.1.json │ │ │ ├── testMatchMultipleSuras.2.json │ │ │ ├── testMatchOneSura.1.json │ │ │ ├── testMatchOneSura.2.json │ │ │ ├── testMatchSuraAndQuran.1.json │ │ │ ├── testMatchSuraAndQuran.2.json │ │ │ ├── testMatchSuraAndQuran.3.json │ │ │ ├── testMatchSuraAndQuran.4.json │ │ │ ├── testMatchSuraAndQuran.5.json │ │ │ ├── testMatchSuraAndQuran.6.json │ │ │ ├── testMatchSuraAndQuranWithIncorrectTashkeel.1.json │ │ │ ├── testMatchSuraAndQuranWithIncorrectTashkeel.2.json │ │ │ ├── testMatchTranslation.1.json │ │ │ ├── testMatchTranslation.2.json │ │ │ ├── testNumbers.1.json │ │ │ ├── testNumbers.2.json │ │ │ └── testNumbers.3.json │ │ └── SearchRecentsServiceTests/ │ │ ├── testPopularTerms.1.json │ │ └── testPopularTerms.2.json │ ├── ReadingService/ │ │ ├── Sources/ │ │ │ ├── ReadingPreferences.swift │ │ │ ├── ReadingRemoteResources.swift │ │ │ ├── ReadingResourceDownloader.swift │ │ │ └── ReadingResourcesService.swift │ │ └── Tests/ │ │ ├── ReadingRemoteResourcesFake.swift │ │ └── ReadingResourcesServiceTests.swift │ ├── ReciterService/ │ │ ├── Sources/ │ │ │ ├── AudioFileListRetriever.swift │ │ │ ├── AudioUnzipper.swift │ │ │ ├── DownloadedRecitersService.swift │ │ │ ├── RecentRecitersService.swift │ │ │ ├── Reciter+Localization.swift │ │ │ ├── ReciterAudioDeleter.swift │ │ │ ├── ReciterDataRetriever.swift │ │ │ ├── ReciterPreferences.swift │ │ │ └── ReciterSizeInfoRetriever.swift │ │ └── Tests/ │ │ ├── DownloadedRecitersServiceTests.swift │ │ ├── RecentRecitersServiceTests.swift │ │ └── ReciterSizeInfoRetrieverTests.swift │ ├── ReciterServiceFake/ │ │ ├── Reciter+Fixture.swift │ │ └── Reciter+Preparation.swift │ ├── SettingsService/ │ │ ├── ReviewPersistence.swift │ │ └── ReviewService.swift │ ├── TestResources/ │ │ └── TestResources.swift │ ├── TranslationService/ │ │ ├── Sources/ │ │ │ ├── LocalTranslationsRetriever.swift │ │ │ ├── SelectedTranslationsPreferences.swift │ │ │ ├── TranslationDeleter.swift │ │ │ ├── TranslationNetworkManager.swift │ │ │ ├── TranslationUnzipper.swift │ │ │ ├── TranslationsDownloader.swift │ │ │ ├── TranslationsParser.swift │ │ │ ├── TranslationsRepository.swift │ │ │ └── TranslationsVersionUpdater.swift │ │ └── Tests/ │ │ ├── LocalTranslationsRetrieverTests.swift │ │ ├── SelectedTranslationsPreferencesTests.swift │ │ ├── TranslationDeleterTests.swift │ │ ├── TranslationsDownloaderTests.swift │ │ └── TranslationsRepositoryTests.swift │ ├── TranslationServiceFake/ │ │ ├── LocalTranslationsFake.swift │ │ └── TranslationTestData.swift │ ├── WordFrameService/ │ │ ├── WordFrame+Extension.swift │ │ └── WordFrameProcessor.swift │ └── WordTextService/ │ ├── Sources/ │ │ ├── WordTextPreferences.swift │ │ └── WordTextService.swift │ └── Tests/ │ └── WordTextServiceTests.swift ├── Example/ │ ├── QuranEngineApp/ │ │ ├── Classes/ │ │ │ ├── Analytics.swift │ │ │ ├── AppDelegate.swift │ │ │ ├── Container.swift │ │ │ ├── QuranEngineApp-Bridging-Header.h │ │ │ └── SceneDelegate.swift │ │ ├── Info.plist │ │ └── Resources/ │ │ ├── Assets.xcassets/ │ │ │ ├── AccentColor.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── app-image.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── quran-engine2.imageset/ │ │ │ │ └── Contents.json │ │ │ └── readings/ │ │ │ ├── Contents.json │ │ │ ├── hafs_1405.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── hafs_1421.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── hafs_1439.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── hafs_1440.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── hafs_1441.imageset/ │ │ │ │ └── Contents.json │ │ │ └── tajweed.imageset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ └── LaunchScreen.storyboard │ │ └── reciters.plist │ └── QuranEngineApp.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── QuranEngineApp.xcscheme ├── Features/ │ ├── AdvancedAudioOptionsFeature/ │ │ ├── AdvancedAudioOptions.swift │ │ ├── AdvancedAudioOptionsBuilder.swift │ │ ├── AdvancedAudioOptionsView.swift │ │ ├── AdvancedAudioOptionsViewModel.swift │ │ ├── AdvancedAudioVersesViewController.swift │ │ └── Runs++.swift │ ├── AppDependencies/ │ │ └── AppDependencies.swift │ ├── AppMigrationFeature/ │ │ ├── FileSystemMigrator.swift │ │ ├── MigrationView.swift │ │ ├── MigrationViewController.swift │ │ └── RecitersPathMigrator.swift │ ├── AppStructureFeature/ │ │ ├── App/ │ │ │ ├── AppBuilder.swift │ │ │ ├── AppInteractor.swift │ │ │ └── AppViewController.swift │ │ ├── Common/ │ │ │ ├── TabBuilder.swift │ │ │ ├── TabInteractor.swift │ │ │ └── TabViewController.swift │ │ ├── Launch/ │ │ │ ├── LaunchBuilder.swift │ │ │ └── LaunchStartup.swift │ │ └── Tabs/ │ │ ├── BookmarksTab.swift │ │ ├── HomeTab.swift │ │ ├── NotesTab.swift │ │ ├── SearchTab.swift │ │ └── SettingsTab.swift │ ├── AudioBannerFeature/ │ │ ├── AudioBannerBuilder.swift │ │ ├── AudioBannerView.swift │ │ ├── AudioBannerViewModel.swift │ │ └── RemoteCommandsHandler.swift │ ├── AudioDownloadsFeature/ │ │ ├── AudioDownloadItem.swift │ │ ├── AudioDownloadsBuilder.swift │ │ ├── AudioDownloadsView.swift │ │ ├── AudioDownloadsViewController.swift │ │ └── AudioDownloadsViewModel.swift │ ├── AyahMenuFeature/ │ │ ├── AyahMenuBuilder.swift │ │ ├── AyahMenuViewController.swift │ │ └── AyahMenuViewModel.swift │ ├── BookmarksFeature/ │ │ ├── Sources/ │ │ │ ├── BookmarksBuilder.swift │ │ │ ├── BookmarksPreferences.swift │ │ │ ├── BookmarksView.swift │ │ │ ├── BookmarksViewController.swift │ │ │ └── BookmarksViewModel.swift │ │ └── Tests/ │ │ └── BookmarksViewModelTests.swift │ ├── FeaturesSupport/ │ │ ├── Analytics.Screen.swift │ │ ├── CommonAnalytics.swift │ │ └── QuranNavigator.swift │ ├── HomeFeature/ │ │ ├── HomeBuilder.swift │ │ ├── HomePreferences.swift │ │ ├── HomeView.swift │ │ ├── HomeViewController.swift │ │ ├── HomeViewModel.swift │ │ └── QuarterItem.swift │ ├── MoreMenuFeature/ │ │ ├── MoreMenuBuilder.swift │ │ ├── MoreMenuController.swift │ │ ├── MoreMenuModel.swift │ │ ├── MoreMenuViewModel.swift │ │ └── views/ │ │ ├── FontSizeStepper.swift │ │ ├── MoreMenuDeviceRotation.swift │ │ ├── MoreMenuEmpty.swift │ │ ├── MoreMenuFontSize.swift │ │ ├── MoreMenuModeSelector.swift │ │ ├── MoreMenuThemeSettings.swift │ │ ├── MoreMenuThemeSettingsViewModel.swift │ │ ├── MoreMenuTranslationSelector.swift │ │ ├── MoreMenuTwoPages.swift │ │ ├── MoreMenuVerticalScrolling.swift │ │ ├── MoreMenuView.swift │ │ ├── MoreMenuWordPointer.swift │ │ └── MoreMenuWordPointerType.swift │ ├── NoteEditorFeature/ │ │ ├── NoteEditorBuilder.swift │ │ ├── NoteEditorInteractor.swift │ │ └── NoteEditorViewController.swift │ ├── NotesFeature/ │ │ ├── NoteItem.swift │ │ ├── NotesBuilder.swift │ │ ├── NotesView.swift │ │ ├── NotesViewController.swift │ │ └── NotesViewModel.swift │ ├── QuranContentFeature/ │ │ ├── ContentBuilder.swift │ │ ├── ContentViewController.swift │ │ ├── ContentViewModel.swift │ │ ├── PagesView.swift │ │ └── QuranInput.swift │ ├── QuranImageFeature/ │ │ ├── ContentImageBuilder.swift │ │ ├── ContentImageView.swift │ │ ├── ContentImageViewModel.swift │ │ ├── ContentLineView.swift │ │ └── ContentLineViewModel.swift │ ├── QuranPagesFeature/ │ │ ├── Page+Localization.swift │ │ ├── PageGeometryActions.swift │ │ └── QuranPaginationView.swift │ ├── QuranTranslationFeature/ │ │ ├── ContentTranslationBuilder.swift │ │ ├── ContentTranslationView.swift │ │ ├── ContentTranslationViewModel.swift │ │ ├── Translation+UI.swift │ │ ├── TranslationFootnote.swift │ │ ├── TranslationItem+View.swift │ │ ├── TranslationItem.swift │ │ └── TranslationURL.swift │ ├── QuranViewFeature/ │ │ ├── QuranBuilder.swift │ │ ├── QuranInteractor.swift │ │ ├── QuranView.swift │ │ └── QuranViewController.swift │ ├── ReadingSelectorFeature/ │ │ ├── ReadingSelectorBuilder.swift │ │ ├── ReadingSelectorViewController.swift │ │ ├── ReadingSelectorViewModel.swift │ │ └── View/ │ │ ├── Reading+Resources.swift │ │ ├── ReadingDetails.swift │ │ ├── ReadingImage.swift │ │ ├── ReadingImageView.swift │ │ ├── ReadingInfo.swift │ │ ├── ReadingItem.swift │ │ └── ReadingSelector.swift │ ├── ReciterListFeature/ │ │ ├── ReciterListBuilder.swift │ │ ├── ReciterListView.swift │ │ ├── ReciterListViewController.swift │ │ └── ReciterListViewModel.swift │ ├── SearchFeature/ │ │ ├── SearchBuilder.swift │ │ ├── SearchTypes.swift │ │ ├── SearchView.swift │ │ ├── SearchViewController.swift │ │ └── SearchViewModel.swift │ ├── SettingsFeature/ │ │ ├── Sources/ │ │ │ ├── ContactUsService.swift │ │ │ ├── Diagnostics/ │ │ │ │ ├── DiagnosticsBuilder.swift │ │ │ │ ├── DiagnosticsService.swift │ │ │ │ ├── DiagnosticsView.swift │ │ │ │ └── DiagnosticsViewModel.swift │ │ │ ├── SettingsBuilder.swift │ │ │ ├── SettingsRootView.swift │ │ │ ├── SettingsRootViewModel.swift │ │ │ └── UIViewController+Share.swift │ │ └── Tests/ │ │ └── SettingsRootViewModelTests.swift │ ├── TranslationVerseFeature/ │ │ ├── TranslationVerseBuilder.swift │ │ ├── TranslationVerseView.swift │ │ ├── TranslationVerseViewController.swift │ │ └── TranslationVerseViewModel.swift │ ├── TranslationsFeature/ │ │ ├── TranslationItem.swift │ │ ├── TranslationsListBuilder.swift │ │ ├── TranslationsListView.swift │ │ ├── TranslationsListViewModel.swift │ │ └── TranslationsViewController.swift │ ├── WhatsNewFeature/ │ │ ├── AppWhatsNew.swift │ │ ├── AppWhatsNewController.swift │ │ ├── AppWhatsNewVersionStore.swift │ │ └── whats-new.plist │ └── WordPointerFeature/ │ ├── WordPointerBuilder.swift │ ├── WordPointerViewController.swift │ └── WordPointerViewModel.swift ├── LICENSE ├── Makefile ├── Model/ │ ├── QuranAnnotations/ │ │ ├── LastPage.swift │ │ ├── Note.swift │ │ ├── PageBookmark.swift │ │ └── QuranHighlights.swift │ ├── QuranAudio/ │ │ ├── AudioDownloadedSize.swift │ │ ├── AudioEnd.swift │ │ ├── AyahTiming.swift │ │ ├── RangeTiming.swift │ │ ├── Reciter+URLs.swift │ │ ├── Reciter.swift │ │ ├── SuraTiming.swift │ │ └── Timing.swift │ ├── QuranGeometry/ │ │ ├── AyahNumberLocation.swift │ │ ├── ImagePage.swift │ │ ├── SuraHeaderLocation.swift │ │ ├── WordFrame.swift │ │ ├── WordFrameCollection.swift │ │ ├── WordFrameLine.swift │ │ └── WordFrameScale.swift │ ├── QuranKit/ │ │ ├── Sources/ │ │ │ ├── AyahNumber.swift │ │ │ ├── Hizb.swift │ │ │ ├── Juz.swift │ │ │ ├── LastAyahFinder/ │ │ │ │ ├── JuzBasedLastAyahFinder.swift │ │ │ │ ├── LastAyahFinder.swift │ │ │ │ ├── PageBasedLastAyahFinder.swift │ │ │ │ ├── QuranBasedLastAyahFinder.swift │ │ │ │ └── SuraBasedLastAyahFinder.swift │ │ │ ├── LazyAtomic.swift │ │ │ ├── Navigatable.swift │ │ │ ├── Page.swift │ │ │ ├── Quarter.swift │ │ │ ├── Quran.swift │ │ │ ├── QuranGroup.swift │ │ │ ├── QuranValueStorage.swift │ │ │ ├── Reading.swift │ │ │ ├── ReadingInfo/ │ │ │ │ ├── Madani1405QuranReadingInfoRawData.swift │ │ │ │ ├── Madani1440QuranReadingInfoRawData.swift │ │ │ │ └── QuranReadingInfoRawData.swift │ │ │ ├── Sura.swift │ │ │ ├── Util.swift │ │ │ └── Word.swift │ │ └── Tests/ │ │ ├── AyahNumberTests.swift │ │ ├── HizbTests.swift │ │ ├── JuzTests.swift │ │ ├── PageTests.swift │ │ ├── QuarterTests.swift │ │ └── SuraTests.swift │ └── QuranText/ │ ├── FontSize.swift │ ├── QuranMode.swift │ ├── SearchResults.swift │ ├── TranslatedVerses.swift │ ├── Translation+URLs.swift │ ├── Translation.swift │ └── WordTextType.swift ├── Package.resolved ├── Package.swift ├── QuranEngine-Package.xctestplan ├── README.md ├── UI/ │ ├── NoorFont/ │ │ └── FontName.swift │ ├── NoorUI/ │ │ ├── BaseControllers/ │ │ │ ├── BaseNavigationController.swift │ │ │ ├── BaseViewController.swift │ │ │ └── UIViewController+Error.swift │ │ ├── Colors/ │ │ │ ├── Color+extension.swift │ │ │ └── Colors.xcassets/ │ │ │ ├── Contents.json │ │ │ ├── appTint.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-calm-bg.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-calm-text.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-focus-bg.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-focus-text.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-original-bg.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-original-text.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-paper-bg.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-paper-text.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── theme-quiet-bg.colorset/ │ │ │ │ └── Contents.json │ │ │ └── theme-quiet-text.colorset/ │ │ │ └── Contents.json │ │ ├── Components/ │ │ │ ├── ActiveRoundedButton.swift │ │ │ ├── AppStoreDownloadButton.swift │ │ │ ├── AppearanceModeSelector.swift │ │ │ ├── ChoicesView.swift │ │ │ ├── DataUnavailableView.swift │ │ │ ├── DisclosureIndicator.swift │ │ │ ├── DropdownButton.swift │ │ │ ├── ErrorAlertModifier.swift │ │ │ ├── List/ │ │ │ │ ├── NoorList.swift │ │ │ │ ├── NoorListItem.swift │ │ │ │ └── NoorSection.swift │ │ │ ├── LoadingView.swift │ │ │ ├── MultipartText.swift │ │ │ ├── ProminentRoundedButton.swift │ │ │ └── ThemeStyleSelector.swift │ │ ├── Features/ │ │ │ ├── AudioBanner/ │ │ │ │ └── AudioBannerViewUI.swift │ │ │ ├── AyahMenu/ │ │ │ │ ├── AyahMenuUI.swift │ │ │ │ └── AyahMenuView.swift │ │ │ ├── Content/ │ │ │ │ └── ContentStatusView.swift │ │ │ ├── Note/ │ │ │ │ ├── EditableNote.swift │ │ │ │ ├── Note.Color++.swift │ │ │ │ ├── NoteCircle.swift │ │ │ │ ├── NoteEditorView.swift │ │ │ │ └── UIViewController+Note.swift │ │ │ └── Quran/ │ │ │ ├── AdaptiveImageScrollView.swift │ │ │ ├── AdaptiveQuranScrollView.swift │ │ │ ├── ImageDecorationsView.swift │ │ │ ├── QuranArabicText.swift │ │ │ ├── QuranPageFooter.swift │ │ │ ├── QuranPageHeader.swift │ │ │ ├── QuranPageSeparators.swift │ │ │ ├── QuranScrollingViewModifier.swift │ │ │ ├── QuranSuraName.swift │ │ │ ├── QuranThemedImage.swift │ │ │ ├── QuranTranslationReferenceVerse.swift │ │ │ ├── QuranTranslationTextChunk.swift │ │ │ ├── QuranTranslatorName.swift │ │ │ └── QuranVerseSeparator.swift │ │ ├── Font/ │ │ │ ├── FontName++.swift │ │ │ └── FontSize++.swift │ │ ├── Formatters/ │ │ │ └── TimeAgo.swift │ │ ├── Images/ │ │ │ ├── Images.xcassets/ │ │ │ │ ├── Contents.json │ │ │ │ ├── ayah-end-marker.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── pointer-25.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── rotate_to_landscape-25.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── rotate_to_portrait-25.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── settings-25.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── settings_filled-25.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── sura_header.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── NoorImage.swift │ │ │ └── NoorSystemImage.swift │ │ ├── Miscellaneous/ │ │ │ ├── ContentDimension.swift │ │ │ ├── Dimensions.swift │ │ │ ├── ReadableInsetsViewModifier.swift │ │ │ ├── TestResource+Path.swift │ │ │ └── ThemedColorInvert.swift │ │ ├── Pager/ │ │ │ └── PageViewController.swift │ │ ├── Shapes/ │ │ │ └── Arc.swift │ │ └── Theme/ │ │ ├── AppearanceModeViews.swift │ │ ├── QuranHighlights+Theme.swift │ │ ├── ThemeService.swift │ │ └── ThemeStyleViews.swift │ ├── UIx/ │ │ ├── SwiftUI/ │ │ │ ├── CollectionView/ │ │ │ │ ├── CollectionView.swift │ │ │ │ ├── CollectionViewController.swift │ │ │ │ ├── CollectionViewDataSource.swift │ │ │ │ ├── CollectionViewReader.swift │ │ │ │ ├── CollectionViewScroller.swift │ │ │ │ ├── HostingCollectionViewCell.swift │ │ │ │ └── ListSection.swift │ │ │ ├── Epoxy/ │ │ │ │ ├── CollectionViewScrollToItemHelper.swift │ │ │ │ ├── DataIDProviding.swift │ │ │ │ ├── EpoxyIntrinsicContentSizeInvalidator.swift │ │ │ │ ├── EpoxySwiftUIHostingController.swift │ │ │ │ ├── EpoxySwiftUIHostingView.swift │ │ │ │ ├── EpoxySwiftUILayoutMargins.swift │ │ │ │ ├── README.md │ │ │ │ └── _Compatibility.swift │ │ │ ├── Miscellaneous/ │ │ │ │ ├── AsyncAction.swift │ │ │ │ ├── BackgroundHighlightingStyle.swift │ │ │ │ ├── CustomButtonStyle.swift │ │ │ │ ├── EdgeInsets++.swift │ │ │ │ ├── EditController.swift │ │ │ │ ├── SwiftUIColor+extension.swift │ │ │ │ ├── UIKitNavigator.swift │ │ │ │ ├── View+Task.swift │ │ │ │ ├── View+URL.swift │ │ │ │ ├── View+onSizeChange.swift │ │ │ │ └── WrappingHStack.swift │ │ │ ├── Mutate.swift │ │ │ ├── SingleChoice/ │ │ │ │ ├── SingleChoiceRow.swift │ │ │ │ └── SingleChoiceSelector.swift │ │ │ ├── Toast/ │ │ │ │ ├── Toast.swift │ │ │ │ └── ToastEnvironmentKey.swift │ │ │ └── Views/ │ │ │ ├── AttributedString++.swift │ │ │ ├── AutoSizingHostingController.swift │ │ │ ├── AutoUpdatingPreferredContentSizeHostingController.swift │ │ │ ├── CloseButton.swift │ │ │ ├── CocoaNavigationBar.swift │ │ │ ├── CocoaNavigationView.swift │ │ │ ├── CollectionTracker.swift │ │ │ ├── HostingCell.swift │ │ │ ├── InvertInDarkModeModifier.swift │ │ │ ├── PopoverNavigationController.swift │ │ │ ├── PreferredContentSizeMatchesScrollView.swift │ │ │ ├── SheetPresentationDetents.swift │ │ │ ├── SingleAxisGeometryReader.swift │ │ │ ├── StaticViewControllerRepresentable.swift │ │ │ ├── TextAlignmentModifier.swift │ │ │ ├── TextView.swift │ │ │ ├── UIViewControllerReader.swift │ │ │ └── WindowSafeAreaInsetsReaderViewModifier.swift │ │ └── UIKit/ │ │ ├── DataSources/ │ │ │ ├── DefaultSection.swift │ │ │ └── NSDiffableDataSourceSnapshot++.swift │ │ ├── Extensions/ │ │ │ ├── CALayer+Extension.swift │ │ │ ├── SegmentedControl+Extension.swift │ │ │ ├── String+Size.swift │ │ │ ├── UIBezierPath+Extension.swift │ │ │ ├── UIColor+Extension.swift │ │ │ ├── UIImage+Extension.swift │ │ │ ├── UITableView+Extension.swift │ │ │ ├── UIView+AutoLayout.swift │ │ │ ├── UIView+Extension.swift │ │ │ ├── UIViewController+Extensions.swift │ │ │ └── UIWIndow+Extensions.swift │ │ ├── Miscellaneous/ │ │ │ ├── NSDirectionalEdgeInsets++.swift │ │ │ ├── PresentationsMonitor.swift │ │ │ └── ScrollViewPageBehavior.swift │ │ ├── Popover/ │ │ │ ├── PhonePopoverPresenter.swift │ │ │ └── PopoverPresenter.swift │ │ └── Views/ │ │ ├── BackgroundColorButton.swift │ │ ├── ByPassTouchesView.swift │ │ ├── CircleView.swift │ │ ├── CircularView.swift │ │ ├── GradientView.swift │ │ ├── MagnifyingGlass.swift │ │ ├── RoundedShadowView.swift │ │ ├── ScrollViewController.swift │ │ ├── SearchControllerWithNoCancelButton.swift │ │ └── TwoLineNavigationTitleView.swift │ └── ViewConstrainer/ │ ├── GroupConstrainer.swift │ ├── SingleConstrainer.swift │ ├── UIView+Const.swift │ └── ViewConstrainer.swift ├── agents.md └── codecov.yml