Full Code of gedoor/legado for AI

master 0486da3c0255 cached
1746 files
11.0 MB
3.0M tokens
2427 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (11,967K chars total). Download the full file to get everything.
Repository: gedoor/legado
Branch: master
Commit: 0486da3c0255
Files: 1746
Total size: 11.0 MB

Directory structure:
gitextract_9ap85jiu/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── 01-bugReport.yml
│   │   ├── 02-featureRequest.yml
│   │   └── config.yml
│   ├── dependabot.yml
│   ├── scripts/
│   │   ├── cronet.sh
│   │   ├── lzy_web.py
│   │   └── tg_bot.py
│   └── workflows/
│       ├── autoupdatefork.yml
│       ├── cronet.yml
│       ├── legado.jks
│       ├── release.yml
│       ├── stale.yml
│       ├── test.yml
│       └── web.yml
├── .gitignore
├── CHANGELOG.md
├── English.md
├── LICENSE
├── README.md
├── api.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── cronet-proguard-rules.pro
│   ├── cronetlib/
│   │   ├── cronet_api.jar
│   │   ├── cronet_impl_common_java.jar
│   │   ├── cronet_impl_native_java.jar
│   │   ├── cronet_impl_platform_java.jar
│   │   └── cronet_shared_java.jar
│   ├── download.gradle
│   ├── google-services.json
│   ├── proguard-rules.pro
│   ├── schemas/
│   │   └── io.legado.app.data.AppDatabase/
│   │       ├── 1.json
│   │       ├── 10.json
│   │       ├── 11.json
│   │       ├── 12.json
│   │       ├── 13.json
│   │       ├── 14.json
│   │       ├── 15.json
│   │       ├── 16.json
│   │       ├── 17.json
│   │       ├── 18.json
│   │       ├── 19.json
│   │       ├── 2.json
│   │       ├── 20.json
│   │       ├── 21.json
│   │       ├── 22.json
│   │       ├── 23.json
│   │       ├── 24.json
│   │       ├── 25.json
│   │       ├── 26.json
│   │       ├── 27.json
│   │       ├── 28.json
│   │       ├── 29.json
│   │       ├── 3.json
│   │       ├── 30.json
│   │       ├── 31.json
│   │       ├── 32.json
│   │       ├── 33.json
│   │       ├── 34.json
│   │       ├── 35.json
│   │       ├── 36.json
│   │       ├── 37.json
│   │       ├── 38.json
│   │       ├── 39.json
│   │       ├── 4.json
│   │       ├── 40.json
│   │       ├── 41.json
│   │       ├── 42.json
│   │       ├── 43.json
│   │       ├── 44.json
│   │       ├── 45.json
│   │       ├── 46.json
│   │       ├── 47.json
│   │       ├── 48.json
│   │       ├── 49.json
│   │       ├── 5.json
│   │       ├── 50.json
│   │       ├── 51.json
│   │       ├── 52.json
│   │       ├── 53.json
│   │       ├── 54.json
│   │       ├── 55.json
│   │       ├── 56.json
│   │       ├── 57.json
│   │       ├── 58.json
│   │       ├── 59.json
│   │       ├── 6.json
│   │       ├── 60.json
│   │       ├── 61.json
│   │       ├── 62.json
│   │       ├── 63.json
│   │       ├── 64.json
│   │       ├── 65.json
│   │       ├── 66.json
│   │       ├── 67.json
│   │       ├── 68.json
│   │       ├── 69.json
│   │       ├── 7.json
│   │       ├── 70.json
│   │       ├── 71.json
│   │       ├── 72.json
│   │       ├── 73.json
│   │       ├── 74.json
│   │       ├── 75.json
│   │       ├── 8.json
│   │       └── 9.json
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── io/
│       │           └── legado/
│       │               └── app/
│       │                   ├── AndroidJsTest.kt
│       │                   ├── ExampleInstrumentedTest.kt
│       │                   ├── HttpTest.kt
│       │                   ├── HttpTtsTest.kt
│       │                   ├── MigrationTest.kt
│       │                   └── UpdateTest.kt
│       ├── debug/
│       │   └── res/
│       │       ├── values/
│       │       │   └── strings.xml
│       │       └── values-zh/
│       │           └── strings.xml
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/
│       │   │   ├── 18PlusList.txt
│       │   │   ├── LICENSE.md
│       │   │   ├── cronet.json
│       │   │   ├── defaultData/
│       │   │   │   ├── bookSources.json
│       │   │   │   ├── coverRule.json
│       │   │   │   ├── dictRules.json
│       │   │   │   ├── directLinkUpload.json
│       │   │   │   ├── httpTTS.json
│       │   │   │   ├── keyboardAssists.json
│       │   │   │   ├── readConfig.json
│       │   │   │   ├── rssSources.json
│       │   │   │   ├── themeConfig.json
│       │   │   │   └── txtTocRule.json
│       │   │   ├── disclaimer.md
│       │   │   ├── epub/
│       │   │   │   ├── chapter.html
│       │   │   │   ├── cover.html
│       │   │   │   ├── fonts.css
│       │   │   │   ├── intro.html
│       │   │   │   └── main.css
│       │   │   ├── privacyPolicy.md
│       │   │   ├── storageHelp.md
│       │   │   ├── updateLog.md
│       │   │   └── web/
│       │   │       ├── assets/
│       │   │       │   ├── css/
│       │   │       │   │   └── main.css
│       │   │       │   └── js/
│       │   │       │       ├── dist.js
│       │   │       │       └── md5.js
│       │   │       ├── help/
│       │   │       │   ├── index.html
│       │   │       │   ├── js/
│       │   │       │   │   ├── main.js
│       │   │       │   │   ├── marked-highlight.umd.js
│       │   │       │   │   └── require.js
│       │   │       │   └── md/
│       │   │       │       ├── ExtensionContentType.md
│       │   │       │       ├── SourceMBookHelp.md
│       │   │       │       ├── SourceMRssHelp.md
│       │   │       │       ├── appHelp.md
│       │   │       │       ├── debugHelp.md
│       │   │       │       ├── dictRuleHelp.md
│       │   │       │       ├── httpTTSHelp.md
│       │   │       │       ├── jsHelp.md
│       │   │       │       ├── readMenuHelp.md
│       │   │       │       ├── regexHelp.md
│       │   │       │       ├── replaceRuleHelp.md
│       │   │       │       ├── ruleHelp.md
│       │   │       │       ├── txtTocRuleHelp.md
│       │   │       │       ├── webDavBookHelp.md
│       │   │       │       ├── webDavHelp.md
│       │   │       │       └── xpathHelp.md
│       │   │       ├── index.html
│       │   │       ├── uploadBook/
│       │   │       │   ├── css/
│       │   │       │   │   └── wifi_send.css
│       │   │       │   ├── index.html
│       │   │       │   └── js/
│       │   │       │       ├── common.js
│       │   │       │       └── html5_fun.js
│       │   │       └── vue/
│       │   │           ├── assets/
│       │   │           │   ├── BookChapter-BsiFtdIw.css
│       │   │           │   ├── BookChapter-Cs3stH93.js
│       │   │           │   ├── BookShelf-00b2QCsd.css
│       │   │           │   ├── BookShelf-DIQtBULC.js
│       │   │           │   ├── index-CrxHVQK7.css
│       │   │           │   ├── index-Wr40-hHf.js
│       │   │           │   ├── loading-C4J6hIxs.js
│       │   │           │   ├── loading-DkQYEuap.css
│       │   │           │   ├── vendor-CXe1BRiH.css
│       │   │           │   └── vendor-KSDcS24u.js
│       │   │           └── index.html
│       │   ├── java/
│       │   │   └── io/
│       │   │       └── legado/
│       │   │           └── app/
│       │   │               ├── App.kt
│       │   │               ├── README.md
│       │   │               ├── api/
│       │   │               │   ├── ReaderProvider.kt
│       │   │               │   ├── ReturnData.kt
│       │   │               │   ├── ShortCuts.kt
│       │   │               │   └── controller/
│       │   │               │       ├── BookController.kt
│       │   │               │       ├── BookSourceController.kt
│       │   │               │       ├── ReplaceRuleController.kt
│       │   │               │       └── RssSourceController.kt
│       │   │               ├── base/
│       │   │               │   ├── AppContextWrapper.kt
│       │   │               │   ├── BaseActivity.kt
│       │   │               │   ├── BaseDialogFragment.kt
│       │   │               │   ├── BaseFragment.kt
│       │   │               │   ├── BasePrefDialogFragment.kt
│       │   │               │   ├── BaseService.kt
│       │   │               │   ├── BaseViewModel.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── VMBaseActivity.kt
│       │   │               │   ├── VMBaseFragment.kt
│       │   │               │   └── adapter/
│       │   │               │       ├── DiffRecyclerAdapter.kt
│       │   │               │       ├── ItemAnimation.kt
│       │   │               │       ├── ItemViewHolder.kt
│       │   │               │       ├── RecyclerAdapter.kt
│       │   │               │       └── animations/
│       │   │               │           ├── AlphaInAnimation.kt
│       │   │               │           ├── BaseAnimation.kt
│       │   │               │           ├── ScaleInAnimation.kt
│       │   │               │           ├── SlideInBottomAnimation.kt
│       │   │               │           ├── SlideInLeftAnimation.kt
│       │   │               │           └── SlideInRightAnimation.kt
│       │   │               ├── constant/
│       │   │               │   ├── AppConst.kt
│       │   │               │   ├── AppLog.kt
│       │   │               │   ├── AppPattern.kt
│       │   │               │   ├── BookSourceType.kt
│       │   │               │   ├── BookType.kt
│       │   │               │   ├── EventBus.kt
│       │   │               │   ├── IntentAction.kt
│       │   │               │   ├── NotificationId.kt
│       │   │               │   ├── PageAnim.kt
│       │   │               │   ├── PreferKey.kt
│       │   │               │   ├── SourceType.kt
│       │   │               │   ├── Status.kt
│       │   │               │   └── Theme.kt
│       │   │               ├── data/
│       │   │               │   ├── AppDatabase.kt
│       │   │               │   ├── DatabaseMigrations.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── dao/
│       │   │               │   │   ├── BookChapterDao.kt
│       │   │               │   │   ├── BookDao.kt
│       │   │               │   │   ├── BookGroupDao.kt
│       │   │               │   │   ├── BookSourceDao.kt
│       │   │               │   │   ├── BookmarkDao.kt
│       │   │               │   │   ├── CacheDao.kt
│       │   │               │   │   ├── CookieDao.kt
│       │   │               │   │   ├── DictRuleDao.kt
│       │   │               │   │   ├── HttpTTSDao.kt
│       │   │               │   │   ├── KeyboardAssistsDao.kt
│       │   │               │   │   ├── ReadRecordDao.kt
│       │   │               │   │   ├── ReplaceRuleDao.kt
│       │   │               │   │   ├── RssArticleDao.kt
│       │   │               │   │   ├── RssReadRecordDao.kt
│       │   │               │   │   ├── RssSourceDao.kt
│       │   │               │   │   ├── RssStarDao.kt
│       │   │               │   │   ├── RuleSubDao.kt
│       │   │               │   │   ├── SearchBookDao.kt
│       │   │               │   │   ├── SearchKeywordDao.kt
│       │   │               │   │   ├── ServerDao.kt
│       │   │               │   │   └── TxtTocRuleDao.kt
│       │   │               │   └── entities/
│       │   │               │       ├── BaseBook.kt
│       │   │               │       ├── BaseRssArticle.kt
│       │   │               │       ├── BaseSource.kt
│       │   │               │       ├── Book.kt
│       │   │               │       ├── BookChapter.kt
│       │   │               │       ├── BookChapterReview.kt
│       │   │               │       ├── BookGroup.kt
│       │   │               │       ├── BookProgress.kt
│       │   │               │       ├── BookSource.kt
│       │   │               │       ├── BookSourcePart.kt
│       │   │               │       ├── Bookmark.kt
│       │   │               │       ├── Cache.kt
│       │   │               │       ├── Cookie.kt
│       │   │               │       ├── DictRule.kt
│       │   │               │       ├── HttpTTS.kt
│       │   │               │       ├── KeyboardAssist.kt
│       │   │               │       ├── ReadRecord.kt
│       │   │               │       ├── ReadRecordShow.kt
│       │   │               │       ├── ReplaceRule.kt
│       │   │               │       ├── RssArticle.kt
│       │   │               │       ├── RssReadRecord.kt
│       │   │               │       ├── RssSource.kt
│       │   │               │       ├── RssStar.kt
│       │   │               │       ├── RuleSub.kt
│       │   │               │       ├── SearchBook.kt
│       │   │               │       ├── SearchKeyword.kt
│       │   │               │       ├── Server.kt
│       │   │               │       ├── TxtTocRule.kt
│       │   │               │       └── rule/
│       │   │               │           ├── BookInfoRule.kt
│       │   │               │           ├── BookListRule.kt
│       │   │               │           ├── ContentRule.kt
│       │   │               │           ├── ExploreKind.kt
│       │   │               │           ├── ExploreRule.kt
│       │   │               │           ├── FlexChildStyle.kt
│       │   │               │           ├── ReviewRule.kt
│       │   │               │           ├── RowUi.kt
│       │   │               │           ├── SearchRule.kt
│       │   │               │           └── TocRule.kt
│       │   │               ├── exception/
│       │   │               │   ├── ConcurrentException.kt
│       │   │               │   ├── ContentEmptyException.kt
│       │   │               │   ├── EmptyFileException.kt
│       │   │               │   ├── InvalidBooksDirException.kt
│       │   │               │   ├── NoBooksDirException.kt
│       │   │               │   ├── NoStackTraceException.kt
│       │   │               │   ├── RegexTimeoutException.kt
│       │   │               │   └── TocEmptyException.kt
│       │   │               ├── help/
│       │   │               │   ├── AppFreezeMonitor.kt
│       │   │               │   ├── AppWebDav.kt
│       │   │               │   ├── CacheManager.kt
│       │   │               │   ├── ConcurrentRateLimiter.kt
│       │   │               │   ├── CrashHandler.kt
│       │   │               │   ├── DefaultData.kt
│       │   │               │   ├── DirectLinkUpload.kt
│       │   │               │   ├── DispatchersMonitor.kt
│       │   │               │   ├── EventMessage.kt
│       │   │               │   ├── ExecutorService.kt
│       │   │               │   ├── IntentData.kt
│       │   │               │   ├── IntentHelp.kt
│       │   │               │   ├── JsEncodeUtils.kt
│       │   │               │   ├── JsExtensions.kt
│       │   │               │   ├── LauncherIconHelp.kt
│       │   │               │   ├── LayoutManager.kt
│       │   │               │   ├── LifecycleHelp.kt
│       │   │               │   ├── MediaHelp.kt
│       │   │               │   ├── PaintPool.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── ReplaceAnalyzer.kt
│       │   │               │   ├── RuleBigDataHelp.kt
│       │   │               │   ├── RuleComplete.kt
│       │   │               │   ├── TTS.kt
│       │   │               │   ├── book/
│       │   │               │   │   ├── BookContent.kt
│       │   │               │   │   ├── BookExtensions.kt
│       │   │               │   │   ├── BookHelp.kt
│       │   │               │   │   ├── ContentHelp.kt
│       │   │               │   │   └── ContentProcessor.kt
│       │   │               │   ├── config/
│       │   │               │   │   ├── AppConfig.kt
│       │   │               │   │   ├── LocalConfig.kt
│       │   │               │   │   ├── ReadBookConfig.kt
│       │   │               │   │   ├── ReadTipConfig.kt
│       │   │               │   │   ├── SourceConfig.kt
│       │   │               │   │   └── ThemeConfig.kt
│       │   │               │   ├── coroutine/
│       │   │               │   │   ├── ActivelyCancelException.kt
│       │   │               │   │   ├── CompositeCoroutine.kt
│       │   │               │   │   ├── Coroutine.kt
│       │   │               │   │   └── CoroutineContainer.kt
│       │   │               │   ├── crypto/
│       │   │               │   │   ├── AsymmetricCrypto.kt
│       │   │               │   │   ├── README.md
│       │   │               │   │   ├── Sign.kt
│       │   │               │   │   └── SymmetricCryptoAndroid.kt
│       │   │               │   ├── exoplayer/
│       │   │               │   │   ├── ExoPlayerHelper.kt
│       │   │               │   │   └── InputStreamDataSource.kt
│       │   │               │   ├── glide/
│       │   │               │   │   ├── AsyncRecycleBitmapPool.kt
│       │   │               │   │   ├── BlurTransformation.kt
│       │   │               │   │   ├── FilePathLoader.kt
│       │   │               │   │   ├── GlideHeaders.kt
│       │   │               │   │   ├── ImageLoader.kt
│       │   │               │   │   ├── LegadoDataUrlLoader.kt
│       │   │               │   │   ├── LegadoGlideModule.kt
│       │   │               │   │   ├── OkHttpModeLoaderFactory.kt
│       │   │               │   │   ├── OkHttpModelLoader.kt
│       │   │               │   │   ├── OkHttpStreamFetcher.kt
│       │   │               │   │   └── progress/
│       │   │               │   │       ├── OnProgressListener.kt
│       │   │               │   │       ├── ProgressManager.kt
│       │   │               │   │       └── ProgressResponseBody.kt
│       │   │               │   ├── http/
│       │   │               │   │   ├── BackstageWebView.kt
│       │   │               │   │   ├── CookieManager.kt
│       │   │               │   │   ├── CookieStore.kt
│       │   │               │   │   ├── Cronet.kt
│       │   │               │   │   ├── DecompressInterceptor.kt
│       │   │               │   │   ├── HttpHelper.kt
│       │   │               │   │   ├── ObsoleteUrlFactory.kt
│       │   │               │   │   ├── OkHttpExceptionInterceptor.kt
│       │   │               │   │   ├── OkHttpUtils.kt
│       │   │               │   │   ├── OkhttpUncaughtExceptionHandler.kt
│       │   │               │   │   ├── RequestMethod.kt
│       │   │               │   │   ├── SSLHelper.kt
│       │   │               │   │   ├── StrResponse.kt
│       │   │               │   │   └── api/
│       │   │               │   │       └── CookieManagerInterface.kt
│       │   │               │   ├── rhino/
│       │   │               │   │   └── NativeBaseSource.kt
│       │   │               │   ├── source/
│       │   │               │   │   ├── BaseSourceExtensions.kt
│       │   │               │   │   ├── BookSourceExtensions.kt
│       │   │               │   │   ├── RssSourceExtensions.kt
│       │   │               │   │   ├── SourceHelp.kt
│       │   │               │   │   └── SourceVerificationHelp.kt
│       │   │               │   ├── storage/
│       │   │               │   │   ├── Backup.kt
│       │   │               │   │   ├── BackupAES.kt
│       │   │               │   │   ├── BackupConfig.kt
│       │   │               │   │   ├── ImportOldData.kt
│       │   │               │   │   └── Restore.kt
│       │   │               │   └── update/
│       │   │               │       ├── AppReleaseInfo.kt
│       │   │               │       ├── AppUpdate.kt
│       │   │               │       └── AppUpdateGitHub.kt
│       │   │               ├── lib/
│       │   │               │   ├── README.md
│       │   │               │   ├── aliyun/
│       │   │               │   │   └── ALiYun.kt
│       │   │               │   ├── cronet/
│       │   │               │   │   ├── AbsCallBack.kt
│       │   │               │   │   ├── BodyUploadProvider.kt
│       │   │               │   │   ├── CallbackResult.kt
│       │   │               │   │   ├── CallbackStep.kt
│       │   │               │   │   ├── CronetCoroutineInterceptor.kt
│       │   │               │   │   ├── CronetHelper.kt
│       │   │               │   │   ├── CronetInterceptor.kt
│       │   │               │   │   ├── CronetLoader.kt
│       │   │               │   │   ├── LargeBodyUploadProvider.kt
│       │   │               │   │   ├── NewCallBack.kt
│       │   │               │   │   └── OldCallback.kt
│       │   │               │   ├── dialogs/
│       │   │               │   │   ├── AlertBuilder.kt
│       │   │               │   │   ├── AndroidAlertBuilder.kt
│       │   │               │   │   ├── AndroidDialogs.kt
│       │   │               │   │   ├── AndroidSelectors.kt
│       │   │               │   │   └── SelectItem.kt
│       │   │               │   ├── icu4j/
│       │   │               │   │   ├── CharsetDetector.java
│       │   │               │   │   ├── CharsetMatch.java
│       │   │               │   │   ├── CharsetRecog_2022.java
│       │   │               │   │   ├── CharsetRecog_UTF8.java
│       │   │               │   │   ├── CharsetRecog_Unicode.java
│       │   │               │   │   ├── CharsetRecog_mbcs.java
│       │   │               │   │   ├── CharsetRecog_sbcs.java
│       │   │               │   │   └── CharsetRecognizer.java
│       │   │               │   ├── mobi/
│       │   │               │   │   ├── KF6Book.kt
│       │   │               │   │   ├── KF8Book.kt
│       │   │               │   │   ├── MobiBook.kt
│       │   │               │   │   ├── MobiReader.kt
│       │   │               │   │   ├── PDBFile.kt
│       │   │               │   │   ├── decompress/
│       │   │               │   │   │   ├── CDICData.kt
│       │   │               │   │   │   ├── Decompressor.kt
│       │   │               │   │   │   ├── HuffcdicDecompressor.kt
│       │   │               │   │   │   ├── Lz77Decompressor.kt
│       │   │               │   │   │   └── PlainDecompressor.kt
│       │   │               │   │   ├── entities/
│       │   │               │   │   │   ├── ExthRecordType.kt
│       │   │               │   │   │   ├── FdstHeader.kt
│       │   │               │   │   │   ├── Fragment.kt
│       │   │               │   │   │   ├── IndexData.kt
│       │   │               │   │   │   ├── IndexEntry.kt
│       │   │               │   │   │   ├── IndexTag.kt
│       │   │               │   │   │   ├── IndxHeader.kt
│       │   │               │   │   │   ├── KF6Section.kt
│       │   │               │   │   │   ├── KF8Header.kt
│       │   │               │   │   │   ├── KF8Pos.kt
│       │   │               │   │   │   ├── KF8Resource.kt
│       │   │               │   │   │   ├── KF8Section.kt
│       │   │               │   │   │   ├── MobiEntryHeaders.kt
│       │   │               │   │   │   ├── MobiHeader.kt
│       │   │               │   │   │   ├── MobiMetadata.kt
│       │   │               │   │   │   ├── NCX.kt
│       │   │               │   │   │   ├── PalmDocHeader.kt
│       │   │               │   │   │   ├── Ptagx.kt
│       │   │               │   │   │   ├── Skeleton.kt
│       │   │               │   │   │   ├── TOC.kt
│       │   │               │   │   │   ├── TagxHeader.kt
│       │   │               │   │   │   └── TagxTag.kt
│       │   │               │   │   └── utils/
│       │   │               │   │       ├── BitwiseExtensions.kt
│       │   │               │   │       └── ByteBufferExtensions.kt
│       │   │               │   ├── permission/
│       │   │               │   │   ├── OnErrorCallback.kt
│       │   │               │   │   ├── OnPermissionsDeniedCallback.kt
│       │   │               │   │   ├── OnPermissionsGrantedCallback.kt
│       │   │               │   │   ├── OnPermissionsResultCallback.kt
│       │   │               │   │   ├── OnRequestPermissionsResultCallback.kt
│       │   │               │   │   ├── PermissionActivity.kt
│       │   │               │   │   ├── Permissions.kt
│       │   │               │   │   ├── PermissionsCompat.kt
│       │   │               │   │   ├── Request.kt
│       │   │               │   │   ├── RequestManager.kt
│       │   │               │   │   └── RequestPlugins.kt
│       │   │               │   ├── prefs/
│       │   │               │   │   ├── ColorPreference.kt
│       │   │               │   │   ├── EditTextPreference.kt
│       │   │               │   │   ├── EditTextPreferenceDialog.kt
│       │   │               │   │   ├── IconListPreference.kt
│       │   │               │   │   ├── ListPreferenceDialog.kt
│       │   │               │   │   ├── MultiSelectListPreferenceDialog.kt
│       │   │               │   │   ├── NameListPreference.kt
│       │   │               │   │   ├── Preference.kt
│       │   │               │   │   ├── PreferenceCategory.kt
│       │   │               │   │   ├── SwitchPreference.kt
│       │   │               │   │   └── fragment/
│       │   │               │   │       └── PreferenceFragment.kt
│       │   │               │   ├── theme/
│       │   │               │   │   ├── MaterialValueHelper.kt
│       │   │               │   │   ├── Selector.kt
│       │   │               │   │   ├── ThemeStore.kt
│       │   │               │   │   ├── ThemeStoreInterface.kt
│       │   │               │   │   ├── ThemeStorePrefKeys.kt
│       │   │               │   │   ├── ThemeUtils.kt
│       │   │               │   │   ├── TintHelper.kt
│       │   │               │   │   ├── ViewUtils.kt
│       │   │               │   │   └── view/
│       │   │               │   │       ├── ThemeBottomNavigationVIew.kt
│       │   │               │   │       ├── ThemeCheckBox.kt
│       │   │               │   │       ├── ThemeEditText.kt
│       │   │               │   │       ├── ThemeProgressBar.kt
│       │   │               │   │       ├── ThemeRadioButton.kt
│       │   │               │   │       ├── ThemeRadioNoButton.kt
│       │   │               │   │       ├── ThemeSeekBar.kt
│       │   │               │   │       └── ThemeSwitch.kt
│       │   │               │   └── webdav/
│       │   │               │       ├── Authorization.kt
│       │   │               │       ├── WebDav.kt
│       │   │               │       ├── WebDavException.kt
│       │   │               │       └── WebDavFile.kt
│       │   │               ├── model/
│       │   │               │   ├── AudioPlay.kt
│       │   │               │   ├── BookCover.kt
│       │   │               │   ├── CacheBook.kt
│       │   │               │   ├── CheckSource.kt
│       │   │               │   ├── Debug.kt
│       │   │               │   ├── Download.kt
│       │   │               │   ├── ImageProvider.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── ReadAloud.kt
│       │   │               │   ├── ReadBook.kt
│       │   │               │   ├── ReadManga.kt
│       │   │               │   ├── SharedJsScope.kt
│       │   │               │   ├── analyzeRule/
│       │   │               │   │   ├── AnalyzeByJSonPath.kt
│       │   │               │   │   ├── AnalyzeByJSoup.kt
│       │   │               │   │   ├── AnalyzeByRegex.kt
│       │   │               │   │   ├── AnalyzeByXPath.kt
│       │   │               │   │   ├── AnalyzeRule.kt
│       │   │               │   │   ├── AnalyzeUrl.kt
│       │   │               │   │   ├── CustomUrl.kt
│       │   │               │   │   ├── QueryTTF.java
│       │   │               │   │   ├── RuleAnalyzer.kt
│       │   │               │   │   ├── RuleData.kt
│       │   │               │   │   └── RuleDataInterface.kt
│       │   │               │   ├── localBook/
│       │   │               │   │   ├── BaseLocalBookParse.kt
│       │   │               │   │   ├── EpubFile.kt
│       │   │               │   │   ├── LocalBook.kt
│       │   │               │   │   ├── MobiFile.kt
│       │   │               │   │   ├── PdfFile.kt
│       │   │               │   │   ├── README.md
│       │   │               │   │   ├── TextFile.kt
│       │   │               │   │   └── UmdFile.kt
│       │   │               │   ├── remote/
│       │   │               │   │   ├── RemoteBook.kt
│       │   │               │   │   ├── RemoteBookManager.kt
│       │   │               │   │   └── RemoteBookWebDav.kt
│       │   │               │   ├── rss/
│       │   │               │   │   ├── Rss.kt
│       │   │               │   │   ├── RssParserByRule.kt
│       │   │               │   │   └── RssParserDefault.kt
│       │   │               │   └── webBook/
│       │   │               │       ├── BookChapterList.kt
│       │   │               │       ├── BookContent.kt
│       │   │               │       ├── BookInfo.kt
│       │   │               │       ├── BookList.kt
│       │   │               │       ├── SearchModel.kt
│       │   │               │       └── WebBook.kt
│       │   │               ├── receiver/
│       │   │               │   ├── MediaButtonReceiver.kt
│       │   │               │   ├── NetworkChangedListener.kt
│       │   │               │   ├── SharedReceiverActivity.kt
│       │   │               │   └── TimeBatteryReceiver.kt
│       │   │               ├── service/
│       │   │               │   ├── AudioPlayService.kt
│       │   │               │   ├── BaseReadAloudService.kt
│       │   │               │   ├── CacheBookService.kt
│       │   │               │   ├── CheckSourceService.kt
│       │   │               │   ├── DownloadService.kt
│       │   │               │   ├── ExportBookService.kt
│       │   │               │   ├── HttpReadAloudService.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── TTSReadAloudService.kt
│       │   │               │   ├── WebService.kt
│       │   │               │   └── WebTileService.kt
│       │   │               ├── ui/
│       │   │               │   ├── README.md
│       │   │               │   ├── about/
│       │   │               │   │   ├── AboutActivity.kt
│       │   │               │   │   ├── AboutFragment.kt
│       │   │               │   │   ├── AppLogDialog.kt
│       │   │               │   │   ├── CrashLogsDialog.kt
│       │   │               │   │   ├── ReadRecordActivity.kt
│       │   │               │   │   └── UpdateDialog.kt
│       │   │               │   ├── association/
│       │   │               │   │   ├── AddToBookshelfDialog.kt
│       │   │               │   │   ├── BaseAssociationViewModel.kt
│       │   │               │   │   ├── FileAssociationActivity.kt
│       │   │               │   │   ├── FileAssociationViewModel.kt
│       │   │               │   │   ├── ImportBookSourceDialog.kt
│       │   │               │   │   ├── ImportBookSourceViewModel.kt
│       │   │               │   │   ├── ImportDictRuleDialog.kt
│       │   │               │   │   ├── ImportDictRuleViewModel.kt
│       │   │               │   │   ├── ImportHttpTtsDialog.kt
│       │   │               │   │   ├── ImportHttpTtsViewModel.kt
│       │   │               │   │   ├── ImportReplaceRuleDialog.kt
│       │   │               │   │   ├── ImportReplaceRuleViewModel.kt
│       │   │               │   │   ├── ImportRssSourceDialog.kt
│       │   │               │   │   ├── ImportRssSourceViewModel.kt
│       │   │               │   │   ├── ImportThemeDialog.kt
│       │   │               │   │   ├── ImportThemeViewModel.kt
│       │   │               │   │   ├── ImportTxtTocRuleDialog.kt
│       │   │               │   │   ├── ImportTxtTocRuleViewModel.kt
│       │   │               │   │   ├── OnLineImportActivity.kt
│       │   │               │   │   ├── OnLineImportViewModel.kt
│       │   │               │   │   ├── OpenUrlConfirmActivity.kt
│       │   │               │   │   ├── OpenUrlConfirmDialog.kt
│       │   │               │   │   ├── OpenUrlConfirmViewModel.kt
│       │   │               │   │   ├── VerificationCodeActivity.kt
│       │   │               │   │   ├── VerificationCodeDialog.kt
│       │   │               │   │   └── VerificationCodeViewModel.kt
│       │   │               │   ├── book/
│       │   │               │   │   ├── audio/
│       │   │               │   │   │   ├── AudioPlayActivity.kt
│       │   │               │   │   │   ├── AudioPlayViewModel.kt
│       │   │               │   │   │   └── TimerSliderPopup.kt
│       │   │               │   │   ├── bookmark/
│       │   │               │   │   │   ├── AllBookmarkActivity.kt
│       │   │               │   │   │   ├── AllBookmarkViewModel.kt
│       │   │               │   │   │   ├── BookmarkAdapter.kt
│       │   │               │   │   │   ├── BookmarkDecoration.kt
│       │   │               │   │   │   └── BookmarkDialog.kt
│       │   │               │   │   ├── cache/
│       │   │               │   │   │   ├── CacheActivity.kt
│       │   │               │   │   │   ├── CacheAdapter.kt
│       │   │               │   │   │   └── CacheViewModel.kt
│       │   │               │   │   ├── changecover/
│       │   │               │   │   │   ├── ChangeCoverDialog.kt
│       │   │               │   │   │   ├── ChangeCoverViewModel.kt
│       │   │               │   │   │   └── CoverAdapter.kt
│       │   │               │   │   ├── changesource/
│       │   │               │   │   │   ├── ChangeBookSourceAdapter.kt
│       │   │               │   │   │   ├── ChangeBookSourceDialog.kt
│       │   │               │   │   │   ├── ChangeBookSourceViewModel.kt
│       │   │               │   │   │   ├── ChangeChapterSourceAdapter.kt
│       │   │               │   │   │   ├── ChangeChapterSourceDialog.kt
│       │   │               │   │   │   ├── ChangeChapterSourceViewModel.kt
│       │   │               │   │   │   └── ChangeChapterTocAdapter.kt
│       │   │               │   │   ├── explore/
│       │   │               │   │   │   ├── ExploreShowActivity.kt
│       │   │               │   │   │   ├── ExploreShowAdapter.kt
│       │   │               │   │   │   └── ExploreShowViewModel.kt
│       │   │               │   │   ├── group/
│       │   │               │   │   │   ├── GroupEditDialog.kt
│       │   │               │   │   │   ├── GroupManageDialog.kt
│       │   │               │   │   │   ├── GroupSelectDialog.kt
│       │   │               │   │   │   └── GroupViewModel.kt
│       │   │               │   │   ├── import/
│       │   │               │   │   │   ├── BaseImportBookActivity.kt
│       │   │               │   │   │   ├── local/
│       │   │               │   │   │   │   ├── ImportBook.kt
│       │   │               │   │   │   │   ├── ImportBookActivity.kt
│       │   │               │   │   │   │   ├── ImportBookAdapter.kt
│       │   │               │   │   │   │   └── ImportBookViewModel.kt
│       │   │               │   │   │   └── remote/
│       │   │               │   │   │       ├── RemoteBookActivity.kt
│       │   │               │   │   │       ├── RemoteBookAdapter.kt
│       │   │               │   │   │       ├── RemoteBookSort.kt
│       │   │               │   │   │       ├── RemoteBookViewModel.kt
│       │   │               │   │   │       ├── ServerConfigDialog.kt
│       │   │               │   │   │       ├── ServerConfigViewModel.kt
│       │   │               │   │   │       ├── ServersDialog.kt
│       │   │               │   │   │       └── ServersViewModel.kt
│       │   │               │   │   ├── info/
│       │   │               │   │   │   ├── BookInfoActivity.kt
│       │   │               │   │   │   ├── BookInfoViewModel.kt
│       │   │               │   │   │   └── edit/
│       │   │               │   │   │       ├── BookInfoEditActivity.kt
│       │   │               │   │   │       └── BookInfoEditViewModel.kt
│       │   │               │   │   ├── manage/
│       │   │               │   │   │   ├── BookAdapter.kt
│       │   │               │   │   │   ├── BookshelfManageActivity.kt
│       │   │               │   │   │   ├── BookshelfManageViewModel.kt
│       │   │               │   │   │   └── SourcePickerDialog.kt
│       │   │               │   │   ├── manga/
│       │   │               │   │   │   ├── ReadMangaActivity.kt
│       │   │               │   │   │   ├── ReadMangaViewModel.kt
│       │   │               │   │   │   ├── config/
│       │   │               │   │   │   │   ├── MangaColorFilterConfig.kt
│       │   │               │   │   │   │   ├── MangaColorFilterDialog.kt
│       │   │               │   │   │   │   ├── MangaEpaperDialog.kt
│       │   │               │   │   │   │   ├── MangaFooterConfig.kt
│       │   │               │   │   │   │   └── MangaFooterSettingDialog.kt
│       │   │               │   │   │   ├── entities/
│       │   │               │   │   │   │   ├── BaseMangaPage.kt
│       │   │               │   │   │   │   ├── EpaperTransformation.kt
│       │   │               │   │   │   │   ├── GrayscaleTransformation.kt
│       │   │               │   │   │   │   ├── MangaChapter.kt
│       │   │               │   │   │   │   ├── MangaContent.kt
│       │   │               │   │   │   │   ├── MangaPage.kt
│       │   │               │   │   │   │   └── ReaderLoading.kt
│       │   │               │   │   │   └── recyclerview/
│       │   │               │   │   │       ├── GestureDetectorWithLongTap.kt
│       │   │               │   │   │       ├── MangaAdapter.kt
│       │   │               │   │   │       ├── MangaLayoutManager.kt
│       │   │               │   │   │       ├── MangaVH.kt
│       │   │               │   │   │       ├── ScrollTimer.kt
│       │   │               │   │   │       ├── WebtoonFrame.kt
│       │   │               │   │   │       └── WebtoonRecyclerView.kt
│       │   │               │   │   ├── read/
│       │   │               │   │   │   ├── BaseReadBookActivity.kt
│       │   │               │   │   │   ├── ContentEditDialog.kt
│       │   │               │   │   │   ├── EffectiveReplacesDialog.kt
│       │   │               │   │   │   ├── MangaMenu.kt
│       │   │               │   │   │   ├── ReadBookActivity.kt
│       │   │               │   │   │   ├── ReadBookViewModel.kt
│       │   │               │   │   │   ├── ReadMenu.kt
│       │   │               │   │   │   ├── SearchMenu.kt
│       │   │               │   │   │   ├── TextActionMenu.kt
│       │   │               │   │   │   ├── config/
│       │   │               │   │   │   │   ├── AutoReadDialog.kt
│       │   │               │   │   │   │   ├── BgAdapter.kt
│       │   │               │   │   │   │   ├── BgTextConfigDialog.kt
│       │   │               │   │   │   │   ├── ChineseConverter.kt
│       │   │               │   │   │   │   ├── ClickActionConfigDialog.kt
│       │   │               │   │   │   │   ├── HttpTtsEditDialog.kt
│       │   │               │   │   │   │   ├── HttpTtsEditViewModel.kt
│       │   │               │   │   │   │   ├── MoreConfigDialog.kt
│       │   │               │   │   │   │   ├── PaddingConfigDialog.kt
│       │   │               │   │   │   │   ├── PageKeyDialog.kt
│       │   │               │   │   │   │   ├── ReadAloudConfigDialog.kt
│       │   │               │   │   │   │   ├── ReadAloudDialog.kt
│       │   │               │   │   │   │   ├── ReadStyleDialog.kt
│       │   │               │   │   │   │   ├── SpeakEngineDialog.kt
│       │   │               │   │   │   │   ├── SpeakEngineViewModel.kt
│       │   │               │   │   │   │   ├── TextFontWeightConverter.kt
│       │   │               │   │   │   │   └── TipConfigDialog.kt
│       │   │               │   │   │   └── page/
│       │   │               │   │   │       ├── AutoPager.kt
│       │   │               │   │   │       ├── ContentTextView.kt
│       │   │               │   │   │       ├── PageView.kt
│       │   │               │   │   │       ├── ReadView.kt
│       │   │               │   │   │       ├── api/
│       │   │               │   │   │       │   ├── DataSource.kt
│       │   │               │   │   │       │   └── PageFactory.kt
│       │   │               │   │   │       ├── delegate/
│       │   │               │   │   │       │   ├── CoverPageDelegate.kt
│       │   │               │   │   │       │   ├── HorizontalPageDelegate.kt
│       │   │               │   │   │       │   ├── NoAnimPageDelegate.kt
│       │   │               │   │   │       │   ├── PageDelegate.kt
│       │   │               │   │   │       │   ├── ScrollPageDelegate.kt
│       │   │               │   │   │       │   ├── SimulationPageDelegate.kt
│       │   │               │   │   │       │   └── SlidePageDelegate.kt
│       │   │               │   │   │       ├── entities/
│       │   │               │   │   │       │   ├── PageDirection.kt
│       │   │               │   │   │       │   ├── TextChapter.kt
│       │   │               │   │   │       │   ├── TextLine.kt
│       │   │               │   │   │       │   ├── TextPage.kt
│       │   │               │   │   │       │   ├── TextParagraph.kt
│       │   │               │   │   │       │   ├── TextPos.kt
│       │   │               │   │   │       │   └── column/
│       │   │               │   │   │       │       ├── BaseColumn.kt
│       │   │               │   │   │       │       ├── ButtonColumn.kt
│       │   │               │   │   │       │       ├── ImageColumn.kt
│       │   │               │   │   │       │       ├── ReviewColumn.kt
│       │   │               │   │   │       │       └── TextColumn.kt
│       │   │               │   │   │       └── provider/
│       │   │               │   │   │           ├── ChapterProvider.kt
│       │   │               │   │   │           ├── LayoutProgressListener.kt
│       │   │               │   │   │           ├── TextChapterLayout.kt
│       │   │               │   │   │           ├── TextMeasure.kt
│       │   │               │   │   │           ├── TextPageFactory.kt
│       │   │               │   │   │           └── ZhLayout.kt
│       │   │               │   │   ├── search/
│       │   │               │   │   │   ├── BookAdapter.kt
│       │   │               │   │   │   ├── HistoryKeyAdapter.kt
│       │   │               │   │   │   ├── SearchActivity.kt
│       │   │               │   │   │   ├── SearchAdapter.kt
│       │   │               │   │   │   ├── SearchScope.kt
│       │   │               │   │   │   ├── SearchScopeDialog.kt
│       │   │               │   │   │   └── SearchViewModel.kt
│       │   │               │   │   ├── searchContent/
│       │   │               │   │   │   ├── SearchContentActivity.kt
│       │   │               │   │   │   ├── SearchContentAdapter.kt
│       │   │               │   │   │   ├── SearchContentViewModel.kt
│       │   │               │   │   │   └── SearchResult.kt
│       │   │               │   │   ├── source/
│       │   │               │   │   │   ├── debug/
│       │   │               │   │   │   │   ├── BookSourceDebugActivity.kt
│       │   │               │   │   │   │   ├── BookSourceDebugAdapter.kt
│       │   │               │   │   │   │   └── BookSourceDebugModel.kt
│       │   │               │   │   │   ├── edit/
│       │   │               │   │   │   │   ├── BookSourceEditActivity.kt
│       │   │               │   │   │   │   ├── BookSourceEditAdapter.kt
│       │   │               │   │   │   │   └── BookSourceEditViewModel.kt
│       │   │               │   │   │   └── manage/
│       │   │               │   │   │       ├── BookSourceActivity.kt
│       │   │               │   │   │       ├── BookSourceAdapter.kt
│       │   │               │   │   │       ├── BookSourceSort.kt
│       │   │               │   │   │       ├── BookSourceViewModel.kt
│       │   │               │   │   │       └── GroupManageDialog.kt
│       │   │               │   │   └── toc/
│       │   │               │   │       ├── BookmarkAdapter.kt
│       │   │               │   │       ├── BookmarkFragment.kt
│       │   │               │   │       ├── ChapterListAdapter.kt
│       │   │               │   │       ├── ChapterListFragment.kt
│       │   │               │   │       ├── TocActivity.kt
│       │   │               │   │       ├── TocActivityResult.kt
│       │   │               │   │       ├── TocViewModel.kt
│       │   │               │   │       └── rule/
│       │   │               │   │           ├── TxtTocRuleActivity.kt
│       │   │               │   │           ├── TxtTocRuleAdapter.kt
│       │   │               │   │           ├── TxtTocRuleDialog.kt
│       │   │               │   │           ├── TxtTocRuleEditDialog.kt
│       │   │               │   │           └── TxtTocRuleViewModel.kt
│       │   │               │   ├── browser/
│       │   │               │   │   ├── WebViewActivity.kt
│       │   │               │   │   └── WebViewModel.kt
│       │   │               │   ├── config/
│       │   │               │   │   ├── BackupConfigFragment.kt
│       │   │               │   │   ├── CheckSourceConfig.kt
│       │   │               │   │   ├── ConfigActivity.kt
│       │   │               │   │   ├── ConfigTag.kt
│       │   │               │   │   ├── ConfigViewModel.kt
│       │   │               │   │   ├── CoverConfigFragment.kt
│       │   │               │   │   ├── CoverRuleConfigDialog.kt
│       │   │               │   │   ├── DirectLinkUploadConfig.kt
│       │   │               │   │   ├── OtherConfigFragment.kt
│       │   │               │   │   ├── ThemeConfigFragment.kt
│       │   │               │   │   ├── ThemeListDialog.kt
│       │   │               │   │   └── WelcomeConfigFragment.kt
│       │   │               │   ├── dict/
│       │   │               │   │   ├── DictDialog.kt
│       │   │               │   │   ├── DictViewModel.kt
│       │   │               │   │   └── rule/
│       │   │               │   │       ├── DictRuleActivity.kt
│       │   │               │   │       ├── DictRuleAdapter.kt
│       │   │               │   │       ├── DictRuleEditDialog.kt
│       │   │               │   │       └── DictRuleViewModel.kt
│       │   │               │   ├── file/
│       │   │               │   │   ├── FileManageActivity.kt
│       │   │               │   │   ├── FileManageViewModel.kt
│       │   │               │   │   ├── FilePickerDialog.kt
│       │   │               │   │   ├── FilePickerViewModel.kt
│       │   │               │   │   ├── HandleFileActivity.kt
│       │   │               │   │   ├── HandleFileContract.kt
│       │   │               │   │   ├── HandleFileViewModel.kt
│       │   │               │   │   └── utils/
│       │   │               │   │       └── FilePickerIcon.java
│       │   │               │   ├── font/
│       │   │               │   │   ├── FontAdapter.kt
│       │   │               │   │   └── FontSelectDialog.kt
│       │   │               │   ├── login/
│       │   │               │   │   ├── SourceLoginActivity.kt
│       │   │               │   │   ├── SourceLoginDialog.kt
│       │   │               │   │   ├── SourceLoginViewModel.kt
│       │   │               │   │   └── WebViewLoginFragment.kt
│       │   │               │   ├── main/
│       │   │               │   │   ├── MainActivity.kt
│       │   │               │   │   ├── MainFragmentInterface.kt
│       │   │               │   │   ├── MainViewModel.kt
│       │   │               │   │   ├── bookshelf/
│       │   │               │   │   │   ├── BaseBookshelfFragment.kt
│       │   │               │   │   │   ├── BookshelfViewModel.kt
│       │   │               │   │   │   ├── style1/
│       │   │               │   │   │   │   ├── BookshelfFragment1.kt
│       │   │               │   │   │   │   └── books/
│       │   │               │   │   │   │       ├── BaseBooksAdapter.kt
│       │   │               │   │   │   │       ├── BooksAdapterGrid.kt
│       │   │               │   │   │   │       ├── BooksAdapterList.kt
│       │   │               │   │   │   │       └── BooksFragment.kt
│       │   │               │   │   │   └── style2/
│       │   │               │   │   │       ├── BaseBooksAdapter.kt
│       │   │               │   │   │       ├── BooksAdapterGrid.kt
│       │   │               │   │   │       ├── BooksAdapterList.kt
│       │   │               │   │   │       └── BookshelfFragment2.kt
│       │   │               │   │   ├── explore/
│       │   │               │   │   │   ├── ExploreAdapter.kt
│       │   │               │   │   │   ├── ExploreDiffItemCallBack.kt
│       │   │               │   │   │   ├── ExploreFragment.kt
│       │   │               │   │   │   └── ExploreViewModel.kt
│       │   │               │   │   ├── my/
│       │   │               │   │   │   └── MyFragment.kt
│       │   │               │   │   └── rss/
│       │   │               │   │       ├── RssAdapter.kt
│       │   │               │   │       ├── RssFragment.kt
│       │   │               │   │       └── RssViewModel.kt
│       │   │               │   ├── qrcode/
│       │   │               │   │   ├── QrCodeActivity.kt
│       │   │               │   │   ├── QrCodeFragment.kt
│       │   │               │   │   ├── QrCodeResult.kt
│       │   │               │   │   └── ScanResultCallback.kt
│       │   │               │   ├── replace/
│       │   │               │   │   ├── GroupManageDialog.kt
│       │   │               │   │   ├── ReplaceRuleActivity.kt
│       │   │               │   │   ├── ReplaceRuleAdapter.kt
│       │   │               │   │   ├── ReplaceRuleViewModel.kt
│       │   │               │   │   └── edit/
│       │   │               │   │       ├── ReplaceEditActivity.kt
│       │   │               │   │       └── ReplaceEditViewModel.kt
│       │   │               │   ├── rss/
│       │   │               │   │   ├── article/
│       │   │               │   │   │   ├── BaseRssArticlesAdapter.kt
│       │   │               │   │   │   ├── ReadRecordDialog.kt
│       │   │               │   │   │   ├── RssArticlesAdapter.kt
│       │   │               │   │   │   ├── RssArticlesAdapter1.kt
│       │   │               │   │   │   ├── RssArticlesAdapter2.kt
│       │   │               │   │   │   ├── RssArticlesFragment.kt
│       │   │               │   │   │   ├── RssArticlesViewModel.kt
│       │   │               │   │   │   ├── RssSortActivity.kt
│       │   │               │   │   │   └── RssSortViewModel.kt
│       │   │               │   │   ├── favorites/
│       │   │               │   │   │   ├── RssFavoritesActivity.kt
│       │   │               │   │   │   ├── RssFavoritesAdapter.kt
│       │   │               │   │   │   ├── RssFavoritesDialog.kt
│       │   │               │   │   │   ├── RssFavoritesFragment.kt
│       │   │               │   │   │   └── RssFavoritesViewModel.kt
│       │   │               │   │   ├── read/
│       │   │               │   │   │   ├── ReadRssActivity.kt
│       │   │               │   │   │   ├── ReadRssViewModel.kt
│       │   │               │   │   │   ├── RssJsExtensions.kt
│       │   │               │   │   │   └── VisibleWebView.kt
│       │   │               │   │   ├── source/
│       │   │               │   │   │   ├── debug/
│       │   │               │   │   │   │   ├── RssSourceDebugActivity.kt
│       │   │               │   │   │   │   ├── RssSourceDebugAdapter.kt
│       │   │               │   │   │   │   └── RssSourceDebugModel.kt
│       │   │               │   │   │   ├── edit/
│       │   │               │   │   │   │   ├── RssSourceEditActivity.kt
│       │   │               │   │   │   │   ├── RssSourceEditAdapter.kt
│       │   │               │   │   │   │   └── RssSourceEditViewModel.kt
│       │   │               │   │   │   └── manage/
│       │   │               │   │   │       ├── GroupManageDialog.kt
│       │   │               │   │   │       ├── RssSourceActivity.kt
│       │   │               │   │   │       ├── RssSourceAdapter.kt
│       │   │               │   │   │       └── RssSourceViewModel.kt
│       │   │               │   │   └── subscription/
│       │   │               │   │       ├── RuleSubActivity.kt
│       │   │               │   │       └── RuleSubAdapter.kt
│       │   │               │   ├── welcome/
│       │   │               │   │   └── WelcomeActivity.kt
│       │   │               │   └── widget/
│       │   │               │       ├── BatteryView.kt
│       │   │               │       ├── DetailSeekBar.kt
│       │   │               │       ├── LabelsBar.kt
│       │   │               │       ├── NoChildScrollNestedScrollView.kt
│       │   │               │       ├── PopupAction.kt
│       │   │               │       ├── ReaderInfoBarView.kt
│       │   │               │       ├── SearchView.kt
│       │   │               │       ├── SelectActionBar.kt
│       │   │               │       ├── ShadowLayout.kt
│       │   │               │       ├── TitleBar.kt
│       │   │               │       ├── anima/
│       │   │               │       │   ├── RefreshProgressBar.kt
│       │   │               │       │   ├── RotateLoading.kt
│       │   │               │       │   └── explosion_field/
│       │   │               │       │       ├── ExplosionAnimator.kt
│       │   │               │       │       ├── ExplosionField.kt
│       │   │               │       │       ├── ExplosionView.kt
│       │   │               │       │       ├── OnAnimatorListener.kt
│       │   │               │       │       └── Utils.kt
│       │   │               │       ├── checkbox/
│       │   │               │       │   └── SmoothCheckBox.kt
│       │   │               │       ├── code/
│       │   │               │       │   ├── CodeView.kt
│       │   │               │       │   ├── CodeViewExtensions.kt
│       │   │               │       │   └── KeywordTokenizer.kt
│       │   │               │       ├── dialog/
│       │   │               │       │   ├── CodeDialog.kt
│       │   │               │       │   ├── PhotoDialog.kt
│       │   │               │       │   ├── TextDialog.kt
│       │   │               │       │   ├── TextListDialog.kt
│       │   │               │       │   ├── UrlOptionDialog.kt
│       │   │               │       │   ├── VariableDialog.kt
│       │   │               │       │   └── WaitDialog.kt
│       │   │               │       ├── dynamiclayout/
│       │   │               │       │   ├── DynamicFrameLayout.kt
│       │   │               │       │   └── ViewSwitcher.kt
│       │   │               │       ├── image/
│       │   │               │       │   ├── ArcView.kt
│       │   │               │       │   ├── CircleImageView.kt
│       │   │               │       │   ├── CoverImageView.kt
│       │   │               │       │   ├── FilletImageView.kt
│       │   │               │       │   ├── ImageButton.kt
│       │   │               │       │   ├── PhotoView.kt
│       │   │               │       │   └── photo/
│       │   │               │       │       ├── Info.kt
│       │   │               │       │       └── RotateGestureDetector.kt
│       │   │               │       ├── keyboard/
│       │   │               │       │   ├── KeyboardAssistsConfig.kt
│       │   │               │       │   └── KeyboardToolPop.kt
│       │   │               │       ├── number/
│       │   │               │       │   └── NumberPickerDialog.kt
│       │   │               │       ├── recycler/
│       │   │               │       │   ├── DividerNoLast.kt
│       │   │               │       │   ├── DragSelectTouchHelper.kt
│       │   │               │       │   ├── HeaderAdapterDataObserver.kt
│       │   │               │       │   ├── ItemTouchCallback.kt
│       │   │               │       │   ├── LoadMoreView.kt
│       │   │               │       │   ├── NoChildScrollLinearLayoutManager.kt
│       │   │               │       │   ├── RecyclerViewAtPager2.kt
│       │   │               │       │   ├── UpLinearLayoutManager.kt
│       │   │               │       │   ├── VerticalDivider.kt
│       │   │               │       │   ├── ViewPager2Container.kt
│       │   │               │       │   └── scroller/
│       │   │               │       │       ├── FastScrollRecyclerView.kt
│       │   │               │       │       ├── FastScrollStateChangeListener.kt
│       │   │               │       │       └── FastScroller.kt
│       │   │               │       ├── seekbar/
│       │   │               │       │   ├── SeekBarChangeListener.kt
│       │   │               │       │   ├── VerticalSeekBar.kt
│       │   │               │       │   └── VerticalSeekBarWrapper.kt
│       │   │               │       └── text/
│       │   │               │           ├── AccentBgTextView.kt
│       │   │               │           ├── AccentStrokeTextView.kt
│       │   │               │           ├── AccentTextView.kt
│       │   │               │           ├── AutoCompleteTextView.kt
│       │   │               │           ├── BadgeView.kt
│       │   │               │           ├── BevelLabelView.kt
│       │   │               │           ├── EditEntity.kt
│       │   │               │           ├── MultilineTextView.kt
│       │   │               │           ├── PrimaryTextView.kt
│       │   │               │           ├── ScrollMultiAutoCompleteTextView.kt
│       │   │               │           ├── ScrollTextView.kt
│       │   │               │           ├── SecondaryTextView.kt
│       │   │               │           ├── StrokeTextView.kt
│       │   │               │           └── TextInputLayout.kt
│       │   │               ├── utils/
│       │   │               │   ├── ACache.kt
│       │   │               │   ├── ActivityExtensions.kt
│       │   │               │   ├── ActivityResult.kt
│       │   │               │   ├── ActivityResultContracts.kt
│       │   │               │   ├── AlphanumComparator.kt
│       │   │               │   ├── AnimationExtensions.kt
│       │   │               │   ├── ArchiveUtils.kt
│       │   │               │   ├── AsyncFileHandler.kt
│       │   │               │   ├── BitmapUtils.kt
│       │   │               │   ├── BookChapterExtensions.kt
│       │   │               │   ├── ByteArrayExtensions.kt
│       │   │               │   ├── ChineseUtils.kt
│       │   │               │   ├── CollectionExtensions.kt
│       │   │               │   ├── ColorUtils.kt
│       │   │               │   ├── ConfigurationExtensions.kt
│       │   │               │   ├── ConflateLiveData.kt
│       │   │               │   ├── ConstraintModify.kt
│       │   │               │   ├── ContextExtensions.kt
│       │   │               │   ├── ConvertExtensions.kt
│       │   │               │   ├── CookieManagerExtensions.kt
│       │   │               │   ├── CoroutineExtensions.kt
│       │   │               │   ├── CustomExportUtils.kt
│       │   │               │   ├── Debounce.kt
│       │   │               │   ├── DebugLog.kt
│       │   │               │   ├── DialogExtensions.kt
│       │   │               │   ├── DocumentUtils.kt
│       │   │               │   ├── DrawableUtils.kt
│       │   │               │   ├── EncoderUtils.kt
│       │   │               │   ├── EncodingDetect.kt
│       │   │               │   ├── EventBusExtensions.kt
│       │   │               │   ├── FileDocExtensions.kt
│       │   │               │   ├── FileExtensions.kt
│       │   │               │   ├── FileUtils.kt
│       │   │               │   ├── FlowExtensions.kt
│       │   │               │   ├── FragmentExtensions.kt
│       │   │               │   ├── GsonExtensions.kt
│       │   │               │   ├── HandlerUtils.kt
│       │   │               │   ├── HtmlFormatter.kt
│       │   │               │   ├── ImageUtils.kt
│       │   │               │   ├── InputStreamExtensions.kt
│       │   │               │   ├── IntentExtensions.kt
│       │   │               │   ├── IntentType.kt
│       │   │               │   ├── JsURL.kt
│       │   │               │   ├── JsonExtensions.kt
│       │   │               │   ├── JsoupExtensions.kt
│       │   │               │   ├── LogUtils.kt
│       │   │               │   ├── MD5Utils.kt
│       │   │               │   ├── MapExtensions.kt
│       │   │               │   ├── MenuExtensions.kt
│       │   │               │   ├── MenuItemExtensions.kt
│       │   │               │   ├── MutableLiveDataExtensions.kt
│       │   │               │   ├── NavigationViewUtils.kt
│       │   │               │   ├── NetworkUtils.kt
│       │   │               │   ├── PaintExtensions.kt
│       │   │               │   ├── ParcelFileDescriptorChannel.kt
│       │   │               │   ├── PreferencesExtensions.kt
│       │   │               │   ├── QRCodeUtils.kt
│       │   │               │   ├── RandomColor.kt
│       │   │               │   ├── RealPathUtil.kt
│       │   │               │   ├── RecyclerViewExtensions.kt
│       │   │               │   ├── RegexExtensions.kt
│       │   │               │   ├── RequestManagerExtensions.kt
│       │   │               │   ├── Snackbars.kt
│       │   │               │   ├── StringExtensions.kt
│       │   │               │   ├── StringUtils.kt
│       │   │               │   ├── SvgUtils.kt
│       │   │               │   ├── SyncedRenderer.kt
│       │   │               │   ├── SystemUtils.kt
│       │   │               │   ├── Throttle.kt
│       │   │               │   ├── ThrowableExtensions.kt
│       │   │               │   ├── TimeUtils.kt
│       │   │               │   ├── ToastUtils.kt
│       │   │               │   ├── ToolBarExtensions.kt
│       │   │               │   ├── UriExtensions.kt
│       │   │               │   ├── UrlUtil.kt
│       │   │               │   ├── Utf8BomUtils.kt
│       │   │               │   ├── ViewExtensions.kt
│       │   │               │   ├── WebSettingsExtensions.kt
│       │   │               │   ├── WindowInsetsExtensions.kt
│       │   │               │   ├── canvasrecorder/
│       │   │               │   │   ├── BaseCanvasRecorder.kt
│       │   │               │   │   ├── CanvasRecorder.kt
│       │   │               │   │   ├── CanvasRecorderApi23Impl.kt
│       │   │               │   │   ├── CanvasRecorderApi29Impl.kt
│       │   │               │   │   ├── CanvasRecorderExtensions.kt
│       │   │               │   │   ├── CanvasRecorderFactory.kt
│       │   │               │   │   ├── CanvasRecorderImpl.kt
│       │   │               │   │   ├── CanvasRecorderLocked.kt
│       │   │               │   │   └── pools/
│       │   │               │   │       ├── CanvasPool.kt
│       │   │               │   │       ├── PicturePool.kt
│       │   │               │   │       └── RenderNodePool.kt
│       │   │               │   ├── compress/
│       │   │               │   │   ├── LibArchiveUtils.kt
│       │   │               │   │   └── ZipUtils.kt
│       │   │               │   ├── objectpool/
│       │   │               │   │   ├── BaseObjectPool.kt
│       │   │               │   │   ├── BaseSafeObjectPool.kt
│       │   │               │   │   ├── ObjectPool.kt
│       │   │               │   │   ├── ObjectPoolExtensions.kt
│       │   │               │   │   └── ObjectPoolLocked.kt
│       │   │               │   └── viewbindingdelegate/
│       │   │               │       ├── ActivityViewBindings.kt
│       │   │               │       ├── FragmentViewBindings.kt
│       │   │               │       └── ViewBindingProperty.kt
│       │   │               └── web/
│       │   │                   ├── HttpServer.kt
│       │   │                   ├── ReadMe.md
│       │   │                   ├── WebSocketServer.kt
│       │   │                   ├── socket/
│       │   │                   │   ├── BookSearchWebSocket.kt
│       │   │                   │   ├── BookSourceDebugWebSocket.kt
│       │   │                   │   └── RssSourceDebugWebSocket.kt
│       │   │                   └── utils/
│       │   │                       └── AssetsWeb.kt
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── anim_none.xml
│       │       │   ├── anim_readbook_bottom_in.xml
│       │       │   ├── anim_readbook_bottom_out.xml
│       │       │   ├── anim_readbook_top_in.xml
│       │       │   └── anim_readbook_top_out.xml
│       │       ├── color/
│       │       │   └── selector_image.xml
│       │       ├── drawable/
│       │       │   ├── bg_chapter_item_divider.xml
│       │       │   ├── bg_edit.xml
│       │       │   ├── bg_eink_border_bottom.xml
│       │       │   ├── bg_eink_border_dialog.xml
│       │       │   ├── bg_eink_border_top.xml
│       │       │   ├── bg_find_book_group.xml
│       │       │   ├── bg_gradient.xml
│       │       │   ├── bg_img_border.xml
│       │       │   ├── bg_item_focused_on_tv.xml
│       │       │   ├── bg_popup_menu.xml
│       │       │   ├── bg_prefs_color.xml
│       │       │   ├── bg_searchview.xml
│       │       │   ├── bg_shadow_bottom.xml
│       │       │   ├── bg_shadow_bottom_night.xml
│       │       │   ├── bg_shadow_top.xml
│       │       │   ├── bg_shadow_top_night.xml
│       │       │   ├── bg_textfield_search.xml
│       │       │   ├── fastscroll_bubble.xml
│       │       │   ├── fastscroll_handle.xml
│       │       │   ├── fastscroll_track.xml
│       │       │   ├── ic_add.xml
│       │       │   ├── ic_add_online.xml
│       │       │   ├── ic_arrange.xml
│       │       │   ├── ic_arrow_back.xml
│       │       │   ├── ic_arrow_down.xml
│       │       │   ├── ic_arrow_drop_down.xml
│       │       │   ├── ic_arrow_drop_up.xml
│       │       │   ├── ic_arrow_right.xml
│       │       │   ├── ic_author.xml
│       │       │   ├── ic_auto_page.xml
│       │       │   ├── ic_auto_page_stop.xml
│       │       │   ├── ic_backup.xml
│       │       │   ├── ic_baseline_close.xml
│       │       │   ├── ic_baseline_sort_24.xml
│       │       │   ├── ic_book_has.xml
│       │       │   ├── ic_book_last.xml
│       │       │   ├── ic_bookmark.xml
│       │       │   ├── ic_bottom_books.xml
│       │       │   ├── ic_bottom_books_e.xml
│       │       │   ├── ic_bottom_books_s.xml
│       │       │   ├── ic_bottom_explore.xml
│       │       │   ├── ic_bottom_explore_e.xml
│       │       │   ├── ic_bottom_explore_s.xml
│       │       │   ├── ic_bottom_person.xml
│       │       │   ├── ic_bottom_person_e.xml
│       │       │   ├── ic_bottom_person_s.xml
│       │       │   ├── ic_bottom_rss_feed.xml
│       │       │   ├── ic_bottom_rss_feed_e.xml
│       │       │   ├── ic_bottom_rss_feed_s.xml
│       │       │   ├── ic_brightness.xml
│       │       │   ├── ic_brightness_auto.xml
│       │       │   ├── ic_bubble_chart.xml
│       │       │   ├── ic_bug_report.xml
│       │       │   ├── ic_cfg_about.xml
│       │       │   ├── ic_cfg_backup.xml
│       │       │   ├── ic_cfg_donate.xml
│       │       │   ├── ic_cfg_other.xml
│       │       │   ├── ic_cfg_replace.xml
│       │       │   ├── ic_cfg_source.xml
│       │       │   ├── ic_cfg_theme.xml
│       │       │   ├── ic_cfg_web.xml
│       │       │   ├── ic_chapter_list.xml
│       │       │   ├── ic_check.xml
│       │       │   ├── ic_check_source.xml
│       │       │   ├── ic_clear_all.xml
│       │       │   ├── ic_copy.xml
│       │       │   ├── ic_create_folder_outline.xml
│       │       │   ├── ic_cursor_left.xml
│       │       │   ├── ic_cursor_right.xml
│       │       │   ├── ic_daytime.xml
│       │       │   ├── ic_divider.xml
│       │       │   ├── ic_download.xml
│       │       │   ├── ic_download_line.xml
│       │       │   ├── ic_edit.xml
│       │       │   ├── ic_exchange.xml
│       │       │   ├── ic_exchange_order.xml
│       │       │   ├── ic_exit.xml
│       │       │   ├── ic_expand_less.xml
│       │       │   ├── ic_expand_more.xml
│       │       │   ├── ic_export.xml
│       │       │   ├── ic_fast_forward.xml
│       │       │   ├── ic_fast_rewind.xml
│       │       │   ├── ic_find_replace.xml
│       │       │   ├── ic_folder.xml
│       │       │   ├── ic_folder_open.xml
│       │       │   ├── ic_folder_outline.xml
│       │       │   ├── ic_groups.xml
│       │       │   ├── ic_help.xml
│       │       │   ├── ic_history.xml
│       │       │   ├── ic_image.xml
│       │       │   ├── ic_import.xml
│       │       │   ├── ic_interface_setting.xml
│       │       │   ├── ic_launcher1.xml
│       │       │   ├── ic_launcher1_b.xml
│       │       │   ├── ic_launcher2.xml
│       │       │   ├── ic_launcher3.xml
│       │       │   ├── ic_launcher4.xml
│       │       │   ├── ic_launcher4_b.xml
│       │       │   ├── ic_launcher5.xml
│       │       │   ├── ic_launcher5_b.xml
│       │       │   ├── ic_launcher6.xml
│       │       │   ├── ic_launcher7.xml
│       │       │   ├── ic_launcher7_b.xml
│       │       │   ├── ic_lock_outline.xml
│       │       │   ├── ic_menu.xml
│       │       │   ├── ic_more.xml
│       │       │   ├── ic_more_vert.xml
│       │       │   ├── ic_network_check.xml
│       │       │   ├── ic_outline_cloud_24.xml
│       │       │   ├── ic_outline_delete.xml
│       │       │   ├── ic_pause_24dp.xml
│       │       │   ├── ic_pause_outline_24dp.xml
│       │       │   ├── ic_play_24dp.xml
│       │       │   ├── ic_play_mode_list_end_stop.xml
│       │       │   ├── ic_play_mode_list_loop.xml
│       │       │   ├── ic_play_mode_random.xml
│       │       │   ├── ic_play_mode_single_loop.xml
│       │       │   ├── ic_play_outline_24dp.xml
│       │       │   ├── ic_praise.xml
│       │       │   ├── ic_read_aloud.xml
│       │       │   ├── ic_reduce.xml
│       │       │   ├── ic_refresh_black_24dp.xml
│       │       │   ├── ic_refresh_white_24dp.xml
│       │       │   ├── ic_restore.xml
│       │       │   ├── ic_save.xml
│       │       │   ├── ic_scan.xml
│       │       │   ├── ic_scoring.xml
│       │       │   ├── ic_screen.xml
│       │       │   ├── ic_search.xml
│       │       │   ├── ic_search_hint.xml
│       │       │   ├── ic_settings.xml
│       │       │   ├── ic_share.xml
│       │       │   ├── ic_skip_next.xml
│       │       │   ├── ic_skip_previous.xml
│       │       │   ├── ic_sort.xml
│       │       │   ├── ic_star.xml
│       │       │   ├── ic_star_border.xml
│       │       │   ├── ic_stop_black_24dp.xml
│       │       │   ├── ic_storage_black_24dp.xml
│       │       │   ├── ic_swap_horiz.xml
│       │       │   ├── ic_time_add_24dp.xml
│       │       │   ├── ic_timer_black_24dp.xml
│       │       │   ├── ic_toc.xml
│       │       │   ├── ic_translate.xml
│       │       │   ├── ic_update.xml
│       │       │   ├── ic_view_quilt.xml
│       │       │   ├── ic_visibility_off.xml
│       │       │   ├── ic_volume_up.xml
│       │       │   ├── ic_web_outline.xml
│       │       │   ├── ic_web_service_noti.xml
│       │       │   ├── recyclerview_divider_horizontal.xml
│       │       │   ├── recyclerview_divider_vertical.xml
│       │       │   ├── selector_btn_accent_bg.xml
│       │       │   ├── selector_circle_btn_bg.xml
│       │       │   ├── selector_common_bg.xml
│       │       │   ├── selector_fillet_btn_bg.xml
│       │       │   ├── selector_tv_black.xml
│       │       │   ├── shape_card_view.xml
│       │       │   ├── shape_circle.xml
│       │       │   ├── shape_fillet_btn.xml
│       │       │   ├── shape_fillet_btn_press.xml
│       │       │   ├── shape_pop_checkaddshelf_bg.xml
│       │       │   ├── shape_radius_10dp.xml
│       │       │   ├── shape_radius_1dp.xml
│       │       │   ├── shape_space_divider.xml
│       │       │   ├── shape_text_cursor.xml
│       │       │   └── shape_translucent_card.xml
│       │       ├── layout/
│       │       │   ├── activity_about.xml
│       │       │   ├── activity_all_bookmark.xml
│       │       │   ├── activity_arrange_book.xml
│       │       │   ├── activity_audio_play.xml
│       │       │   ├── activity_book_info.xml
│       │       │   ├── activity_book_info_edit.xml
│       │       │   ├── activity_book_read.xml
│       │       │   ├── activity_book_search.xml
│       │       │   ├── activity_book_source.xml
│       │       │   ├── activity_book_source_edit.xml
│       │       │   ├── activity_cache_book.xml
│       │       │   ├── activity_chapter_list.xml
│       │       │   ├── activity_config.xml
│       │       │   ├── activity_dict_rule.xml
│       │       │   ├── activity_donate.xml
│       │       │   ├── activity_explore_show.xml
│       │       │   ├── activity_file_manage.xml
│       │       │   ├── activity_import_book.xml
│       │       │   ├── activity_main.xml
│       │       │   ├── activity_manga.xml
│       │       │   ├── activity_qrcode_capture.xml
│       │       │   ├── activity_read_record.xml
│       │       │   ├── activity_replace_edit.xml
│       │       │   ├── activity_replace_rule.xml
│       │       │   ├── activity_rss_artivles.xml
│       │       │   ├── activity_rss_favorites.xml
│       │       │   ├── activity_rss_read.xml
│       │       │   ├── activity_rss_source.xml
│       │       │   ├── activity_rss_source_edit.xml
│       │       │   ├── activity_rule_sub.xml
│       │       │   ├── activity_search_content.xml
│       │       │   ├── activity_source_debug.xml
│       │       │   ├── activity_source_login.xml
│       │       │   ├── activity_translucence.xml
│       │       │   ├── activity_txt_toc_rule.xml
│       │       │   ├── activity_web_view.xml
│       │       │   ├── activity_welcome.xml
│       │       │   ├── dialog_add_to_bookshelf.xml
│       │       │   ├── dialog_auto_read.xml
│       │       │   ├── dialog_book_change_source.xml
│       │       │   ├── dialog_book_group_edit.xml
│       │       │   ├── dialog_book_group_picker.xml
│       │       │   ├── dialog_bookmark.xml
│       │       │   ├── dialog_bookshelf_config.xml
│       │       │   ├── dialog_change_cover.xml
│       │       │   ├── dialog_chapter_change_source.xml
│       │       │   ├── dialog_check_source_config.xml
│       │       │   ├── dialog_click_action_config.xml
│       │       │   ├── dialog_code_view.xml
│       │       │   ├── dialog_content_edit.xml
│       │       │   ├── dialog_cover_rule_config.xml
│       │       │   ├── dialog_custom_group.xml
│       │       │   ├── dialog_dict.xml
│       │       │   ├── dialog_dict_rule_edit.xml
│       │       │   ├── dialog_direct_link_upload_config.xml
│       │       │   ├── dialog_download_choice.xml
│       │       │   ├── dialog_edit_text.xml
│       │       │   ├── dialog_file_chooser.xml
│       │       │   ├── dialog_font_select.xml
│       │       │   ├── dialog_http_tts_edit.xml
│       │       │   ├── dialog_image_blurring.xml
│       │       │   ├── dialog_login.xml
│       │       │   ├── dialog_manga_color_filter.xml
│       │       │   ├── dialog_manga_epaper.xml
│       │       │   ├── dialog_manga_footer_setting.xml
│       │       │   ├── dialog_multiple_edit_text.xml
│       │       │   ├── dialog_number_picker.xml
│       │       │   ├── dialog_open_url_confirm.xml
│       │       │   ├── dialog_page_key.xml
│       │       │   ├── dialog_photo_view.xml
│       │       │   ├── dialog_progressbar_view.xml
│       │       │   ├── dialog_read_aloud.xml
│       │       │   ├── dialog_read_bg_text.xml
│       │       │   ├── dialog_read_book_style.xml
│       │       │   ├── dialog_read_padding.xml
│       │       │   ├── dialog_recycler_view.xml
│       │       │   ├── dialog_rss_favorite_config.xml
│       │       │   ├── dialog_rule_sub_edit.xml
│       │       │   ├── dialog_search_scope.xml
│       │       │   ├── dialog_select_section_export.xml
│       │       │   ├── dialog_simulated_reading.xml
│       │       │   ├── dialog_source_picker.xml
│       │       │   ├── dialog_text_view.xml
│       │       │   ├── dialog_tip_config.xml
│       │       │   ├── dialog_toc_regex.xml
│       │       │   ├── dialog_toc_regex_edit.xml
│       │       │   ├── dialog_update.xml
│       │       │   ├── dialog_url_option_edit.xml
│       │       │   ├── dialog_variable.xml
│       │       │   ├── dialog_verification_code_view.xml
│       │       │   ├── dialog_wait.xml
│       │       │   ├── dialog_webdav_server.xml
│       │       │   ├── fragment_bookmark.xml
│       │       │   ├── fragment_books.xml
│       │       │   ├── fragment_bookshelf1.xml
│       │       │   ├── fragment_bookshelf2.xml
│       │       │   ├── fragment_chapter_list.xml
│       │       │   ├── fragment_explore.xml
│       │       │   ├── fragment_my_config.xml
│       │       │   ├── fragment_rss.xml
│       │       │   ├── fragment_rss_articles.xml
│       │       │   ├── fragment_web_view_login.xml
│       │       │   ├── item_1line_text.xml
│       │       │   ├── item_1line_text_and_del.xml
│       │       │   ├── item_app_log.xml
│       │       │   ├── item_arrange_book.xml
│       │       │   ├── item_bg_image.xml
│       │       │   ├── item_book_file_import.xml
│       │       │   ├── item_book_group_manage.xml
│       │       │   ├── item_book_manga_edge.xml
│       │       │   ├── item_book_manga_page.xml
│       │       │   ├── item_book_source.xml
│       │       │   ├── item_bookmark.xml
│       │       │   ├── item_bookshelf_grid.xml
│       │       │   ├── item_bookshelf_grid_group.xml
│       │       │   ├── item_bookshelf_list.xml
│       │       │   ├── item_bookshelf_list_group.xml
│       │       │   ├── item_change_source.xml
│       │       │   ├── item_chapter_list.xml
│       │       │   ├── item_check_box.xml
│       │       │   ├── item_cover.xml
│       │       │   ├── item_dict_rule.xml
│       │       │   ├── item_download.xml
│       │       │   ├── item_file.xml
│       │       │   ├── item_file_picker.xml
│       │       │   ├── item_fillet_text.xml
│       │       │   ├── item_find_book.xml
│       │       │   ├── item_font.xml
│       │       │   ├── item_group_manage.xml
│       │       │   ├── item_group_select.xml
│       │       │   ├── item_http_tts.xml
│       │       │   ├── item_icon_preference.xml
│       │       │   ├── item_import_book.xml
│       │       │   ├── item_log.xml
│       │       │   ├── item_path_picker.xml
│       │       │   ├── item_radio_button.xml
│       │       │   ├── item_read_record.xml
│       │       │   ├── item_read_style.xml
│       │       │   ├── item_replace_rule.xml
│       │       │   ├── item_rss.xml
│       │       │   ├── item_rss_article.xml
│       │       │   ├── item_rss_article_1.xml
│       │       │   ├── item_rss_article_2.xml
│       │       │   ├── item_rss_read_record.xml
│       │       │   ├── item_rss_source.xml
│       │       │   ├── item_rule_sub.xml
│       │       │   ├── item_search.xml
│       │       │   ├── item_search_list.xml
│       │       │   ├── item_server_select.xml
│       │       │   ├── item_source_edit.xml
│       │       │   ├── item_source_edit_check_box.xml
│       │       │   ├── item_source_import.xml
│       │       │   ├── item_text.xml
│       │       │   ├── item_theme_config.xml
│       │       │   ├── item_toc_regex.xml
│       │       │   ├── item_txt_toc_rule.xml
│       │       │   ├── popup_action.xml
│       │       │   ├── popup_action_menu.xml
│       │       │   ├── popup_keyboard_tool.xml
│       │       │   ├── popup_seek_bar.xml
│       │       │   ├── view_action_button.xml
│       │       │   ├── view_book_page.xml
│       │       │   ├── view_detail_seek_bar.xml
│       │       │   ├── view_dynamic.xml
│       │       │   ├── view_error.xml
│       │       │   ├── view_fastscroller.xml
│       │       │   ├── view_icon.xml
│       │       │   ├── view_load_more.xml
│       │       │   ├── view_loading.xml
│       │       │   ├── view_manga_menu.xml
│       │       │   ├── view_navigation_badge.xml
│       │       │   ├── view_preference.xml
│       │       │   ├── view_preference_category.xml
│       │       │   ├── view_read_menu.xml
│       │       │   ├── view_refresh_recycler.xml
│       │       │   ├── view_search.xml
│       │       │   ├── view_search_menu.xml
│       │       │   ├── view_select_action_bar.xml
│       │       │   ├── view_tab_layout.xml
│       │       │   ├── view_tab_layout_min.xml
│       │       │   ├── view_title_bar.xml
│       │       │   ├── view_title_bar_dark.xml
│       │       │   └── view_toast.xml
│       │       ├── layout-land/
│       │       │   └── activity_book_info.xml
│       │       ├── menu/
│       │       │   ├── about.xml
│       │       │   ├── app_log.xml
│       │       │   ├── app_update.xml
│       │       │   ├── audio_play.xml
│       │       │   ├── backup_restore.xml
│       │       │   ├── book_cache.xml
│       │       │   ├── book_cache_download.xml
│       │       │   ├── book_group_manage.xml
│       │       │   ├── book_info.xml
│       │       │   ├── book_info_edit.xml
│       │       │   ├── book_manga.xml
│       │       │   ├── book_read.xml
│       │       │   ├── book_read_change_source.xml
│       │       │   ├── book_read_record.xml
│       │       │   ├── book_read_refresh.xml
│       │       │   ├── book_read_source.xml
│       │       │   ├── book_remote.xml
│       │       │   ├── book_search.xml
│       │       │   ├── book_search_scope.xml
│       │       │   ├── book_source.xml
│       │       │   ├── book_source_debug.xml
│       │       │   ├── book_source_item.xml
│       │       │   ├── book_source_sel.xml
│       │       │   ├── book_toc.xml
│       │       │   ├── bookmark.xml
│       │       │   ├── bookshelf_manage.xml
│       │       │   ├── bookshelf_menage_sel.xml
│       │       │   ├── change_cover.xml
│       │       │   ├── change_source.xml
│       │       │   ├── change_source_item.xml
│       │       │   ├── code_edit.xml
│       │       │   ├── content_edit.xml
│       │       │   ├── content_search.xml
│       │       │   ├── content_select_action.xml
│       │       │   ├── crash_log.xml
│       │       │   ├── dialog_text.xml
│       │       │   ├── dict_rule.xml
│       │       │   ├── dict_rule_edit.xml
│       │       │   ├── dict_rule_sel.xml
│       │       │   ├── direct_link_upload_config.xml
│       │       │   ├── explore_item.xml
│       │       │   ├── file_chooser.xml
│       │       │   ├── file_long_click.xml
│       │       │   ├── font_select.xml
│       │       │   ├── group_manage.xml
│       │       │   ├── import_book.xml
│       │       │   ├── import_book_sel.xml
│       │       │   ├── import_replace.xml
│       │       │   ├── import_source.xml
│       │       │   ├── keyboard_assists_config.xml
│       │       │   ├── main_bnv.xml
│       │       │   ├── main_bookshelf.xml
│       │       │   ├── main_explore.xml
│       │       │   ├── main_my.xml
│       │       │   ├── main_rss.xml
│       │       │   ├── open_url_confirm.xml
│       │       │   ├── qr_code_scan.xml
│       │       │   ├── replace_edit.xml
│       │       │   ├── replace_rule.xml
│       │       │   ├── replace_rule_item.xml
│       │       │   ├── replace_rule_sel.xml
│       │       │   ├── rss_articles.xml
│       │       │   ├── rss_favorites.xml
│       │       │   ├── rss_main_item.xml
│       │       │   ├── rss_read.xml
│       │       │   ├── rss_read_record.xml
│       │       │   ├── rss_source.xml
│       │       │   ├── rss_source_debug.xml
│       │       │   ├── rss_source_item.xml
│       │       │   ├── rss_source_sel.xml
│       │       │   ├── save.xml
│       │       │   ├── search_view.xml
│       │       │   ├── server_config.xml
│       │       │   ├── servers.xml
│       │       │   ├── source_edit.xml
│       │       │   ├── source_login.xml
│       │       │   ├── source_picker.xml
│       │       │   ├── source_sub_item.xml
│       │       │   ├── source_subscription.xml
│       │       │   ├── source_webview_login.xml
│       │       │   ├── speak_engine.xml
│       │       │   ├── speak_engine_edit.xml
│       │       │   ├── theme_config.xml
│       │       │   ├── theme_list.xml
│       │       │   ├── txt_toc_rule.xml
│       │       │   ├── txt_toc_rule_edit.xml
│       │       │   ├── txt_toc_rule_item.xml
│       │       │   ├── txt_toc_rule_sel.xml
│       │       │   ├── verification_code.xml
│       │       │   └── web_view.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   ├── launcher1.xml
│       │       │   ├── launcher2.xml
│       │       │   ├── launcher3.xml
│       │       │   ├── launcher4.xml
│       │       │   ├── launcher5.xml
│       │       │   └── launcher6.xml
│       │       ├── values/
│       │       │   ├── array_values.xml
│       │       │   ├── arrays.xml
│       │       │   ├── attrs.xml
│       │       │   ├── colors.xml
│       │       │   ├── colors_material_design.xml
│       │       │   ├── dimens.xml
│       │       │   ├── ids.xml
│       │       │   ├── non_translat.xml
│       │       │   ├── strings.xml
│       │       │   └── styles.xml
│       │       ├── values-es-rES/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP/
│       │       │   └── strings.xml
│       │       ├── values-night/
│       │       │   ├── colors.xml
│       │       │   └── styles.xml
│       │       ├── values-pt-rBR/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-vi/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-zh/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-zh-rHK/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       └── xml/
│       │           ├── about.xml
│       │           ├── file_paths.xml
│       │           ├── network_security_config.xml
│       │           ├── pref_config_aloud.xml
│       │           ├── pref_config_backup.xml
│       │           ├── pref_config_cover.xml
│       │           ├── pref_config_other.xml
│       │           ├── pref_config_read.xml
│       │           ├── pref_config_theme.xml
│       │           ├── pref_config_welcome.xml
│       │           ├── pref_main.xml
│       │           └── spen_remote_actions.xml
│       └── test/
│           └── java/
│               └── io/
│                   └── legado/
│                       └── app/
│                           ├── ExampleUnitTest.kt
│                           └── JsTest.kt
├── avd.bat
├── avd.sh
├── build.gradle
├── gradle/
│   ├── libs.versions.toml
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── modules/
│   ├── book/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── consumer-rules.pro
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── me/
│   │           │       └── ag2s/
│   │           │           ├── base/
│   │           │           │   ├── PfdHelper.java
│   │           │           │   └── ThrowableUtils.java
│   │           │           ├── epublib/
│   │           │           │   ├── Constants.java
│   │           │           │   ├── browsersupport/
│   │           │           │   │   ├── NavigationEvent.java
│   │           │           │   │   ├── NavigationEventListener.java
│   │           │           │   │   ├── NavigationHistory.java
│   │           │           │   │   ├── Navigator.java
│   │           │           │   │   └── package-info.java
│   │           │           │   ├── domain/
│   │           │           │   │   ├── Author.java
│   │           │           │   │   ├── Date.java
│   │           │           │   │   ├── EpubBook.java
│   │           │           │   │   ├── EpubResourceProvider.java
│   │           │           │   │   ├── FileResourceProvider.java
│   │           │           │   │   ├── Guide.java
│   │           │           │   │   ├── GuideReference.java
│   │           │           │   │   ├── Identifier.java
│   │           │           │   │   ├── LazyResource.java
│   │           │           │   │   ├── LazyResourceProvider.java
│   │           │           │   │   ├── ManifestItemProperties.java
│   │           │           │   │   ├── ManifestItemRefProperties.java
│   │           │           │   │   ├── ManifestProperties.java
│   │           │           │   │   ├── MediaType.java
│   │           │           │   │   ├── MediaTypes.java
│   │           │           │   │   ├── Metadata.java
│   │           │           │   │   ├── Relator.java
│   │           │           │   │   ├── Resource.java
│   │           │           │   │   ├── ResourceInputStream.java
│   │           │           │   │   ├── ResourceReference.java
│   │           │           │   │   ├── Resources.java
│   │           │           │   │   ├── Spine.java
│   │           │           │   │   ├── SpineReference.java
│   │           │           │   │   ├── TOCReference.java
│   │           │           │   │   ├── TableOfContents.java
│   │           │           │   │   └── TitledResourceReference.java
│   │           │           │   ├── epub/
│   │           │           │   │   ├── BookProcessor.java
│   │           │           │   │   ├── BookProcessorPipeline.java
│   │           │           │   │   ├── DOMUtil.java
│   │           │           │   │   ├── EpubProcessorSupport.java
│   │           │           │   │   ├── EpubReader.java
│   │           │           │   │   ├── EpubWriter.java
│   │           │           │   │   ├── EpubWriterProcessor.java
│   │           │           │   │   ├── HtmlProcessor.java
│   │           │           │   │   ├── NCXDocumentV2.java
│   │           │           │   │   ├── NCXDocumentV3.java
│   │           │           │   │   ├── PackageDocumentBase.java
│   │           │           │   │   ├── PackageDocumentMetadataReader.java
│   │           │           │   │   ├── PackageDocumentMetadataWriter.java
│   │           │           │   │   ├── PackageDocumentReader.java
│   │           │           │   │   ├── PackageDocumentWriter.java
│   │           │           │   │   └── ResourcesLoader.java
│   │           │           │   └── util/
│   │           │           │       ├── CollectionUtil.java
│   │           │           │       ├── IOUtil.java
│   │           │           │       ├── NoCloseOutputStream.java
│   │           │           │       ├── NoCloseWriter.java
│   │           │           │       ├── ResourceUtil.java
│   │           │           │       ├── StringUtil.java
│   │           │           │       ├── URLEncodeUtil.java
│   │           │           │       ├── commons/
│   │           │           │       │   └── io/
│   │           │           │       │       ├── BOMInputStream.java
│   │           │           │       │       ├── ByteOrderMark.java
│   │           │           │       │       ├── IOConsumer.java
│   │           │           │       │       ├── ProxyInputStream.java
│   │           │           │       │       ├── XmlStreamReader.java
│   │           │           │       │       └── XmlStreamReaderException.java
│   │           │           │       └── zip/
│   │           │           │           ├── AndroidZipEntry.java
│   │           │           │           ├── AndroidZipFile.java
│   │           │           │           ├── ZipConstants.java
│   │           │           │           ├── ZipEntryWrapper.java
│   │           │           │           ├── ZipException.java
│   │           │           │           └── ZipFileWrapper.java
│   │           │           └── umdlib/
│   │           │               ├── domain/
│   │           │               │   ├── UmdBook.java
│   │           │               │   ├── UmdChapters.java
│   │           │               │   ├── UmdCover.java
│   │           │               │   ├── UmdEnd.java
│   │           │               │   └── UmdHeader.java
│   │           │               ├── tool/
│   │           │               │   ├── StreamReader.java
│   │           │               │   ├── UmdUtils.java
│   │           │               │   └── WrapOutputStream.java
│   │           │               └── umd/
│   │           │                   └── UmdReader.java
│   │           └── resources/
│   │               ├── dtd/
│   │               │   ├── openebook.org/
│   │               │   │   └── dtds/
│   │               │   │       └── oeb-1.2/
│   │               │   │           ├── oeb12.ent
│   │               │   │           └── oebpkg12.dtd
│   │               │   ├── www.daisy.org/
│   │               │   │   └── z3986/
│   │               │   │       └── 2005/
│   │               │   │           └── ncx-2005-1.dtd
│   │               │   └── www.w3.org/
│   │               │       └── TR/
│   │               │           ├── ruby/
│   │               │           │   └── xhtml-ruby-1.mod
│   │               │           ├── xhtml-modularization/
│   │               │           │   └── DTD/
│   │               │           │       ├── xhtml-arch-1.mod
│   │               │           │       ├── xhtml-attribs-1.mod
│   │               │           │       ├── xhtml-base-1.mod
│   │               │           │       ├── xhtml-bdo-1.mod
│   │               │           │       ├── xhtml-blkphras-1.mod
│   │               │           │       ├── xhtml-blkpres-1.mod
│   │               │           │       ├── xhtml-blkstruct-1.mod
│   │               │           │       ├── xhtml-charent-1.mod
│   │               │           │       ├── xhtml-csismap-1.mod
│   │               │           │       ├── xhtml-datatypes-1.mod
│   │               │           │       ├── xhtml-datatypes-1.mod.1
│   │               │           │       ├── xhtml-edit-1.mod
│   │               │           │       ├── xhtml-events-1.mod
│   │               │           │       ├── xhtml-form-1.mod
│   │               │           │       ├── xhtml-framework-1.mod
│   │               │           │       ├── xhtml-hypertext-1.mod
│   │               │           │       ├── xhtml-image-1.mod
│   │               │           │       ├── xhtml-inlphras-1.mod
│   │               │           │       ├── xhtml-inlpres-1.mod
│   │               │           │       ├── xhtml-inlstruct-1.mod
│   │               │           │       ├── xhtml-inlstyle-1.mod
│   │               │           │       ├── xhtml-lat1.ent
│   │               │           │       ├── xhtml-link-1.mod
│   │               │           │       ├── xhtml-list-1.mod
│   │               │           │       ├── xhtml-meta-1.mod
│   │               │           │       ├── xhtml-notations-1.mod
│   │               │           │       ├── xhtml-object-1.mod
│   │               │           │       ├── xhtml-param-1.mod
│   │               │           │       ├── xhtml-pres-1.mod
│   │               │           │       ├── xhtml-qname-1.mod
│   │               │           │       ├── xhtml-script-1.mod
│   │               │           │       ├── xhtml-special.ent
│   │               │           │       ├── xhtml-ssismap-1.mod
│   │               │           │       ├── xhtml-struct-1.mod
│   │               │           │       ├── xhtml-style-1.mod
│   │               │           │       ├── xhtml-symbol.ent
│   │               │           │       ├── xhtml-symbol.ent.1
│   │               │           │       ├── xhtml-table-1.mod
│   │               │           │       ├── xhtml-text-1.mod
│   │               │           │       └── xhtml11-model-1.mod
│   │               │           ├── xhtml1/
│   │               │           │   └── DTD/
│   │               │           │       ├── xhtml-lat1.ent
│   │               │           │       ├── xhtml-special.ent
│   │               │           │       ├── xhtml-symbol.ent
│   │               │           │       ├── xhtml1-strict.dtd
│   │               │           │       └── xhtml1-transitional.dtd
│   │               │           └── xhtml11/
│   │               │               └── DTD/
│   │               │                   └── xhtml11.dtd
│   │               └── log4j.properties
│   ├── rhino/
│   │   ├── build.gradle
│   │   ├── consumer-rules.pro
│   │   ├── lib/
│   │   │   └── rhino-1.7.14.jar
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── script/
│   │                       ├── AbstractScriptEngine.kt
│   │                       ├── Bindings.kt
│   │                       ├── Compilable.kt
│   │                       ├── CompiledScript.kt
│   │                       ├── Invocable.kt
│   │                       ├── RhinoContextFactory.kt
│   │                       ├── ScriptBindings.kt
│   │                       ├── ScriptBindingsExtensions.kt
│   │                       ├── ScriptContext.kt
│   │                       ├── ScriptEngine.kt
│   │                       ├── ScriptException.kt
│   │                       ├── SimpleBindings.kt
│   │                       ├── SimpleScriptContext.kt
│   │                       └── rhino/
│   │                           ├── ClassNameMatcher.kt
│   │                           ├── CollectionExtensions.kt
│   │                           ├── ExternalScriptable.kt
│   │                           ├── InterfaceImplementor.kt
│   │                           ├── JSAdapter.kt
│   │                           ├── JavaAdapter.kt
│   │                           ├── JavaObjectWrapFactory.kt
│   │                           ├── ProtectedNativeJavaClass.kt
│   │                           ├── ReadOnlyJavaObject.kt
│   │                           ├── RhinoClassShutter.kt
│   │                           ├── RhinoCompiledScript.kt
│   │                           ├── RhinoContext.kt
│   │                           ├── RhinoErrors.kt
│   │                           ├── RhinoExtensions.kt
│   │                           ├── RhinoScriptEngine.kt
│   │                           ├── RhinoTopLevel.kt
│   │                           ├── RhinoWrapFactory.kt
│   │                           └── VMBridgeReflect.kt
│   └── web/
│       ├── .browserslistrc
│       ├── .editorconfig
│       ├── .gitignore
│       ├── .prettierignore
│       ├── .prettierrc.json
│       ├── LICENSE
│       ├── README.md
│       ├── env.d.ts
│       ├── eslint.config.mjs
│       ├── index.html
│       ├── package.json
│       ├── scripts/
│       │   └── sync.js
│       ├── src/
│       │   ├── App.vue
│       │   ├── api/
│       │   │   ├── api.ts
│       │   │   ├── axios.ts
│       │   │   └── index.ts
│       │   ├── assets/
│       │   │   ├── bookshelf.css
│       │   │   ├── code.css
│       │   │   ├── fonts/
│       │   │   │   ├── iconfont.css
│       │   │   │   ├── popfont.css
│       │   │   │   └── shelffont.css
│       │   │   ├── kbd.css
│       │   │   └── sourceeditor.css
│       │   ├── auto-imports.d.ts
│       │   ├── book.d.ts
│       │   ├── components/
│       │   │   ├── BookItems.vue
│       │   │   ├── CatalogItem.vue
│       │   │   ├── ChapterContent.vue
│       │   │   ├── PopCatalog.vue
│       │   │   ├── ReadSettings.vue
│       │   │   ├── SourceDebug.vue
│       │   │   ├── SourceHelp.vue
│       │   │   ├── SourceItem.vue
│       │   │   ├── SourceJson.vue
│       │   │   ├── SourceList.vue
│       │   │   ├── SourceTabForm.vue
│       │   │   ├── SourceTabTools.vue
│       │   │   └── ToolBar.vue
│       │   ├── components.d.ts
│       │   ├── config/
│       │   │   ├── bookSourceEditConfig.ts
│       │   │   ├── rssSourceEditConfig.ts
│       │   │   ├── sourceConfig.d.ts
│       │   │   └── themeConfig.ts
│       │   ├── hooks/
│       │   │   ├── loading.css
│       │   │   └── loading.ts
│       │   ├── main.ts
│       │   ├── pages/
│       │   │   ├── bookshelf/
│       │   │   │   ├── README.md
│       │   │   │   ├── index.html
│       │   │   │   └── main.js
│       │   │   └── source/
│       │   │       ├── README.md
│       │   │       ├── index.html
│       │   │       └── main.js
│       │   ├── plugins/
│       │   │   ├── jump.d.ts
│       │   │   └── jump.js
│       │   ├── router/
│       │   │   ├── bookRouter.ts
│       │   │   ├── index.ts
│       │   │   └── sourceRouter.ts
│       │   ├── source.d.ts
│       │   ├── store/
│       │   │   ├── bookStore.ts
│       │   │   ├── connectionStore.ts
│       │   │   ├── index.ts
│       │   │   └── sourceStore.ts
│       │   ├── utils/
│       │   │   ├── souce.ts
│       │   │   └── utils.ts
│       │   ├── views/
│       │   │   ├── BookChapter.vue
│       │   │   ├── BookShelf.vue
│       │   │   └── SourceEditor.vue
│       │   └── web.d.ts
│       ├── tsconfig.app.json
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
├── package.json
└── settings.gradle

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

================================================
FILE: .github/ISSUE_TEMPLATE/01-bugReport.yml
================================================
name: BUG提交 / BUG Report
description: Report bugs to developers
labels: ["BUG"]
body:
  - type: checkboxes
    attributes:
      label: 确认 / Assignments
      description: 提交issue请确保完成以下前提,否则该issue可能被忽略 / Make sure you read checkboxs below
      options:
        - label: 搜索现有issues,不存在相似或相关的issue / No similar or related issues
          required: true
        - label: 最新[测试版](https://github.com/gedoor/legado/releases/beta)依然存在此问题 / Latest beta app does not work
          required: true
        - label: 此问题和Xposed、Lsposed、Magisk、手机主题、浏览器插件、无障碍服务等无关 / Make sure your machine is not touched by hook frameworks, plugins, accessibility etc
          required: true

  - type: textarea
    attributes:
      label: 问题描述 / Describe Bugs
    validations:
      required: true
  - type: textarea
    attributes:
      label: 复现步骤 / How to reproduce
    validations:
      required: true
  - type: checkboxes
    attributes:
      label: 确认 / Assignment
      options:
        - label: 已经提交复现所需要的附加资料 / Submit additions related with bugs
          required: true
  - type: textarea
    attributes:
      label: 其他信息 / Additions
      description: |
        反馈WEB书架前端问题时请提供浏览器版本信息,如Edge 129.0.2792.89
      placeholder: "请用```将提交的内容包裹"

  - type: textarea
    attributes:
      label: 日志提交 / Relevant log output
      description: |
        阅读日志位于我的-关于-崩溃日志、保存日志、书架-右上角-日志,或者自行使用log工具抓取日志
        如果崩溃日志中包含`java.lang.OutOfMemoryError`,请安装最新测试版,在其他设置里打开记录堆转储,复现崩溃后去关于那里点保存日志,然后去备份目录里将heapDump文件夹里的文件打包压缩一下上传上来
      placeholder: "请用```将日志内容包裹"

  - type: input
    attributes:
      label: 阅读版本 / Legado version
      placeholder: "3.22.110823"
    validations:
      required: true
  - type: input
    attributes:
      label: Android版本 / Android version
      placeholder: "Android 12"
    validations:
      required: true
  - type: input
    attributes:
      label: 机型 / Model
      placeholder: "Redmi K30 Pro"
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/02-featureRequest.yml
================================================
name: 功能请求 / Features
description: Request new features
labels: ["需求"]
body:
  - type: checkboxes
    attributes:
      label: 确认 / Assignments
      description: 提交issue请确保完成以下前提,否则该issue可能被忽略 / Make sure you read checkbox below 
      options:
        - label: 搜索现有issues,不存在相似或相关的issue / No related requests
          required: true
        - label: 最新[测试版](https://github.com/gedoor/legado/releases/beta)没有此功能 / Latest beta app does not this feature
          required: true

  - type: textarea
    attributes:
      label: 功能描述 / Features
      placeholder: 请清晰的、详细的描述你想要的功能
    validations:
      required: true
  - type: textarea
    attributes:
      label: 期望实现方式 / How to implement
      placeholder: 阅读应该如何实现该功能
    validations:
      required: true
  - type: input
    attributes:
      label: 阅读版本 / Legado version
      placeholder: "3.22.110823"
    validations:
      required: true
  - type: textarea
    attributes:
      label: 附加信息 / Additions
      placeholder: 其他的与功能相关的附加信息
  - type: textarea
    attributes:
      label: 效果演示 / Demo
      placeholder: 可以手绘一些草图,或者提供可借鉴的图片


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: 简繁转化
    url: https://github.com/liuyueyi/quick-chinese-transfer/issues/new
    about: 简繁转化问题请优先到quick-chinese-transfer反馈
  - name: 讨论 / Discussions
    url: https://github.com/gedoor/legado/discussions
    about: Please ask and answer questions here.
  - name: 常见问题 / Wiki
    url: https://github.com/gedoor/legado/wiki
    about: Read wiki if your are new here.


================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
registries:
  maven-google:
    type: maven-repository
    # url: https://maven.google.com
    url: https://dl.google.com/dl/android/maven2/
    password: dummy
    username: dummy
  maven-central:
    type: maven-repository
    url: https://repo1.maven.org/maven2/
    password: dummy
    username: dummy
  maven-jitpack:
    type: maven-repository
    url: https://jitpack.io
    password: dummy
    username: dummy

updates:
  - package-ecosystem: gradle
    directory: "/"
    schedule:
      interval: "weekly"
    registries: "*"
    open-pull-requests-limit: 20
    groups:
      kotlin_KSP:
        patterns:
          - "org.jetbrains.kotlin:*"
          - "com.google.devtools.ksp"
  # Maintain dependencies for GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
  - package-ecosystem: npm
    directory: "modules/web"
    schedule:
      interval: "weekly"


================================================
FILE: .github/scripts/cronet.sh
================================================
#!/usr/bin/env bash

#分支Stable Dev Beta
branch=$1
#api 最大偏移
max_offset=$2

[ -z $1 ] && branch=Stable
[ -z $2 ] && max_offset=3
[ -z $GITHUB_ENV ] && echo "Error: Unexpected github workflow environment" && exit

offset=0

function fetch_version() {
    # 获取最新cronet版本
    lastest_cronet_version=`curl -s "https://chromiumdash.appspot.com/fetch_releases?channel=$branch&platform=Android&num=1&offset=$offset" | jq .[0].version -r`
    echo "lastest_cronet_version: $lastest_cronet_version"
    #lastest_cronet_version=100.0.4845.0
    lastest_cronet_main_version=${lastest_cronet_version%%\.*}.0.0.0
    check_version_exit
}
function check_version_exit() {
    # 检查版本是否存在
    local jar_url="https://storage.googleapis.com/chromium-cronet/android/$lastest_cronet_version/Release/cronet/cronet_api.jar"
    statusCode=$(curl -s -I -w %{http_code} "$jar_url" -o /dev/null)
    if [ $statusCode == "404" ]; then
        echo "storage.googleapis.com return 404 for cronet $lastest_cronet_version"
        if [[ $max_offset > $offset ]]; then
            offset=$(expr $offset + 1)
            echo "retry with offset $offset"
            fetch_version
        else
            exit
        fi
    fi
}
function version_compare() {
    # 版本号比较 本地版本小于远程版本时返回0
    local local_version=$1
    local remote_version=$2
    if [[ $local_version == $remote_version ]]; then
        return 1
    fi
    if [[ $(printf '%s\n' "$1" "$2" | sort -V | head -n1) == $remote_version ]]; then
        return 1
    else
        return 0
    fi
}

# 添加变量到github env
function write_github_env_variable() {
    echo "$1=$2" >> $GITHUB_ENV
}

function sync_proguard_rules() {
    local raw_github_git="https://raw.githubusercontent.com/chromium/chromium/$lastest_cronet_version"
    local proguard_paths=(
      components/cronet/android/cronet_combined_impl_native_proguard_golden.cfg
    )
    local proguard_rules_path="$GITHUB_WORKSPACE/app/cronet-proguard-rules.pro"
    rm -f $proguard_rules_path
    echo "fetch cronet proguard rules from upstream $raw_github_git"
    for path in ${proguard_paths[@]}
    do
        echo "fetching $path ..."
        curl "$raw_github_git/$path" >> $proguard_rules_path
    done
}
##########
# 获取本地cronet版本
path=$GITHUB_WORKSPACE/gradle.properties
current_cronet_version=`cat $path | grep CronetVersion | sed s/CronetVersion=//`
echo "current_cronet_version: $current_cronet_version"

echo "fetch $branch release info from https://chromiumdash.appspot.com ..."
fetch_version

if version_compare $current_cronet_version $lastest_cronet_version; then
    # 更新gradle.properties
    sed -i s/CronetVersion=.*/CronetVersion=$lastest_cronet_version/ $path
    sed -i s/CronetMainVersion=.*/CronetMainVersion=$lastest_cronet_main_version/ $path
    # 更新cronet_proguard_rules.pro
    sync_proguard_rules
    # 更新cronet版本
    sed -i "s/## cronet版本: .*/## cronet版本: $lastest_cronet_version/" $GITHUB_WORKSPACE/app/src/main/assets/updateLog.md
    # 生成pull request信息
    write_github_env_variable PR_TITLE "Bump cronet from $current_cronet_version to $lastest_cronet_version"
    write_github_env_variable PR_BODY "Changes in the [Git log](https://chromium.googlesource.com/chromium/src/+log/$current_cronet_version..$lastest_cronet_version)"
    # 生成cronet flag
    write_github_env_variable cronet ok
fi


================================================
FILE: .github/scripts/lzy_web.py
================================================
import requests, os, datetime, sys

# Cookie 中 phpdisk_info 的值
cookie_phpdisk_info = os.environ.get('phpdisk_info')
# Cookie 中 ylogin 的值
cookie_ylogin = os.environ.get('ylogin')

# 请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Referer': 'https://pc.woozooo.com/account.php?action=login'
}

# 小饼干
cookie = {
    'ylogin': cookie_ylogin,
    'phpdisk_info': cookie_phpdisk_info
}


# 日志打印
def log(msg):
    utc_time = datetime.datetime.utcnow()
    china_time = utc_time + datetime.timedelta(hours=8)
    print(f"[{china_time.strftime('%Y.%m.%d %H:%M:%S')}] {msg}")


# 检查是否已登录
def login_by_cookie():
    url_account = "https://pc.woozooo.com/account.php"
    if cookie['phpdisk_info'] is None:
        log('ERROR: 请指定 Cookie 中 phpdisk_info 的值!')
        return False
    if cookie['ylogin'] is None:
        log('ERROR: 请指定 Cookie 中 ylogin 的值!')
        return False
    res = requests.get(url_account, headers=headers, cookies=cookie, verify=True)
    if '网盘用户登录' in res.text:
        log('ERROR: 登录失败,请更新Cookie')
        return False
    else:
        log('登录成功')
        return True


# 上传文件
def upload_file(file_dir, folder_id):
    file_name = os.path.basename(file_dir)
    url_upload = "https://up.woozooo.com/fileup.php"
    headers['Referer'] = f'https://up.woozooo.com/mydisk.php?item=files&action=index&u={cookie_ylogin}'
    post_data = {
        "task": "1",
        "folder_id": folder_id,
        "id": "WU_FILE_0",
        "name": file_name,
    }
    files = {'upload_file': (file_name, open(file_dir, "rb"), 'application/octet-stream')}
    res = requests.post(url_upload, data=post_data, files=files, headers=headers, cookies=cookie, timeout=120).json()
    log(f"{file_dir} -> {res['info']}")
    return res['zt'] == 1


# 上传文件夹内的文件
def upload_folder(folder_dir, folder_id):
    file_list = sorted(os.listdir(folder_dir), reverse=True)
    for file in file_list:
        path = os.path.join(folder_dir, file)
        if os.path.isfile(path):
            upload_file(path, folder_id)
        else:
            upload_folder(path, folder_id)


# 上传
def upload(dir, folder_id):
    if dir is None:
        log('ERROR: 请指定上传的文件路径')
        return
    if folder_id is None:
        log('ERROR: 请指定蓝奏云的文件夹id')
        return
    if os.path.isfile(dir):
        upload_file(dir, str(folder_id))
    else:
        upload_folder(dir, str(folder_id))


if __name__ == '__main__':
    argv = sys.argv[1:]
    if len(argv) != 2:
        log('ERROR: 参数错误,请以这种格式重新尝试\npython lzy_web.py 需上传的路径 蓝奏云文件夹id')
    # 需上传的路径
    upload_path = argv[0]
    # 蓝奏云文件夹id
    lzy_folder_id = argv[1]
    if login_by_cookie():
        upload(upload_path, lzy_folder_id)


================================================
FILE: .github/scripts/tg_bot.py
================================================
import os, sys, telebot

# 上传文件
def upload_file(tb, chat_id, file_dir):
    doc = open(file_dir, 'rb')
    tb.send_document(chat_id, doc)

# 上传文件夹内的文件
def upload_folder(tb, chat_id, folder_dir):
    file_list = sorted(os.listdir(folder_dir))
    for file in file_list:
        path = os.path.join(folder_dir, file)
        if os.path.isfile(path):
            upload_file(tb, chat_id, path)
        else:
            upload_folder(tb, chat_id, path)

# 上传
def upload(tb, chat_id, dir):
    if tb is None:
        log('ERROR: 输入正确的token')
        return
    if chat_id is None:
        log('ERROR: 输入正确的chat_id')
        return
    if dir is None:
        log('ERROR: 请指定上传的文件路径')
        return
    if os.path.isfile(dir):
        upload_file(tb, chat_id, dir)
    else:
        upload_folder(tb, chat_id, dir)

if __name__ == '__main__':
    argv = sys.argv[1:]
    if len(argv) != 3:
        log('ERROR: 参数错误,请以这种格式重新尝试\npython tg_bot.py $token $chat_id 待上传的路径')
    # Token
    TOKEN = argv[0]
    # chat_id
    chat_id = argv[1]
    # 待上传文件的路径
    upload_path = argv[2]
    #创建连接
    tb = telebot.TeleBot(TOKEN)
    #开始上传
    upload(tb, chat_id, upload_path)


================================================
FILE: .github/workflows/autoupdatefork.yml
================================================
#更新fork
name: update fork

on: 
  schedule:
    - cron: '0 16 * * *' #0点定时任务

jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ github.event.repository.owner.id == github.event.sender.id && github.actor != 'gedoor' }}
    steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Set env
      run: |
        git config --global user.email "github-actions@github.com"
        git config --global user.name "github-actions"
    - name: Update fork
      run: |
        git remote add upstream https://github.com/gedoor/legado.git
        git remote -v
        git fetch upstream
        git checkout master
        git merge upstream/master
        git push origin master


================================================
FILE: .github/workflows/cronet.yml
================================================
name: Update Cronet

on:
  schedule:
  # 周一北京时间9点
    - cron: 0 1 * * 1
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ github.repository == 'gedoor/legado' }}
    steps:
      - uses: actions/checkout@v4

      - name: Check Cronet Updates
        run: source .github/scripts/cronet.sh

      - name: Set up JDK 17
        if: ${{ env.cronet == 'ok' }}
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: 17

      - uses: gradle/actions/setup-gradle@v4
        if: ${{ env.cronet == 'ok' }}

      - name: Download Cronet
        if: ${{ env.cronet == 'ok' }}
        run: |
          chmod +x gradlew
          ./gradlew app:downloadCronet

      - name: Create Pull Request
        if: ${{ env.cronet == 'ok' }}
        uses: peter-evans/create-pull-request@v7
        continue-on-error: true
        with:
          token: ${{ secrets.ACTIONS_TOKEN }}
          title: ${{ env.PR_TITLE }}
          commit-message: |
            ${{ env.PR_TITLE }}
            - ${{ env.PR_BODY }}
          body: ${{ env.PR_BODY }}
          branch: cronet
          delete-branch: true
          add-paths: |
            *cronet*jar
            *cronet.json
            *updateLog.md
            *gradle.properties
            *cronet-proguard-rules.pro


================================================
FILE: .github/workflows/release.yml
================================================
name: Release Build

on:
#  push:
#    branches:
#      - master
#    paths:
#      - 'CHANGELOG.md'
  workflow_dispatch:

jobs:
  prepare:
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master'
    outputs:
      version: ${{ steps.set-ver.outputs.version }}
      play: ${{ steps.check.outputs.play }}
      sign: ${{ steps.check.outputs.sign }}
    steps:
      - id: set-ver
        run: |
          echo "version=$(date -d "8 hour" -u +3.%y.%m%d%H)" >> $GITHUB_OUTPUT
      - id: check
        run: |
          if [ ! -z "${{ secrets.RELEASE_KEY_STORE }}" ]; then
            echo "sign=yes" >> $GITHUB_OUTPUT
          fi
          if [ ! -z "${{ secrets.SERVICE_ACCOUNT_JSON }}" ]; then
            echo "play=yes" >> $GITHUB_OUTPUT
          fi

  build:
    needs: prepare
    if: ${{ needs.prepare.outputs.sign }}
    strategy:
      matrix:
        product: [ app, google ]
      fail-fast: false
    runs-on: ubuntu-latest
    env:
      product: ${{ matrix.product }}
      VERSION: ${{ needs.prepare.outputs.version }}
      play: ${{ needs.prepare.outputs.play }}
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: 17

      - name: Release Apk Sign
        run: |
          # not use this output
          # echo "KeyStore=yes" >> $GITHUB_OUTPUT
          echo -e "\n" >> gradle.properties
          echo RELEASE_KEY_ALIAS='${{ secrets.RELEASE_KEY_ALIAS }}' >> gradle.properties
          echo RELEASE_KEY_PASSWORD='${{ secrets.RELEASE_KEY_PASSWORD }}' >> gradle.properties
          echo RELEASE_STORE_PASSWORD='${{ secrets.RELEASE_STORE_PASSWORD }}' >> gradle.properties
          echo RELEASE_STORE_FILE='./key.jks' >> gradle.properties
          echo ${{ secrets.RELEASE_KEY_STORE }} | base64 --decode > $GITHUB_WORKSPACE/app/key.jks

      - name: Unify Version Name
        run: |
          echo "统一版本号"
          sed "/def version/c def version = \"${{ env.VERSION }}\"" $GITHUB_WORKSPACE/app/build.gradle  -i

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Build With Gradle
        run: |
          echo "开始进行${{ env.product }}构建"
          chmod +x gradlew
          ./gradlew assemble${{ env.product }}release --build-cache --parallel --daemon --warning-mode all

      - name: Organize the Files
        run: |
          mkdir -p ${{ github.workspace }}/apk/
          cp -rf ${{ github.workspace }}/app/build/outputs/apk/*/*/*.apk ${{ github.workspace }}/apk/
          
      - name: Upload App To Artifact
        uses: actions/upload-artifact@v4
        with:
          name: legado_${{ env.product }}
          path: ${{ github.workspace }}/apk/*.apk

      - name: Release
        if: ${{ env.product == 'app' }}
        uses: softprops/action-gh-release@v2
        with:
          name: legado_app_${{ env.VERSION }}
          tag_name: ${{ env.VERSION }}
          body_path: ${{ github.workspace }}/CHANGELOG.md
          draft: false
          prerelease: false
          files: ${{ github.workspace }}/apk/legado_app_*.apk
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Prepare For GooglePlay
        if: env.product == 'google' && env.play == 'yes'
        run: |
          mkdir -p ReleaseNotes
          ln -s ${{ github.workspace }}/CHANGELOG.md ReleaseNotes/whatsnew-en-US
          ln -s ${{ github.workspace }}/CHANGELOG.md ReleaseNotes/whatsnew-zh-CN

      - name: Release To GooglePlay
        if: env.product == 'google' && env.play == 'yes'
        uses: r0adkll/upload-google-play@v1
        with:
          serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
          packageName: io.legado.play
          releaseFiles: ${{ github.workspace }}/apk/legado_google_*.apk
          track: production
          whatsNewDirectory: ${{ github.workspace }}/ReleaseNotes

      - name: Push Assets To "release" Branch
        if: ${{ github.actor == 'gedoor' }}
        run: |
          cd $GITHUB_WORKSPACE/apk/
          git init
          git checkout -b release
          git config --global user.name "github-actions[bot]"
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git remote add origin "https://${{ github.actor }}:${{ secrets.ACTIONS_TOKEN }}@github.com/${{ github.actor }}/release"
          git add *.apk
          git commit -m "${{ env.VERSION }}"
          git push -f -u origin release
          
      - name: Purge Jsdelivr Cache
        if: ${{ github.actor == 'gedoor' }}
        run: |
          result=$(curl -s https://purge.jsdelivr.net/gh/${{ github.actor }}/release@release/)
          if echo $result |grep -q 'success.*true'; then
            echo "jsdelivr缓存更新成功"
          else
            echo $result
          fi


================================================
FILE: .github/workflows/stale.yml
================================================
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: closeStaleIssue

on:
  schedule:
  # 每5天北京时间9点
  - cron: '30 1 1/5 * *'
  workflow_dispatch:

jobs:
  stale:

    runs-on: ubuntu-latest
    if: ${{ github.repository == 'gedoor/legado' }}
    permissions:
      issues: write

    steps:
    - uses: actions/stale@v9
      with:
        repo-token: ${{ secrets.GITHUB_TOKEN }}
        stale-issue-message: '由于长期没有状态更新,该问题将于5天后自动关闭。如有需要可重新打开。'
        days-before-stale: 30
        days-before-close: 5
        operations-per-run: 100


================================================
FILE: .github/workflows/test.yml
================================================
name: Test Build

on:
  push:
    branches:
      - master
    paths:
      - '**'
      # - '!**/assets/**'
      # - '!**.md'
      - '!**/ISSUE_TEMPLATE/**'
      - '!**/modules/web/**'
  pull_request:
    paths-ignore:
      - '**/modules/web/**'
  workflow_run:
    workflows: [Build Web]
    branches: [master]
    types:
      - completed
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:

  prepare:
    runs-on: ubuntu-latest
    if: ${{ !startsWith(github.event.head_commit.message, 'Merge pull request') }}
    outputs:
      version: ${{ steps.set-ver.outputs.version }}
      versionL: ${{ steps.set-ver.outputs.versionL }}
      lanzou: ${{ steps.check.outputs.lanzou }}
      telegram: ${{ steps.check.outputs.telegram }}
    steps:
      - id: set-ver
        run: |
          echo "version=$(date -d "8 hour" -u +3.%y.%m%d%H)" >> $GITHUB_OUTPUT
          echo "versionL=$(date -d "8 hour" -u +3.%y.%m%d%H%M)" >> $GITHUB_OUTPUT
      - id: check
        run: |
          if [ ${{ secrets.LANZOU_ID }} ]; then
            echo "lanzou=yes" >> $GITHUB_OUTPUT
          fi
          if [ ${{ secrets.BOT_TOKEN }} ]; then
            echo "telegram=yes" >> $GITHUB_OUTPUT
          fi

  build:
    needs: prepare
    strategy:
      matrix:
        product: [ app ]
        type: [ release, releaseA ]
      fail-fast: false
    runs-on: ubuntu-latest
    env:
      product: ${{ matrix.product }}
      type: ${{ matrix.type }}
      VERSION: ${{ needs.prepare.outputs.version }}
      VERSIONL: ${{ needs.prepare.outputs.versionL }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: 17
      - name: Clear 18PlusList.txt
        run: |
          echo "清空18PlusList.txt"
          echo "">$GITHUB_WORKSPACE/app/src/main/assets/18PlusList.txt
      - name: Release Apk Sign
        run: |
          echo "给apk增加签名"
          cp $GITHUB_WORKSPACE/.github/workflows/legado.jks $GITHUB_WORKSPACE/app/legado.jks
          sed '$a\RELEASE_STORE_FILE=./legado.jks'          $GITHUB_WORKSPACE/gradle.properties -i
          sed '$a\RELEASE_KEY_ALIAS=legado'                 $GITHUB_WORKSPACE/gradle.properties -i
          sed '$a\RELEASE_STORE_PASSWORD=gedoor_legado'     $GITHUB_WORKSPACE/gradle.properties -i
          sed '$a\RELEASE_KEY_PASSWORD=gedoor_legado'       $GITHUB_WORKSPACE/gradle.properties -i

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v4

      - name: Build With Gradle
        continue-on-error: true
        run: |
          if [ ${{ env.type }} == 'release' ]; then
            typeName="原包名"
          else
            typeName="共存"
            sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle  -i
            sed 's/.release/.releaseA/'     $GITHUB_WORKSPACE/app/google-services.json -i
          fi
          echo "统一版本号"
          sed "/def version/c def version = \"${{ env.VERSION }}\"" $GITHUB_WORKSPACE/app/build.gradle  -i
          echo "开始${{ env.product }}$typeName构建"
          chmod +x gradlew
          ./gradlew assemble${{ env.product }}release --build-cache --parallel --daemon --warning-mode all
          echo "修改APK文件名"
          mkdir -p ${{ github.workspace }}/apk/
          for file in `ls ${{ github.workspace }}/app/build/outputs/apk/*/*/*.apk`; do
            mv "$file" ${{ github.workspace }}/apk/legado_${{ env.product }}_${{ env.VERSIONL }}_$typeName.apk
          done
          echo "移动mapping文件"
          mkdir -p ${{ github.workspace }}/mapping/
          for file in `ls ${{ github.workspace }}/app/build/outputs/mapping/*/mapping.txt`; do
            mv "$file" ${{ github.workspace }}/mapping/mapping.txt
          done

      - name: Move Missing Rules Files
        run: |
          echo "移动missing_rules.txt文件"
          mkdir -p ${{ github.workspace }}/mapping/
          for file in `ls ${{ github.workspace }}/app/build/outputs/mapping/*/missing_rules.txt`; do
            mv "$file" ${{ github.workspace }}/mapping/missing_rules.txt
          done

      - name: Upload Missing Rules File To Artifact
        uses: actions/upload-artifact@v4
        with:
          name: legado.${{ env.product }}.${{ env.type }}.mapping.missing_rules
          if-no-files-found: ignore
          path: ${{ github.workspace }}/mapping/missing_rules.txt

      - name: Check Build production
        run: |
          if [ ! -d ${{ github.workspace }}/apk ]; then
            echo "Build production not found! Check gradle logs."
            exit 1
          fi
          cd ${{ github.workspace }}/apk/
          if [ ! -e legado_*.apk ]; then
            echo "Build production not found! Check gradle logs."
            exit 1
          fi

      - name: Upload App To Artifact
        uses: actions/upload-artifact@v4
        with:
          name: legado.${{ env.product }}.${{ env.type }}
          if-no-files-found: ignore
          path: ${{ github.workspace }}/apk/*.apk

      - name: Upload Mapping File To Artifact
        uses: actions/upload-artifact@v4
        with:
          name: legado.${{ env.product }}.${{ env.type }}.mapping
          if-no-files-found: ignore
          path: ${{ github.workspace }}/mapping/mapping.txt

  prerelease:
    needs: [ prepare, build ]
    if: github.event_name != 'pull_request' && github.repository == 'gedoor/legado'
    runs-on: ubuntu-latest
    env: 
      VERSION: ${{ needs.prepare.outputs.version }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: apk/

      - working-directory: apk/
        run: |
          mv */*.apk .
          rm -rf */

          for file in `ls *.apk`; do
            if [[ "$file" == *原包名* ]]; then
              mv "$file" $(echo $file | sed s/原包名/release/)
            else
              mv "$file" $(echo $file | sed s/共存/releaseA/)
            fi
          done

      - name: Delete Pre-Release
        run: |
          if gh release view beta &>/dev/null; then
            gh release delete beta -y
          fi
        env:
          GH_TOKEN: ${{ github.token }}
      
      - name: Create or update beta tag
        uses: richardsimko/update-tag@v1
        with:
          tag_name: beta
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Publish Pre-Release
        uses: ncipollo/release-action@v1
        with:
          name: legado_app_${{ env.VERSION }}
          tag: "beta"
          body: |
            此版本为测试版,签名与正式版不同,可能存在不稳定情况,升级前请务必备份好数据。
            releaseA 为共存版本,可同时安装使用,功能没有区别。
          prerelease: true
          artifacts: ${{ github.workspace }}/apk/*.apk

  lanzou:
    needs: [ prepare, build ]
    if: ${{ github.event_name != 'pull_request' && needs.prepare.outputs.lanzou == 'yes' }}
    runs-on: ubuntu-latest
    env:
      # 登录蓝奏云后在控制台运行document.cookie
      ylogin: ${{ secrets.LANZOU_ID }}
      phpdisk_info: ${{ secrets.LANZOU_PSD }}
      # 蓝奏云里的文件夹ID(阅读3测试版:2670621)
      LANZOU_FOLDER_ID: ${{ secrets.LANZOU_FOLDER_ID }}
      #蓝奏云分享链接
      LANZOU_URL: ${{ secrets.LANZOU_URL }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: apk/
      - working-directory: apk/
        run: mv */*.apk . ;rm -rf */
      - name: Upload To Lanzou
        continue-on-error: true
        run: |
          path="$GITHUB_WORKSPACE/apk/"
          python3 $GITHUB_WORKSPACE/.github/scripts/lzy_web.py "$path" "$LANZOU_FOLDER_ID"
          echo "[$(date -u -d '+8 hour' '+%Y.%m.%d %H:%M:%S')] 分享链接: $LANZOU_URL"

  test_Branch:
    needs: [ prepare, build ]
    runs-on: ubuntu-latest
    if: ${{ github.event_name != 'pull_request' && github.actor == 'gedoor' }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: apk/
      - working-directory: apk/
        run: mv */*.apk . ;rm -rf */
      - name: Push To "test" Branch
        run: |
          cd $GITHUB_WORKSPACE/apk/
          git init
          git checkout -b test
          git config --global user.name "github-actions[bot]"
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git remote add origin "https://${{ github.actor }}:${{ secrets.ACTIONS_TOKEN }}@github.com/${{ github.actor }}/release"
          git add *.apk
          git commit -m "${{ needs.prepare.outputs.versionL }}"
          git push -f -u origin test

  telegram:
    needs: [ prepare, build ]
    if: ${{ github.event_name != 'pull_request' && needs.prepare.outputs.telegram == 'yes' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: apk/
      - working-directory: apk/
        run: |
          for file in `ls */*.apk`; do
            mv "$file" "$(echo "$file"|sed -e 's#.*\/##g' -e "s/_/ /g" -e 's/legado/阅读/')"
          done
          rm -rf */
      - name: Post to channel
        uses: xireiki/channel-post@v1
        with:
          chat_id: ${{ secrets.CHANNEL_ID }}
          bot_token: ${{ secrets.BOT_TOKEN }}
          context: "#阅读 #Legado #Beta ${{ needs.prepare.outputs.versionL }}"
          path: apk/*
          method: sendFile


================================================
FILE: .github/workflows/web.yml
================================================
name: Build Web

on:
  push:
    branches:
      - master
    paths:
      - '**/modules/web/**'
  pull_request:
    paths:
      - '**/modules/web/**'
  workflow_dispatch:

env:
  UPSTREAM_REPOSITORY: gedoor/legado

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - uses: pnpm/action-setup@v4
        name: Install pnpm
        id: pnpm-install
        with:
          version: 9
          run_install: false

      - name: Get pnpm store directory
        id: pnpm-cache
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v4
        name: Setup pnpm cache
        with:
          path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/web/package.json') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: Build and move files
        working-directory: modules/web
        run: |
          pnpm i
          pnpm build
          version="v$(date -d "8 hour" -u +3.%y.%m%d%H)"
          echo "APP_VER=$version" >> $GITHUB_ENV

      - name: push changes
        if: ${{ github.event_name != 'pull_request' && github.repository == env.UPSTREAM_REPOSITORY }}
        uses: stefanzweifel/git-auto-commit-action@v5.1.0
        with:
          commit_message: Bump web ${{ env.APP_VER}}
          file_pattern: app/src/main/assets/web/vue/



================================================
FILE: .gitignore
================================================
*.iml
.gradle
local.properties
.DS_Store
/build
build/
/captures
.externalNativeBuild
/release
/tmp
node_modules/
/app/app
/app/google
/app/gradle.properties
package-lock.json
.idea/
# Kotlin 2.0
.kotlin/


================================================
FILE: CHANGELOG.md
================================================
**2022/10/02**

* 更新cronet: 106.0.5249.79
* 正文选择菜单朗读按钮长按可切换朗读选择内容和从选择开始处一直朗读
* 源编辑输入框设置最大行数12,在行数特别多的时候更容易滚动到其它输入
* 修复某些情况下无法搜索到标题的bug,净化规则较多的可能会降低搜索速度 by Xwite
* 修复文件类书源换源后阅读bug by Xwite
* Cronet 支持DnsHttpsSvcb by g2s20150909
* 修复web进度同步问题 by 821938089
* 启用混淆以减小app大小 有bug请带日志反馈
* 其它一些优化


================================================
FILE: English.md
================================================
# [English](English.md) [中文](README.md)

[![icon_android](https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/icon_android.png)](https://play.google.com/store/apps/details?id=io.legado.play.release)
<a href="https://jb.gg/OpenSourceSupport" target="_blank">
<img width="24" height="24" src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg?_gl=1*135yekd*_ga*OTY4Mjg4NDYzLjE2Mzk0NTE3MzQ.*_ga_9J976DJZ68*MTY2OTE2MzM5Ny4xMy4wLjE2NjkxNjMzOTcuNjAuMC4w&_ga=2.257292110.451256242.1669085120-968288463.1639451734" alt="idea"/>
</a>
<div align="center">
<img width="125" height="125" src="https://github.com/gedoor/legado/raw/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" alt="legado"/>  
  
Legado / 开源阅读
<br>
<a href="https://gedoor.github.io" target="_blank">gedoor.github.io</a> / <a href="https://www.legado.top/" target="_blank">legado.top</a>
<br>
Legado is a free and open source novel reader for Android.
</div>

[![](https://img.shields.io/badge/-Contents:-696969.svg)](#contents) [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-) [![](https://img.shields.io/badge/-Download-F5F5F5.svg)](#Download-) [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-) [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-) [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-) [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-) [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-)

>New user?
>
>The software does not provide content, you need to add it manually, such as importing book sources, etc. 
>Take a look at [official help documentation](https://www.yuque.com/legado/wiki),Maybe there's an answer you need inside.

# Function [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-)

You can customize the book source, set your own rules, and capture web page data. The rules are simple and easy to understand. There are rules in the software. List bookshelf, grid bookshelf switch freely. The book source rules support search and discovery, and all the functions of finding books and reading books are all customized, making it easier to find books.
* Custom ebook sources, set your own rules to capture web data, the rules are simple and easy to understand, the software has a rule description.
* eBook sources rules support search and discovery, all find books and read books function all custom, find books more convenient.
* Schedule updating your library for new chapters.
* Online reading from web sources that can be imported in bulk
* Local reading of Auto-download episodes.
* Local reading of TXT or EPUB files
* ebook Wishlist
* Big text viewer. You can open eBook and txt in 1GB size
* Automatic text replacement for removing ad in content
* List bookshelf, grid bookshelf free to switch.
* Subscription content, you can subscribe to any content you want to see, see what you want to see
* A configurable reader with fonts, background, page transitions mode and other settings
* Timer. Set interval time to listen ebook, time up, ebook  turn off completely.
* TTS book reader. tts can optionally be install“smartvoice-4.1.0” or ”Speech Services by Google“  Give your baby a storybook to listen to and teach your baby to talk, 
* Dark mode and E-Ink mode support and Web service support
* Create backups to local or WebDav server
* Decentralization web3
* Support replacement purification, it is very convenient to remove the content of advertisement replacement.
* Support local TXT, EPUB reading, manual browsing, intelligent scanning.
* Support highly customized reading interface, switch font, color, background, line spacing, paragraph spacing, bold, simplified and traditional conversion.
* Support multiple page turning modes, covering, emulating, sliding, scrolling, etc.


<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>

# Download [![](https://img.shields.io/badge/-Download-F5F5F5.svg)](#Download-)

#### Android

* [Releases](https://github.com/gedoor/legado/releases/latest)
* [Google play - $1.99](https://play.google.com/store/apps/details?id=io.legado.play.release)
* [Coolapk](https://www.coolapk.com/apk/io.legado.app.release)
* [\#Beta](https://kunfei.lanzoui.com/b0f810h4b)
* [IzzyOnDroid F-Droid Repository](https://apt.izzysoft.de/fdroid/index/apk/io.legado.app.release)


#### IOS

* Stopped(No release) - [Github](https://github.com/gedoor/YueDuFlutter)

<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>

# Community [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-)

#### Telegram

[![Telegram-group](https://img.shields.io/badge/Telegram-group-blue)](https://t.me/yueduguanfang) [![Telegram-channel](https://img.shields.io/badge/Telegram-channel-blue)](https://t.me/legado_channels)

#### Discord

[![Discord](https://img.shields.io/discord/560731361414086666?color=%235865f2&label=Discord)](https://discord.gg/VtUfRyzRXn)

#### Other

https://www.yuque.com/legado/wiki/community

<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>

# API [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-)

* Legado 3.0 The API is provided in 2 ways: `Web way` and `Content Provider way`. You can call it yourself as needed in [here](api.md). 
* One-click import by url recall reading, url format: legado://import/{path}?src={url}
* Path Type: bookSource,rssSource,replaceRule,textTocRule,httpTTS,theme,readConfig,dictRule,addToBookshelf
* path type explanation: Book source, subscription source, replacement rules, local txt novel directory rules, online reading engine, theme, reading layout, [add to bookshelf](/app/src/main/java/io/legado/app/ui/association/AddToBookshelfDialog.kt)

<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>

# Other [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-)

##### Disclaimers

https://gedoor.github.io/Disclaimer

##### Legado 3.0

* [eBook sources rules](https://mgz0227.github.io/The-tutorial-of-Legado/)
* [Update Log](/app/src/main/assets/updateLog.md)
* [Help Documentation](/app/src/main/assets/web/help/md/appHelp.md)
* [web bookshelf](https://github.com/gedoor/legado_web_bookshelf)
* [web source editor](https://github.com/gedoor/legado_web_source_editor)

<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>

# Grateful [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-)

> * org.jsoup:jsoup
> * cn.wanghaomiao:JsoupXpath
> * com.jayway.jsonpath:json-path
> * com.github.gedoor:rhino-android
> * com.squareup.okhttp3:okhttp
> * com.github.bumptech.glide:glide
> * org.nanohttpd:nanohttpd
> * org.nanohttpd:nanohttpd-websocket
> * cn.bingoogolapple:bga-qrcode-zxing
> * com.jaredrummler:colorpicker
> * org.apache.commons:commons-text
> * io.noties.markwon:core
> * io.noties.markwon:image-glide
> * com.hankcs:hanlp
> * com.positiondev.epublib:epublib-core

<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>

# Interface [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-)

<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B1.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B2.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B3.jpg" width="270">
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B4.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B5.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B6.jpg" width="270">

<a href="#readme">
    <img src="https://img.shields.io/badge/-Top-orange.svg" alt="#" align="right">
</a>


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    Legado  Copyright (C) 2019-2023  gedoor
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.


================================================
FILE: README.md
================================================
# [English](English.md) [中文](README.md)

[![icon_android](https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/icon_android.png)](https://play.google.com/store/apps/details?id=io.legado.play.release)
<a href="https://jb.gg/OpenSourceSupport" target="_blank">
<img width="24" height="24" src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg?_gl=1*135yekd*_ga*OTY4Mjg4NDYzLjE2Mzk0NTE3MzQ.*_ga_9J976DJZ68*MTY2OTE2MzM5Ny4xMy4wLjE2NjkxNjMzOTcuNjAuMC4w&_ga=2.257292110.451256242.1669085120-968288463.1639451734" alt="idea"/>
</a>

<div align="center">
<img width="125" height="125" src="https://github.com/gedoor/legado/raw/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" alt="legado"/>  
  
Legado / 开源阅读
<br>
<a href="https://gedoor.github.io" target="_blank">gedoor.github.io</a> / <a href="https://www.legado.top/" target="_blank">legado.top</a>
<br>
Legado is a free and open source novel reader for Android.
</div>

[![](https://img.shields.io/badge/-Contents:-696969.svg)](#contents) [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-主要功能-) [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-交流社区-) [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-) [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-其他-) [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-感谢-) [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-界面-)

>新用户?
>
>软件不提供内容,需要您自己手动添加,例如导入书源等。
>看看 [官方帮助文档](https://www.yuque.com/legado/wiki),也许里面就有你要的答案。

# Function-主要功能 [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-主要功能-)
[English](English.md)

<details><summary>中文</summary>
1.自定义书源,自己设置规则,抓取网页数据,规则简单易懂,软件内有规则说明。<br>
2.列表书架,网格书架自由切换。<br>
3.书源规则支持搜索及发现,所有找书看书功能全部自定义,找书更方便。<br>
4.订阅内容,可以订阅想看的任何内容,看你想看<br>
5.支持替换净化,去除广告替换内容很方便。<br>
6.支持本地TXT、EPUB阅读,手动浏览,智能扫描。<br>
7.支持高度自定义阅读界面,切换字体、颜色、背景、行距、段距、加粗、简繁转换等。<br>
8.支持多种翻页模式,覆盖、仿真、滑动、滚动等。<br>
9.软件开源,持续优化,无广告。
</details>

<a href="#readme">
    <img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Community-交流社区 [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-交流社区-)

#### Telegram
[![Telegram-group](https://img.shields.io/badge/Telegram-%E7%BE%A4%E7%BB%84-blue)](https://t.me/yueduguanfang) [![Telegram-channel](https://img.shields.io/badge/Telegram-%E9%A2%91%E9%81%93-blue)](https://t.me/legado_channels)

#### Discord
[![Discord](https://img.shields.io/discord/560731361414086666?color=%235865f2&label=Discord)](https://discord.gg/VtUfRyzRXn)

#### Other
https://www.yuque.com/legado/wiki/community

<a href="#readme">
    <img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# API [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-)
* 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。 
* 可通过url唤起阅读进行一键导入,url格式: legado://import/{path}?src={url}
* path类型: bookSource,rssSource,replaceRule,textTocRule,httpTTS,theme,readConfig,dictRule,[addToBookshelf](/app/src/main/java/io/legado/app/ui/association/AddToBookshelfDialog.kt)
* path类型解释: 书源,订阅源,替换规则,本地txt小说目录规则,在线朗读引擎,主题,阅读排版,添加到书架

<a href="#readme">
    <img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Other-其他 [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-其他-)
##### 免责声明
https://gedoor.github.io/Disclaimer

##### 阅读3.0
* [书源规则](https://mgz0227.github.io/The-tutorial-of-Legado/)
* [更新日志](/app/src/main/assets/updateLog.md)
* [帮助文档](/app/src/main/assets/web/help/md/appHelp.md)
* [web端书架](https://github.com/gedoor/legado_web_bookshelf)
* [web端源编辑](https://github.com/gedoor/legado_web_source_editor)

<a href="#readme">
    <img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Grateful-感谢 [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-感谢-)
> * org.jsoup:jsoup
> * cn.wanghaomiao:JsoupXpath
> * com.jayway.jsonpath:json-path
> * com.github.gedoor:rhino-android
> * com.squareup.okhttp3:okhttp
> * com.github.bumptech.glide:glide
> * org.nanohttpd:nanohttpd
> * org.nanohttpd:nanohttpd-websocket
> * cn.bingoogolapple:bga-qrcode-zxing
> * com.jaredrummler:colorpicker
> * org.apache.commons:commons-text
> * io.noties.markwon:core
> * io.noties.markwon:image-glide
> * com.hankcs:hanlp
> * com.positiondev.epublib:epublib-core
<a href="#readme">
    <img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Interface-界面 [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-界面-)
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B1.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B2.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B3.jpg" width="270">
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B4.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B5.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B6.jpg" width="270">

<a href="#readme">
    <img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>


================================================
FILE: api.md
================================================
# 阅读[API](/app/src/main/java/io/legado/app/api/controller)

## 对于[Web](/app/src/main/java/io/legado/app/web/)的配置

您需要先在设置中启用"Web 服务"。

## 使用

### Web

以下说明假设您的操作在本机进行,且开放端口为1234。  
如果您要从远程计算机访问[阅读](),请将`127.0.0.1`替换成手机IP。

#### 插入单个书源

请求BODY内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookSource.kt)

```
URL = http://127.0.0.1:1234/saveBookSource
Method = POST
```

#### 插入多个书源or订阅源

请求BODY内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。

```
URL = http://127.0.0.1:1234/saveBookSources
URL = http://127.0.0.1:1234/saveRssSources
Method = POST
```

#### 获取书源

```
URL = http://127.0.0.1:1234/getBookSource?url=xxx
URL = http://127.0.0.1:1234/getRssSource?url=xxx
Method = GET
``` 

#### 获取所有书源or订阅源

```
URL = http://127.0.0.1:1234/getBookSources
URL = http://127.0.0.1:1234/getRssSources
Method = GET
```

#### 删除多个书源or订阅源

请求BODY内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。

```
URL = http://127.0.0.1:1234/deleteBookSources
URL = http://127.0.0.1:1234/deleteRssSources
Method = POST
```

#### 调试源

key为书源搜索关键词,tag为源链接

```
URL = ws://127.0.0.1:1235/bookSourceDebug
URL = ws://127.0.0.1:1235/rssSourceDebug
Message = { key: [String], tag: [String] }
```

#### 获取替换规则

```
URL = http://127.0.0.1:1234/getReplaceRules
Method = GET
```

#### 替换规则管理

请求BODY内容为`JSON`字符串,  
替换规则参考[这个文件](/app/src/main/java/io/legado/app/data/entities/ReplaceRule.kt)。

##### 删除

```
URL = http://127.0.0.1:1234/deleteReplaceRule
Method = POST
Body = [ReplaceRule]
```
##### 插入

```
URL = http://127.0.0.1:1234/saveReplaceRule
Method = POST
Body = [ReplaceRule]
```

##### 测试

返回测试文本text替换结果

```
URL = http://127.0.0.1:1234/testReplaceRule
Method = POST
Body = { rule: [ReplaceRule], text: [String] }
```

#### 搜索在线书籍

若想获取对应的书籍的目录正文 请先**插入书籍**以启用缓存,如果试读后决定不添加到书籍,请**删除书籍**

```
URL = ws://127.0.0.1:1235/searchBook
Message = { key: [String] }
```

#### 插入书籍

请求BODY内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/Book.kt)。

```
URL = http://127.0.0.1:1234/saveBook
Method = POST
```

#### 删除书籍

```
URL = http://127.0.0.1:1234/deleteBook
Method = POST
```

#### 获取所有书籍

```
URL = http://127.0.0.1:1234/getBookshelf
Method = GET
```

获取APP内的所有书籍。

#### 获取书籍章节列表

```
URL = http://127.0.0.1:1234/getChapterList?url=xxx
Method = GET
```

获取指定图书的章节列表。

#### 获取书籍内容

```
URL = http://127.0.0.1:1234/getBookContent?url=xxx&index=1
Method = GET
```

获取指定图书的第`index`章节的文本内容。

#### 获取封面

```
URL = http://127.0.0.1:1234/cover?path=xxxxx
Method = GET
```

#### 获取正文图片

```
URL = http://127.0.0.1:1234/image?url=${bookUrl}&path=${picUrl}&width=${width}
Method = GET
```

#### 保存书籍进度

请求BODY内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookProgress.kt)。

```
URL = http://127.0.0.1:1234/saveBookProgress
Method = POST
```

### [Content Provider](/app/src/main/java/io/legado/app/api/ReaderProvider.kt)


* 需声明`io.legado.READ_WRITE`权限
* `providerHost`为`包名.readerProvider`, 如`io.legado.app.release.readerProvider`,不同包的地址不同,防止冲突安装失败
* 以下出现的`providerHost`请自行替换

#### 插入单个书源or订阅源

创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookSource.kt)

```
URL = content://providerHost/bookSource/insert
URL = content://providerHost/rssSource/insert
Method = insert
```

#### 插入多个书源or订阅源

创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。

```
URL = content://providerHost/bookSources/insert
URL = content://providerHost/rssSources/insert
Method = insert
```

#### 获取书源or订阅源

获取指定URL对应的书源信息。  
用`Cursor.getString(0)`取出返回结果。

```
URL = content://providerHost/bookSource/query?url=xxx
URL = content://providerHost/rssSource/query?url=xxx
Method = query
```

#### 获取所有书源or订阅源

获取APP内的所有订阅源。  
用`Cursor.getString(0)`取出返回结果。

```
URL = content://providerHost/bookSources/query
URL = content://providerHost/rssSources/query
Method = query
```

#### 删除多个书源or订阅源

创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/BookSource.kt),**为数组格式**。

```
URL = content://providerHost/bookSources/delete
URL = content://providerHost/rssSources/delete
Method = delete
```

#### 插入书籍

创建`Key="json"`的`ContentValues`,内容为`JSON`字符串,  
格式参考[这个文件](/app/src/main/java/io/legado/app/data/entities/Book.kt)。

```
URL = content://providerHost/book/insert
Method = insert
```

#### 获取所有书籍

获取APP内的所有书籍。  
用`Cursor.getString(0)`取出返回结果。

```
URL = content://providerHost/books/query
Method = query
```

#### 获取书籍章节列表

获取指定图书的章节列表。   
用`Cursor.getString(0)`取出返回结果。

```
URL = content://providerHost/book/chapter/query?url=xxx
Method = query
```

#### 获取书籍内容

获取指定图书的第`index`章节的文本内容。     
用`Cursor.getString(0)`取出返回结果。

```
URL = content://providerHost/book/content/query?url=xxx&index=1
Method = query
```

#### 获取封面

```
URL = content://providerHost/book/cover/query?path=xxxx
Method = query
```


================================================
FILE: app/.gitignore
================================================
/build
/so

================================================
FILE: app/build.gradle
================================================
plugins {
//    id "com.android.application"
//    id 'org.jetbrains.kotlin.android'
//    id 'kotlin-parcelize'
//    //id 'kotlin-kapt'
//    id 'com.google.devtools.ksp'
//    id "com.google.gms.google-services"

    alias libs.plugins.android.application
    alias libs.plugins.kotlin.android
    alias libs.plugins.kotlin.parcelize
    alias libs.plugins.room
    alias libs.plugins.ksp
    alias libs.plugins.google.services
}
apply from: 'download.gradle'

static def releaseTime() {
    return new Date().format("yy.MMddHH", TimeZone.getTimeZone("GMT+8"))
}

def name = "legado"
def version = "3." + releaseTime()
def gitCommits = Integer.parseInt('git rev-list HEAD --count'.execute().text.trim())

android {
    compileSdk = compile_sdk_version
    namespace = 'io.legado.app'
    kotlin {
        jvmToolchain {
            languageVersion.set(JavaLanguageVersion.of(17))
        }
    }

    signingConfigs {
        if (project.hasProperty("RELEASE_STORE_FILE")) {
            myConfig {
                storeFile file(RELEASE_STORE_FILE)
                storePassword RELEASE_STORE_PASSWORD
                keyAlias RELEASE_KEY_ALIAS
                keyPassword RELEASE_KEY_PASSWORD
                enableV1Signing = true
                enableV2Signing = true
                enableV3Signing = true
                enableV4Signing = true
            }
        }
    }
    defaultConfig {
        applicationId "io.legado.app"
        minSdk 21
        targetSdk 36
        versionCode 10000 + gitCommits
        versionName version
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        project.ext.set("archivesBaseName", name + "_" + version)

        buildConfigField "String", "Cronet_Version", "\"$CronetVersion\""
        buildConfigField "String", "Cronet_Main_Version", "\"$CronetMainVersion\""

        javaCompileOptions {
            annotationProcessorOptions {
                arguments += [
                        "room.incremental"     : "true",
                        "room.expandProjection": "true",
                        "room.schemaLocation"  : "$projectDir/schemas".toString()
                ]
            }
        }
    }
    buildFeatures {
        buildConfig = true
        viewBinding = true
    }
    buildTypes {
        release {
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                signingConfig signingConfigs.myConfig
            }
            applicationIdSuffix '.release'
            if (getApplicationIdSuffix() == '.releaseA') {
                manifestPlaceholders.put("app_name", "@string/app_name_a")
            } else {
                manifestPlaceholders.put("app_name", "@string/app_name")
            }

            minifyEnabled true
            shrinkResources = true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'cronet-proguard-rules.pro'
        }
        debug {
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                signingConfig signingConfigs.myConfig
            }
            manifestPlaceholders.put("app_name", "@string/app_name")

            applicationIdSuffix '.debug'
            versionNameSuffix 'debug'
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'cronet-proguard-rules.pro'
        }
    }
    //noinspection GrDeprecatedAPIUsage
    flavorDimensions = ['mode']
    productFlavors {
        app {
            dimension "mode"
            manifestPlaceholders.put("APP_CHANNEL_VALUE", "app")
        }
    }

    android.applicationVariants.configureEach { variant ->
        variant.outputs.configureEach {
            def flavor = variant.productFlavors[0].name
            outputFileName = "${name}_${flavor}_${defaultConfig.versionName}.apk"
        }
    }


    room {
        schemaDirectory "$projectDir/schemas"
    }
    // 设定Room的KSP参数
    ksp {
        arg("room.incremental", "true")
        arg("room.expandProjection", "true")
        arg("room.generateKotlin", "false")
        //arg("room.schemaLocation", "$projectDir/schemas")

    }

    compileOptions {
        // Flag to enable support for the new language APIs
        coreLibraryDesugaringEnabled = true
        // Sets Java compatibility
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    packaging {
        resources.excludes.add('META-INF/*')
    }

    sourceSets {
        // Adds exported schema location as test app assets.
        androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    }
    lint {
        checkDependencies = true
    }
    tasks.withType(JavaCompile).tap {
        configureEach {
            //options.compilerArgs << "-Xlint:unchecked"
        }
    }
}

dependencies {
    //compileOnly "com.android.tools.build:gradle:$agp_version"
    //noinspection GradleDependency,GradlePackageUpdate
    //coreLibraryDesugaring('com.android.tools:desugar_jdk_libs_nio:2.0.4')
    coreLibraryDesugaring(libs.desugar)
    testImplementation(libs.junit)
    androidTestImplementation(libs.bundles.androidTest)
    //kotlin
    //noinspection GradleDependency,DifferentStdlibGradleVersion
    implementation(libs.kotlin.stdlib)
    //Kotlin反射
    //noinspection GradleDependency,DifferentStdlibGradleVersion
    //implementation(libs.kotlin.reflect)


    //协程
    //def coroutines_version = '1.7.3'
    implementation(libs.bundles.coroutines)


    //图像处理库Toolkit
    implementation(libs.renderscript.intrinsics.replacement.toolkit)

    //androidX
    implementation(libs.core.ktx)
    implementation(libs.appcompat.appcompat)
    implementation(libs.activity.ktx)
    implementation(libs.fragment.ktx)
    implementation(libs.preference.ktx)
    implementation(libs.androidx.constraintlayout)
    implementation(libs.androidx.swiperefreshlayout)
    implementation(libs.androidx.recyclerview)
    implementation(libs.androidx.viewpager2)
    implementation(libs.androidx.webkit)
    implementation(libs.androidx.documentfile)

    //google
    implementation(libs.material)
    implementation(libs.flexbox)
    implementation(libs.gson)

    //lifecycle
    implementation(libs.lifecycle.common.java8)
    implementation(libs.lifecycle.service)

    //media
    implementation(libs.media.media)
    // For media playback using ExoPlayer
    implementation(libs.media3.exoplayer)
    // For loading data using the OkHttp network stack
    implementation(libs.media3.datasource.okhttp)
    // For exposing and controlling media sessions
    //implementation "androidx.media3:media3-session:$media3_version"

    //Splitties
    implementation(libs.splitties.appctx)
    implementation(libs.splitties.systemservices)
    implementation(libs.splitties.views)

    //room sql语句不高亮解决方法https://issuetracker.google.com/issues/234612964#comment6
    implementation(libs.room.runtime)
    implementation(libs.room.ktx)
    //kapt("androidx.room:room-compiler:$room_version")
    ksp(libs.room.compiler)
    androidTestImplementation(libs.room.testing)

    //liveEventBus
    implementation(libs.liveeventbus)

    //规则相关
    implementation(libs.jsoup)
    implementation(libs.json.path)
    implementation(libs.jsoupxpath)
    implementation(project(path: ':modules:book'))
    implementation(project(path: ':modules:rhino'))

    //JS rhino

    //网络
    implementation(libs.okhttp)
    implementation(fileTree(dir: 'cronetlib', include: ['*.jar', '*.aar']))
    implementation(libs.protobuf.javalite)

    //Glide
    implementation(libs.glide.glide)
    implementation(libs.glide.okhttp)
    ksp(libs.glide.ksp)

    //Svg
    implementation(libs.androidsvg)
    //Glide svg plugin
    implementation(libs.glide.svg)

    //webServer
    implementation(libs.nanohttpd.nanohttpd)
    implementation(libs.nanohttpd.websocket)

    //二维码
    //noinspection GradleDependency
    implementation(libs.zxing.lite)

    //颜色选择
    implementation(libs.colorpicker)

    //压缩解压
    implementation libs.libarchive

    //apache
    implementation(libs.commons.text)

    //MarkDown
    implementation(libs.markwon.core)
    implementation(libs.markwon.image.glide)
    implementation(libs.markwon.ext.tables)
    implementation(libs.markwon.html)

    //转换繁体
    implementation(libs.quick.chinese.transfer.core)

    //加解密类库,有些书源使用
    //noinspection GradleDependency,GradlePackageUpdate
    implementation(libs.hutool.crypto)

    //firebase, 崩溃统计和性能统计
    implementation platform(libs.firebase.bom)
    implementation libs.firebase.analytics
    implementation libs.firebase.perf

    implementation libs.glide.recyclerview

    //LeakCanary, 内存泄露检测
    //debugImplementation('com.squareup.leakcanary:leakcanary-android:2.7')

    //com.github.AmrDeveloper:CodeView代码编辑已集成到应用内
    //epubLib集成到应用内
}


================================================
FILE: app/cronet-proguard-rules.pro
================================================
# -------- Config Path: base/android/proguard/shared_with_cronet.flags --------
# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Contains flags that we want to apply not only to Chromium APKs, but also to
# third-party apps that bundle the Cronet library.

# WARNING: rules in this file are applied to entire third-party APKs, not just
# Chromium code. They MUST be scoped appropriately to avoid side effects on app
# code that we do not own.

# Keep all CREATOR fields within Parcelable that are kept.
-keepclassmembers class !cr_allowunused,org.chromium.** implements android.os.Parcelable {
  public static *** CREATOR;
}

# Don't obfuscate Parcelables as they might be marshalled outside Chrome.
# If we annotated all Parcelables that get put into Bundles other than
# for saveInstanceState (e.g. PendingIntents), then we could actually keep the
# names of just those ones. For now, we'll just keep them all.
-keepnames,allowaccessmodification class !cr_allowunused,org.chromium.** implements android.os.Parcelable {}

# Keep all enum values and valueOf methods. See
# http://proguard.sourceforge.net/index.html#manual/examples.html
# for the reason for this. Also, see http://crbug.com/248037.
-keepclassmembers enum !cr_allowunused,org.chromium.** {
    public static **[] values();
}

# Required to remove fields until b/274802355 is resolved.
-assumevalues class !cr_allowunused,** {
  final org.chromium.base.ThreadUtils$ThreadChecker * return _NONNULL_;
}
# -------- Config Path: build/android/chromium_annotations.flags --------
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Contains flags related to annotations in //build/android that can be safely
# shared with Cronet, and thus would be appropriate for third-party apps to
# include.

# Keep all annotation related attributes that can affect runtime
-keepattributes RuntimeVisible*Annotations
-keepattributes AnnotationDefault

# Keeps for class level annotations.
-keep,allowaccessmodification @org.chromium.build.annotations.UsedByReflection class ** {}

# Keeps for method level annotations.
-keepclasseswithmembers,allowaccessmodification class ** {
  @org.chromium.build.annotations.UsedByReflection <methods>;
}
-keepclasseswithmembers,allowaccessmodification class ** {
  @org.chromium.build.annotations.UsedByReflection <fields>;
}

# Never inline classes, methods, or fields with this annotation, but allow
# shrinking and obfuscation.
# Relevant to fields when they are needed to store strong references to objects
# that are held as weak references by native code.
-if @org.chromium.build.annotations.DoNotInline class * {
    *** *(...);
}
-keep,allowobfuscation,allowaccessmodification class <1> {
    *** <2>(...);
}
-keepclassmembers,allowobfuscation,allowaccessmodification class * {
   @org.chromium.build.annotations.DoNotInline <methods>;
}
-keepclassmembers,allowobfuscation,allowaccessmodification class * {
   @org.chromium.build.annotations.DoNotInline <fields>;
}

-alwaysinline class * {
    @org.chromium.build.annotations.AlwaysInline *;
}

# Keep all logs (Log.VERBOSE = 2). R8 does not allow setting to 0.
-maximumremovedandroidloglevel 1 class ** {
   @org.chromium.build.annotations.DoNotStripLogs <methods>;
}
-maximumremovedandroidloglevel 1 @org.chromium.build.annotations.DoNotStripLogs class ** {
   <methods>;
}

# Never merge classes horizontally or vertically with this annotation.
# Relevant to classes being used as a key in maps or sets.
-keep,allowaccessmodification,allowobfuscation,allowshrinking @org.chromium.build.annotations.DoNotClassMerge class *

# Mark members annotated with IdentifierNameString as identifier name strings
-identifiernamestring class * {
    @org.chromium.build.annotations.IdentifierNameString *;
}

# Mark fields with this to help R8 figure out that they cannot be null.
# Use assumevalues in addition to assumenosideeffects block because Google3 proguard cannot parse
# assumenosideeffects blocks which overwrite return value.
-assumevalues class ** {
  @org.chromium.build.annotations.AssumeNonNull *** *(...) return _NONNULL_;
}
-assumenosideeffects class ** {
  @org.chromium.build.annotations.AssumeNonNull *** *(...);
}
-assumevalues class ** {
  @org.chromium.build.annotations.AssumeNonNull *** * return _NONNULL_;
}
-assumenosideeffects class ** {
  @org.chromium.build.annotations.AssumeNonNull *** *;
}
# -------- Config Path: components/cronet/android/cronet_impl_common_proguard.cfg --------
# Proguard config for apps that depend on cronet_impl_common_java.jar.

# Used through reflection by the API code to figure out the version of the impl
# code it's talking to.
-keep public class org.chromium.net.impl.ImplVersion {
  public *;
}

-dontwarn com.google.errorprone.annotations.DoNotMock
# -------- Config Path: components/cronet/android/cronet_impl_native_proguard.cfg --------
# Proguard config for apps that depend on cronet_impl_native_java.jar.

# This constructor is called using the reflection from Cronet API (cronet_api.jar).
-keep class org.chromium.net.impl.NativeCronetProvider {
    public <init>(android.content.Context);
}

# While Chrome doesn't need to keep these with their version of R8, some cronet
# users may be on other optimizers which still require the annotation to be
# kept in order for the keep rules to work.
-keep @interface org.chromium.build.annotations.DoNotInline
-keep @interface org.chromium.build.annotations.UsedByReflection
-keep @interface org.chromium.build.annotations.IdentifierNameString
-keep @interface org.jni_zero.AccessedByNative
-keep @interface org.jni_zero.CalledByNative
-keep @interface org.jni_zero.CalledByNativeUnchecked

# Suppress unnecessary warnings.
-dontnote org.chromium.net.ProxyChangeListener$ProxyReceiver
-dontnote org.chromium.net.AndroidKeyStore
# Needs 'void setTextAppearance(int)' (API level 23).
-dontwarn org.chromium.base.ApiCompatibilityUtils
# Needs 'boolean onSearchRequested(android.view.SearchEvent)' (API level 23).
-dontwarn org.chromium.base.WindowCallbackWrapper

# Generated for chrome apk and not included into cronet.
-dontwarn org.chromium.base.multidex.ChromiumMultiDexInstaller
-dontwarn org.chromium.base.library_loader.LibraryLoader
-dontwarn org.chromium.base.SysUtils
-dontwarn org.chromium.build.NativeLibraries

# Objects of this type are passed around by native code, but the class
# is never used directly by native code. Since the class is not loaded, it does
# not need to be preserved as an entry point.
-dontnote org.chromium.net.UrlRequest$ResponseHeadersMap
# https://android.googlesource.com/platform/sdk/+/marshmallow-mr1-release/files/proguard-android.txt#54
-dontwarn android.support.**

# This class should be explicitly kept to avoid failure if
# class/merging/horizontal proguard optimization is enabled.
-keep class org.chromium.base.CollectionUtil

# Skip protobuf runtime check for isOnAndroidDevice().
# A nice-to-have optimization shamelessly stolen from //third_party/protobuf/java/lite/proguard.pgcfg.
-assumevalues class com.google.protobuf.Android {
    static boolean ASSUME_ANDROID return true;
}

# See crbug.com/1440987. We must keep every native that we are manually
# registering. If Cronet bumps its min-sdk past 21, we may be able to move to
# automatic JNI registration.
-keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class org.chromium.**,J.N {
  native <methods>;
}

# Protobuf builder uses reflection so make sure ProGuard leaves it alone. See
# https://crbug.com/1395764.
# Note that we can't simply use the rule from
# //third_party/protobuf/java/lite/proguard.pgcfg, because some users who
# consume our ProGuard rules do not want all their protos to be kept. Instead,
# use a more specific rule that covers Chromium protos only.
-keepclassmembers class org.chromium.** extends com.google.protobuf.GeneratedMessageLite {
  <fields>;
}
# -------- Config Path: components/cronet/android/cronet_shared_proguard.cfg --------
# Proguard config for apps that depend on cronet_shared_java.jar (which should
# be all apps that depend on any part of Cronet)

# Part of the Android System SDK, so ProGuard won't be able to resolve it if
# running against the standard SDK.
-dontwarn android.util.StatsEvent
-dontwarn android.util.StatsEvent$*
# There is also an undefined reference to android.util.StatsLog.write(), which
# R8 appears to be fine with but other processors (e.g. internal Google
# ProGuard) may not be. See b/315269496.
-dontwarn android.util.StatsLog
# -------- Config Path: third_party/androidx/androidx_annotations.flags --------
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

-keep @androidx.annotation.Keep class *
-keepclasseswithmembers,allowaccessmodification class * {
  @androidx.annotation.Keep <fields>;
}
-keepclasseswithmembers,allowaccessmodification class * {
  @androidx.annotation.Keep <methods>;
}
# -------- Config Path: third_party/jni_zero/proguard.flags --------
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Keeps for method level annotations.
-keepclasseswithmembers,allowaccessmodification class ** {
  @org.jni_zero.AccessedByNative <fields>;
}
-keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
  @org.jni_zero.CalledByNative <methods>;
}
-keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
  @org.jni_zero.CalledByNativeUnchecked <methods>;
}

# Allow unused native methods to be removed, but prevent renaming on those that
# are kept.
# TODO(crbug.com/315973491): Restrict the broad scope of this rule.
-keepclasseswithmembernames,includedescriptorclasses,allowaccessmodification class ** {
  native <methods>;
}


================================================
FILE: app/download.gradle
================================================
import java.security.MessageDigest

apply plugin: 'de.undercouch.download'

def BASE_PATH = "https://storage.googleapis.com/chromium-cronet/android/" + CronetVersion + "/Release/cronet/"
def assetsDir = projectDir.toString() + "/src/main/assets"
def libPath = projectDir.toString() + "/cronetlib"
def soPath = projectDir.toString() + "/so"

/**
 * 从文件生成MD5
 * @param file
 * @return
 */
static def generateMD5(final file) {
    MessageDigest digest = MessageDigest.getInstance("MD5")
    file.withInputStream() { is ->
        byte[] buffer = new byte[1024]
        //noinspection GroovyUnusedAssignment
        int numRead = 0
        while ((numRead = is.read(buffer)) > 0) {
            digest.update(buffer, 0, numRead)
        }
    }
    return String.format("%032x", new BigInteger(1, digest.digest())).toLowerCase()
}

/**
 * 下载Cronet相关的jar
 */
tasks.register('downloadJar', Download) {
    src([
            BASE_PATH + "cronet_api.jar",
            BASE_PATH + "cronet_impl_common_java.jar",
            BASE_PATH + "cronet_impl_native_java.jar",
            BASE_PATH + "cronet_impl_platform_java.jar",
            BASE_PATH + "cronet_shared_java.jar"
    ])
    dest libPath
    overwrite true
    onlyIfModified false
}
/**
 * 下载Cronet的arm64-v8a so
 */
tasks.register('downloadARM64', Download) {
    src BASE_PATH + "libs/arm64-v8a/libcronet." + CronetVersion + ".so"
    dest soPath + "/arm64-v8a.so"
    overwrite true
    onlyIfModified true
}
/**
 * 下载Cronet的armeabi-v7a so
 */
tasks.register('downloadARMv7', Download) {
    src BASE_PATH + "libs/armeabi-v7a/libcronet." + CronetVersion + ".so"
    dest soPath + "/armeabi-v7a.so"
    overwrite true
    onlyIfModified true
}
/**
 * 下载Cronet的x86_64 so
 */
tasks.register('downloadX86_64', Download) {
    src BASE_PATH + "libs/x86_64/libcronet." + CronetVersion + ".so"
    dest soPath + "/x86_64.so"
    overwrite true
    onlyIfModified true
}
/**
 * 下载Cronet的x86 so
 */
tasks.register('downloadX86', Download) {
    src BASE_PATH + "libs/x86/libcronet." + CronetVersion + ".so"
    dest soPath + "/x86.so"
    overwrite true
    onlyIfModified true
}

/**
 * 更新Cronet版本时执行这个task
 * 先更改gradle.properties 里面的版本号,然后再执行
 * gradlew app:downloadCronet
 */
tasks.register('downloadCronet') {
    dependsOn downloadJar, downloadARM64, downloadARMv7, downloadX86_64, downloadX86

    doLast {
        StringBuilder sb = new StringBuilder("{")
        def files = new File(soPath).listFiles()
        for (File file : files) {
            println file.name.replace(".so", "")
            sb.append("\"").append(file.name.replace(".so", "")).append("\":\"").append(generateMD5(file)).append("\",")
        }
        sb.append("\"version\":\"").append(CronetVersion).append("\"}")

        println sb.toString()

        println assetsDir
        def f1 = new File(assetsDir + "/cronet.json")
        if (!f1.exists()) {
            f1.parentFile.mkdirs()
            f1.createNewFile()
        }
        f1.text = sb.toString()

    }


}




================================================
FILE: app/google-services.json
================================================
{
  "project_info": {
    "project_number": "453392274790",
    "firebase_url": "https://legado-fca69.firebaseio.com",
    "project_id": "legado-fca69",
    "storage_bucket": "legado-fca69.appspot.com"
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:453392274790:android:c4eac14b1410eec5f624a7",
        "android_client_info": {
          "package_name": "io.legado.app.debug"
        }
      },
      "oauth_client": [
        {
          "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    },
    {
      "client_info": {
        "mobilesdk_app_id": "1:453392274790:android:c1481c1c3d3f51eff624a7",
        "android_client_info": {
          "package_name": "io.legado.app.release"
        }
      },
      "oauth_client": [
        {
          "client_id": "453392274790-trrgennt5njr1lhil1sgtf0ogcgd38fo.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "io.legado.app.release",
            "certificate_hash": "fd67dba87b7b761631266f19ddde249054aac5c1"
          }
        },
        {
          "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    },
    {
      "client_info": {
        "mobilesdk_app_id": "1:453392274790:android:b891abd2331577dff624a7",
        "android_client_info": {
          "package_name": "io.legado.play.release"
        }
      },
      "oauth_client": [
        {
          "client_id": "453392274790-f8sjn6ohs72rg1dvp0pdvk42nkq54p0k.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "io.legado.play.release",
            "certificate_hash": "00819ace9891386e535967cbafd6a88f3797bd5b"
          }
        },
        {
          "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    },
    {
      "client_info": {
        "mobilesdk_app_id": "1:453392274790:android:b891abd2331577dff624a7",
        "android_client_info": {
          "package_name": "io.legado.play.debug"
        }
      },
      "oauth_client": [
        {
          "client_id": "453392274790-f8sjn6ohs72rg1dvp0pdvk42nkq54p0k.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "io.legado.play.debug",
            "certificate_hash": "00819ace9891386e535967cbafd6a88f3797bd5b"
          }
        },
        {
          "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyD90mfNLhA7cAzzI9SonpSz5mrF5BnmyJA"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "453392274790-hnbpatpce9hbjiggj76hgo7queu86atq.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    }
  ],
  "configuration_version": "1"
}

================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# 混合时不使用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames

# 这句话能够使我们的项目混淆后产生映射文件
# 包含有类名->混淆后类名的映射关系
-verbose

# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses

# 避免混淆泛型
-keepattributes Signature

# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*

-flattenpackagehierarchy

#############################################
#
# Android开发中一些需要保留的公共部分
#
#############################################
# 屏蔽错误Unresolved class name
#noinspection ShrinkerUnresolvedReference

# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
-assumenosideeffects class android.util.Log {
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}

# 保持js引擎调用的java类
-keep class * extends io.legado.app.help.JsExtensions{*;}
# 数据类
-keep class **.data.entities.**{*;}
# hutool-core hutool-crypto
-keep class
!cn.hutool.core.util.RuntimeUtil,
!cn.hutool.core.util.ClassLoaderUtil,
!cn.hutool.core.util.ReflectUtil,
!cn.hutool.core.util.SerializeUtil,
!cn.hutool.core.util.ClassUtil,
cn.hutool.core.codec.**,
cn.hutool.core.util.**{*;}
-keep class cn.hutool.crypto.**{*;}
-dontwarn cn.hutool.**
# 缓存 Cookie
-keep class **.help.http.CookieStore{*;}
-keep class **.help.CacheManager{*;}
# StrResponse
-keep class **.help.http.StrResponse{*;}

# markwon
-dontwarn org.commonmark.ext.gfm.**

-keep class okhttp3.*{*;}
-keep class okio.*{*;}
-keep class com.jayway.jsonpath.*{*;}

# LiveEventBus
-keepclassmembers class androidx.lifecycle.LiveData {
    *** mObservers;
    *** mActiveCount;
}
-keepclassmembers class androidx.arch.core.internal.SafeIterableMap {
    *** size();
    *** putIfAbsent(...);
}

## ChangeBookSourceDialog initNavigationView
-keepclassmembers class androidx.appcompat.widget.Toolbar {
    *** mNavButtonView;
}

# MenuExtensions applyOpenTint
-keepnames class androidx.appcompat.view.menu.SubMenuBuilder
-keep class androidx.appcompat.view.menu.MenuBuilder {
    *** setOptionalIconsVisible(...);
    *** getNonActionItems();
}

# FileDocExtensions.kt treeDocumentFileConstructor
-keep class androidx.documentfile.provider.TreeDocumentFile {
    <init>(...);
}

# JsoupXpath
-keep,allowobfuscation class * implements org.seimicrawler.xpath.core.AxisSelector{*;}
-keep,allowobfuscation class * implements org.seimicrawler.xpath.core.NodeTest{*;}
-keep,allowobfuscation class * implements org.seimicrawler.xpath.core.Function{*;}

## JSOUP
-keep class org.jsoup.**{*;}
-dontwarn org.jspecify.annotations.NullMarked

## ExoPlayer 反射设置ua 保证该私有变量不被混淆
-keepclassmembers class androidx.media3.datasource.cache.CacheDataSource$Factory {
    *** upstreamDataSourceFactory;
}
## ExoPlayer 如果还不能播放就取消注释这个
# -keep class com.google.android.exoplayer2.** {*;}

## 对外提供api
-keep class io.legado.app.api.ReturnData{*;}

# Cronet
-keepclassmembers class org.chromium.net.X509Util {
    *** sDefaultTrustManager;
    *** sTestTrustManager;
}

# Throwable
-keepnames class * extends java.lang.Throwable
-keepclassmembernames,allowobfuscation class * extends java.lang.Throwable{*;}


================================================
FILE: app/schemas/io.legado.app.data.AppDatabase/1.json
================================================
{
  "formatVersion": 1,
  "database": {
    "version": 1,
    "identityHash": "d9ed367fc7241a61e9f770d416c4f887",
    "entities": [
      {
        "tableName": "books",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL, `group` INTEGER NOT NULL, `latestChapterTitle` TEXT, `latestChapterTime` INTEGER NOT NULL, `lastCheckTime` INTEGER NOT NULL, `lastCheckCount` INTEGER NOT NULL, `totalChapterNum` INTEGER NOT NULL, `durChapterTitle` TEXT, `durChapterIndex` INTEGER NOT NULL, `durChapterPos` INTEGER NOT NULL, `durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL, `order` INTEGER NOT NULL, `originOrder` INTEGER NOT NULL, `useReplaceRule` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`bookUrl`))",
        "fields": [
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "tocUrl",
            "columnName": "tocUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "originName",
            "columnName": "originName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "author",
            "columnName": "author",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "kind",
            "columnName": "kind",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customTag",
            "columnName": "customTag",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "coverUrl",
            "columnName": "coverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customCoverUrl",
            "columnName": "customCoverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "intro",
            "columnName": "intro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customIntro",
            "columnName": "customIntro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "charset",
            "columnName": "charset",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "type",
            "columnName": "type",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "group",
            "columnName": "group",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "latestChapterTitle",
            "columnName": "latestChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "latestChapterTime",
            "columnName": "latestChapterTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastCheckTime",
            "columnName": "lastCheckTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastCheckCount",
            "columnName": "lastCheckCount",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "totalChapterNum",
            "columnName": "totalChapterNum",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterTitle",
            "columnName": "durChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "durChapterIndex",
            "columnName": "durChapterIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterPos",
            "columnName": "durChapterPos",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterTime",
            "columnName": "durChapterTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "wordCount",
            "columnName": "wordCount",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "canUpdate",
            "columnName": "canUpdate",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "originOrder",
            "columnName": "originOrder",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "useReplaceRule",
            "columnName": "useReplaceRule",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "bookUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_books_bookUrl",
            "unique": true,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_books_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "book_groups",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`groupId` INTEGER NOT NULL, `groupName` TEXT NOT NULL, `order` INTEGER NOT NULL, PRIMARY KEY(`groupId`))",
        "fields": [
          {
            "fieldPath": "groupId",
            "columnName": "groupId",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "groupName",
            "columnName": "groupName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "groupId"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "book_sources",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceUrl` TEXT NOT NULL, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `header` TEXT, `loginUrl` TEXT, `lastUpdateTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, PRIMARY KEY(`bookSourceUrl`))",
        "fields": [
          {
            "fieldPath": "bookSourceName",
            "columnName": "bookSourceName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookSourceGroup",
            "columnName": "bookSourceGroup",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "bookSourceUrl",
            "columnName": "bookSourceUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookSourceType",
            "columnName": "bookSourceType",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "bookUrlPattern",
            "columnName": "bookUrlPattern",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customOrder",
            "columnName": "customOrder",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enabled",
            "columnName": "enabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enabledExplore",
            "columnName": "enabledExplore",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "header",
            "columnName": "header",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "loginUrl",
            "columnName": "loginUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "lastUpdateTime",
            "columnName": "lastUpdateTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "weight",
            "columnName": "weight",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "exploreUrl",
            "columnName": "exploreUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleExplore",
            "columnName": "ruleExplore",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "searchUrl",
            "columnName": "searchUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleSearch",
            "columnName": "ruleSearch",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleBookInfo",
            "columnName": "ruleBookInfo",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleToc",
            "columnName": "ruleToc",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleContent",
            "columnName": "ruleContent",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "bookSourceUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_book_sources_bookSourceUrl",
            "unique": false,
            "columnNames": [
              "bookSourceUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_book_sources_bookSourceUrl` ON `${TABLE_NAME}` (`bookSourceUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "chapters",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `bookUrl` TEXT NOT NULL, `index` INTEGER NOT NULL, `resourceUrl` TEXT, `tag` TEXT, `start` INTEGER, `end` INTEGER, `variable` TEXT, PRIMARY KEY(`url`, `bookUrl`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )",
        "fields": [
          {
            "fieldPath": "url",
            "columnName": "url",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "title",
            "columnName": "title",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "index",
            "columnName": "index",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "resourceUrl",
            "columnName": "resourceUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "tag",
            "columnName": "tag",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "start",
            "columnName": "start",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "end",
            "columnName": "end",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "url",
            "bookUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_chapters_bookUrl",
            "unique": false,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_chapters_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          },
          {
            "name": "index_chapters_bookUrl_index",
            "unique": true,
            "columnNames": [
              "bookUrl",
              "index"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_chapters_bookUrl_index` ON `${TABLE_NAME}` (`bookUrl`, `index`)"
          }
        ],
        "foreignKeys": [
          {
            "table": "books",
            "onDelete": "CASCADE",
            "onUpdate": "NO ACTION",
            "columns": [
              "bookUrl"
            ],
            "referencedColumns": [
              "bookUrl"
            ]
          }
        ]
      },
      {
        "tableName": "replace_rules",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `group` TEXT, `pattern` TEXT NOT NULL, `replacement` TEXT NOT NULL, `scope` TEXT, `isEnabled` INTEGER NOT NULL, `isRegex` INTEGER NOT NULL, `sortOrder` INTEGER NOT NULL)",
        "fields": [
          {
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "group",
            "columnName": "group",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "pattern",
            "columnName": "pattern",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "replacement",
            "columnName": "replacement",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "scope",
            "columnName": "scope",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "isEnabled",
            "columnName": "isEnabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "isRegex",
            "columnName": "isRegex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "sortOrder",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "id"
          ],
          "autoGenerate": true
        },
        "indices": [
          {
            "name": "index_replace_rules_id",
            "unique": false,
            "columnNames": [
              "id"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_replace_rules_id` ON `${TABLE_NAME}` (`id`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "searchBooks",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `coverUrl` TEXT, `intro` TEXT, `wordCount` TEXT, `latestChapterTitle` TEXT, `tocUrl` TEXT NOT NULL, `time` INTEGER NOT NULL, `variable` TEXT, `originOrder` INTEGER NOT NULL, PRIMARY KEY(`bookUrl`))",
        "fields": [
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "originName",
            "columnName": "originName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "type",
            "columnName": "type",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "author",
            "columnName": "author",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "kind",
            "columnName": "kind",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "coverUrl",
            "columnName": "coverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "intro",
            "columnName": "intro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "wordCount",
            "columnName": "wordCount",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "latestChapterTitle",
            "columnName": "latestChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "tocUrl",
            "columnName": "tocUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "time",
            "columnName": "time",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "originOrder",
            "columnName": "originOrder",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "bookUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_searchBooks_bookUrl",
            "unique": true,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_searchBooks_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "search_keywords",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`word` TEXT NOT NULL, `usage` INTEGER NOT NULL, `lastUseTime` INTEGER NOT NULL, PRIMARY KEY(`word`))",
        "fields": [
          {
            "fieldPath": "word",
            "columnName": "word",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "usage",
            "columnName": "usage",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastUseTime",
            "columnName": "lastUseTime",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "word"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_search_keywords_word",
            "unique": true,
            "columnNames": [
              "word"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_search_keywords_word` ON `${TABLE_NAME}` (`word`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "cookies",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `cookie` TEXT NOT NULL, PRIMARY KEY(`url`))",
        "fields": [
          {
            "fieldPath": "url",
            "columnName": "url",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "cookie",
            "columnName": "cookie",
            "affinity": "TEXT",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "url"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_cookies_url",
            "unique": true,
            "columnNames": [
              "url"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_cookies_url` ON `${TABLE_NAME}` (`url`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "rssSources",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sourceUrl` TEXT NOT NULL, `sourceName` TEXT NOT NULL, `sourceIcon` TEXT NOT NULL, `sourceGroup` TEXT, `enabled` INTEGER NOT NULL, `ruleArticles` TEXT, `ruleNextPage` TEXT, `ruleTitle` TEXT, `rulePubDate` TEXT, `ruleCategories` TEXT, `ruleDescription` TEXT, `ruleImage` TEXT, `ruleLink` TEXT, `ruleContent` TEXT, `enableJs` INTEGER NOT NULL, `loadWithBaseUrl` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, PRIMARY KEY(`sourceUrl`))",
        "fields": [
          {
            "fieldPath": "sourceUrl",
            "columnName": "sourceUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sourceName",
            "columnName": "sourceName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sourceIcon",
            "columnName": "sourceIcon",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sourceGroup",
            "columnName": "sourceGroup",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "enabled",
            "columnName": "enabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "ruleArticles",
            "columnName": "ruleArticles",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleNextPage",
            "columnName": "ruleNextPage",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleTitle",
            "columnName": "ruleTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "rulePubDate",
            "columnName": "rulePubDate",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleCategories",
            "columnName": "ruleCategories",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleDescription",
            "columnName": "ruleDescription",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleImage",
            "columnName": "ruleImage",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleLink",
            "columnName": "ruleLink",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleContent",
            "columnName": "ruleContent",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "enableJs",
            "columnName": "enableJs",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "loadWithBaseUrl",
            "columnName": "loadWithBaseUrl",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "customOrder",
            "columnName": "customOrder",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "sourceUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_rssSources_sourceUrl",
            "unique": false,
            "columnNames": [
              "sourceUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_rssSources_sourceUrl` ON `${TABLE_NAME}` (`sourceUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "bookmarks",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`time` INTEGER NOT NULL, `bookUrl` TEXT NOT NULL, `bookName` TEXT NOT NULL, `chapterName` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `pageIndex` INTEGER NOT NULL, `content` TEXT NOT NULL, PRIMARY KEY(`time`))",
        "fields": [
          {
            "fieldPath": "time",
            "columnName": "time",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookName",
            "columnName": "bookName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "chapterName",
            "columnName": "chapterName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "chapterIndex",
            "columnName": "chapterIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "pageIndex",
            "columnName": "pageIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "content",
            "columnName": "content",
            "affinity": "TEXT",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "time"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_bookmarks_bookUrl",
            "unique": true,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_bookmarks_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "rssArticles",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `title` TEXT NOT NULL, `order` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, `categories` TEXT, `read` INTEGER NOT NULL, `star` INTEGER NOT NULL, PRIMARY KEY(`origin`, `link`))",
        "fields": [
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "title",
            "columnName": "title",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "link",
            "columnName": "link",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "pubDate",
            "columnName": "pubDate",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "description",
            "columnName": "description",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "content",
            "columnName": "content",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "image",
            "columnName": "image",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "categories",
            "columnName": "categories",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "read",
            "columnName": "read",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "star",
            "columnName": "star",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "origin",
            "link"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd9ed367fc7241a61e9f770d416c4f887')"
    ]
  }
}

================================================
FILE: app/schemas/io.legado.app.data.AppDatabase/10.json
================================================
{
  "formatVersion": 1,
  "database": {
    "version": 10,
    "identityHash": "a9744f575dad6d4774cccc433921973b",
    "entities": [
      {
        "tableName": "books",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL, `group` INTEGER NOT NULL, `latestChapterTitle` TEXT, `latestChapterTime` INTEGER NOT NULL, `lastCheckTime` INTEGER NOT NULL, `lastCheckCount` INTEGER NOT NULL, `totalChapterNum` INTEGER NOT NULL, `durChapterTitle` TEXT, `durChapterIndex` INTEGER NOT NULL, `durChapterPos` INTEGER NOT NULL, `durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL, `order` INTEGER NOT NULL, `originOrder` INTEGER NOT NULL, `useReplaceRule` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`name`, `author`))",
        "fields": [
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "tocUrl",
            "columnName": "tocUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "originName",
            "columnName": "originName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "author",
            "columnName": "author",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "kind",
            "columnName": "kind",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customTag",
            "columnName": "customTag",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "coverUrl",
            "columnName": "coverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customCoverUrl",
            "columnName": "customCoverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "intro",
            "columnName": "intro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customIntro",
            "columnName": "customIntro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "charset",
            "columnName": "charset",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "type",
            "columnName": "type",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "group",
            "columnName": "group",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "latestChapterTitle",
            "columnName": "latestChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "latestChapterTime",
            "columnName": "latestChapterTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastCheckTime",
            "columnName": "lastCheckTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastCheckCount",
            "columnName": "lastCheckCount",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "totalChapterNum",
            "columnName": "totalChapterNum",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterTitle",
            "columnName": "durChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "durChapterIndex",
            "columnName": "durChapterIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterPos",
            "columnName": "durChapterPos",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterTime",
            "columnName": "durChapterTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "wordCount",
            "columnName": "wordCount",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "canUpdate",
            "columnName": "canUpdate",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "originOrder",
            "columnName": "originOrder",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "useReplaceRule",
            "columnName": "useReplaceRule",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "name",
            "author"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_books_bookUrl",
            "unique": true,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_books_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "book_groups",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`groupId` INTEGER NOT NULL, `groupName` TEXT NOT NULL, `order` INTEGER NOT NULL, PRIMARY KEY(`groupId`))",
        "fields": [
          {
            "fieldPath": "groupId",
            "columnName": "groupId",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "groupName",
            "columnName": "groupName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "groupId"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "book_sources",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceUrl` TEXT NOT NULL, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `header` TEXT, `loginUrl` TEXT, `lastUpdateTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, PRIMARY KEY(`bookSourceUrl`))",
        "fields": [
          {
            "fieldPath": "bookSourceName",
            "columnName": "bookSourceName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookSourceGroup",
            "columnName": "bookSourceGroup",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "bookSourceUrl",
            "columnName": "bookSourceUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookSourceType",
            "columnName": "bookSourceType",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "bookUrlPattern",
            "columnName": "bookUrlPattern",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customOrder",
            "columnName": "customOrder",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enabled",
            "columnName": "enabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enabledExplore",
            "columnName": "enabledExplore",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "header",
            "columnName": "header",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "loginUrl",
            "columnName": "loginUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "lastUpdateTime",
            "columnName": "lastUpdateTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "weight",
            "columnName": "weight",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "exploreUrl",
            "columnName": "exploreUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleExplore",
            "columnName": "ruleExplore",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "searchUrl",
            "columnName": "searchUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleSearch",
            "columnName": "ruleSearch",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleBookInfo",
            "columnName": "ruleBookInfo",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleToc",
            "columnName": "ruleToc",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleContent",
            "columnName": "ruleContent",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "bookSourceUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_book_sources_bookSourceUrl",
            "unique": false,
            "columnNames": [
              "bookSourceUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_book_sources_bookSourceUrl` ON `${TABLE_NAME}` (`bookSourceUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "chapters",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `bookUrl` TEXT NOT NULL, `index` INTEGER NOT NULL, `resourceUrl` TEXT, `tag` TEXT, `start` INTEGER, `end` INTEGER, `variable` TEXT, PRIMARY KEY(`url`, `bookUrl`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )",
        "fields": [
          {
            "fieldPath": "url",
            "columnName": "url",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "title",
            "columnName": "title",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "index",
            "columnName": "index",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "resourceUrl",
            "columnName": "resourceUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "tag",
            "columnName": "tag",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "start",
            "columnName": "start",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "end",
            "columnName": "end",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "url",
            "bookUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_chapters_bookUrl",
            "unique": false,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_chapters_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          },
          {
            "name": "index_chapters_bookUrl_index",
            "unique": true,
            "columnNames": [
              "bookUrl",
              "index"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_chapters_bookUrl_index` ON `${TABLE_NAME}` (`bookUrl`, `index`)"
          }
        ],
        "foreignKeys": [
          {
            "table": "books",
            "onDelete": "CASCADE",
            "onUpdate": "NO ACTION",
            "columns": [
              "bookUrl"
            ],
            "referencedColumns": [
              "bookUrl"
            ]
          }
        ]
      },
      {
        "tableName": "replace_rules",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `group` TEXT, `pattern` TEXT NOT NULL, `replacement` TEXT NOT NULL, `scope` TEXT, `isEnabled` INTEGER NOT NULL, `isRegex` INTEGER NOT NULL, `sortOrder` INTEGER NOT NULL)",
        "fields": [
          {
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "group",
            "columnName": "group",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "pattern",
            "columnName": "pattern",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "replacement",
            "columnName": "replacement",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "scope",
            "columnName": "scope",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "isEnabled",
            "columnName": "isEnabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "isRegex",
            "columnName": "isRegex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "sortOrder",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "id"
          ],
          "autoGenerate": true
        },
        "indices": [
          {
            "name": "index_replace_rules_id",
            "unique": false,
            "columnNames": [
              "id"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_replace_rules_id` ON `${TABLE_NAME}` (`id`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "searchBooks",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `coverUrl` TEXT, `intro` TEXT, `wordCount` TEXT, `latestChapterTitle` TEXT, `tocUrl` TEXT NOT NULL, `time` INTEGER NOT NULL, `variable` TEXT, `originOrder` INTEGER NOT NULL, PRIMARY KEY(`bookUrl`), FOREIGN KEY(`origin`) REFERENCES `book_sources`(`bookSourceUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )",
        "fields": [
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "originName",
            "columnName": "originName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "type",
            "columnName": "type",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "author",
            "columnName": "author",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "kind",
            "columnName": "kind",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "coverUrl",
            "columnName": "coverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "intro",
            "columnName": "intro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "wordCount",
            "columnName": "wordCount",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "latestChapterTitle",
            "columnName": "latestChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "tocUrl",
            "columnName": "tocUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "time",
            "columnName": "time",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "originOrder",
            "columnName": "originOrder",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "bookUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_searchBooks_bookUrl",
            "unique": true,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_searchBooks_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          },
          {
            "name": "index_searchBooks_origin",
            "unique": false,
            "columnNames": [
              "origin"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_searchBooks_origin` ON `${TABLE_NAME}` (`origin`)"
          }
        ],
        "foreignKeys": [
          {
            "table": "book_sources",
            "onDelete": "CASCADE",
            "onUpdate": "NO ACTION",
            "columns": [
              "origin"
            ],
            "referencedColumns": [
              "bookSourceUrl"
            ]
          }
        ]
      },
      {
        "tableName": "search_keywords",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`word` TEXT NOT NULL, `usage` INTEGER NOT NULL, `lastUseTime` INTEGER NOT NULL, PRIMARY KEY(`word`))",
        "fields": [
          {
            "fieldPath": "word",
            "columnName": "word",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "usage",
            "columnName": "usage",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastUseTime",
            "columnName": "lastUseTime",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "word"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_search_keywords_word",
            "unique": true,
            "columnNames": [
              "word"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_search_keywords_word` ON `${TABLE_NAME}` (`word`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "cookies",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `cookie` TEXT NOT NULL, PRIMARY KEY(`url`))",
        "fields": [
          {
            "fieldPath": "url",
            "columnName": "url",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "cookie",
            "columnName": "cookie",
            "affinity": "TEXT",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "url"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_cookies_url",
            "unique": true,
            "columnNames": [
              "url"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_cookies_url` ON `${TABLE_NAME}` (`url`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "rssSources",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sourceUrl` TEXT NOT NULL, `sourceName` TEXT NOT NULL, `sourceIcon` TEXT NOT NULL, `sourceGroup` TEXT, `enabled` INTEGER NOT NULL, `sortUrl` TEXT, `ruleArticles` TEXT, `ruleNextPage` TEXT, `ruleTitle` TEXT, `rulePubDate` TEXT, `ruleDescription` TEXT, `ruleImage` TEXT, `ruleLink` TEXT, `ruleContent` TEXT, `header` TEXT, `enableJs` INTEGER NOT NULL, `loadWithBaseUrl` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, PRIMARY KEY(`sourceUrl`))",
        "fields": [
          {
            "fieldPath": "sourceUrl",
            "columnName": "sourceUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sourceName",
            "columnName": "sourceName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sourceIcon",
            "columnName": "sourceIcon",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sourceGroup",
            "columnName": "sourceGroup",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "enabled",
            "columnName": "enabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "sortUrl",
            "columnName": "sortUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleArticles",
            "columnName": "ruleArticles",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleNextPage",
            "columnName": "ruleNextPage",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleTitle",
            "columnName": "ruleTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "rulePubDate",
            "columnName": "rulePubDate",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleDescription",
            "columnName": "ruleDescription",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleImage",
            "columnName": "ruleImage",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleLink",
            "columnName": "ruleLink",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleContent",
            "columnName": "ruleContent",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "header",
            "columnName": "header",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "enableJs",
            "columnName": "enableJs",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "loadWithBaseUrl",
            "columnName": "loadWithBaseUrl",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "customOrder",
            "columnName": "customOrder",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "sourceUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_rssSources_sourceUrl",
            "unique": false,
            "columnNames": [
              "sourceUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_rssSources_sourceUrl` ON `${TABLE_NAME}` (`sourceUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "bookmarks",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`time` INTEGER NOT NULL, `bookUrl` TEXT NOT NULL, `bookName` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `pageIndex` INTEGER NOT NULL, `chapterName` TEXT NOT NULL, `content` TEXT NOT NULL, PRIMARY KEY(`time`))",
        "fields": [
          {
            "fieldPath": "time",
            "columnName": "time",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookName",
            "columnName": "bookName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "chapterIndex",
            "columnName": "chapterIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "pageIndex",
            "columnName": "pageIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "chapterName",
            "columnName": "chapterName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "content",
            "columnName": "content",
            "affinity": "TEXT",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "time"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_bookmarks_time",
            "unique": true,
            "columnNames": [
              "time"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_bookmarks_time` ON `${TABLE_NAME}` (`time`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "rssArticles",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `sort` TEXT NOT NULL, `title` TEXT NOT NULL, `order` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, `read` INTEGER NOT NULL, PRIMARY KEY(`origin`, `link`))",
        "fields": [
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sort",
            "columnName": "sort",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "title",
            "columnName": "title",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "link",
            "columnName": "link",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "pubDate",
            "columnName": "pubDate",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "description",
            "columnName": "description",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "content",
            "columnName": "content",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "image",
            "columnName": "image",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "read",
            "columnName": "read",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "origin",
            "link"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "rssReadRecords",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record` TEXT NOT NULL, `read` INTEGER NOT NULL, PRIMARY KEY(`record`))",
        "fields": [
          {
            "fieldPath": "record",
            "columnName": "record",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "read",
            "columnName": "read",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "record"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "rssStars",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `sort` TEXT NOT NULL, `title` TEXT NOT NULL, `starTime` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, PRIMARY KEY(`origin`, `link`))",
        "fields": [
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "sort",
            "columnName": "sort",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "title",
            "columnName": "title",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "starTime",
            "columnName": "starTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "link",
            "columnName": "link",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "pubDate",
            "columnName": "pubDate",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "description",
            "columnName": "description",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "content",
            "columnName": "content",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "image",
            "columnName": "image",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "origin",
            "link"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "txtTocRules",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `rule` TEXT NOT NULL, `serialNumber` INTEGER NOT NULL, `enable` INTEGER NOT NULL, PRIMARY KEY(`name`))",
        "fields": [
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "rule",
            "columnName": "rule",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "serialNumber",
            "columnName": "serialNumber",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enable",
            "columnName": "enable",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "name"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a9744f575dad6d4774cccc433921973b')"
    ]
  }
}

================================================
FILE: app/schemas/io.legado.app.data.AppDatabase/11.json
================================================
{
  "formatVersion": 1,
  "database": {
    "version": 11,
    "identityHash": "d3019908fa3212a7ac8eb87ac2f33369",
    "entities": [
      {
        "tableName": "books",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `tocUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL, `group` INTEGER NOT NULL, `latestChapterTitle` TEXT, `latestChapterTime` INTEGER NOT NULL, `lastCheckTime` INTEGER NOT NULL, `lastCheckCount` INTEGER NOT NULL, `totalChapterNum` INTEGER NOT NULL, `durChapterTitle` TEXT, `durChapterIndex` INTEGER NOT NULL, `durChapterPos` INTEGER NOT NULL, `durChapterTime` INTEGER NOT NULL, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL, `order` INTEGER NOT NULL, `originOrder` INTEGER NOT NULL, `useReplaceRule` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`name`, `author`))",
        "fields": [
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "tocUrl",
            "columnName": "tocUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "origin",
            "columnName": "origin",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "originName",
            "columnName": "originName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "author",
            "columnName": "author",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "kind",
            "columnName": "kind",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customTag",
            "columnName": "customTag",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "coverUrl",
            "columnName": "coverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customCoverUrl",
            "columnName": "customCoverUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "intro",
            "columnName": "intro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customIntro",
            "columnName": "customIntro",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "charset",
            "columnName": "charset",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "type",
            "columnName": "type",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "group",
            "columnName": "group",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "latestChapterTitle",
            "columnName": "latestChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "latestChapterTime",
            "columnName": "latestChapterTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastCheckTime",
            "columnName": "lastCheckTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "lastCheckCount",
            "columnName": "lastCheckCount",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "totalChapterNum",
            "columnName": "totalChapterNum",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterTitle",
            "columnName": "durChapterTitle",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "durChapterIndex",
            "columnName": "durChapterIndex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterPos",
            "columnName": "durChapterPos",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "durChapterTime",
            "columnName": "durChapterTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "wordCount",
            "columnName": "wordCount",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "canUpdate",
            "columnName": "canUpdate",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "originOrder",
            "columnName": "originOrder",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "useReplaceRule",
            "columnName": "useReplaceRule",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "name",
            "author"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_books_bookUrl",
            "unique": true,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_books_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "book_groups",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`groupId` INTEGER NOT NULL, `groupName` TEXT NOT NULL, `order` INTEGER NOT NULL, PRIMARY KEY(`groupId`))",
        "fields": [
          {
            "fieldPath": "groupId",
            "columnName": "groupId",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "groupName",
            "columnName": "groupName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "order",
            "columnName": "order",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
          "columnNames": [
            "groupId"
          ],
          "autoGenerate": false
        },
        "indices": [],
        "foreignKeys": []
      },
      {
        "tableName": "book_sources",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceUrl` TEXT NOT NULL, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `header` TEXT, `loginUrl` TEXT, `lastUpdateTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, PRIMARY KEY(`bookSourceUrl`))",
        "fields": [
          {
            "fieldPath": "bookSourceName",
            "columnName": "bookSourceName",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookSourceGroup",
            "columnName": "bookSourceGroup",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "bookSourceUrl",
            "columnName": "bookSourceUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookSourceType",
            "columnName": "bookSourceType",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "bookUrlPattern",
            "columnName": "bookUrlPattern",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "customOrder",
            "columnName": "customOrder",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enabled",
            "columnName": "enabled",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "enabledExplore",
            "columnName": "enabledExplore",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "header",
            "columnName": "header",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "loginUrl",
            "columnName": "loginUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "lastUpdateTime",
            "columnName": "lastUpdateTime",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "weight",
            "columnName": "weight",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "exploreUrl",
            "columnName": "exploreUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleExplore",
            "columnName": "ruleExplore",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "searchUrl",
            "columnName": "searchUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleSearch",
            "columnName": "ruleSearch",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleBookInfo",
            "columnName": "ruleBookInfo",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleToc",
            "columnName": "ruleToc",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "ruleContent",
            "columnName": "ruleContent",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "bookSourceUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_book_sources_bookSourceUrl",
            "unique": false,
            "columnNames": [
              "bookSourceUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_book_sources_bookSourceUrl` ON `${TABLE_NAME}` (`bookSourceUrl`)"
          }
        ],
        "foreignKeys": []
      },
      {
        "tableName": "chapters",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `bookUrl` TEXT NOT NULL, `index` INTEGER NOT NULL, `resourceUrl` TEXT, `tag` TEXT, `start` INTEGER, `end` INTEGER, `variable` TEXT, PRIMARY KEY(`url`, `bookUrl`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )",
        "fields": [
          {
            "fieldPath": "url",
            "columnName": "url",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "title",
            "columnName": "title",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "bookUrl",
            "columnName": "bookUrl",
            "affinity": "TEXT",
            "notNull": true
          },
          {
            "fieldPath": "index",
            "columnName": "index",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
            "fieldPath": "resourceUrl",
            "columnName": "resourceUrl",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "tag",
            "columnName": "tag",
            "affinity": "TEXT",
            "notNull": false
          },
          {
            "fieldPath": "start",
            "columnName": "start",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "end",
            "columnName": "end",
            "affinity": "INTEGER",
            "notNull": false
          },
          {
            "fieldPath": "variable",
            "columnName": "variable",
            "affinity": "TEXT",
            "notNull": false
          }
        ],
        "primaryKey": {
          "columnNames": [
            "url",
            "bookUrl"
          ],
          "autoGenerate": false
        },
        "indices": [
          {
            "name": "index_chapters_bookUrl",
            "unique": false,
            "columnNames": [
              "bookUrl"
            ],
            "createSql": "CREATE INDEX IF NOT EXISTS `index_chapters_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)"
          },
          {
            "name": "index_chapters_bookUrl_index",
            "unique": true,
            "columnNames": [
              "bookUrl",
              "index"
            ],
            "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_chapters_bookUrl_index` ON `${TABLE_NAME}` (`bookUrl`, `index`)"
          }
        ],
        "foreignKeys": [
          {
            "table": "books",
            "onDelete": "CASCADE",
            "onUpdat
Download .txt
gitextract_9ap85jiu/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── 01-bugReport.yml
│   │   ├── 02-featureRequest.yml
│   │   └── config.yml
│   ├── dependabot.yml
│   ├── scripts/
│   │   ├── cronet.sh
│   │   ├── lzy_web.py
│   │   └── tg_bot.py
│   └── workflows/
│       ├── autoupdatefork.yml
│       ├── cronet.yml
│       ├── legado.jks
│       ├── release.yml
│       ├── stale.yml
│       ├── test.yml
│       └── web.yml
├── .gitignore
├── CHANGELOG.md
├── English.md
├── LICENSE
├── README.md
├── api.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── cronet-proguard-rules.pro
│   ├── cronetlib/
│   │   ├── cronet_api.jar
│   │   ├── cronet_impl_common_java.jar
│   │   ├── cronet_impl_native_java.jar
│   │   ├── cronet_impl_platform_java.jar
│   │   └── cronet_shared_java.jar
│   ├── download.gradle
│   ├── google-services.json
│   ├── proguard-rules.pro
│   ├── schemas/
│   │   └── io.legado.app.data.AppDatabase/
│   │       ├── 1.json
│   │       ├── 10.json
│   │       ├── 11.json
│   │       ├── 12.json
│   │       ├── 13.json
│   │       ├── 14.json
│   │       ├── 15.json
│   │       ├── 16.json
│   │       ├── 17.json
│   │       ├── 18.json
│   │       ├── 19.json
│   │       ├── 2.json
│   │       ├── 20.json
│   │       ├── 21.json
│   │       ├── 22.json
│   │       ├── 23.json
│   │       ├── 24.json
│   │       ├── 25.json
│   │       ├── 26.json
│   │       ├── 27.json
│   │       ├── 28.json
│   │       ├── 29.json
│   │       ├── 3.json
│   │       ├── 30.json
│   │       ├── 31.json
│   │       ├── 32.json
│   │       ├── 33.json
│   │       ├── 34.json
│   │       ├── 35.json
│   │       ├── 36.json
│   │       ├── 37.json
│   │       ├── 38.json
│   │       ├── 39.json
│   │       ├── 4.json
│   │       ├── 40.json
│   │       ├── 41.json
│   │       ├── 42.json
│   │       ├── 43.json
│   │       ├── 44.json
│   │       ├── 45.json
│   │       ├── 46.json
│   │       ├── 47.json
│   │       ├── 48.json
│   │       ├── 49.json
│   │       ├── 5.json
│   │       ├── 50.json
│   │       ├── 51.json
│   │       ├── 52.json
│   │       ├── 53.json
│   │       ├── 54.json
│   │       ├── 55.json
│   │       ├── 56.json
│   │       ├── 57.json
│   │       ├── 58.json
│   │       ├── 59.json
│   │       ├── 6.json
│   │       ├── 60.json
│   │       ├── 61.json
│   │       ├── 62.json
│   │       ├── 63.json
│   │       ├── 64.json
│   │       ├── 65.json
│   │       ├── 66.json
│   │       ├── 67.json
│   │       ├── 68.json
│   │       ├── 69.json
│   │       ├── 7.json
│   │       ├── 70.json
│   │       ├── 71.json
│   │       ├── 72.json
│   │       ├── 73.json
│   │       ├── 74.json
│   │       ├── 75.json
│   │       ├── 8.json
│   │       └── 9.json
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── io/
│       │           └── legado/
│       │               └── app/
│       │                   ├── AndroidJsTest.kt
│       │                   ├── ExampleInstrumentedTest.kt
│       │                   ├── HttpTest.kt
│       │                   ├── HttpTtsTest.kt
│       │                   ├── MigrationTest.kt
│       │                   └── UpdateTest.kt
│       ├── debug/
│       │   └── res/
│       │       ├── values/
│       │       │   └── strings.xml
│       │       └── values-zh/
│       │           └── strings.xml
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/
│       │   │   ├── 18PlusList.txt
│       │   │   ├── LICENSE.md
│       │   │   ├── cronet.json
│       │   │   ├── defaultData/
│       │   │   │   ├── bookSources.json
│       │   │   │   ├── coverRule.json
│       │   │   │   ├── dictRules.json
│       │   │   │   ├── directLinkUpload.json
│       │   │   │   ├── httpTTS.json
│       │   │   │   ├── keyboardAssists.json
│       │   │   │   ├── readConfig.json
│       │   │   │   ├── rssSources.json
│       │   │   │   ├── themeConfig.json
│       │   │   │   └── txtTocRule.json
│       │   │   ├── disclaimer.md
│       │   │   ├── epub/
│       │   │   │   ├── chapter.html
│       │   │   │   ├── cover.html
│       │   │   │   ├── fonts.css
│       │   │   │   ├── intro.html
│       │   │   │   └── main.css
│       │   │   ├── privacyPolicy.md
│       │   │   ├── storageHelp.md
│       │   │   ├── updateLog.md
│       │   │   └── web/
│       │   │       ├── assets/
│       │   │       │   ├── css/
│       │   │       │   │   └── main.css
│       │   │       │   └── js/
│       │   │       │       ├── dist.js
│       │   │       │       └── md5.js
│       │   │       ├── help/
│       │   │       │   ├── index.html
│       │   │       │   ├── js/
│       │   │       │   │   ├── main.js
│       │   │       │   │   ├── marked-highlight.umd.js
│       │   │       │   │   └── require.js
│       │   │       │   └── md/
│       │   │       │       ├── ExtensionContentType.md
│       │   │       │       ├── SourceMBookHelp.md
│       │   │       │       ├── SourceMRssHelp.md
│       │   │       │       ├── appHelp.md
│       │   │       │       ├── debugHelp.md
│       │   │       │       ├── dictRuleHelp.md
│       │   │       │       ├── httpTTSHelp.md
│       │   │       │       ├── jsHelp.md
│       │   │       │       ├── readMenuHelp.md
│       │   │       │       ├── regexHelp.md
│       │   │       │       ├── replaceRuleHelp.md
│       │   │       │       ├── ruleHelp.md
│       │   │       │       ├── txtTocRuleHelp.md
│       │   │       │       ├── webDavBookHelp.md
│       │   │       │       ├── webDavHelp.md
│       │   │       │       └── xpathHelp.md
│       │   │       ├── index.html
│       │   │       ├── uploadBook/
│       │   │       │   ├── css/
│       │   │       │   │   └── wifi_send.css
│       │   │       │   ├── index.html
│       │   │       │   └── js/
│       │   │       │       ├── common.js
│       │   │       │       └── html5_fun.js
│       │   │       └── vue/
│       │   │           ├── assets/
│       │   │           │   ├── BookChapter-BsiFtdIw.css
│       │   │           │   ├── BookChapter-Cs3stH93.js
│       │   │           │   ├── BookShelf-00b2QCsd.css
│       │   │           │   ├── BookShelf-DIQtBULC.js
│       │   │           │   ├── index-CrxHVQK7.css
│       │   │           │   ├── index-Wr40-hHf.js
│       │   │           │   ├── loading-C4J6hIxs.js
│       │   │           │   ├── loading-DkQYEuap.css
│       │   │           │   ├── vendor-CXe1BRiH.css
│       │   │           │   └── vendor-KSDcS24u.js
│       │   │           └── index.html
│       │   ├── java/
│       │   │   └── io/
│       │   │       └── legado/
│       │   │           └── app/
│       │   │               ├── App.kt
│       │   │               ├── README.md
│       │   │               ├── api/
│       │   │               │   ├── ReaderProvider.kt
│       │   │               │   ├── ReturnData.kt
│       │   │               │   ├── ShortCuts.kt
│       │   │               │   └── controller/
│       │   │               │       ├── BookController.kt
│       │   │               │       ├── BookSourceController.kt
│       │   │               │       ├── ReplaceRuleController.kt
│       │   │               │       └── RssSourceController.kt
│       │   │               ├── base/
│       │   │               │   ├── AppContextWrapper.kt
│       │   │               │   ├── BaseActivity.kt
│       │   │               │   ├── BaseDialogFragment.kt
│       │   │               │   ├── BaseFragment.kt
│       │   │               │   ├── BasePrefDialogFragment.kt
│       │   │               │   ├── BaseService.kt
│       │   │               │   ├── BaseViewModel.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── VMBaseActivity.kt
│       │   │               │   ├── VMBaseFragment.kt
│       │   │               │   └── adapter/
│       │   │               │       ├── DiffRecyclerAdapter.kt
│       │   │               │       ├── ItemAnimation.kt
│       │   │               │       ├── ItemViewHolder.kt
│       │   │               │       ├── RecyclerAdapter.kt
│       │   │               │       └── animations/
│       │   │               │           ├── AlphaInAnimation.kt
│       │   │               │           ├── BaseAnimation.kt
│       │   │               │           ├── ScaleInAnimation.kt
│       │   │               │           ├── SlideInBottomAnimation.kt
│       │   │               │           ├── SlideInLeftAnimation.kt
│       │   │               │           └── SlideInRightAnimation.kt
│       │   │               ├── constant/
│       │   │               │   ├── AppConst.kt
│       │   │               │   ├── AppLog.kt
│       │   │               │   ├── AppPattern.kt
│       │   │               │   ├── BookSourceType.kt
│       │   │               │   ├── BookType.kt
│       │   │               │   ├── EventBus.kt
│       │   │               │   ├── IntentAction.kt
│       │   │               │   ├── NotificationId.kt
│       │   │               │   ├── PageAnim.kt
│       │   │               │   ├── PreferKey.kt
│       │   │               │   ├── SourceType.kt
│       │   │               │   ├── Status.kt
│       │   │               │   └── Theme.kt
│       │   │               ├── data/
│       │   │               │   ├── AppDatabase.kt
│       │   │               │   ├── DatabaseMigrations.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── dao/
│       │   │               │   │   ├── BookChapterDao.kt
│       │   │               │   │   ├── BookDao.kt
│       │   │               │   │   ├── BookGroupDao.kt
│       │   │               │   │   ├── BookSourceDao.kt
│       │   │               │   │   ├── BookmarkDao.kt
│       │   │               │   │   ├── CacheDao.kt
│       │   │               │   │   ├── CookieDao.kt
│       │   │               │   │   ├── DictRuleDao.kt
│       │   │               │   │   ├── HttpTTSDao.kt
│       │   │               │   │   ├── KeyboardAssistsDao.kt
│       │   │               │   │   ├── ReadRecordDao.kt
│       │   │               │   │   ├── ReplaceRuleDao.kt
│       │   │               │   │   ├── RssArticleDao.kt
│       │   │               │   │   ├── RssReadRecordDao.kt
│       │   │               │   │   ├── RssSourceDao.kt
│       │   │               │   │   ├── RssStarDao.kt
│       │   │               │   │   ├── RuleSubDao.kt
│       │   │               │   │   ├── SearchBookDao.kt
│       │   │               │   │   ├── SearchKeywordDao.kt
│       │   │               │   │   ├── ServerDao.kt
│       │   │               │   │   └── TxtTocRuleDao.kt
│       │   │               │   └── entities/
│       │   │               │       ├── BaseBook.kt
│       │   │               │       ├── BaseRssArticle.kt
│       │   │               │       ├── BaseSource.kt
│       │   │               │       ├── Book.kt
│       │   │               │       ├── BookChapter.kt
│       │   │               │       ├── BookChapterReview.kt
│       │   │               │       ├── BookGroup.kt
│       │   │               │       ├── BookProgress.kt
│       │   │               │       ├── BookSource.kt
│       │   │               │       ├── BookSourcePart.kt
│       │   │               │       ├── Bookmark.kt
│       │   │               │       ├── Cache.kt
│       │   │               │       ├── Cookie.kt
│       │   │               │       ├── DictRule.kt
│       │   │               │       ├── HttpTTS.kt
│       │   │               │       ├── KeyboardAssist.kt
│       │   │               │       ├── ReadRecord.kt
│       │   │               │       ├── ReadRecordShow.kt
│       │   │               │       ├── ReplaceRule.kt
│       │   │               │       ├── RssArticle.kt
│       │   │               │       ├── RssReadRecord.kt
│       │   │               │       ├── RssSource.kt
│       │   │               │       ├── RssStar.kt
│       │   │               │       ├── RuleSub.kt
│       │   │               │       ├── SearchBook.kt
│       │   │               │       ├── SearchKeyword.kt
│       │   │               │       ├── Server.kt
│       │   │               │       ├── TxtTocRule.kt
│       │   │               │       └── rule/
│       │   │               │           ├── BookInfoRule.kt
│       │   │               │           ├── BookListRule.kt
│       │   │               │           ├── ContentRule.kt
│       │   │               │           ├── ExploreKind.kt
│       │   │               │           ├── ExploreRule.kt
│       │   │               │           ├── FlexChildStyle.kt
│       │   │               │           ├── ReviewRule.kt
│       │   │               │           ├── RowUi.kt
│       │   │               │           ├── SearchRule.kt
│       │   │               │           └── TocRule.kt
│       │   │               ├── exception/
│       │   │               │   ├── ConcurrentException.kt
│       │   │               │   ├── ContentEmptyException.kt
│       │   │               │   ├── EmptyFileException.kt
│       │   │               │   ├── InvalidBooksDirException.kt
│       │   │               │   ├── NoBooksDirException.kt
│       │   │               │   ├── NoStackTraceException.kt
│       │   │               │   ├── RegexTimeoutException.kt
│       │   │               │   └── TocEmptyException.kt
│       │   │               ├── help/
│       │   │               │   ├── AppFreezeMonitor.kt
│       │   │               │   ├── AppWebDav.kt
│       │   │               │   ├── CacheManager.kt
│       │   │               │   ├── ConcurrentRateLimiter.kt
│       │   │               │   ├── CrashHandler.kt
│       │   │               │   ├── DefaultData.kt
│       │   │               │   ├── DirectLinkUpload.kt
│       │   │               │   ├── DispatchersMonitor.kt
│       │   │               │   ├── EventMessage.kt
│       │   │               │   ├── ExecutorService.kt
│       │   │               │   ├── IntentData.kt
│       │   │               │   ├── IntentHelp.kt
│       │   │               │   ├── JsEncodeUtils.kt
│       │   │               │   ├── JsExtensions.kt
│       │   │               │   ├── LauncherIconHelp.kt
│       │   │               │   ├── LayoutManager.kt
│       │   │               │   ├── LifecycleHelp.kt
│       │   │               │   ├── MediaHelp.kt
│       │   │               │   ├── PaintPool.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── ReplaceAnalyzer.kt
│       │   │               │   ├── RuleBigDataHelp.kt
│       │   │               │   ├── RuleComplete.kt
│       │   │               │   ├── TTS.kt
│       │   │               │   ├── book/
│       │   │               │   │   ├── BookContent.kt
│       │   │               │   │   ├── BookExtensions.kt
│       │   │               │   │   ├── BookHelp.kt
│       │   │               │   │   ├── ContentHelp.kt
│       │   │               │   │   └── ContentProcessor.kt
│       │   │               │   ├── config/
│       │   │               │   │   ├── AppConfig.kt
│       │   │               │   │   ├── LocalConfig.kt
│       │   │               │   │   ├── ReadBookConfig.kt
│       │   │               │   │   ├── ReadTipConfig.kt
│       │   │               │   │   ├── SourceConfig.kt
│       │   │               │   │   └── ThemeConfig.kt
│       │   │               │   ├── coroutine/
│       │   │               │   │   ├── ActivelyCancelException.kt
│       │   │               │   │   ├── CompositeCoroutine.kt
│       │   │               │   │   ├── Coroutine.kt
│       │   │               │   │   └── CoroutineContainer.kt
│       │   │               │   ├── crypto/
│       │   │               │   │   ├── AsymmetricCrypto.kt
│       │   │               │   │   ├── README.md
│       │   │               │   │   ├── Sign.kt
│       │   │               │   │   └── SymmetricCryptoAndroid.kt
│       │   │               │   ├── exoplayer/
│       │   │               │   │   ├── ExoPlayerHelper.kt
│       │   │               │   │   └── InputStreamDataSource.kt
│       │   │               │   ├── glide/
│       │   │               │   │   ├── AsyncRecycleBitmapPool.kt
│       │   │               │   │   ├── BlurTransformation.kt
│       │   │               │   │   ├── FilePathLoader.kt
│       │   │               │   │   ├── GlideHeaders.kt
│       │   │               │   │   ├── ImageLoader.kt
│       │   │               │   │   ├── LegadoDataUrlLoader.kt
│       │   │               │   │   ├── LegadoGlideModule.kt
│       │   │               │   │   ├── OkHttpModeLoaderFactory.kt
│       │   │               │   │   ├── OkHttpModelLoader.kt
│       │   │               │   │   ├── OkHttpStreamFetcher.kt
│       │   │               │   │   └── progress/
│       │   │               │   │       ├── OnProgressListener.kt
│       │   │               │   │       ├── ProgressManager.kt
│       │   │               │   │       └── ProgressResponseBody.kt
│       │   │               │   ├── http/
│       │   │               │   │   ├── BackstageWebView.kt
│       │   │               │   │   ├── CookieManager.kt
│       │   │               │   │   ├── CookieStore.kt
│       │   │               │   │   ├── Cronet.kt
│       │   │               │   │   ├── DecompressInterceptor.kt
│       │   │               │   │   ├── HttpHelper.kt
│       │   │               │   │   ├── ObsoleteUrlFactory.kt
│       │   │               │   │   ├── OkHttpExceptionInterceptor.kt
│       │   │               │   │   ├── OkHttpUtils.kt
│       │   │               │   │   ├── OkhttpUncaughtExceptionHandler.kt
│       │   │               │   │   ├── RequestMethod.kt
│       │   │               │   │   ├── SSLHelper.kt
│       │   │               │   │   ├── StrResponse.kt
│       │   │               │   │   └── api/
│       │   │               │   │       └── CookieManagerInterface.kt
│       │   │               │   ├── rhino/
│       │   │               │   │   └── NativeBaseSource.kt
│       │   │               │   ├── source/
│       │   │               │   │   ├── BaseSourceExtensions.kt
│       │   │               │   │   ├── BookSourceExtensions.kt
│       │   │               │   │   ├── RssSourceExtensions.kt
│       │   │               │   │   ├── SourceHelp.kt
│       │   │               │   │   └── SourceVerificationHelp.kt
│       │   │               │   ├── storage/
│       │   │               │   │   ├── Backup.kt
│       │   │               │   │   ├── BackupAES.kt
│       │   │               │   │   ├── BackupConfig.kt
│       │   │               │   │   ├── ImportOldData.kt
│       │   │               │   │   └── Restore.kt
│       │   │               │   └── update/
│       │   │               │       ├── AppReleaseInfo.kt
│       │   │               │       ├── AppUpdate.kt
│       │   │               │       └── AppUpdateGitHub.kt
│       │   │               ├── lib/
│       │   │               │   ├── README.md
│       │   │               │   ├── aliyun/
│       │   │               │   │   └── ALiYun.kt
│       │   │               │   ├── cronet/
│       │   │               │   │   ├── AbsCallBack.kt
│       │   │               │   │   ├── BodyUploadProvider.kt
│       │   │               │   │   ├── CallbackResult.kt
│       │   │               │   │   ├── CallbackStep.kt
│       │   │               │   │   ├── CronetCoroutineInterceptor.kt
│       │   │               │   │   ├── CronetHelper.kt
│       │   │               │   │   ├── CronetInterceptor.kt
│       │   │               │   │   ├── CronetLoader.kt
│       │   │               │   │   ├── LargeBodyUploadProvider.kt
│       │   │               │   │   ├── NewCallBack.kt
│       │   │               │   │   └── OldCallback.kt
│       │   │               │   ├── dialogs/
│       │   │               │   │   ├── AlertBuilder.kt
│       │   │               │   │   ├── AndroidAlertBuilder.kt
│       │   │               │   │   ├── AndroidDialogs.kt
│       │   │               │   │   ├── AndroidSelectors.kt
│       │   │               │   │   └── SelectItem.kt
│       │   │               │   ├── icu4j/
│       │   │               │   │   ├── CharsetDetector.java
│       │   │               │   │   ├── CharsetMatch.java
│       │   │               │   │   ├── CharsetRecog_2022.java
│       │   │               │   │   ├── CharsetRecog_UTF8.java
│       │   │               │   │   ├── CharsetRecog_Unicode.java
│       │   │               │   │   ├── CharsetRecog_mbcs.java
│       │   │               │   │   ├── CharsetRecog_sbcs.java
│       │   │               │   │   └── CharsetRecognizer.java
│       │   │               │   ├── mobi/
│       │   │               │   │   ├── KF6Book.kt
│       │   │               │   │   ├── KF8Book.kt
│       │   │               │   │   ├── MobiBook.kt
│       │   │               │   │   ├── MobiReader.kt
│       │   │               │   │   ├── PDBFile.kt
│       │   │               │   │   ├── decompress/
│       │   │               │   │   │   ├── CDICData.kt
│       │   │               │   │   │   ├── Decompressor.kt
│       │   │               │   │   │   ├── HuffcdicDecompressor.kt
│       │   │               │   │   │   ├── Lz77Decompressor.kt
│       │   │               │   │   │   └── PlainDecompressor.kt
│       │   │               │   │   ├── entities/
│       │   │               │   │   │   ├── ExthRecordType.kt
│       │   │               │   │   │   ├── FdstHeader.kt
│       │   │               │   │   │   ├── Fragment.kt
│       │   │               │   │   │   ├── IndexData.kt
│       │   │               │   │   │   ├── IndexEntry.kt
│       │   │               │   │   │   ├── IndexTag.kt
│       │   │               │   │   │   ├── IndxHeader.kt
│       │   │               │   │   │   ├── KF6Section.kt
│       │   │               │   │   │   ├── KF8Header.kt
│       │   │               │   │   │   ├── KF8Pos.kt
│       │   │               │   │   │   ├── KF8Resource.kt
│       │   │               │   │   │   ├── KF8Section.kt
│       │   │               │   │   │   ├── MobiEntryHeaders.kt
│       │   │               │   │   │   ├── MobiHeader.kt
│       │   │               │   │   │   ├── MobiMetadata.kt
│       │   │               │   │   │   ├── NCX.kt
│       │   │               │   │   │   ├── PalmDocHeader.kt
│       │   │               │   │   │   ├── Ptagx.kt
│       │   │               │   │   │   ├── Skeleton.kt
│       │   │               │   │   │   ├── TOC.kt
│       │   │               │   │   │   ├── TagxHeader.kt
│       │   │               │   │   │   └── TagxTag.kt
│       │   │               │   │   └── utils/
│       │   │               │   │       ├── BitwiseExtensions.kt
│       │   │               │   │       └── ByteBufferExtensions.kt
│       │   │               │   ├── permission/
│       │   │               │   │   ├── OnErrorCallback.kt
│       │   │               │   │   ├── OnPermissionsDeniedCallback.kt
│       │   │               │   │   ├── OnPermissionsGrantedCallback.kt
│       │   │               │   │   ├── OnPermissionsResultCallback.kt
│       │   │               │   │   ├── OnRequestPermissionsResultCallback.kt
│       │   │               │   │   ├── PermissionActivity.kt
│       │   │               │   │   ├── Permissions.kt
│       │   │               │   │   ├── PermissionsCompat.kt
│       │   │               │   │   ├── Request.kt
│       │   │               │   │   ├── RequestManager.kt
│       │   │               │   │   └── RequestPlugins.kt
│       │   │               │   ├── prefs/
│       │   │               │   │   ├── ColorPreference.kt
│       │   │               │   │   ├── EditTextPreference.kt
│       │   │               │   │   ├── EditTextPreferenceDialog.kt
│       │   │               │   │   ├── IconListPreference.kt
│       │   │               │   │   ├── ListPreferenceDialog.kt
│       │   │               │   │   ├── MultiSelectListPreferenceDialog.kt
│       │   │               │   │   ├── NameListPreference.kt
│       │   │               │   │   ├── Preference.kt
│       │   │               │   │   ├── PreferenceCategory.kt
│       │   │               │   │   ├── SwitchPreference.kt
│       │   │               │   │   └── fragment/
│       │   │               │   │       └── PreferenceFragment.kt
│       │   │               │   ├── theme/
│       │   │               │   │   ├── MaterialValueHelper.kt
│       │   │               │   │   ├── Selector.kt
│       │   │               │   │   ├── ThemeStore.kt
│       │   │               │   │   ├── ThemeStoreInterface.kt
│       │   │               │   │   ├── ThemeStorePrefKeys.kt
│       │   │               │   │   ├── ThemeUtils.kt
│       │   │               │   │   ├── TintHelper.kt
│       │   │               │   │   ├── ViewUtils.kt
│       │   │               │   │   └── view/
│       │   │               │   │       ├── ThemeBottomNavigationVIew.kt
│       │   │               │   │       ├── ThemeCheckBox.kt
│       │   │               │   │       ├── ThemeEditText.kt
│       │   │               │   │       ├── ThemeProgressBar.kt
│       │   │               │   │       ├── ThemeRadioButton.kt
│       │   │               │   │       ├── ThemeRadioNoButton.kt
│       │   │               │   │       ├── ThemeSeekBar.kt
│       │   │               │   │       └── ThemeSwitch.kt
│       │   │               │   └── webdav/
│       │   │               │       ├── Authorization.kt
│       │   │               │       ├── WebDav.kt
│       │   │               │       ├── WebDavException.kt
│       │   │               │       └── WebDavFile.kt
│       │   │               ├── model/
│       │   │               │   ├── AudioPlay.kt
│       │   │               │   ├── BookCover.kt
│       │   │               │   ├── CacheBook.kt
│       │   │               │   ├── CheckSource.kt
│       │   │               │   ├── Debug.kt
│       │   │               │   ├── Download.kt
│       │   │               │   ├── ImageProvider.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── ReadAloud.kt
│       │   │               │   ├── ReadBook.kt
│       │   │               │   ├── ReadManga.kt
│       │   │               │   ├── SharedJsScope.kt
│       │   │               │   ├── analyzeRule/
│       │   │               │   │   ├── AnalyzeByJSonPath.kt
│       │   │               │   │   ├── AnalyzeByJSoup.kt
│       │   │               │   │   ├── AnalyzeByRegex.kt
│       │   │               │   │   ├── AnalyzeByXPath.kt
│       │   │               │   │   ├── AnalyzeRule.kt
│       │   │               │   │   ├── AnalyzeUrl.kt
│       │   │               │   │   ├── CustomUrl.kt
│       │   │               │   │   ├── QueryTTF.java
│       │   │               │   │   ├── RuleAnalyzer.kt
│       │   │               │   │   ├── RuleData.kt
│       │   │               │   │   └── RuleDataInterface.kt
│       │   │               │   ├── localBook/
│       │   │               │   │   ├── BaseLocalBookParse.kt
│       │   │               │   │   ├── EpubFile.kt
│       │   │               │   │   ├── LocalBook.kt
│       │   │               │   │   ├── MobiFile.kt
│       │   │               │   │   ├── PdfFile.kt
│       │   │               │   │   ├── README.md
│       │   │               │   │   ├── TextFile.kt
│       │   │               │   │   └── UmdFile.kt
│       │   │               │   ├── remote/
│       │   │               │   │   ├── RemoteBook.kt
│       │   │               │   │   ├── RemoteBookManager.kt
│       │   │               │   │   └── RemoteBookWebDav.kt
│       │   │               │   ├── rss/
│       │   │               │   │   ├── Rss.kt
│       │   │               │   │   ├── RssParserByRule.kt
│       │   │               │   │   └── RssParserDefault.kt
│       │   │               │   └── webBook/
│       │   │               │       ├── BookChapterList.kt
│       │   │               │       ├── BookContent.kt
│       │   │               │       ├── BookInfo.kt
│       │   │               │       ├── BookList.kt
│       │   │               │       ├── SearchModel.kt
│       │   │               │       └── WebBook.kt
│       │   │               ├── receiver/
│       │   │               │   ├── MediaButtonReceiver.kt
│       │   │               │   ├── NetworkChangedListener.kt
│       │   │               │   ├── SharedReceiverActivity.kt
│       │   │               │   └── TimeBatteryReceiver.kt
│       │   │               ├── service/
│       │   │               │   ├── AudioPlayService.kt
│       │   │               │   ├── BaseReadAloudService.kt
│       │   │               │   ├── CacheBookService.kt
│       │   │               │   ├── CheckSourceService.kt
│       │   │               │   ├── DownloadService.kt
│       │   │               │   ├── ExportBookService.kt
│       │   │               │   ├── HttpReadAloudService.kt
│       │   │               │   ├── README.md
│       │   │               │   ├── TTSReadAloudService.kt
│       │   │               │   ├── WebService.kt
│       │   │               │   └── WebTileService.kt
│       │   │               ├── ui/
│       │   │               │   ├── README.md
│       │   │               │   ├── about/
│       │   │               │   │   ├── AboutActivity.kt
│       │   │               │   │   ├── AboutFragment.kt
│       │   │               │   │   ├── AppLogDialog.kt
│       │   │               │   │   ├── CrashLogsDialog.kt
│       │   │               │   │   ├── ReadRecordActivity.kt
│       │   │               │   │   └── UpdateDialog.kt
│       │   │               │   ├── association/
│       │   │               │   │   ├── AddToBookshelfDialog.kt
│       │   │               │   │   ├── BaseAssociationViewModel.kt
│       │   │               │   │   ├── FileAssociationActivity.kt
│       │   │               │   │   ├── FileAssociationViewModel.kt
│       │   │               │   │   ├── ImportBookSourceDialog.kt
│       │   │               │   │   ├── ImportBookSourceViewModel.kt
│       │   │               │   │   ├── ImportDictRuleDialog.kt
│       │   │               │   │   ├── ImportDictRuleViewModel.kt
│       │   │               │   │   ├── ImportHttpTtsDialog.kt
│       │   │               │   │   ├── ImportHttpTtsViewModel.kt
│       │   │               │   │   ├── ImportReplaceRuleDialog.kt
│       │   │               │   │   ├── ImportReplaceRuleViewModel.kt
│       │   │               │   │   ├── ImportRssSourceDialog.kt
│       │   │               │   │   ├── ImportRssSourceViewModel.kt
│       │   │               │   │   ├── ImportThemeDialog.kt
│       │   │               │   │   ├── ImportThemeViewModel.kt
│       │   │               │   │   ├── ImportTxtTocRuleDialog.kt
│       │   │               │   │   ├── ImportTxtTocRuleViewModel.kt
│       │   │               │   │   ├── OnLineImportActivity.kt
│       │   │               │   │   ├── OnLineImportViewModel.kt
│       │   │               │   │   ├── OpenUrlConfirmActivity.kt
│       │   │               │   │   ├── OpenUrlConfirmDialog.kt
│       │   │               │   │   ├── OpenUrlConfirmViewModel.kt
│       │   │               │   │   ├── VerificationCodeActivity.kt
│       │   │               │   │   ├── VerificationCodeDialog.kt
│       │   │               │   │   └── VerificationCodeViewModel.kt
│       │   │               │   ├── book/
│       │   │               │   │   ├── audio/
│       │   │               │   │   │   ├── AudioPlayActivity.kt
│       │   │               │   │   │   ├── AudioPlayViewModel.kt
│       │   │               │   │   │   └── TimerSliderPopup.kt
│       │   │               │   │   ├── bookmark/
│       │   │               │   │   │   ├── AllBookmarkActivity.kt
│       │   │               │   │   │   ├── AllBookmarkViewModel.kt
│       │   │               │   │   │   ├── BookmarkAdapter.kt
│       │   │               │   │   │   ├── BookmarkDecoration.kt
│       │   │               │   │   │   └── BookmarkDialog.kt
│       │   │               │   │   ├── cache/
│       │   │               │   │   │   ├── CacheActivity.kt
│       │   │               │   │   │   ├── CacheAdapter.kt
│       │   │               │   │   │   └── CacheViewModel.kt
│       │   │               │   │   ├── changecover/
│       │   │               │   │   │   ├── ChangeCoverDialog.kt
│       │   │               │   │   │   ├── ChangeCoverViewModel.kt
│       │   │               │   │   │   └── CoverAdapter.kt
│       │   │               │   │   ├── changesource/
│       │   │               │   │   │   ├── ChangeBookSourceAdapter.kt
│       │   │               │   │   │   ├── ChangeBookSourceDialog.kt
│       │   │               │   │   │   ├── ChangeBookSourceViewModel.kt
│       │   │               │   │   │   ├── ChangeChapterSourceAdapter.kt
│       │   │               │   │   │   ├── ChangeChapterSourceDialog.kt
│       │   │               │   │   │   ├── ChangeChapterSourceViewModel.kt
│       │   │               │   │   │   └── ChangeChapterTocAdapter.kt
│       │   │               │   │   ├── explore/
│       │   │               │   │   │   ├── ExploreShowActivity.kt
│       │   │               │   │   │   ├── ExploreShowAdapter.kt
│       │   │               │   │   │   └── ExploreShowViewModel.kt
│       │   │               │   │   ├── group/
│       │   │               │   │   │   ├── GroupEditDialog.kt
│       │   │               │   │   │   ├── GroupManageDialog.kt
│       │   │               │   │   │   ├── GroupSelectDialog.kt
│       │   │               │   │   │   └── GroupViewModel.kt
│       │   │               │   │   ├── import/
│       │   │               │   │   │   ├── BaseImportBookActivity.kt
│       │   │               │   │   │   ├── local/
│       │   │               │   │   │   │   ├── ImportBook.kt
│       │   │               │   │   │   │   ├── ImportBookActivity.kt
│       │   │               │   │   │   │   ├── ImportBookAdapter.kt
│       │   │               │   │   │   │   └── ImportBookViewModel.kt
│       │   │               │   │   │   └── remote/
│       │   │               │   │   │       ├── RemoteBookActivity.kt
│       │   │               │   │   │       ├── RemoteBookAdapter.kt
│       │   │               │   │   │       ├── RemoteBookSort.kt
│       │   │               │   │   │       ├── RemoteBookViewModel.kt
│       │   │               │   │   │       ├── ServerConfigDialog.kt
│       │   │               │   │   │       ├── ServerConfigViewModel.kt
│       │   │               │   │   │       ├── ServersDialog.kt
│       │   │               │   │   │       └── ServersViewModel.kt
│       │   │               │   │   ├── info/
│       │   │               │   │   │   ├── BookInfoActivity.kt
│       │   │               │   │   │   ├── BookInfoViewModel.kt
│       │   │               │   │   │   └── edit/
│       │   │               │   │   │       ├── BookInfoEditActivity.kt
│       │   │               │   │   │       └── BookInfoEditViewModel.kt
│       │   │               │   │   ├── manage/
│       │   │               │   │   │   ├── BookAdapter.kt
│       │   │               │   │   │   ├── BookshelfManageActivity.kt
│       │   │               │   │   │   ├── BookshelfManageViewModel.kt
│       │   │               │   │   │   └── SourcePickerDialog.kt
│       │   │               │   │   ├── manga/
│       │   │               │   │   │   ├── ReadMangaActivity.kt
│       │   │               │   │   │   ├── ReadMangaViewModel.kt
│       │   │               │   │   │   ├── config/
│       │   │               │   │   │   │   ├── MangaColorFilterConfig.kt
│       │   │               │   │   │   │   ├── MangaColorFilterDialog.kt
│       │   │               │   │   │   │   ├── MangaEpaperDialog.kt
│       │   │               │   │   │   │   ├── MangaFooterConfig.kt
│       │   │               │   │   │   │   └── MangaFooterSettingDialog.kt
│       │   │               │   │   │   ├── entities/
│       │   │               │   │   │   │   ├── BaseMangaPage.kt
│       │   │               │   │   │   │   ├── EpaperTransformation.kt
│       │   │               │   │   │   │   ├── GrayscaleTransformation.kt
│       │   │               │   │   │   │   ├── MangaChapter.kt
│       │   │               │   │   │   │   ├── MangaContent.kt
│       │   │               │   │   │   │   ├── MangaPage.kt
│       │   │               │   │   │   │   └── ReaderLoading.kt
│       │   │               │   │   │   └── recyclerview/
│       │   │               │   │   │       ├── GestureDetectorWithLongTap.kt
│       │   │               │   │   │       ├── MangaAdapter.kt
│       │   │               │   │   │       ├── MangaLayoutManager.kt
│       │   │               │   │   │       ├── MangaVH.kt
│       │   │               │   │   │       ├── ScrollTimer.kt
│       │   │               │   │   │       ├── WebtoonFrame.kt
│       │   │               │   │   │       └── WebtoonRecyclerView.kt
│       │   │               │   │   ├── read/
│       │   │               │   │   │   ├── BaseReadBookActivity.kt
│       │   │               │   │   │   ├── ContentEditDialog.kt
│       │   │               │   │   │   ├── EffectiveReplacesDialog.kt
│       │   │               │   │   │   ├── MangaMenu.kt
│       │   │               │   │   │   ├── ReadBookActivity.kt
│       │   │               │   │   │   ├── ReadBookViewModel.kt
│       │   │               │   │   │   ├── ReadMenu.kt
│       │   │               │   │   │   ├── SearchMenu.kt
│       │   │               │   │   │   ├── TextActionMenu.kt
│       │   │               │   │   │   ├── config/
│       │   │               │   │   │   │   ├── AutoReadDialog.kt
│       │   │               │   │   │   │   ├── BgAdapter.kt
│       │   │               │   │   │   │   ├── BgTextConfigDialog.kt
│       │   │               │   │   │   │   ├── ChineseConverter.kt
│       │   │               │   │   │   │   ├── ClickActionConfigDialog.kt
│       │   │               │   │   │   │   ├── HttpTtsEditDialog.kt
│       │   │               │   │   │   │   ├── HttpTtsEditViewModel.kt
│       │   │               │   │   │   │   ├── MoreConfigDialog.kt
│       │   │               │   │   │   │   ├── PaddingConfigDialog.kt
│       │   │               │   │   │   │   ├── PageKeyDialog.kt
│       │   │               │   │   │   │   ├── ReadAloudConfigDialog.kt
│       │   │               │   │   │   │   ├── ReadAloudDialog.kt
│       │   │               │   │   │   │   ├── ReadStyleDialog.kt
│       │   │               │   │   │   │   ├── SpeakEngineDialog.kt
│       │   │               │   │   │   │   ├── SpeakEngineViewModel.kt
│       │   │               │   │   │   │   ├── TextFontWeightConverter.kt
│       │   │               │   │   │   │   └── TipConfigDialog.kt
│       │   │               │   │   │   └── page/
│       │   │               │   │   │       ├── AutoPager.kt
│       │   │               │   │   │       ├── ContentTextView.kt
│       │   │               │   │   │       ├── PageView.kt
│       │   │               │   │   │       ├── ReadView.kt
│       │   │               │   │   │       ├── api/
│       │   │               │   │   │       │   ├── DataSource.kt
│       │   │               │   │   │       │   └── PageFactory.kt
│       │   │               │   │   │       ├── delegate/
│       │   │               │   │   │       │   ├── CoverPageDelegate.kt
│       │   │               │   │   │       │   ├── HorizontalPageDelegate.kt
│       │   │               │   │   │       │   ├── NoAnimPageDelegate.kt
│       │   │               │   │   │       │   ├── PageDelegate.kt
│       │   │               │   │   │       │   ├── ScrollPageDelegate.kt
│       │   │               │   │   │       │   ├── SimulationPageDelegate.kt
│       │   │               │   │   │       │   └── SlidePageDelegate.kt
│       │   │               │   │   │       ├── entities/
│       │   │               │   │   │       │   ├── PageDirection.kt
│       │   │               │   │   │       │   ├── TextChapter.kt
│       │   │               │   │   │       │   ├── TextLine.kt
│       │   │               │   │   │       │   ├── TextPage.kt
│       │   │               │   │   │       │   ├── TextParagraph.kt
│       │   │               │   │   │       │   ├── TextPos.kt
│       │   │               │   │   │       │   └── column/
│       │   │               │   │   │       │       ├── BaseColumn.kt
│       │   │               │   │   │       │       ├── ButtonColumn.kt
│       │   │               │   │   │       │       ├── ImageColumn.kt
│       │   │               │   │   │       │       ├── ReviewColumn.kt
│       │   │               │   │   │       │       └── TextColumn.kt
│       │   │               │   │   │       └── provider/
│       │   │               │   │   │           ├── ChapterProvider.kt
│       │   │               │   │   │           ├── LayoutProgressListener.kt
│       │   │               │   │   │           ├── TextChapterLayout.kt
│       │   │               │   │   │           ├── TextMeasure.kt
│       │   │               │   │   │           ├── TextPageFactory.kt
│       │   │               │   │   │           └── ZhLayout.kt
│       │   │               │   │   ├── search/
│       │   │               │   │   │   ├── BookAdapter.kt
│       │   │               │   │   │   ├── HistoryKeyAdapter.kt
│       │   │               │   │   │   ├── SearchActivity.kt
│       │   │               │   │   │   ├── SearchAdapter.kt
│       │   │               │   │   │   ├── SearchScope.kt
│       │   │               │   │   │   ├── SearchScopeDialog.kt
│       │   │               │   │   │   └── SearchViewModel.kt
│       │   │               │   │   ├── searchContent/
│       │   │               │   │   │   ├── SearchContentActivity.kt
│       │   │               │   │   │   ├── SearchContentAdapter.kt
│       │   │               │   │   │   ├── SearchContentViewModel.kt
│       │   │               │   │   │   └── SearchResult.kt
│       │   │               │   │   ├── source/
│       │   │               │   │   │   ├── debug/
│       │   │               │   │   │   │   ├── BookSourceDebugActivity.kt
│       │   │               │   │   │   │   ├── BookSourceDebugAdapter.kt
│       │   │               │   │   │   │   └── BookSourceDebugModel.kt
│       │   │               │   │   │   ├── edit/
│       │   │               │   │   │   │   ├── BookSourceEditActivity.kt
│       │   │               │   │   │   │   ├── BookSourceEditAdapter.kt
│       │   │               │   │   │   │   └── BookSourceEditViewModel.kt
│       │   │               │   │   │   └── manage/
│       │   │               │   │   │       ├── BookSourceActivity.kt
│       │   │               │   │   │       ├── BookSourceAdapter.kt
│       │   │               │   │   │       ├── BookSourceSort.kt
│       │   │               │   │   │       ├── BookSourceViewModel.kt
│       │   │               │   │   │       └── GroupManageDialog.kt
│       │   │               │   │   └── toc/
│       │   │               │   │       ├── BookmarkAdapter.kt
│       │   │               │   │       ├── BookmarkFragment.kt
│       │   │               │   │       ├── ChapterListAdapter.kt
│       │   │               │   │       ├── ChapterListFragment.kt
│       │   │               │   │       ├── TocActivity.kt
│       │   │               │   │       ├── TocActivityResult.kt
│       │   │               │   │       ├── TocViewModel.kt
│       │   │               │   │       └── rule/
│       │   │               │   │           ├── TxtTocRuleActivity.kt
│       │   │               │   │           ├── TxtTocRuleAdapter.kt
│       │   │               │   │           ├── TxtTocRuleDialog.kt
│       │   │               │   │           ├── TxtTocRuleEditDialog.kt
│       │   │               │   │           └── TxtTocRuleViewModel.kt
│       │   │               │   ├── browser/
│       │   │               │   │   ├── WebViewActivity.kt
│       │   │               │   │   └── WebViewModel.kt
│       │   │               │   ├── config/
│       │   │               │   │   ├── BackupConfigFragment.kt
│       │   │               │   │   ├── CheckSourceConfig.kt
│       │   │               │   │   ├── ConfigActivity.kt
│       │   │               │   │   ├── ConfigTag.kt
│       │   │               │   │   ├── ConfigViewModel.kt
│       │   │               │   │   ├── CoverConfigFragment.kt
│       │   │               │   │   ├── CoverRuleConfigDialog.kt
│       │   │               │   │   ├── DirectLinkUploadConfig.kt
│       │   │               │   │   ├── OtherConfigFragment.kt
│       │   │               │   │   ├── ThemeConfigFragment.kt
│       │   │               │   │   ├── ThemeListDialog.kt
│       │   │               │   │   └── WelcomeConfigFragment.kt
│       │   │               │   ├── dict/
│       │   │               │   │   ├── DictDialog.kt
│       │   │               │   │   ├── DictViewModel.kt
│       │   │               │   │   └── rule/
│       │   │               │   │       ├── DictRuleActivity.kt
│       │   │               │   │       ├── DictRuleAdapter.kt
│       │   │               │   │       ├── DictRuleEditDialog.kt
│       │   │               │   │       └── DictRuleViewModel.kt
│       │   │               │   ├── file/
│       │   │               │   │   ├── FileManageActivity.kt
│       │   │               │   │   ├── FileManageViewModel.kt
│       │   │               │   │   ├── FilePickerDialog.kt
│       │   │               │   │   ├── FilePickerViewModel.kt
│       │   │               │   │   ├── HandleFileActivity.kt
│       │   │               │   │   ├── HandleFileContract.kt
│       │   │               │   │   ├── HandleFileViewModel.kt
│       │   │               │   │   └── utils/
│       │   │               │   │       └── FilePickerIcon.java
│       │   │               │   ├── font/
│       │   │               │   │   ├── FontAdapter.kt
│       │   │               │   │   └── FontSelectDialog.kt
│       │   │               │   ├── login/
│       │   │               │   │   ├── SourceLoginActivity.kt
│       │   │               │   │   ├── SourceLoginDialog.kt
│       │   │               │   │   ├── SourceLoginViewModel.kt
│       │   │               │   │   └── WebViewLoginFragment.kt
│       │   │               │   ├── main/
│       │   │               │   │   ├── MainActivity.kt
│       │   │               │   │   ├── MainFragmentInterface.kt
│       │   │               │   │   ├── MainViewModel.kt
│       │   │               │   │   ├── bookshelf/
│       │   │               │   │   │   ├── BaseBookshelfFragment.kt
│       │   │               │   │   │   ├── BookshelfViewModel.kt
│       │   │               │   │   │   ├── style1/
│       │   │               │   │   │   │   ├── BookshelfFragment1.kt
│       │   │               │   │   │   │   └── books/
│       │   │               │   │   │   │       ├── BaseBooksAdapter.kt
│       │   │               │   │   │   │       ├── BooksAdapterGrid.kt
│       │   │               │   │   │   │       ├── BooksAdapterList.kt
│       │   │               │   │   │   │       └── BooksFragment.kt
│       │   │               │   │   │   └── style2/
│       │   │               │   │   │       ├── BaseBooksAdapter.kt
│       │   │               │   │   │       ├── BooksAdapterGrid.kt
│       │   │               │   │   │       ├── BooksAdapterList.kt
│       │   │               │   │   │       └── BookshelfFragment2.kt
│       │   │               │   │   ├── explore/
│       │   │               │   │   │   ├── ExploreAdapter.kt
│       │   │               │   │   │   ├── ExploreDiffItemCallBack.kt
│       │   │               │   │   │   ├── ExploreFragment.kt
│       │   │               │   │   │   └── ExploreViewModel.kt
│       │   │               │   │   ├── my/
│       │   │               │   │   │   └── MyFragment.kt
│       │   │               │   │   └── rss/
│       │   │               │   │       ├── RssAdapter.kt
│       │   │               │   │       ├── RssFragment.kt
│       │   │               │   │       └── RssViewModel.kt
│       │   │               │   ├── qrcode/
│       │   │               │   │   ├── QrCodeActivity.kt
│       │   │               │   │   ├── QrCodeFragment.kt
│       │   │               │   │   ├── QrCodeResult.kt
│       │   │               │   │   └── ScanResultCallback.kt
│       │   │               │   ├── replace/
│       │   │               │   │   ├── GroupManageDialog.kt
│       │   │               │   │   ├── ReplaceRuleActivity.kt
│       │   │               │   │   ├── ReplaceRuleAdapter.kt
│       │   │               │   │   ├── ReplaceRuleViewModel.kt
│       │   │               │   │   └── edit/
│       │   │               │   │       ├── ReplaceEditActivity.kt
│       │   │               │   │       └── ReplaceEditViewModel.kt
│       │   │               │   ├── rss/
│       │   │               │   │   ├── article/
│       │   │               │   │   │   ├── BaseRssArticlesAdapter.kt
│       │   │               │   │   │   ├── ReadRecordDialog.kt
│       │   │               │   │   │   ├── RssArticlesAdapter.kt
│       │   │               │   │   │   ├── RssArticlesAdapter1.kt
│       │   │               │   │   │   ├── RssArticlesAdapter2.kt
│       │   │               │   │   │   ├── RssArticlesFragment.kt
│       │   │               │   │   │   ├── RssArticlesViewModel.kt
│       │   │               │   │   │   ├── RssSortActivity.kt
│       │   │               │   │   │   └── RssSortViewModel.kt
│       │   │               │   │   ├── favorites/
│       │   │               │   │   │   ├── RssFavoritesActivity.kt
│       │   │               │   │   │   ├── RssFavoritesAdapter.kt
│       │   │               │   │   │   ├── RssFavoritesDialog.kt
│       │   │               │   │   │   ├── RssFavoritesFragment.kt
│       │   │               │   │   │   └── RssFavoritesViewModel.kt
│       │   │               │   │   ├── read/
│       │   │               │   │   │   ├── ReadRssActivity.kt
│       │   │               │   │   │   ├── ReadRssViewModel.kt
│       │   │               │   │   │   ├── RssJsExtensions.kt
│       │   │               │   │   │   └── VisibleWebView.kt
│       │   │               │   │   ├── source/
│       │   │               │   │   │   ├── debug/
│       │   │               │   │   │   │   ├── RssSourceDebugActivity.kt
│       │   │               │   │   │   │   ├── RssSourceDebugAdapter.kt
│       │   │               │   │   │   │   └── RssSourceDebugModel.kt
│       │   │               │   │   │   ├── edit/
│       │   │               │   │   │   │   ├── RssSourceEditActivity.kt
│       │   │               │   │   │   │   ├── RssSourceEditAdapter.kt
│       │   │               │   │   │   │   └── RssSourceEditViewModel.kt
│       │   │               │   │   │   └── manage/
│       │   │               │   │   │       ├── GroupManageDialog.kt
│       │   │               │   │   │       ├── RssSourceActivity.kt
│       │   │               │   │   │       ├── RssSourceAdapter.kt
│       │   │               │   │   │       └── RssSourceViewModel.kt
│       │   │               │   │   └── subscription/
│       │   │               │   │       ├── RuleSubActivity.kt
│       │   │               │   │       └── RuleSubAdapter.kt
│       │   │               │   ├── welcome/
│       │   │               │   │   └── WelcomeActivity.kt
│       │   │               │   └── widget/
│       │   │               │       ├── BatteryView.kt
│       │   │               │       ├── DetailSeekBar.kt
│       │   │               │       ├── LabelsBar.kt
│       │   │               │       ├── NoChildScrollNestedScrollView.kt
│       │   │               │       ├── PopupAction.kt
│       │   │               │       ├── ReaderInfoBarView.kt
│       │   │               │       ├── SearchView.kt
│       │   │               │       ├── SelectActionBar.kt
│       │   │               │       ├── ShadowLayout.kt
│       │   │               │       ├── TitleBar.kt
│       │   │               │       ├── anima/
│       │   │               │       │   ├── RefreshProgressBar.kt
│       │   │               │       │   ├── RotateLoading.kt
│       │   │               │       │   └── explosion_field/
│       │   │               │       │       ├── ExplosionAnimator.kt
│       │   │               │       │       ├── ExplosionField.kt
│       │   │               │       │       ├── ExplosionView.kt
│       │   │               │       │       ├── OnAnimatorListener.kt
│       │   │               │       │       └── Utils.kt
│       │   │               │       ├── checkbox/
│       │   │               │       │   └── SmoothCheckBox.kt
│       │   │               │       ├── code/
│       │   │               │       │   ├── CodeView.kt
│       │   │               │       │   ├── CodeViewExtensions.kt
│       │   │               │       │   └── KeywordTokenizer.kt
│       │   │               │       ├── dialog/
│       │   │               │       │   ├── CodeDialog.kt
│       │   │               │       │   ├── PhotoDialog.kt
│       │   │               │       │   ├── TextDialog.kt
│       │   │               │       │   ├── TextListDialog.kt
│       │   │               │       │   ├── UrlOptionDialog.kt
│       │   │               │       │   ├── VariableDialog.kt
│       │   │               │       │   └── WaitDialog.kt
│       │   │               │       ├── dynamiclayout/
│       │   │               │       │   ├── DynamicFrameLayout.kt
│       │   │               │       │   └── ViewSwitcher.kt
│       │   │               │       ├── image/
│       │   │               │       │   ├── ArcView.kt
│       │   │               │       │   ├── CircleImageView.kt
│       │   │               │       │   ├── CoverImageView.kt
│       │   │               │       │   ├── FilletImageView.kt
│       │   │               │       │   ├── ImageButton.kt
│       │   │               │       │   ├── PhotoView.kt
│       │   │               │       │   └── photo/
│       │   │               │       │       ├── Info.kt
│       │   │               │       │       └── RotateGestureDetector.kt
│       │   │               │       ├── keyboard/
│       │   │               │       │   ├── KeyboardAssistsConfig.kt
│       │   │               │       │   └── KeyboardToolPop.kt
│       │   │               │       ├── number/
│       │   │               │       │   └── NumberPickerDialog.kt
│       │   │               │       ├── recycler/
│       │   │               │       │   ├── DividerNoLast.kt
│       │   │               │       │   ├── DragSelectTouchHelper.kt
│       │   │               │       │   ├── HeaderAdapterDataObserver.kt
│       │   │               │       │   ├── ItemTouchCallback.kt
│       │   │               │       │   ├── LoadMoreView.kt
│       │   │               │       │   ├── NoChildScrollLinearLayoutManager.kt
│       │   │               │       │   ├── RecyclerViewAtPager2.kt
│       │   │               │       │   ├── UpLinearLayoutManager.kt
│       │   │               │       │   ├── VerticalDivider.kt
│       │   │               │       │   ├── ViewPager2Container.kt
│       │   │               │       │   └── scroller/
│       │   │               │       │       ├── FastScrollRecyclerView.kt
│       │   │               │       │       ├── FastScrollStateChangeListener.kt
│       │   │               │       │       └── FastScroller.kt
│       │   │               │       ├── seekbar/
│       │   │               │       │   ├── SeekBarChangeListener.kt
│       │   │               │       │   ├── VerticalSeekBar.kt
│       │   │               │       │   └── VerticalSeekBarWrapper.kt
│       │   │               │       └── text/
│       │   │               │           ├── AccentBgTextView.kt
│       │   │               │           ├── AccentStrokeTextView.kt
│       │   │               │           ├── AccentTextView.kt
│       │   │               │           ├── AutoCompleteTextView.kt
│       │   │               │           ├── BadgeView.kt
│       │   │               │           ├── BevelLabelView.kt
│       │   │               │           ├── EditEntity.kt
│       │   │               │           ├── MultilineTextView.kt
│       │   │               │           ├── PrimaryTextView.kt
│       │   │               │           ├── ScrollMultiAutoCompleteTextView.kt
│       │   │               │           ├── ScrollTextView.kt
│       │   │               │           ├── SecondaryTextView.kt
│       │   │               │           ├── StrokeTextView.kt
│       │   │               │           └── TextInputLayout.kt
│       │   │               ├── utils/
│       │   │               │   ├── ACache.kt
│       │   │               │   ├── ActivityExtensions.kt
│       │   │               │   ├── ActivityResult.kt
│       │   │               │   ├── ActivityResultContracts.kt
│       │   │               │   ├── AlphanumComparator.kt
│       │   │               │   ├── AnimationExtensions.kt
│       │   │               │   ├── ArchiveUtils.kt
│       │   │               │   ├── AsyncFileHandler.kt
│       │   │               │   ├── BitmapUtils.kt
│       │   │               │   ├── BookChapterExtensions.kt
│       │   │               │   ├── ByteArrayExtensions.kt
│       │   │               │   ├── ChineseUtils.kt
│       │   │               │   ├── CollectionExtensions.kt
│       │   │               │   ├── ColorUtils.kt
│       │   │               │   ├── ConfigurationExtensions.kt
│       │   │               │   ├── ConflateLiveData.kt
│       │   │               │   ├── ConstraintModify.kt
│       │   │               │   ├── ContextExtensions.kt
│       │   │               │   ├── ConvertExtensions.kt
│       │   │               │   ├── CookieManagerExtensions.kt
│       │   │               │   ├── CoroutineExtensions.kt
│       │   │               │   ├── CustomExportUtils.kt
│       │   │               │   ├── Debounce.kt
│       │   │               │   ├── DebugLog.kt
│       │   │               │   ├── DialogExtensions.kt
│       │   │               │   ├── DocumentUtils.kt
│       │   │               │   ├── DrawableUtils.kt
│       │   │               │   ├── EncoderUtils.kt
│       │   │               │   ├── EncodingDetect.kt
│       │   │               │   ├── EventBusExtensions.kt
│       │   │               │   ├── FileDocExtensions.kt
│       │   │               │   ├── FileExtensions.kt
│       │   │               │   ├── FileUtils.kt
│       │   │               │   ├── FlowExtensions.kt
│       │   │               │   ├── FragmentExtensions.kt
│       │   │               │   ├── GsonExtensions.kt
│       │   │               │   ├── HandlerUtils.kt
│       │   │               │   ├── HtmlFormatter.kt
│       │   │               │   ├── ImageUtils.kt
│       │   │               │   ├── InputStreamExtensions.kt
│       │   │               │   ├── IntentExtensions.kt
│       │   │               │   ├── IntentType.kt
│       │   │               │   ├── JsURL.kt
│       │   │               │   ├── JsonExtensions.kt
│       │   │               │   ├── JsoupExtensions.kt
│       │   │               │   ├── LogUtils.kt
│       │   │               │   ├── MD5Utils.kt
│       │   │               │   ├── MapExtensions.kt
│       │   │               │   ├── MenuExtensions.kt
│       │   │               │   ├── MenuItemExtensions.kt
│       │   │               │   ├── MutableLiveDataExtensions.kt
│       │   │               │   ├── NavigationViewUtils.kt
│       │   │               │   ├── NetworkUtils.kt
│       │   │               │   ├── PaintExtensions.kt
│       │   │               │   ├── ParcelFileDescriptorChannel.kt
│       │   │               │   ├── PreferencesExtensions.kt
│       │   │               │   ├── QRCodeUtils.kt
│       │   │               │   ├── RandomColor.kt
│       │   │               │   ├── RealPathUtil.kt
│       │   │               │   ├── RecyclerViewExtensions.kt
│       │   │               │   ├── RegexExtensions.kt
│       │   │               │   ├── RequestManagerExtensions.kt
│       │   │               │   ├── Snackbars.kt
│       │   │               │   ├── StringExtensions.kt
│       │   │               │   ├── StringUtils.kt
│       │   │               │   ├── SvgUtils.kt
│       │   │               │   ├── SyncedRenderer.kt
│       │   │               │   ├── SystemUtils.kt
│       │   │               │   ├── Throttle.kt
│       │   │               │   ├── ThrowableExtensions.kt
│       │   │               │   ├── TimeUtils.kt
│       │   │               │   ├── ToastUtils.kt
│       │   │               │   ├── ToolBarExtensions.kt
│       │   │               │   ├── UriExtensions.kt
│       │   │               │   ├── UrlUtil.kt
│       │   │               │   ├── Utf8BomUtils.kt
│       │   │               │   ├── ViewExtensions.kt
│       │   │               │   ├── WebSettingsExtensions.kt
│       │   │               │   ├── WindowInsetsExtensions.kt
│       │   │               │   ├── canvasrecorder/
│       │   │               │   │   ├── BaseCanvasRecorder.kt
│       │   │               │   │   ├── CanvasRecorder.kt
│       │   │               │   │   ├── CanvasRecorderApi23Impl.kt
│       │   │               │   │   ├── CanvasRecorderApi29Impl.kt
│       │   │               │   │   ├── CanvasRecorderExtensions.kt
│       │   │               │   │   ├── CanvasRecorderFactory.kt
│       │   │               │   │   ├── CanvasRecorderImpl.kt
│       │   │               │   │   ├── CanvasRecorderLocked.kt
│       │   │               │   │   └── pools/
│       │   │               │   │       ├── CanvasPool.kt
│       │   │               │   │       ├── PicturePool.kt
│       │   │               │   │       └── RenderNodePool.kt
│       │   │               │   ├── compress/
│       │   │               │   │   ├── LibArchiveUtils.kt
│       │   │               │   │   └── ZipUtils.kt
│       │   │               │   ├── objectpool/
│       │   │               │   │   ├── BaseObjectPool.kt
│       │   │               │   │   ├── BaseSafeObjectPool.kt
│       │   │               │   │   ├── ObjectPool.kt
│       │   │               │   │   ├── ObjectPoolExtensions.kt
│       │   │               │   │   └── ObjectPoolLocked.kt
│       │   │               │   └── viewbindingdelegate/
│       │   │               │       ├── ActivityViewBindings.kt
│       │   │               │       ├── FragmentViewBindings.kt
│       │   │               │       └── ViewBindingProperty.kt
│       │   │               └── web/
│       │   │                   ├── HttpServer.kt
│       │   │                   ├── ReadMe.md
│       │   │                   ├── WebSocketServer.kt
│       │   │                   ├── socket/
│       │   │                   │   ├── BookSearchWebSocket.kt
│       │   │                   │   ├── BookSourceDebugWebSocket.kt
│       │   │                   │   └── RssSourceDebugWebSocket.kt
│       │   │                   └── utils/
│       │   │                       └── AssetsWeb.kt
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── anim_none.xml
│       │       │   ├── anim_readbook_bottom_in.xml
│       │       │   ├── anim_readbook_bottom_out.xml
│       │       │   ├── anim_readbook_top_in.xml
│       │       │   └── anim_readbook_top_out.xml
│       │       ├── color/
│       │       │   └── selector_image.xml
│       │       ├── drawable/
│       │       │   ├── bg_chapter_item_divider.xml
│       │       │   ├── bg_edit.xml
│       │       │   ├── bg_eink_border_bottom.xml
│       │       │   ├── bg_eink_border_dialog.xml
│       │       │   ├── bg_eink_border_top.xml
│       │       │   ├── bg_find_book_group.xml
│       │       │   ├── bg_gradient.xml
│       │       │   ├── bg_img_border.xml
│       │       │   ├── bg_item_focused_on_tv.xml
│       │       │   ├── bg_popup_menu.xml
│       │       │   ├── bg_prefs_color.xml
│       │       │   ├── bg_searchview.xml
│       │       │   ├── bg_shadow_bottom.xml
│       │       │   ├── bg_shadow_bottom_night.xml
│       │       │   ├── bg_shadow_top.xml
│       │       │   ├── bg_shadow_top_night.xml
│       │       │   ├── bg_textfield_search.xml
│       │       │   ├── fastscroll_bubble.xml
│       │       │   ├── fastscroll_handle.xml
│       │       │   ├── fastscroll_track.xml
│       │       │   ├── ic_add.xml
│       │       │   ├── ic_add_online.xml
│       │       │   ├── ic_arrange.xml
│       │       │   ├── ic_arrow_back.xml
│       │       │   ├── ic_arrow_down.xml
│       │       │   ├── ic_arrow_drop_down.xml
│       │       │   ├── ic_arrow_drop_up.xml
│       │       │   ├── ic_arrow_right.xml
│       │       │   ├── ic_author.xml
│       │       │   ├── ic_auto_page.xml
│       │       │   ├── ic_auto_page_stop.xml
│       │       │   ├── ic_backup.xml
│       │       │   ├── ic_baseline_close.xml
│       │       │   ├── ic_baseline_sort_24.xml
│       │       │   ├── ic_book_has.xml
│       │       │   ├── ic_book_last.xml
│       │       │   ├── ic_bookmark.xml
│       │       │   ├── ic_bottom_books.xml
│       │       │   ├── ic_bottom_books_e.xml
│       │       │   ├── ic_bottom_books_s.xml
│       │       │   ├── ic_bottom_explore.xml
│       │       │   ├── ic_bottom_explore_e.xml
│       │       │   ├── ic_bottom_explore_s.xml
│       │       │   ├── ic_bottom_person.xml
│       │       │   ├── ic_bottom_person_e.xml
│       │       │   ├── ic_bottom_person_s.xml
│       │       │   ├── ic_bottom_rss_feed.xml
│       │       │   ├── ic_bottom_rss_feed_e.xml
│       │       │   ├── ic_bottom_rss_feed_s.xml
│       │       │   ├── ic_brightness.xml
│       │       │   ├── ic_brightness_auto.xml
│       │       │   ├── ic_bubble_chart.xml
│       │       │   ├── ic_bug_report.xml
│       │       │   ├── ic_cfg_about.xml
│       │       │   ├── ic_cfg_backup.xml
│       │       │   ├── ic_cfg_donate.xml
│       │       │   ├── ic_cfg_other.xml
│       │       │   ├── ic_cfg_replace.xml
│       │       │   ├── ic_cfg_source.xml
│       │       │   ├── ic_cfg_theme.xml
│       │       │   ├── ic_cfg_web.xml
│       │       │   ├── ic_chapter_list.xml
│       │       │   ├── ic_check.xml
│       │       │   ├── ic_check_source.xml
│       │       │   ├── ic_clear_all.xml
│       │       │   ├── ic_copy.xml
│       │       │   ├── ic_create_folder_outline.xml
│       │       │   ├── ic_cursor_left.xml
│       │       │   ├── ic_cursor_right.xml
│       │       │   ├── ic_daytime.xml
│       │       │   ├── ic_divider.xml
│       │       │   ├── ic_download.xml
│       │       │   ├── ic_download_line.xml
│       │       │   ├── ic_edit.xml
│       │       │   ├── ic_exchange.xml
│       │       │   ├── ic_exchange_order.xml
│       │       │   ├── ic_exit.xml
│       │       │   ├── ic_expand_less.xml
│       │       │   ├── ic_expand_more.xml
│       │       │   ├── ic_export.xml
│       │       │   ├── ic_fast_forward.xml
│       │       │   ├── ic_fast_rewind.xml
│       │       │   ├── ic_find_replace.xml
│       │       │   ├── ic_folder.xml
│       │       │   ├── ic_folder_open.xml
│       │       │   ├── ic_folder_outline.xml
│       │       │   ├── ic_groups.xml
│       │       │   ├── ic_help.xml
│       │       │   ├── ic_history.xml
│       │       │   ├── ic_image.xml
│       │       │   ├── ic_import.xml
│       │       │   ├── ic_interface_setting.xml
│       │       │   ├── ic_launcher1.xml
│       │       │   ├── ic_launcher1_b.xml
│       │       │   ├── ic_launcher2.xml
│       │       │   ├── ic_launcher3.xml
│       │       │   ├── ic_launcher4.xml
│       │       │   ├── ic_launcher4_b.xml
│       │       │   ├── ic_launcher5.xml
│       │       │   ├── ic_launcher5_b.xml
│       │       │   ├── ic_launcher6.xml
│       │       │   ├── ic_launcher7.xml
│       │       │   ├── ic_launcher7_b.xml
│       │       │   ├── ic_lock_outline.xml
│       │       │   ├── ic_menu.xml
│       │       │   ├── ic_more.xml
│       │       │   ├── ic_more_vert.xml
│       │       │   ├── ic_network_check.xml
│       │       │   ├── ic_outline_cloud_24.xml
│       │       │   ├── ic_outline_delete.xml
│       │       │   ├── ic_pause_24dp.xml
│       │       │   ├── ic_pause_outline_24dp.xml
│       │       │   ├── ic_play_24dp.xml
│       │       │   ├── ic_play_mode_list_end_stop.xml
│       │       │   ├── ic_play_mode_list_loop.xml
│       │       │   ├── ic_play_mode_random.xml
│       │       │   ├── ic_play_mode_single_loop.xml
│       │       │   ├── ic_play_outline_24dp.xml
│       │       │   ├── ic_praise.xml
│       │       │   ├── ic_read_aloud.xml
│       │       │   ├── ic_reduce.xml
│       │       │   ├── ic_refresh_black_24dp.xml
│       │       │   ├── ic_refresh_white_24dp.xml
│       │       │   ├── ic_restore.xml
│       │       │   ├── ic_save.xml
│       │       │   ├── ic_scan.xml
│       │       │   ├── ic_scoring.xml
│       │       │   ├── ic_screen.xml
│       │       │   ├── ic_search.xml
│       │       │   ├── ic_search_hint.xml
│       │       │   ├── ic_settings.xml
│       │       │   ├── ic_share.xml
│       │       │   ├── ic_skip_next.xml
│       │       │   ├── ic_skip_previous.xml
│       │       │   ├── ic_sort.xml
│       │       │   ├── ic_star.xml
│       │       │   ├── ic_star_border.xml
│       │       │   ├── ic_stop_black_24dp.xml
│       │       │   ├── ic_storage_black_24dp.xml
│       │       │   ├── ic_swap_horiz.xml
│       │       │   ├── ic_time_add_24dp.xml
│       │       │   ├── ic_timer_black_24dp.xml
│       │       │   ├── ic_toc.xml
│       │       │   ├── ic_translate.xml
│       │       │   ├── ic_update.xml
│       │       │   ├── ic_view_quilt.xml
│       │       │   ├── ic_visibility_off.xml
│       │       │   ├── ic_volume_up.xml
│       │       │   ├── ic_web_outline.xml
│       │       │   ├── ic_web_service_noti.xml
│       │       │   ├── recyclerview_divider_horizontal.xml
│       │       │   ├── recyclerview_divider_vertical.xml
│       │       │   ├── selector_btn_accent_bg.xml
│       │       │   ├── selector_circle_btn_bg.xml
│       │       │   ├── selector_common_bg.xml
│       │       │   ├── selector_fillet_btn_bg.xml
│       │       │   ├── selector_tv_black.xml
│       │       │   ├── shape_card_view.xml
│       │       │   ├── shape_circle.xml
│       │       │   ├── shape_fillet_btn.xml
│       │       │   ├── shape_fillet_btn_press.xml
│       │       │   ├── shape_pop_checkaddshelf_bg.xml
│       │       │   ├── shape_radius_10dp.xml
│       │       │   ├── shape_radius_1dp.xml
│       │       │   ├── shape_space_divider.xml
│       │       │   ├── shape_text_cursor.xml
│       │       │   └── shape_translucent_card.xml
│       │       ├── layout/
│       │       │   ├── activity_about.xml
│       │       │   ├── activity_all_bookmark.xml
│       │       │   ├── activity_arrange_book.xml
│       │       │   ├── activity_audio_play.xml
│       │       │   ├── activity_book_info.xml
│       │       │   ├── activity_book_info_edit.xml
│       │       │   ├── activity_book_read.xml
│       │       │   ├── activity_book_search.xml
│       │       │   ├── activity_book_source.xml
│       │       │   ├── activity_book_source_edit.xml
│       │       │   ├── activity_cache_book.xml
│       │       │   ├── activity_chapter_list.xml
│       │       │   ├── activity_config.xml
│       │       │   ├── activity_dict_rule.xml
│       │       │   ├── activity_donate.xml
│       │       │   ├── activity_explore_show.xml
│       │       │   ├── activity_file_manage.xml
│       │       │   ├── activity_import_book.xml
│       │       │   ├── activity_main.xml
│       │       │   ├── activity_manga.xml
│       │       │   ├── activity_qrcode_capture.xml
│       │       │   ├── activity_read_record.xml
│       │       │   ├── activity_replace_edit.xml
│       │       │   ├── activity_replace_rule.xml
│       │       │   ├── activity_rss_artivles.xml
│       │       │   ├── activity_rss_favorites.xml
│       │       │   ├── activity_rss_read.xml
│       │       │   ├── activity_rss_source.xml
│       │       │   ├── activity_rss_source_edit.xml
│       │       │   ├── activity_rule_sub.xml
│       │       │   ├── activity_search_content.xml
│       │       │   ├── activity_source_debug.xml
│       │       │   ├── activity_source_login.xml
│       │       │   ├── activity_translucence.xml
│       │       │   ├── activity_txt_toc_rule.xml
│       │       │   ├── activity_web_view.xml
│       │       │   ├── activity_welcome.xml
│       │       │   ├── dialog_add_to_bookshelf.xml
│       │       │   ├── dialog_auto_read.xml
│       │       │   ├── dialog_book_change_source.xml
│       │       │   ├── dialog_book_group_edit.xml
│       │       │   ├── dialog_book_group_picker.xml
│       │       │   ├── dialog_bookmark.xml
│       │       │   ├── dialog_bookshelf_config.xml
│       │       │   ├── dialog_change_cover.xml
│       │       │   ├── dialog_chapter_change_source.xml
│       │       │   ├── dialog_check_source_config.xml
│       │       │   ├── dialog_click_action_config.xml
│       │       │   ├── dialog_code_view.xml
│       │       │   ├── dialog_content_edit.xml
│       │       │   ├── dialog_cover_rule_config.xml
│       │       │   ├── dialog_custom_group.xml
│       │       │   ├── dialog_dict.xml
│       │       │   ├── dialog_dict_rule_edit.xml
│       │       │   ├── dialog_direct_link_upload_config.xml
│       │       │   ├── dialog_download_choice.xml
│       │       │   ├── dialog_edit_text.xml
│       │       │   ├── dialog_file_chooser.xml
│       │       │   ├── dialog_font_select.xml
│       │       │   ├── dialog_http_tts_edit.xml
│       │       │   ├── dialog_image_blurring.xml
│       │       │   ├── dialog_login.xml
│       │       │   ├── dialog_manga_color_filter.xml
│       │       │   ├── dialog_manga_epaper.xml
│       │       │   ├── dialog_manga_footer_setting.xml
│       │       │   ├── dialog_multiple_edit_text.xml
│       │       │   ├── dialog_number_picker.xml
│       │       │   ├── dialog_open_url_confirm.xml
│       │       │   ├── dialog_page_key.xml
│       │       │   ├── dialog_photo_view.xml
│       │       │   ├── dialog_progressbar_view.xml
│       │       │   ├── dialog_read_aloud.xml
│       │       │   ├── dialog_read_bg_text.xml
│       │       │   ├── dialog_read_book_style.xml
│       │       │   ├── dialog_read_padding.xml
│       │       │   ├── dialog_recycler_view.xml
│       │       │   ├── dialog_rss_favorite_config.xml
│       │       │   ├── dialog_rule_sub_edit.xml
│       │       │   ├── dialog_search_scope.xml
│       │       │   ├── dialog_select_section_export.xml
│       │       │   ├── dialog_simulated_reading.xml
│       │       │   ├── dialog_source_picker.xml
│       │       │   ├── dialog_text_view.xml
│       │       │   ├── dialog_tip_config.xml
│       │       │   ├── dialog_toc_regex.xml
│       │       │   ├── dialog_toc_regex_edit.xml
│       │       │   ├── dialog_update.xml
│       │       │   ├── dialog_url_option_edit.xml
│       │       │   ├── dialog_variable.xml
│       │       │   ├── dialog_verification_code_view.xml
│       │       │   ├── dialog_wait.xml
│       │       │   ├── dialog_webdav_server.xml
│       │       │   ├── fragment_bookmark.xml
│       │       │   ├── fragment_books.xml
│       │       │   ├── fragment_bookshelf1.xml
│       │       │   ├── fragment_bookshelf2.xml
│       │       │   ├── fragment_chapter_list.xml
│       │       │   ├── fragment_explore.xml
│       │       │   ├── fragment_my_config.xml
│       │       │   ├── fragment_rss.xml
│       │       │   ├── fragment_rss_articles.xml
│       │       │   ├── fragment_web_view_login.xml
│       │       │   ├── item_1line_text.xml
│       │       │   ├── item_1line_text_and_del.xml
│       │       │   ├── item_app_log.xml
│       │       │   ├── item_arrange_book.xml
│       │       │   ├── item_bg_image.xml
│       │       │   ├── item_book_file_import.xml
│       │       │   ├── item_book_group_manage.xml
│       │       │   ├── item_book_manga_edge.xml
│       │       │   ├── item_book_manga_page.xml
│       │       │   ├── item_book_source.xml
│       │       │   ├── item_bookmark.xml
│       │       │   ├── item_bookshelf_grid.xml
│       │       │   ├── item_bookshelf_grid_group.xml
│       │       │   ├── item_bookshelf_list.xml
│       │       │   ├── item_bookshelf_list_group.xml
│       │       │   ├── item_change_source.xml
│       │       │   ├── item_chapter_list.xml
│       │       │   ├── item_check_box.xml
│       │       │   ├── item_cover.xml
│       │       │   ├── item_dict_rule.xml
│       │       │   ├── item_download.xml
│       │       │   ├── item_file.xml
│       │       │   ├── item_file_picker.xml
│       │       │   ├── item_fillet_text.xml
│       │       │   ├── item_find_book.xml
│       │       │   ├── item_font.xml
│       │       │   ├── item_group_manage.xml
│       │       │   ├── item_group_select.xml
│       │       │   ├── item_http_tts.xml
│       │       │   ├── item_icon_preference.xml
│       │       │   ├── item_import_book.xml
│       │       │   ├── item_log.xml
│       │       │   ├── item_path_picker.xml
│       │       │   ├── item_radio_button.xml
│       │       │   ├── item_read_record.xml
│       │       │   ├── item_read_style.xml
│       │       │   ├── item_replace_rule.xml
│       │       │   ├── item_rss.xml
│       │       │   ├── item_rss_article.xml
│       │       │   ├── item_rss_article_1.xml
│       │       │   ├── item_rss_article_2.xml
│       │       │   ├── item_rss_read_record.xml
│       │       │   ├── item_rss_source.xml
│       │       │   ├── item_rule_sub.xml
│       │       │   ├── item_search.xml
│       │       │   ├── item_search_list.xml
│       │       │   ├── item_server_select.xml
│       │       │   ├── item_source_edit.xml
│       │       │   ├── item_source_edit_check_box.xml
│       │       │   ├── item_source_import.xml
│       │       │   ├── item_text.xml
│       │       │   ├── item_theme_config.xml
│       │       │   ├── item_toc_regex.xml
│       │       │   ├── item_txt_toc_rule.xml
│       │       │   ├── popup_action.xml
│       │       │   ├── popup_action_menu.xml
│       │       │   ├── popup_keyboard_tool.xml
│       │       │   ├── popup_seek_bar.xml
│       │       │   ├── view_action_button.xml
│       │       │   ├── view_book_page.xml
│       │       │   ├── view_detail_seek_bar.xml
│       │       │   ├── view_dynamic.xml
│       │       │   ├── view_error.xml
│       │       │   ├── view_fastscroller.xml
│       │       │   ├── view_icon.xml
│       │       │   ├── view_load_more.xml
│       │       │   ├── view_loading.xml
│       │       │   ├── view_manga_menu.xml
│       │       │   ├── view_navigation_badge.xml
│       │       │   ├── view_preference.xml
│       │       │   ├── view_preference_category.xml
│       │       │   ├── view_read_menu.xml
│       │       │   ├── view_refresh_recycler.xml
│       │       │   ├── view_search.xml
│       │       │   ├── view_search_menu.xml
│       │       │   ├── view_select_action_bar.xml
│       │       │   ├── view_tab_layout.xml
│       │       │   ├── view_tab_layout_min.xml
│       │       │   ├── view_title_bar.xml
│       │       │   ├── view_title_bar_dark.xml
│       │       │   └── view_toast.xml
│       │       ├── layout-land/
│       │       │   └── activity_book_info.xml
│       │       ├── menu/
│       │       │   ├── about.xml
│       │       │   ├── app_log.xml
│       │       │   ├── app_update.xml
│       │       │   ├── audio_play.xml
│       │       │   ├── backup_restore.xml
│       │       │   ├── book_cache.xml
│       │       │   ├── book_cache_download.xml
│       │       │   ├── book_group_manage.xml
│       │       │   ├── book_info.xml
│       │       │   ├── book_info_edit.xml
│       │       │   ├── book_manga.xml
│       │       │   ├── book_read.xml
│       │       │   ├── book_read_change_source.xml
│       │       │   ├── book_read_record.xml
│       │       │   ├── book_read_refresh.xml
│       │       │   ├── book_read_source.xml
│       │       │   ├── book_remote.xml
│       │       │   ├── book_search.xml
│       │       │   ├── book_search_scope.xml
│       │       │   ├── book_source.xml
│       │       │   ├── book_source_debug.xml
│       │       │   ├── book_source_item.xml
│       │       │   ├── book_source_sel.xml
│       │       │   ├── book_toc.xml
│       │       │   ├── bookmark.xml
│       │       │   ├── bookshelf_manage.xml
│       │       │   ├── bookshelf_menage_sel.xml
│       │       │   ├── change_cover.xml
│       │       │   ├── change_source.xml
│       │       │   ├── change_source_item.xml
│       │       │   ├── code_edit.xml
│       │       │   ├── content_edit.xml
│       │       │   ├── content_search.xml
│       │       │   ├── content_select_action.xml
│       │       │   ├── crash_log.xml
│       │       │   ├── dialog_text.xml
│       │       │   ├── dict_rule.xml
│       │       │   ├── dict_rule_edit.xml
│       │       │   ├── dict_rule_sel.xml
│       │       │   ├── direct_link_upload_config.xml
│       │       │   ├── explore_item.xml
│       │       │   ├── file_chooser.xml
│       │       │   ├── file_long_click.xml
│       │       │   ├── font_select.xml
│       │       │   ├── group_manage.xml
│       │       │   ├── import_book.xml
│       │       │   ├── import_book_sel.xml
│       │       │   ├── import_replace.xml
│       │       │   ├── import_source.xml
│       │       │   ├── keyboard_assists_config.xml
│       │       │   ├── main_bnv.xml
│       │       │   ├── main_bookshelf.xml
│       │       │   ├── main_explore.xml
│       │       │   ├── main_my.xml
│       │       │   ├── main_rss.xml
│       │       │   ├── open_url_confirm.xml
│       │       │   ├── qr_code_scan.xml
│       │       │   ├── replace_edit.xml
│       │       │   ├── replace_rule.xml
│       │       │   ├── replace_rule_item.xml
│       │       │   ├── replace_rule_sel.xml
│       │       │   ├── rss_articles.xml
│       │       │   ├── rss_favorites.xml
│       │       │   ├── rss_main_item.xml
│       │       │   ├── rss_read.xml
│       │       │   ├── rss_read_record.xml
│       │       │   ├── rss_source.xml
│       │       │   ├── rss_source_debug.xml
│       │       │   ├── rss_source_item.xml
│       │       │   ├── rss_source_sel.xml
│       │       │   ├── save.xml
│       │       │   ├── search_view.xml
│       │       │   ├── server_config.xml
│       │       │   ├── servers.xml
│       │       │   ├── source_edit.xml
│       │       │   ├── source_login.xml
│       │       │   ├── source_picker.xml
│       │       │   ├── source_sub_item.xml
│       │       │   ├── source_subscription.xml
│       │       │   ├── source_webview_login.xml
│       │       │   ├── speak_engine.xml
│       │       │   ├── speak_engine_edit.xml
│       │       │   ├── theme_config.xml
│       │       │   ├── theme_list.xml
│       │       │   ├── txt_toc_rule.xml
│       │       │   ├── txt_toc_rule_edit.xml
│       │       │   ├── txt_toc_rule_item.xml
│       │       │   ├── txt_toc_rule_sel.xml
│       │       │   ├── verification_code.xml
│       │       │   └── web_view.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   ├── launcher1.xml
│       │       │   ├── launcher2.xml
│       │       │   ├── launcher3.xml
│       │       │   ├── launcher4.xml
│       │       │   ├── launcher5.xml
│       │       │   └── launcher6.xml
│       │       ├── values/
│       │       │   ├── array_values.xml
│       │       │   ├── arrays.xml
│       │       │   ├── attrs.xml
│       │       │   ├── colors.xml
│       │       │   ├── colors_material_design.xml
│       │       │   ├── dimens.xml
│       │       │   ├── ids.xml
│       │       │   ├── non_translat.xml
│       │       │   ├── strings.xml
│       │       │   └── styles.xml
│       │       ├── values-es-rES/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP/
│       │       │   └── strings.xml
│       │       ├── values-night/
│       │       │   ├── colors.xml
│       │       │   └── styles.xml
│       │       ├── values-pt-rBR/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-vi/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-zh/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-zh-rHK/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW/
│       │       │   ├── arrays.xml
│       │       │   └── strings.xml
│       │       └── xml/
│       │           ├── about.xml
│       │           ├── file_paths.xml
│       │           ├── network_security_config.xml
│       │           ├── pref_config_aloud.xml
│       │           ├── pref_config_backup.xml
│       │           ├── pref_config_cover.xml
│       │           ├── pref_config_other.xml
│       │           ├── pref_config_read.xml
│       │           ├── pref_config_theme.xml
│       │           ├── pref_config_welcome.xml
│       │           ├── pref_main.xml
│       │           └── spen_remote_actions.xml
│       └── test/
│           └── java/
│               └── io/
│                   └── legado/
│                       └── app/
│                           ├── ExampleUnitTest.kt
│                           └── JsTest.kt
├── avd.bat
├── avd.sh
├── build.gradle
├── gradle/
│   ├── libs.versions.toml
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── modules/
│   ├── book/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── consumer-rules.pro
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── me/
│   │           │       └── ag2s/
│   │           │           ├── base/
│   │           │           │   ├── PfdHelper.java
│   │           │           │   └── ThrowableUtils.java
│   │           │           ├── epublib/
│   │           │           │   ├── Constants.java
│   │           │           │   ├── browsersupport/
│   │           │           │   │   ├── NavigationEvent.java
│   │           │           │   │   ├── NavigationEventListener.java
│   │           │           │   │   ├── NavigationHistory.java
│   │           │           │   │   ├── Navigator.java
│   │           │           │   │   └── package-info.java
│   │           │           │   ├── domain/
│   │           │           │   │   ├── Author.java
│   │           │           │   │   ├── Date.java
│   │           │           │   │   ├── EpubBook.java
│   │           │           │   │   ├── EpubResourceProvider.java
│   │           │           │   │   ├── FileResourceProvider.java
│   │           │           │   │   ├── Guide.java
│   │           │           │   │   ├── GuideReference.java
│   │           │           │   │   ├── Identifier.java
│   │           │           │   │   ├── LazyResource.java
│   │           │           │   │   ├── LazyResourceProvider.java
│   │           │           │   │   ├── ManifestItemProperties.java
│   │           │           │   │   ├── ManifestItemRefProperties.java
│   │           │           │   │   ├── ManifestProperties.java
│   │           │           │   │   ├── MediaType.java
│   │           │           │   │   ├── MediaTypes.java
│   │           │           │   │   ├── Metadata.java
│   │           │           │   │   ├── Relator.java
│   │           │           │   │   ├── Resource.java
│   │           │           │   │   ├── ResourceInputStream.java
│   │           │           │   │   ├── ResourceReference.java
│   │           │           │   │   ├── Resources.java
│   │           │           │   │   ├── Spine.java
│   │           │           │   │   ├── SpineReference.java
│   │           │           │   │   ├── TOCReference.java
│   │           │           │   │   ├── TableOfContents.java
│   │           │           │   │   └── TitledResourceReference.java
│   │           │           │   ├── epub/
│   │           │           │   │   ├── BookProcessor.java
│   │           │           │   │   ├── BookProcessorPipeline.java
│   │           │           │   │   ├── DOMUtil.java
│   │           │           │   │   ├── EpubProcessorSupport.java
│   │           │           │   │   ├── EpubReader.java
│   │           │           │   │   ├── EpubWriter.java
│   │           │           │   │   ├── EpubWriterProcessor.java
│   │           │           │   │   ├── HtmlProcessor.java
│   │           │           │   │   ├── NCXDocumentV2.java
│   │           │           │   │   ├── NCXDocumentV3.java
│   │           │           │   │   ├── PackageDocumentBase.java
│   │           │           │   │   ├── PackageDocumentMetadataReader.java
│   │           │           │   │   ├── PackageDocumentMetadataWriter.java
│   │           │           │   │   ├── PackageDocumentReader.java
│   │           │           │   │   ├── PackageDocumentWriter.java
│   │           │           │   │   └── ResourcesLoader.java
│   │           │           │   └── util/
│   │           │           │       ├── CollectionUtil.java
│   │           │           │       ├── IOUtil.java
│   │           │           │       ├── NoCloseOutputStream.java
│   │           │           │       ├── NoCloseWriter.java
│   │           │           │       ├── ResourceUtil.java
│   │           │           │       ├── StringUtil.java
│   │           │           │       ├── URLEncodeUtil.java
│   │           │           │       ├── commons/
│   │           │           │       │   └── io/
│   │           │           │       │       ├── BOMInputStream.java
│   │           │           │       │       ├── ByteOrderMark.java
│   │           │           │       │       ├── IOConsumer.java
│   │           │           │       │       ├── ProxyInputStream.java
│   │           │           │       │       ├── XmlStreamReader.java
│   │           │           │       │       └── XmlStreamReaderException.java
│   │           │           │       └── zip/
│   │           │           │           ├── AndroidZipEntry.java
│   │           │           │           ├── AndroidZipFile.java
│   │           │           │           ├── ZipConstants.java
│   │           │           │           ├── ZipEntryWrapper.java
│   │           │           │           ├── ZipException.java
│   │           │           │           └── ZipFileWrapper.java
│   │           │           └── umdlib/
│   │           │               ├── domain/
│   │           │               │   ├── UmdBook.java
│   │           │               │   ├── UmdChapters.java
│   │           │               │   ├── UmdCover.java
│   │           │               │   ├── UmdEnd.java
│   │           │               │   └── UmdHeader.java
│   │           │               ├── tool/
│   │           │               │   ├── StreamReader.java
│   │           │               │   ├── UmdUtils.java
│   │           │               │   └── WrapOutputStream.java
│   │           │               └── umd/
│   │           │                   └── UmdReader.java
│   │           └── resources/
│   │               ├── dtd/
│   │               │   ├── openebook.org/
│   │               │   │   └── dtds/
│   │               │   │       └── oeb-1.2/
│   │               │   │           ├── oeb12.ent
│   │               │   │           └── oebpkg12.dtd
│   │               │   ├── www.daisy.org/
│   │               │   │   └── z3986/
│   │               │   │       └── 2005/
│   │               │   │           └── ncx-2005-1.dtd
│   │               │   └── www.w3.org/
│   │               │       └── TR/
│   │               │           ├── ruby/
│   │               │           │   └── xhtml-ruby-1.mod
│   │               │           ├── xhtml-modularization/
│   │               │           │   └── DTD/
│   │               │           │       ├── xhtml-arch-1.mod
│   │               │           │       ├── xhtml-attribs-1.mod
│   │               │           │       ├── xhtml-base-1.mod
│   │               │           │       ├── xhtml-bdo-1.mod
│   │               │           │       ├── xhtml-blkphras-1.mod
│   │               │           │       ├── xhtml-blkpres-1.mod
│   │               │           │       ├── xhtml-blkstruct-1.mod
│   │               │           │       ├── xhtml-charent-1.mod
│   │               │           │       ├── xhtml-csismap-1.mod
│   │               │           │       ├── xhtml-datatypes-1.mod
│   │               │           │       ├── xhtml-datatypes-1.mod.1
│   │               │           │       ├── xhtml-edit-1.mod
│   │               │           │       ├── xhtml-events-1.mod
│   │               │           │       ├── xhtml-form-1.mod
│   │               │           │       ├── xhtml-framework-1.mod
│   │               │           │       ├── xhtml-hypertext-1.mod
│   │               │           │       ├── xhtml-image-1.mod
│   │               │           │       ├── xhtml-inlphras-1.mod
│   │               │           │       ├── xhtml-inlpres-1.mod
│   │               │           │       ├── xhtml-inlstruct-1.mod
│   │               │           │       ├── xhtml-inlstyle-1.mod
│   │               │           │       ├── xhtml-lat1.ent
│   │               │           │       ├── xhtml-link-1.mod
│   │               │           │       ├── xhtml-list-1.mod
│   │               │           │       ├── xhtml-meta-1.mod
│   │               │           │       ├── xhtml-notations-1.mod
│   │               │           │       ├── xhtml-object-1.mod
│   │               │           │       ├── xhtml-param-1.mod
│   │               │           │       ├── xhtml-pres-1.mod
│   │               │           │       ├── xhtml-qname-1.mod
│   │               │           │       ├── xhtml-script-1.mod
│   │               │           │       ├── xhtml-special.ent
│   │               │           │       ├── xhtml-ssismap-1.mod
│   │               │           │       ├── xhtml-struct-1.mod
│   │               │           │       ├── xhtml-style-1.mod
│   │               │           │       ├── xhtml-symbol.ent
│   │               │           │       ├── xhtml-symbol.ent.1
│   │               │           │       ├── xhtml-table-1.mod
│   │               │           │       ├── xhtml-text-1.mod
│   │               │           │       └── xhtml11-model-1.mod
│   │               │           ├── xhtml1/
│   │               │           │   └── DTD/
│   │               │           │       ├── xhtml-lat1.ent
│   │               │           │       ├── xhtml-special.ent
│   │               │           │       ├── xhtml-symbol.ent
│   │               │           │       ├── xhtml1-strict.dtd
│   │               │           │       └── xhtml1-transitional.dtd
│   │               │           └── xhtml11/
│   │               │               └── DTD/
│   │               │                   └── xhtml11.dtd
│   │               └── log4j.properties
│   ├── rhino/
│   │   ├── build.gradle
│   │   ├── consumer-rules.pro
│   │   ├── lib/
│   │   │   └── rhino-1.7.14.jar
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── script/
│   │                       ├── AbstractScriptEngine.kt
│   │                       ├── Bindings.kt
│   │                       ├── Compilable.kt
│   │                       ├── CompiledScript.kt
│   │                       ├── Invocable.kt
│   │                       ├── RhinoContextFactory.kt
│   │                       ├── ScriptBindings.kt
│   │                       ├── ScriptBindingsExtensions.kt
│   │                       ├── ScriptContext.kt
│   │                       ├── ScriptEngine.kt
│   │                       ├── ScriptException.kt
│   │                       ├── SimpleBindings.kt
│   │                       ├── SimpleScriptContext.kt
│   │                       └── rhino/
│   │                           ├── ClassNameMatcher.kt
│   │                           ├── CollectionExtensions.kt
│   │                           ├── ExternalScriptable.kt
│   │                           ├── InterfaceImplementor.kt
│   │                           ├── JSAdapter.kt
│   │                           ├── JavaAdapter.kt
│   │                           ├── JavaObjectWrapFactory.kt
│   │                           ├── ProtectedNativeJavaClass.kt
│   │                           ├── ReadOnlyJavaObject.kt
│   │                           ├── RhinoClassShutter.kt
│   │                           ├── RhinoCompiledScript.kt
│   │                           ├── RhinoContext.kt
│   │                           ├── RhinoErrors.kt
│   │                           ├── RhinoExtensions.kt
│   │                           ├── RhinoScriptEngine.kt
│   │                           ├── RhinoTopLevel.kt
│   │                           ├── RhinoWrapFactory.kt
│   │                           └── VMBridgeReflect.kt
│   └── web/
│       ├── .browserslistrc
│       ├── .editorconfig
│       ├── .gitignore
│       ├── .prettierignore
│       ├── .prettierrc.json
│       ├── LICENSE
│       ├── README.md
│       ├── env.d.ts
│       ├── eslint.config.mjs
│       ├── index.html
│       ├── package.json
│       ├── scripts/
│       │   └── sync.js
│       ├── src/
│       │   ├── App.vue
│       │   ├── api/
│       │   │   ├── api.ts
│       │   │   ├── axios.ts
│       │   │   └── index.ts
│       │   ├── assets/
│       │   │   ├── bookshelf.css
│       │   │   ├── code.css
│       │   │   ├── fonts/
│       │   │   │   ├── iconfont.css
│       │   │   │   ├── popfont.css
│       │   │   │   └── shelffont.css
│       │   │   ├── kbd.css
│       │   │   └── sourceeditor.css
│       │   ├── auto-imports.d.ts
│       │   ├── book.d.ts
│       │   ├── components/
│       │   │   ├── BookItems.vue
│       │   │   ├── CatalogItem.vue
│       │   │   ├── ChapterContent.vue
│       │   │   ├── PopCatalog.vue
│       │   │   ├── ReadSettings.vue
│       │   │   ├── SourceDebug.vue
│       │   │   ├── SourceHelp.vue
│       │   │   ├── SourceItem.vue
│       │   │   ├── SourceJson.vue
│       │   │   ├── SourceList.vue
│       │   │   ├── SourceTabForm.vue
│       │   │   ├── SourceTabTools.vue
│       │   │   └── ToolBar.vue
│       │   ├── components.d.ts
│       │   ├── config/
│       │   │   ├── bookSourceEditConfig.ts
│       │   │   ├── rssSourceEditConfig.ts
│       │   │   ├── sourceConfig.d.ts
│       │   │   └── themeConfig.ts
│       │   ├── hooks/
│       │   │   ├── loading.css
│       │   │   └── loading.ts
│       │   ├── main.ts
│       │   ├── pages/
│       │   │   ├── bookshelf/
│       │   │   │   ├── README.md
│       │   │   │   ├── index.html
│       │   │   │   └── main.js
│       │   │   └── source/
│       │   │       ├── README.md
│       │   │       ├── index.html
│       │   │       └── main.js
│       │   ├── plugins/
│       │   │   ├── jump.d.ts
│       │   │   └── jump.js
│       │   ├── router/
│       │   │   ├── bookRouter.ts
│       │   │   ├── index.ts
│       │   │   └── sourceRouter.ts
│       │   ├── source.d.ts
│       │   ├── store/
│       │   │   ├── bookStore.ts
│       │   │   ├── connectionStore.ts
│       │   │   ├── index.ts
│       │   │   └── sourceStore.ts
│       │   ├── utils/
│       │   │   ├── souce.ts
│       │   │   └── utils.ts
│       │   ├── views/
│       │   │   ├── BookChapter.vue
│       │   │   ├── BookShelf.vue
│       │   │   └── SourceEditor.vue
│       │   └── web.d.ts
│       ├── tsconfig.app.json
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
├── package.json
└── settings.gradle
Download .txt
Showing preview only (216K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2427 symbols across 113 files)

FILE: .github/scripts/lzy_web.py
  function log (line 23) | def log(msg):
  function login_by_cookie (line 30) | def login_by_cookie():
  function upload_file (line 48) | def upload_file(file_dir, folder_id):
  function upload_folder (line 65) | def upload_folder(folder_dir, folder_id):
  function upload (line 76) | def upload(dir, folder_id):

FILE: .github/scripts/tg_bot.py
  function upload_file (line 4) | def upload_file(tb, chat_id, file_dir):
  function upload_folder (line 9) | def upload_folder(tb, chat_id, folder_dir):
  function upload (line 19) | def upload(tb, chat_id, dir):

FILE: app/src/main/assets/web/assets/js/dist.js
  function b (line 5) | function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e...
  function w (line 5) | function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof...
  function d (line 5) | function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e...
  function A (line 5) | function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerC...
  function j (line 5) | function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,...
  function P (line 5) | function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}
  function M (line 5) | function M(e){return e}
  function I (line 5) | function I(e){throw e}
  function W (line 5) | function W(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n...
  function B (line 5) | function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventLi...
  function X (line 5) | function X(e,t){return t.toUpperCase()}
  function V (line 5) | function V(e){return e.replace(z,"ms-").replace(U,X)}
  function Y (line 5) | function Y(){this.expando=k.expando+Y.uid++}
  function ee (line 5) | function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t....
  function le (line 5) | function le(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:functio...
  function fe (line 5) | function fe(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;f>c;c++)(r=e[...
  function ve (line 5) | function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagNa...
  function ye (line 5) | function ye(e,t){for(var n=0,r=e.length;r>n;n++)Q.set(e[n],"globalEval",...
  function we (line 5) | function we(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),...
  function ke (line 5) | function ke(){return!0}
  function Se (line 5) | function Se(){return!1}
  function Ne (line 5) | function Ne(e,t){return e===function(){try{return E.activeElement}catch(...
  function Ae (line 5) | function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"...
  function De (line 5) | function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handle...
  function Oe (line 5) | function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"...
  function Pe (line 5) | function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}
  function Re (line 5) | function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.sli...
  function Me (line 5) | function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&...
  function Ie (line 5) | function Ie(n,r,i,o){r=g.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-...
  function We (line 5) | function We(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)...
  function _e (line 5) | function _e(e,t,n){var r,i,o,a,s=e.style;return(n=n||Fe(e))&&(""!==(a=n....
  function ze (line 5) | function ze(e,t){return{get:function(){return e()?void delete this.get:(...
  function Ge (line 5) | function Ge(e){var t=k.cssProps[e]||Ve[e];return t||(e in Xe?e:Ve[e]=fun...
  function Ze (line 5) | function Ze(e,t,n){var r=ne.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[...
  function et (line 5) | function et(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border...
  function tt (line 5) | function tt(e,t,n){var r=Fe(e),i=(!y.boxSizingReliable()||n)&&"border-bo...
  function nt (line 5) | function nt(e,t,n,r,i){return new nt.prototype.init(e,t,n,r,i)}
  function lt (line 5) | function lt(){it&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnima...
  function ct (line 5) | function ct(){return C.setTimeout(function(){rt=void 0}),rt=Date.now()}
  function ft (line 5) | function ft(e,t){var n,r=0,i={height:e};for(t=t?1:0;4>r;r+=2-t)i["margin...
  function pt (line 5) | function pt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["...
  function dt (line 5) | function dt(o,e,t){var n,a,r=0,i=dt.prefilters.length,s=k.Deferred().alw...
  function mt (line 5) | function mt(e){return(e.match(R)||[]).join(" ")}
  function xt (line 5) | function xt(e){return e.getAttribute&&e.getAttribute("class")||""}
  function bt (line 5) | function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(R)|...
  function qt (line 5) | function qt(n,e,r,i){var t;if(Array.isArray(e))k.each(e,function(e,t){r|...
  function Bt (line 5) | function Bt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var ...
  function _t (line 5) | function _t(t,i,o,a){function l(e){var r;return s[e]=!0,k.each(t[e]||[],...
  function zt (line 5) | function zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)voi...
  function se (line 5) | function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeTy...
  function ue (line 5) | function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cac...
  function le (line 5) | function le(e){return e[k]=!0,e}
  function ce (line 5) | function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(...
  function fe (line 5) | function fe(e,t){for(var n=e.split("|"),r=n.length;r--;)b.attrHandle[n[r...
  function pe (line 5) | function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourc...
  function de (line 5) | function de(t){return function(e){return"input"===e.nodeName.toLowerCase...
  function he (line 5) | function he(n){return function(e){var t=e.nodeName.toLowerCase();return(...
  function ge (line 5) | function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e....
  function ve (line 5) | function ve(a){return le(function(o){return o=+o,le(function(e,t){for(va...
  function ye (line 5) | function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}
  function me (line 5) | function me(){}
  function xe (line 5) | function xe(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}
  function be (line 5) | function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r...
  function we (line 5) | function we(i){return 1<i.length?function(e,t,n){for(var r=i.length;r--;...
  function Te (line 5) | function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;u>s;s++)(...
  function Ce (line 5) | function Ce(d,h,g,v,y,e){return v&&!v[k]&&(v=Ce(v)),y&&!y[k]&&(y=Ce(y,e)...
  function Ee (line 5) | function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.r...
  function l (line 6) | function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(...
  function e (line 6) | function e(){if(u){s.style.cssText="position:absolute;left:-11111px;widt...
  function t (line 6) | function t(e){return Math.round(parseFloat(e))}
  function l (line 7) | function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=vo...
  function u (line 7) | function u(s,o){var u,a,f;if(0==(u=e(s))[t])return n;switch(a=u[i]()[r],...
  function e (line 7) | function e(t,e,n){return"string"==typeof t&&("%"==t.slice(-1)?t=parseInt...
  function e (line 7) | function e(e){t.init(e)}

FILE: app/src/main/assets/web/assets/js/md5.js
  function hex_md5 (line 22) | function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * ch...
  function b64_md5 (line 23) | function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * ch...
  function str_md5 (line 24) | function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * ch...
  function hex_hmac_md5 (line 25) | function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, da...
  function b64_hmac_md5 (line 26) | function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, da...
  function str_hmac_md5 (line 27) | function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, da...
  function md5_vm_test (line 32) | function md5_vm_test()
  function core_md5 (line 40) | function core_md5(x, len)
  function md5_cmn (line 138) | function md5_cmn(q, a, b, x, s, t)
  function md5_ff (line 142) | function md5_ff(a, b, c, d, x, s, t)
  function md5_gg (line 146) | function md5_gg(a, b, c, d, x, s, t)
  function md5_hh (line 150) | function md5_hh(a, b, c, d, x, s, t)
  function md5_ii (line 154) | function md5_ii(a, b, c, d, x, s, t)
  function core_hmac_md5 (line 162) | function core_hmac_md5(key, data)
  function safe_add (line 182) | function safe_add(x, y)
  function bit_rol (line 192) | function bit_rol(num, cnt)
  function str2binl (line 201) | function str2binl(str)
  function binl2str (line 213) | function binl2str(bin)
  function binl2hex (line 225) | function binl2hex(binarray)
  function binl2b64 (line 240) | function binl2b64(binarray)

FILE: app/src/main/assets/web/help/js/main.js
  method highlight (line 25) | highlight(code, lang) {

FILE: app/src/main/assets/web/help/js/marked-highlight.umd.js
  function markedHighlight (line 1) | function markedHighlight(options){if(typeof options==='function'){option...
  function getLang (line 3) | function getLang(lang){return(lang||'').match(/\S*/)[0]}
  function updateToken (line 3) | function updateToken(token){return(code)=>{if(typeof code==='string'&&co...
  function escape (line 3) | function escape(html,encode){if(encode){if(escapeTest.test(html)){return...

FILE: app/src/main/assets/web/help/js/require.js
  function commentReplace (line 5) | function commentReplace(e,t){return t||""}
  function isFunction (line 5) | function isFunction(e){return"[object Function]"===ostring.call(e)}
  function isArray (line 5) | function isArray(e){return"[object Array]"===ostring.call(e)}
  function each (line 5) | function each(e,t){var i;if(e)for(i=0;i<e.length&&(!e[i]||!t(e[i],i,e));...
  function eachReverse (line 5) | function eachReverse(e,t){var i;if(e)for(i=e.length-1;-1<i&&(!e[i]||!t(e...
  function hasProp (line 5) | function hasProp(e,t){return hasOwn.call(e,t)}
  function getOwn (line 5) | function getOwn(e,t){return hasProp(e,t)&&e[t]}
  function eachProp (line 5) | function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}
  function mixin (line 5) | function mixin(i,e,r,n){return e&&eachProp(e,function(e,t){!r&&hasProp(i...
  function bind (line 5) | function bind(e,t){return function(){return t.apply(e,arguments)}}
  function scripts (line 5) | function scripts(){return document.getElementsByTagName("script")}
  function defaultOnError (line 5) | function defaultOnError(e){throw e}
  function getGlobal (line 5) | function getGlobal(e){if(!e)return e;var t=global;return each(e.split("....
  function makeError (line 5) | function makeError(e,t,i,r){var n=new Error(t+"\nhttps://requirejs.org/d...
  function newContext (line 5) | function newContext(u){var i,e,l,c,d,g={waitSeconds:7,baseUrl:"./",paths...
  function getInteractiveScript (line 5) | function getInteractiveScript(){return interactiveScript&&"interactive"=...

FILE: app/src/main/assets/web/uploadBook/js/common.js
  function init (line 25) | function init(){
  function countFileSize (line 44) | function countFileSize(fileSize)
  function substr_string (line 58) | function substr_string(name)
  function checkFile (line 75) | function checkFile(file) {
  function fileQueuedPC (line 94) | function fileQueuedPC(file, type)
  function uploadProgress (line 131) | function uploadProgress(file, bytesLoaded, bytesTotal)
  function uploadSuccess (line 138) | function uploadSuccess(file, serverData, res)
  function findObjectKey (line 146) | function findObjectKey (object, fid){
  function removeFileFromFilesUpload (line 162) | function removeFileFromFilesUpload(files, fid){

FILE: app/src/main/assets/web/uploadBook/js/html5_fun.js
  function addEvent (line 33) | function addEvent(){
  function handleDrop (line 45) | function handleDrop(evt){
  function handleDragOver (line 109) | function handleDragOver(evt){
  function handleDragLeave (line 122) | function handleDragLeave(evt){
  function uploadFiles (line 132) | function uploadFiles(file){
  function loadend (line 178) | function loadend(evt){
  function loadstart (line 182) | function loadstart(evt){
  function progress (line 187) | function progress(evt){
  function abort (line 192) | function abort(evt){
  function error (line 197) | function error(evt){
  function requestLoad (line 205) | function requestLoad(evt){
  function nextUpload (line 210) | function nextUpload(){
  function uploadError (line 221) | function uploadError(){

FILE: app/src/main/assets/web/vue/assets/BookChapter-Cs3stH93.js
  function V (line 1) | function V(){let u=c.scrollTop||c.scrollY||c.pageYOffset;return u=typeof...
  function U (line 1) | function U(u){const i=u.getBoundingClientRect().top,d=c.getBoundingClien...
  function C (line 1) | function C(u){c.scrollTo?c.scrollTo(0,u):c.scrollTop=u}
  function I (line 1) | function I(u){F||(F=u),P=u-F,x=w(P,A,y,h),C(x),P<h?requestAnimationFrame...
  function b (line 1) | function b(){C(A+y),s&&m&&(s.setAttribute("tabindex","-1"),s.focus()),ty...
  function v (line 1) | function v(u,i={}){switch(h=i.duration||1e3,n=i.offset||0,S=i.callback,w...
  method setup (line 1) | setup(c,{expose:s,emit:A}){Je(i=>({v3af0ffa9:y.spacing.letter,v316cdf92:...
  method setup (line 1) | setup(c){const s=me(),A=je(()=>ne.saveReadConfig(s.config),500);be(()=>s...
  method setup (line 1) | setup(c){const s=c,A=n=>n==s.currentChapterIndex,f=l(()=>{const n=s.sour...
  method setup (line 1) | setup(c,{emit:s}){const A=me(),{catalog:f,popCataVisible:n,miniInterface...
  method setup (line 1) | setup(c){const s=D(),{isLoading:A,loadingWrapper:f}=nt(s,"正在获取信息"),n=me(...

FILE: app/src/main/assets/web/vue/assets/BookShelf-DIQtBULC.js
  method setup (line 1) | setup(_,{emit:i}){j(g=>({v2a51eeb0:o(A)}));const k=_,R=i,a=g=>R("bookCli...
  method setup (line 1) | setup(_){const i=he(),k=V(()=>i.isNight),R=s=>{try{s!==void 0&&i.setConf...

FILE: app/src/main/assets/web/vue/assets/index-Wr40-hHf.js
  function t (line 2) | function t(r){const s={};return r.integrity&&(s.integrity=r.integrity),r...
  function n (line 2) | function n(r){if(r.ep)return;r.ep=!0;const s=t(r);fetch(r.href,s)}
  function dt (line 2) | function dt(e,o){const t=Ke("router-view");return g(),C(t)}
  function s (line 2) | function s(c){const a=new Event("vite:preloadError",{cancelable:!0});if(...
  method setup (line 2) | setup(e){return(o,t)=>{const n=We,r=Ce;return g(),E(N,null,[h(n,{icon:i(...
  method loadBookShelf (line 2) | async loadBookShelf(){const e=P.getBookShelf().then(o=>{const{isSuccess:...
  method loadWebCatalog (line 2) | async loadWebCatalog(e){const{bookUrl:o,name:t,chapterIndex:n}=e,r=P.get...
  method setPopCataVisible (line 2) | setPopCataVisible(e){this.popCataVisible=e}
  method setContentLoading (line 2) | setContentLoading(e){this.contentLoading=e}
  method setReadingBook (line 2) | setReadingBook(e){this.readingBook=e}
  method loadWebConfig (line 2) | async loadWebConfig(){if(_e===void 0){const e=await P.getReadConfig();re...
  method setConfig (line 2) | setConfig(e){this.config=Object.assign({},this.config,e)}
  method setReadSettingsVisible (line 2) | setReadSettingsVisible(e){this.readSettingsVisible=e}
  method setShowContent (line 2) | setShowContent(e){this.showContent=e}
  method setMiniInterface (line 2) | setMiniInterface(e){this.miniInterface=e}
  method setSearchBooks (line 2) | async setSearchBooks(e){e.forEach(o=>{this.shelf.every(n=>n.bookUrl!==o....
  method clearSearchBooks (line 2) | clearSearchBooks(){this.searchBooks=[]}
  method saveBookProgress (line 2) | async saveBookProgress(){if(!this.bookProgress)return Promise.resolve();...
  method startDebug (line 2) | startDebug(){this.currentTab="editDebug",this.isDebuging=!0}
  method debugFinish (line 2) | debugFinish(){this.isDebuging=!1}
  method saveSources (line 2) | saveSources(e){G?this.bookSources=me(e):this.rssSources=me(e)}
  method setPushReturnSources (line 2) | setPushReturnSources(e){this.savedSources=e}
  method deleteSources (line 2) | deleteSources(e){const o=G?this.bookSources:this.rssSources;e.forEach(t=...
  method saveCurrentSource (line 2) | saveCurrentSource(){const e=this.currentSource,o=this.sourcesMap;o.set(n...
  method changeCurrentSource (line 2) | changeCurrentSource(e){this.currentSource=JSON.parse(JSON.stringify(e))}
  method changeTabName (line 2) | changeTabName(e){this.currentTab=e,localStorage.setItem("tabName",e)}
  method changeEditTabSource (line 2) | changeEditTabSource(e){this.editTabSource=JSON.parse(JSON.stringify(e))}
  method editHistory (line 2) | editHistory(e){let o;if(localStorage.getItem("history"))o=JSON.parse(loc...
  method editHistoryUndo (line 2) | editHistoryUndo(){if(localStorage.getItem("history")){const e=JSON.parse...
  method clearAllHistory (line 2) | clearAllHistory(){localStorage.setItem("history",JSON.stringify({new:[],...
  method clearEdit (line 2) | clearEdit(){this.editTabSource={},this.currentSource=JSON.parse(JSON.str...
  method clearAllSource (line 2) | clearAllSource(){this.bookSources=[],this.rssSources=[],this.savedSource...
  method setConnectStatus (line 2) | setConnectStatus(e){this.newConnect!==!0&&(this.connectStatus=e)}
  method setConnectType (line 2) | setConnectType(e){this.newConnect!==!0&&(this.connectType=e)}
  method setNewConnect (line 2) | setNewConnect(e){this.newConnect=e}
  method setup (line 2) | setup(e){const o=e,t=F(),n=A(()=>t.currentSourceUrl),r=A(()=>ne(o.source...
  method setup (line 2) | setup(e){const o=F(),t=J([]),n=J(""),r=A(()=>o.sources),s=A(()=>{const d...
  method setup (line 2) | setup(e){const o=F(),t=J(""),n=J("");de(()=>o.isDebuging,()=>{o.isDebugi...
  method setup (line 3) | setup(e){const o=F(),t=J(""),n=async r=>{try{o.changeEditTabSource(JSON....
  method setup (line 3) | setup(e){const o=F(),t=A({get:()=>o.currentTab,set:r=>o.currentTab=r}),n...
  method setup (line 3) | setup(e){const o=F(),t=()=>{const S=k({message:"加载中……",showClose:!0,dura...
  method setup (line 9) | setup(e){const o=F(),t=A(()=>o.currentSource);return(n,r)=>{const s=te,c...
  method setup (line 10) | setup(e){ct();let o;return/bookSource/i.test(location.href)?(o=_o,docume...

FILE: app/src/main/assets/web/vue/assets/vendor-KSDcS24u.js
  function Ku (line 5) | function Ku(e){const t=Object.create(null);for(const n of e.split(","))t...
  function ot (line 5) | function ot(e){if(pe(e)){const t={};for(let n=0;n<e.length;n++){const r=...
  function ey (line 5) | function ey(e){const t={};return e.replace(Qb,"").split(Xb).forEach(n=>{...
  function U (line 5) | function U(e){let t="";if(Ae(e))t=e;else if(pe(e))for(let n=0;n<e.length...
  function wh (line 5) | function wh(e){return!!e||e===""}
  function ry (line 5) | function ry(e,t){if(e.length!==t.length)return!1;let n=!0;for(let r=0;n&...
  function ii (line 5) | function ii(e,t){if(e===t)return!0;let n=nf(e),r=nf(t);if(n||r)return n&...
  function Sh (line 5) | function Sh(e,t){return e.findIndex(n=>ii(n,t))}
  function oy (line 5) | function oy(e){return e==null?"initial":typeof e=="string"?e===""?" ":e:...
  class Ch (line 9) | class Ch{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,th...
    method constructor (line 9) | constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effe...
    method active (line 9) | get active(){return this._active}
    method pause (line 9) | pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(...
    method resume (line 9) | resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,n;if...
    method run (line 9) | run(t){if(this._active){const n=xt;try{return xt=this,t()}finally{xt=n}}}
    method on (line 9) | on(){++this._on===1&&(this.prevScope=xt,xt=this)}
    method off (line 9) | off(){this._on>0&&--this._on===0&&(xt=this.prevScope,this.prevScope=vo...
    method stop (line 9) | stop(t){if(this._active){this._active=!1;let n,r;for(n=0,r=this.effect...
  function Th (line 9) | function Th(e){return new Ch(e)}
  function Fa (line 9) | function Fa(){return xt}
  function Ba (line 9) | function Ba(e,t=!1){xt&&xt.cleanups.push(e)}
  class Oh (line 9) | class Oh{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,...
    method constructor (line 9) | constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.fl...
    method pause (line 9) | pause(){this.flags|=64}
    method resume (line 9) | resume(){this.flags&64&&(this.flags&=-65,wl.has(this)&&(wl.delete(this...
    method notify (line 9) | notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Rh(this)}
    method run (line 9) | run(){if(!(this.flags&1))return this.fn();this.flags|=2,of(this),xh(th...
    method stop (line 9) | stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)Xu(t);this.d...
    method trigger (line 9) | trigger(){this.flags&64?wl.add(this):this.scheduler?this.scheduler():t...
    method runIfDirty (line 9) | runIfDirty(){eu(this)&&this.run()}
    method dirty (line 9) | get dirty(){return eu(this)}
  function Rh (line 9) | function Rh(e,t=!1){if(e.flags|=8,t){e.next=Es,Es=e;return}e.next=Ss,Ss=e}
  function Yu (line 9) | function Yu(){Ah++}
  function Ju (line 9) | function Ju(){if(--Ah>0)return;if(Es){let t=Es;for(Es=void 0;t;){const n...
  function xh (line 9) | function xh(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveL...
  function Ih (line 9) | function Ih(e){let t,n=e.depsTail,r=n;for(;r;){const o=r.prevDep;r.versi...
  function eu (line 9) | function eu(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.versi...
  function Ph (line 9) | function Ph(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersio...
  function Xu (line 9) | function Xu(e,t=!1){const{dep:n,prevSub:r,nextSub:o}=e;if(r&&(r.nextSub=...
  function sy (line 9) | function sy(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=vo...
  function lr (line 9) | function lr(){Nh.push(Sn),Sn=!1}
  function ur (line 9) | function ur(){const e=Nh.pop();Sn=e===void 0?!0:e}
  function of (line 9) | function of(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=et;et=v...
  method constructor (line 9) | constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextD...
  class Da (line 9) | class Da{constructor(t){this.computed=t,this.version=0,this.activeLink=v...
    method constructor (line 9) | constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,t...
    method track (line 9) | track(t){if(!et||!Sn||et===this.computed)return;let n=this.activeLink;...
    method trigger (line 9) | trigger(t){this.version++,Fs++,this.notify(t)}
    method notify (line 9) | notify(t){Yu();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n...
  function Lh (line 9) | function Lh(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&...
  function It (line 9) | function It(e,t,n){if(Sn&&et){let r=aa.get(e);r||aa.set(e,r=new Map);let...
  function nr (line 9) | function nr(e,t,n,r,o,s){const i=aa.get(e);if(!i){Fs++;return}const a=l=...
  function ay (line 9) | function ay(e,t){const n=aa.get(e);return n&&n.get(t)}
  function _o (line 9) | function _o(e){const t=Me(e);return t===e?t:(It(t,"iterate",Bs),Qt(e)?t:...
  function Va (line 9) | function Va(e){return It(e=Me(e),"iterate",Bs),e}
  function Dn (line 9) | function Dn(e,t){return cr(e)?Do(Hn(e)?On(t):t):On(t)}
  method [Symbol.iterator] (line 9) | [Symbol.iterator](){return Sl(this,Symbol.iterator,e=>Dn(this,e))}
  method concat (line 9) | concat(...e){return _o(this).concat(...e.map(t=>pe(t)?_o(t):t))}
  method entries (line 9) | entries(){return Sl(this,"entries",e=>(e[1]=Dn(this,e[1]),e))}
  method every (line 9) | every(e,t){return Yn(this,"every",e,t,void 0,arguments)}
  method filter (line 9) | filter(e,t){return Yn(this,"filter",e,t,n=>n.map(r=>Dn(this,r)),arguments)}
  method find (line 9) | find(e,t){return Yn(this,"find",e,t,n=>Dn(this,n),arguments)}
  method findIndex (line 9) | findIndex(e,t){return Yn(this,"findIndex",e,t,void 0,arguments)}
  method findLast (line 9) | findLast(e,t){return Yn(this,"findLast",e,t,n=>Dn(this,n),arguments)}
  method findLastIndex (line 9) | findLastIndex(e,t){return Yn(this,"findLastIndex",e,t,void 0,arguments)}
  method forEach (line 9) | forEach(e,t){return Yn(this,"forEach",e,t,void 0,arguments)}
  method includes (line 9) | includes(...e){return El(this,"includes",e)}
  method indexOf (line 9) | indexOf(...e){return El(this,"indexOf",e)}
  method join (line 9) | join(e){return _o(this).join(e)}
  method lastIndexOf (line 9) | lastIndexOf(...e){return El(this,"lastIndexOf",e)}
  method map (line 9) | map(e,t){return Yn(this,"map",e,t,void 0,arguments)}
  method pop (line 9) | pop(){return ls(this,"pop")}
  method push (line 9) | push(...e){return ls(this,"push",e)}
  method reduce (line 9) | reduce(e,...t){return sf(this,"reduce",e,t)}
  method reduceRight (line 9) | reduceRight(e,...t){return sf(this,"reduceRight",e,t)}
  method shift (line 9) | shift(){return ls(this,"shift")}
  method some (line 9) | some(e,t){return Yn(this,"some",e,t,void 0,arguments)}
  method splice (line 9) | splice(...e){return ls(this,"splice",e)}
  method toReversed (line 9) | toReversed(){return _o(this).toReversed()}
  method toSorted (line 9) | toSorted(e){return _o(this).toSorted(e)}
  method toSpliced (line 9) | toSpliced(...e){return _o(this).toSpliced(...e)}
  method unshift (line 9) | unshift(...e){return ls(this,"unshift",e)}
  method values (line 9) | values(){return Sl(this,"values",e=>Dn(this,e))}
  function Sl (line 9) | function Sl(e,t,n){const r=Va(e),o=r[t]();return r!==e&&!Qt(e)&&(o._next...
  function Yn (line 9) | function Yn(e,t,n,r,o,s){const i=Va(e),a=i!==e&&!Qt(e),l=i[t];if(l!==uy[...
  function sf (line 9) | function sf(e,t,n,r){const o=Va(e),s=o!==e&&!Qt(e);let i=n,a=!1;o!==e&&(...
  function El (line 9) | function El(e,t,n){const r=Me(e);It(r,"iterate",Bs);const o=r[t](...n);r...
  function ls (line 9) | function ls(e,t,n=[]){lr(),Yu();const r=Me(e)[t].apply(e,n);return Ju(),...
  function fy (line 9) | function fy(e){Tn(e)||(e=String(e));const t=Me(this);return It(t,"has",e...
  class $h (line 9) | class $h{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get...
    method constructor (line 9) | constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}
    method get (line 9) | get(t,n,r){if(n==="__v_skip")return t.__v_skip;const o=this._isReadonl...
  class kh (line 9) | class kh extends $h{constructor(t=!1){super(!1,t)}set(t,n,r,o){let s=t[n...
    method constructor (line 9) | constructor(t=!1){super(!1,t)}
    method set (line 9) | set(t,n,r,o){let s=t[n];const i=pe(t)&&Ma(n);if(!this._isShallow){cons...
    method deleteProperty (line 9) | deleteProperty(t,n){const r=Ve(t,n);t[n];const o=Reflect.deletePropert...
    method has (line 9) | has(t,n){const r=Reflect.has(t,n);return(!Tn(n)||!Mh.has(n))&&It(t,"ha...
    method ownKeys (line 9) | ownKeys(t){return It(t,"iterate",pe(t)?"length":oo),Reflect.ownKeys(t)}
  class dy (line 9) | class dy extends $h{constructor(t=!1){super(!0,t)}set(t,n){return!0}dele...
    method constructor (line 9) | constructor(t=!1){super(!0,t)}
    method set (line 9) | set(t,n){return!0}
    method deleteProperty (line 9) | deleteProperty(t,n){return!0}
  function my (line 9) | function my(e,t,n){return function(...r){const o=this.__v_raw,s=Me(o),i=...
  function Ti (line 9) | function Ti(e){return function(...t){return e==="delete"?!1:e==="clear"?...
  function gy (line 9) | function gy(e,t){const n={get(o){const s=this.__v_raw,i=Me(s),a=Me(o);e|...
  function Zu (line 9) | function Zu(e,t){const n=gy(e,t);return(r,o,s)=>o==="__v_isReactive"?!e:...
  function Ey (line 9) | function Ey(e){switch(e){case"Object":case"Array":return 1;case"Map":cas...
  function _y (line 9) | function _y(e){return e.__v_skip||!Object.isExtensible(e)?0:Ey(Ui(e))}
  function wt (line 9) | function wt(e){return cr(e)?e:ec(e,!1,py,by,Fh)}
  function Qu (line 9) | function Qu(e){return ec(e,!1,vy,yy,Bh)}
  function Mr (line 9) | function Mr(e){return ec(e,!0,hy,wy,Dh)}
  function ec (line 9) | function ec(e,t,n,r,o){if(!Oe(e)||e.__v_raw&&!(t&&e.__v_isReactive))retu...
  function Hn (line 9) | function Hn(e){return cr(e)?Hn(e.__v_raw):!!(e&&e.__v_isReactive)}
  function cr (line 9) | function cr(e){return!!(e&&e.__v_isReadonly)}
  function Qt (line 9) | function Qt(e){return!!(e&&e.__v_isShallow)}
  function ja (line 9) | function ja(e){return e?!!e.__v_raw:!1}
  function Me (line 9) | function Me(e){const t=e&&e.__v_raw;return t?Me(t):e}
  function Ds (line 9) | function Ds(e){return!Ve(e,"__v_skip")&&Object.isExtensible(e)&&yh(e,"__...
  function Ue (line 9) | function Ue(e){return e?e.__v_isRef===!0:!1}
  function V (line 9) | function V(e){return Vh(e,!1)}
  function ir (line 9) | function ir(e){return Vh(e,!0)}
  function Vh (line 9) | function Vh(e,t){return Ue(e)?e:new Cy(e,t)}
  class Cy (line 9) | class Cy{constructor(t,n){this.dep=new Da,this.__v_isRef=!0,this.__v_isS...
    method constructor (line 9) | constructor(t,n){this.dep=new Da,this.__v_isRef=!0,this.__v_isShallow=...
    method value (line 9) | get value(){return this.dep.track(),this._value}
    method value (line 9) | set value(t){const n=this._rawValue,r=this.__v_isShallow||Qt(t)||cr(t)...
  function g (line 9) | function g(e){return Ue(e)?e.value:e}
  function jh (line 9) | function jh(e){return Hn(e)?e:new Proxy(e,Ty)}
  class Oy (line 9) | class Oy{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=thi...
    method constructor (line 9) | constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=n...
    method value (line 9) | get value(){return this._value=this._get()}
    method value (line 9) | set value(t){this._set(t)}
  function Ay (line 9) | function Ay(e){return new Oy(e)}
  function vr (line 9) | function vr(e){const t=pe(e)?new Array(e.length):{};for(const n in e)t[n...
  class Ry (line 9) | class Ry{constructor(t,n,r){this._object=t,this._key=n,this._defaultValu...
    method constructor (line 9) | constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,thi...
    method value (line 9) | get value(){let t=this._object[this._key];return this._shallow&&(t=g(t...
    method value (line 9) | set value(t){if(this._shallow&&Ue(this._raw[this._key])){const n=this....
    method dep (line 9) | get dep(){return ay(this._raw,this._key)}
  class xy (line 9) | class xy{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isRead...
    method constructor (line 9) | constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0...
    method value (line 9) | get value(){return this._value=this._getter()}
  function Jt (line 9) | function Jt(e,t,n){return Ue(e)?e:ve(e)?new xy(e):Oe(e)&&arguments.lengt...
  function zh (line 9) | function zh(e,t,n){return new Ry(e,t,n)}
  class Iy (line 9) | class Iy{constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,t...
    method constructor (line 9) | constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,this.dep...
    method notify (line 9) | notify(){if(this.flags|=16,!(this.flags&8)&&et!==this)return Rh(this,!...
    method value (line 9) | get value(){const t=this.dep.track();return Ph(this),t&&(t.version=thi...
    method value (line 9) | set value(t){this.setter&&this.setter(t)}
  function Py (line 9) | function Py(e,t,n=!1){let r,o;return ve(e)?r=e:(r=e.get,o=e.set),new Iy(...
  function Ny (line 9) | function Ny(e,t=!1,n=Jr){if(n){let r=la.get(n);r||la.set(n,r=[]),r.push(...
  function Ly (line 9) | function Ly(e,t,n=Ye){const{immediate:r,deep:o,once:s,scheduler:i,augmen...
  function rr (line 9) | function rr(e,t=1/0,n){if(t<=0||!Oe(e)||e.__v_skip||(n=n||new Map,(n.get...
  function ai (line 13) | function ai(e,t,n,r){try{return r?e(...r):e()}catch(o){za(o,t,n)}}
  function An (line 13) | function An(e,t,n,r){if(ve(e)){const o=ai(e,t,n,r);return o&&ia(o)&&o.ca...
  function za (line 13) | function za(e,t,n,r=!0){const o=t?t.vnode:null,{errorHandler:s,throwUnha...
  function My (line 13) | function My(e,t,n,r=!0,o=!1){if(o)throw e}
  function Ie (line 13) | function Ie(e){const t=ua||Hh;return e?t.then(this?e.bind(this):e):t}
  function $y (line 13) | function $y(e){let t=kn+1,n=Ft.length;for(;t<n;){const r=t+n>>>1,o=Ft[r]...
  function tc (line 13) | function tc(e){if(!(e.flags&1)){const t=Vs(e),n=Ft[Ft.length-1];!n||!(e....
  function Uh (line 13) | function Uh(){ua||(ua=Hh.then(Wh))}
  function Kh (line 13) | function Kh(e){pe(e)?ko.push(...e):xr&&e.id===-1?xr.splice(xo+1,0,e):e.f...
  function af (line 13) | function af(e,t,n=kn+1){for(;n<Ft.length;n++){const r=Ft[n];if(r&&r.flag...
  function qh (line 13) | function qh(e){if(ko.length){const t=[...new Set(ko)].sort((n,r)=>Vs(n)-...
  function Wh (line 13) | function Wh(e){try{for(kn=0;kn<Ft.length;kn++){const t=Ft[kn];t&&!(t.fla...
  function ca (line 13) | function ca(e){const t=Ct;return Ct=e,Gh=e&&e.type.__scopeId||null,t}
  function ce (line 13) | function ce(e,t=Ct,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&pa(-1)...
  function ct (line 13) | function ct(e,t){if(Ct===null)return e;const n=Ga(Ct),r=e.dirs||(e.dirs=...
  function Ur (line 13) | function Ur(e,t,n,r){const o=e.dirs,s=t&&t.dirs;for(let i=0;i<o.length;i...
  function ft (line 13) | function ft(e,t){if(Pt){let n=Pt.provides;const r=Pt.parent&&Pt.parent.p...
  function Ee (line 13) | function Ee(e,t,n=!1){const r=Ge();if(r||so){let o=so?so._context.provid...
  function ky (line 13) | function ky(){return!!(Ge()||so)}
  function Ha (line 13) | function Ha(e,t){return nc(e,null,t)}
  function he (line 13) | function he(e,t,n){return nc(e,t,n)}
  function nc (line 13) | function nc(e,t,n=Ye){const{immediate:r,deep:o,flush:s,once:i}=n,a=vt({}...
  function Dy (line 13) | function Dy(e,t,n){const r=this.proxy,o=Ae(e)?e.includes(".")?Yh(r,e):()...
  function Yh (line 13) | function Yh(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;o<n...
  method process (line 13) | process(e,t,n,r,o,s,i,a,l,u){const{mc:c,pc:f,pbc:d,o:{insert:v,querySele...
  method remove (line 13) | remove(e,t,n,{um:r,o:{remove:o}},s){const{shapeFlag:i,children:a,anchor:...
  function Ai (line 13) | function Ai(e,t,n,{o:{insert:r},m:o},s=2){s===0&&r(e.targetAnchor,t,n);c...
  function Vy (line 13) | function Vy(e,t,n,r,o,s,{o:{nextSibling:i,parentNode:a,querySelector:l,i...
  function Wi (line 13) | function Wi(e,t){const n=e.ctx;if(n&&n.ut){let r,o;for(t?(r=e.el,o=e.anc...
  function ou (line 13) | function ou(e,t,n,r,o=null){const s=t.targetStart=n(""),i=t.targetAnchor...
  function Qh (line 13) | function Qh(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leaving...
  method setup (line 13) | setup(e,{slots:t}){const n=Ge(),r=Qh();return()=>{const o=t.default&&rc(...
  function nv (line 13) | function nv(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==_t...
  function rv (line 13) | function rv(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||...
  function js (line 13) | function js(e,t,n,r,o){const{appear:s,mode:i,persisted:a=!1,onBeforeEnte...
  function _l (line 13) | function _l(e){if(Ua(e))return e=fr(e),e.children=null,e}
  function ff (line 13) | function ff(e){if(!Ua(e))return Xh(e.type)&&e.children?nv(e.children):e;...
  function uo (line 13) | function uo(e,t){e.shapeFlag&6&&e.component?(e.transition=t,uo(e.compone...
  function rc (line 13) | function rc(e,t=!1,n){let r=[],o=0;for(let s=0;s<e.length;s++){let i=e[s...
  function Z (line 13) | function Z(e,t){return ve(e)?vt({name:e.name},t,{setup:e}):e}
  function ov (line 13) | function ov(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}
  function df (line 13) | function df(e,t){let n;return!!((n=Object.getOwnPropertyDescriptor(e,t))...
  function Cs (line 13) | function Cs(e,t,n,r,o=!1){if(pe(e)){e.forEach((h,b)=>Cs(h,t&&(pe(t)?t[b]...
  function pf (line 13) | function pf(e){const t=fa.get(e);t&&(t.flags|=8,fa.delete(e))}
  function Ka (line 13) | function Ka(e,t){sv(e,"a",t)}
  function oc (line 13) | function oc(e,t){sv(e,"da",t)}
  function sv (line 13) | function sv(e,t,n=Pt){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if...
  function Uy (line 13) | function Uy(e,t,n,r){const o=qa(t,e,r,!0);kr(()=>{Wu(r[t],o)},n)}
  function qa (line 13) | function qa(e,t,n=Pt,r=!1){if(n){const o=n[e]||(n[e]=[]),s=t.__weh||(t._...
  function Gy (line 13) | function Gy(e,t=Pt){qa("ec",e,t)}
  function Yt (line 13) | function Yt(e,t){return ac(ic,e,!0,t)||e}
  function Xe (line 13) | function Xe(e){return Ae(e)?ac(ic,e,!1)||e:e||av}
  function Jy (line 13) | function Jy(e){return ac(Yy,e)}
  function ac (line 13) | function ac(e,t,n=!0,r=!1){const o=Ct||Pt;if(o){const s=o.type;if(e===ic...
  function hf (line 13) | function hf(e,t){return e&&(e[t]||e[Mt(t)]||e[si(Mt(t))])}
  function vf (line 13) | function vf(e,t,n,r){let o;const s=n,i=pe(e);if(i||Ae(e)){const a=i&&Hn(...
  function lv (line 13) | function lv(e,t){for(let n=0;n<t.length;n++){const r=t[n];if(pe(r))for(l...
  function de (line 13) | function de(e,t,n={},r,o){if(Ct.ce||Ct.parent&&Fo(Ct.parent)&&Ct.parent....
  function uv (line 13) | function uv(e){return e.some(t=>cn(t)?!(t.type===_t||t.type===nt&&!uv(t....
  method get (line 13) | get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:r,data:o,...
  method set (line 13) | set({_:e},t,n){const{data:r,setupState:o,ctx:s}=e;return Cl(o,t)?(o[t]=n...
  method has (line 13) | has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,props:s,typ...
  method defineProperty (line 13) | defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Ve(n,"valu...
  function go (line 13) | function go(){return cv().slots}
  function Zy (line 13) | function Zy(){return cv().attrs}
  function cv (line 13) | function cv(e){const t=Ge();return t.setupContext||(t.setupContext=Pv(t))}
  function mf (line 13) | function mf(e){return pe(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}
  function Qy (line 13) | function Qy(e){const t=dv(e),n=e.proxy,r=e.ctx;iu=!1,t.beforeCreate&&gf(...
  function e0 (line 13) | function e0(e,t,n=ht){pe(e)&&(e=au(e));for(const r in e){const o=e[r];le...
  function gf (line 13) | function gf(e,t,n){An(pe(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}
  function fv (line 13) | function fv(e,t,n,r){let o=r.includes(".")?Yh(n,r):()=>n[r];if(Ae(e)){co...
  function dv (line 13) | function dv(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCa...
  function da (line 13) | function da(e,t,n,r=!1){const{mixins:o,extends:s}=t;s&&da(e,s,n,!0),o&&o...
  function bf (line 13) | function bf(e,t){return t?e?function(){return vt(ve(e)?e.call(this,this)...
  function n0 (line 13) | function n0(e,t){return gs(au(e),au(t))}
  function au (line 13) | function au(e){if(pe(e)){const t={};for(let n=0;n<e.length;n++)t[e[n]]=e...
  function $t (line 13) | function $t(e,t){return e?[...new Set([].concat(e,t))]:t}
  function gs (line 13) | function gs(e,t){return e?vt(Object.create(null),e,t):t}
  function yf (line 13) | function yf(e,t){return e?pe(e)&&pe(t)?[...new Set([...e,...t])]:vt(Obje...
  function r0 (line 13) | function r0(e,t){if(!e)return t;if(!t)return e;const n=vt(Object.create(...
  function pv (line 13) | function pv(){return{app:null,config:{isNativeTag:mh,performance:!1,glob...
  function s0 (line 13) | function s0(e,t){return function(r,o=null){ve(r)||(r=vt({},r)),o!=null&&...
  function a0 (line 13) | function a0(e,t,...n){if(e.isUnmounted)return;const r=e.vnode.props||Ye;...
  function hv (line 13) | function hv(e,t,n=!1){const r=n?l0:t.emitsCache,o=r.get(e);if(o!==void 0...
  function Wa (line 13) | function Wa(e,t){return!e||!Na(t)?!1:(t=t.slice(2).replace(/Once$/,""),V...
  function wf (line 13) | function wf(e){const{type:t,vnode:n,proxy:r,withProxy:o,propsOptions:[s]...
  function f0 (line 13) | function f0(e,t,n){const{props:r,children:o,component:s}=e,{props:i,chil...
  function Sf (line 13) | function Sf(e,t,n){const r=Object.keys(t);if(r.length!==Object.keys(e).l...
  function vv (line 13) | function vv(e,t,n){const r=e[n],o=t[n];return n==="style"&&Oe(r)&&Oe(o)?...
  function d0 (line 13) | function d0({vnode:e,parent:t},n){for(;t;){const r=t.subTree;if(r.suspen...
  function p0 (line 13) | function p0(e,t,n,r=!1){const o={},s=gv();e.propsDefaults=Object.create(...
  function h0 (line 13) | function h0(e,t,n,r){const{props:o,attrs:s,vnode:{patchFlag:i}}=e,a=Me(o...
  function yv (line 13) | function yv(e,t,n,r){const[o,s]=e.propsOptions;let i=!1,a;if(t)for(let l...
  function lu (line 13) | function lu(e,t,n,r,o,s){const i=e[n];if(i!=null){const a=Ve(i,"default"...
  function wv (line 13) | function wv(e,t,n=!1){const r=n?v0:t.propsCache,o=r.get(e);if(o)return o...
  function Ef (line 13) | function Ef(e){return e[0]!=="$"&&!ws(e)}
  function y0 (line 13) | function y0(e){return w0(e)}
  function w0 (line 13) | function w0(e,t){const n=ka();n.__VUE__=!0;const{insert:r,remove:o,patch...
  function Tl (line 13) | function Tl({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n...
  function Kr (line 13) | function Kr({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33...
  function S0 (line 13) | function S0(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}
  function cc (line 13) | function cc(e,t,n=!1){const r=e.children,o=t.children;if(pe(r)&&pe(o))fo...
  function E0 (line 13) | function E0(e){const t=e.slice(),n=[0];let r,o,s,i,a;const l=e.length;fo...
  function Cv (line 13) | function Cv(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.as...
  function _f (line 13) | function _f(e){if(e)for(let t=0;t<e.length;t++)e[t].flags|=8}
  function Tv (line 13) | function Tv(e){if(e.placeholder)return e.placeholder;const t=e.component...
  function _0 (line 13) | function _0(e,t){t&&t.pendingBranch?pe(e)?t.effects.push(...e):t.effects...
  function L (line 13) | function L(e=!1){Os.push(Xt=e?null:[])}
  function C0 (line 13) | function C0(){Os.pop(),Xt=Os[Os.length-1]||null}
  function pa (line 13) | function pa(e,t=!1){zs+=e,e<0&&Xt&&t&&(Xt.hasOnce=!0)}
  function Av (line 13) | function Av(e){return e.dynamicChildren=zs>0?Xt||Mo:null,C0(),zs>0&&Xt&&...
  function ee (line 13) | function ee(e,t,n,r,o,s){return Av(le(e,t,n,r,o,s,!0))}
  function fe (line 13) | function fe(e,t,n,r,o){return Av(re(e,t,n,r,o,!0))}
  function cn (line 13) | function cn(e){return e?e.__v_isVNode===!0:!1}
  function Xr (line 13) | function Xr(e,t){return e.type===t.type&&e.key===t.key}
  function le (line 13) | function le(e,t=null,n=null,r=0,o=null,s=e===nt?0:1,i=!1,a=!1){const l={...
  function T0 (line 13) | function T0(e,t=null,n=null,r=0,o=null,s=!1){if((!e||e===av)&&(e=_t),cn(...
  function O0 (line 13) | function O0(e){return e?ja(e)||bv(e)?vt({},e):e:null}
  function fr (line 13) | function fr(e,t,n=!1,r=!1){const{props:o,ref:s,patchFlag:i,children:a,tr...
  function Un (line 13) | function Un(e=" ",t=0){return re(Zo,null,e,t)}
  function ae (line 13) | function ae(e="",t=!1){return t?(L(),fe(_t,null,e)):re(_t,null,e)}
  function Vn (line 13) | function Vn(e){return e==null||typeof e=="boolean"?re(_t):pe(e)?re(nt,nu...
  function tr (line 13) | function tr(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:fr(e)}
  function fc (line 13) | function fc(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(...
  function En (line 13) | function En(...e){const t={};for(let n=0;n<e.length;n++){const r=e[n];fo...
  function Mn (line 13) | function Mn(e,t,n,r=null){An(e,t,7,[n,r])}
  function x0 (line 13) | function x0(e,t,n){const r=e.type,o=(t?t.appContext:e.appContext)||A0,s=...
  function xv (line 13) | function xv(e){return e.vnode.shapeFlag&4}
  function I0 (line 13) | function I0(e,t=!1,n=!1){t&&uu(t);const{props:r,children:o}=e.vnode,s=xv...
  function P0 (line 13) | function P0(e,t){const n=e.type;e.accessCache=Object.create(null),e.prox...
  function Tf (line 13) | function Tf(e,t,n){ve(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render...
  function Iv (line 13) | function Iv(e,t,n){const r=e.type;e.render||(e.render=r.render||ht);{con...
  method get (line 13) | get(e,t){return It(e,"get",""),e[t]}
  function Pv (line 13) | function Pv(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.att...
  function Ga (line 13) | function Ga(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(...
  function L0 (line 13) | function L0(e,t=!0){return ve(e)?e.displayName||e.name:e.name||t&&e.__name}
  function M0 (line 13) | function M0(e){return ve(e)&&"__vccOpts"in e}
  function or (line 13) | function or(e,t,n){try{pa(-1);const r=arguments.length;return r===2?Oe(t...
  method setScopeId (line 17) | setScopeId(e,t){e.setAttribute(t,"")}
  method insertStaticContent (line 17) | insertStaticContent(e,t,n,r,o,s){const i=n?n.previousSibling:t.lastChild...
  function $v (line 17) | function $v(e){const t={};for(const $ in e)$ in Lv||(t[$]=e[$]);if(e.css...
  function j0 (line 17) | function j0(e){if(e==null)return null;if(Oe(e))return[Ol(e.enter),Ol(e.l...
  function Ol (line 17) | function Ol(e){return Jb(e)}
  function $n (line 17) | function $n(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Vo]...
  function Cr (line 17) | function Cr(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));con...
  function xf (line 17) | function xf(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}
  function If (line 17) | function If(e,t,n,r){const o=e._endId=++z0,s=()=>{o===e._endId&&r()};if(...
  function kv (line 17) | function kv(e,t){const n=window.getComputedStyle(e),r=p=>(n[p]||"").spli...
  function Pf (line 17) | function Pf(e,t){for(;e.length<t.length;)e=e.concat(e);return Math.max(....
  function Nf (line 17) | function Nf(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",",".")...
  function fu (line 17) | function fu(e){return(e?e.ownerDocument:document).body.offsetHeight}
  function H0 (line 17) | function H0(e,t,n){const r=e[Vo];r&&(t=(t?[t,...r]:[...r]).join(" ")),t=...
  method beforeMount (line 17) | beforeMount(e,{value:t},{transition:n}){e[va]=e.style.display==="none"?"...
  method mounted (line 17) | mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)}
  method updated (line 17) | updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnt...
  method beforeUnmount (line 17) | beforeUnmount(e,{value:t}){fs(e,t)}
  function fs (line 17) | function fs(e,t){e.style.display=t?e[va]:"none",e[Fv]=!t}
  function bN (line 17) | function bN(e){const t=Ge();if(!t)return;const n=t.ut=(o=e(t.proxy))=>{A...
  function du (line 17) | function du(e,t){if(e.shapeFlag&128){const n=e.suspense;e=n.activeBranch...
  function ma (line 17) | function ma(e,t){if(e.nodeType===1){const n=e.style;let r="";for(const o...
  function K0 (line 17) | function K0(e,t,n){const r=e.style,o=Ae(n);let s=!1;if(n&&!o){if(t)if(Ae...
  function Ji (line 17) | function Ji(e,t,n){if(pe(n))n.forEach(r=>Ji(e,t,r));else if(n==null&&(n=...
  function q0 (line 17) | function q0(e,t){const n=Al[t];if(n)return n;let r=Mt(t);if(r!=="filter"...
  function kf (line 17) | function kf(e,t,n,r,o,s=ny(t)){r&&t.startsWith("xlink:")?n==null?e.remov...
  function Ff (line 17) | function Ff(e,t,n,r,o){if(t==="innerHTML"||t==="textContent"){n!=null&&(...
  function Zr (line 17) | function Zr(e,t,n,r){e.addEventListener(t,n,r)}
  function W0 (line 17) | function W0(e,t,n,r){e.removeEventListener(t,n,r)}
  function G0 (line 17) | function G0(e,t,n,r,o=null){const s=e[Bf]||(e[Bf]={}),i=s[t];if(r&&i)i.v...
  function Y0 (line 17) | function Y0(e){let t;if(Df.test(e)){t={};let r;for(;r=e.match(Df);)e=e.s...
  function Z0 (line 17) | function Z0(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts...
  function Q0 (line 17) | function Q0(e,t){if(pe(t)){const n=e.stopImmediatePropagation;return e.s...
  function tw (line 17) | function tw(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t...
  function nw (line 17) | function nw(e,t){const n=e._def.props;if(!n)return!1;const r=Mt(t);retur...
  method setup (line 17) | setup(e,{slots:t}){const n=Ge(),r=Qh();let o,s;return mo(()=>{if(!o.leng...
  function iw (line 17) | function iw(e){const t=e.el;t[ga]&&t[ga](),t[jf]&&t[jf]()}
  function aw (line 17) | function aw(e){Vv.set(e,jv(e.el))}
  function lw (line 17) | function lw(e){const t=Dv.get(e),n=Vv.get(e),r=t.left-n.left,o=t.top-n.t...
  function jv (line 17) | function jv(e){const t=e.getBoundingClientRect();return{left:t.left,top:...
  function uw (line 17) | function uw(e,t,n){const r=e.cloneNode(),o=e[Vo];o&&o.forEach(a=>{a.spli...
  function cw (line 17) | function cw(e){e.target.composing=!0}
  function zf (line 17) | function zf(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchE...
  function Hf (line 17) | function Hf(e,t,n){return t&&(e=e.trim()),n&&(e=Gu(e)),e}
  method created (line 17) | created(e,{modifiers:{lazy:t,trim:n,number:r}},o){e[Bo]=ba(o);const s=r|...
  method mounted (line 17) | mounted(e,{value:t}){e.value=t??""}
  method beforeUpdate (line 17) | beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:r,trim:o,number:s}},i...
  method created (line 17) | created(e,t,n){e[Bo]=ba(n),Zr(e,"change",()=>{const r=e._modelValue,o=dw...
  method beforeUpdate (line 17) | beforeUpdate(e,t,n){e[Bo]=ba(n),Uf(e,t,n)}
  function Uf (line 17) | function Uf(e,{value:t,oldValue:n},r){e._modelValue=t;let o;if(pe(t))o=S...
  function dw (line 17) | function dw(e){return"_value"in e?e._value:e.value}
  function zv (line 17) | function zv(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}
  function Hv (line 17) | function Hv(){return Kf||(Kf=y0(mw))}
  function bw (line 17) | function bw(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLEl...
  function yw (line 17) | function yw(e){return Ae(e)?document.querySelector(e):e}
  function Uv (line 21) | function Uv(e){return typeof e=="object"||"displayName"in e||"props"in e...
  function ww (line 21) | function ww(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e....
  function xl (line 21) | function xl(e,t){const n={};for(const r in t){const o=t[r];n[r]=Rn(o)?o....
  function qf (line 21) | function qf(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];retur...
  function dc (line 21) | function dc(e){return e==null?"":encodeURI(""+e).replace(Rw,"|").replace...
  function Iw (line 21) | function Iw(e){return dc(e).replace(Gv,"{").replace(Yv,"}").replace(Wv,"...
  function pu (line 21) | function pu(e){return dc(e).replace(qv,"%2B").replace(xw,"+").replace(Kv...
  function Pw (line 21) | function Pw(e){return pu(e).replace(_w,"%3D")}
  function Nw (line 21) | function Nw(e){return dc(e).replace(Kv,"%23").replace(Cw,"%3F")}
  function Lw (line 21) | function Lw(e){return Nw(e).replace(Ew,"%2F")}
  function Us (line 21) | function Us(e){if(e==null)return null;try{return decodeURIComponent(""+e...
  function Il (line 21) | function Il(e,t,n="/"){let r,o={},s="",i="";const a=t.indexOf("#");let l...
  function kw (line 21) | function kw(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+...
  function Wf (line 21) | function Wf(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?...
  function Fw (line 21) | function Fw(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;retur...
  function jo (line 21) | function jo(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}
  function Jv (line 21) | function Jv(e,t){if(Object.keys(e).length!==Object.keys(t).length)return...
  function Bw (line 21) | function Bw(e,t){return Rn(e)?Gf(e,t):Rn(t)?Gf(t,e):(e==null?void 0:e.va...
  function Gf (line 21) | function Gf(e,t){return Rn(t)?e.length===t.length&&e.every((n,r)=>n===t[...
  function Dw (line 21) | function Dw(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t....
  function Vw (line 21) | function Vw(e){if(!e)if(Io){const t=document.querySelector("base");e=t&&...
  function zw (line 21) | function zw(e,t){return e.replace(jw,"#")+t}
  function Hw (line 21) | function Hw(e,t){const n=document.documentElement.getBoundingClientRect(...
  function Uw (line 21) | function Uw(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.s...
  function Yf (line 21) | function Yf(e,t){return(history.state?history.state.position-t:-1)+e}
  function Kw (line 21) | function Kw(e,t){vu.set(e,t)}
  function qw (line 21) | function qw(e){const t=vu.get(e);return vu.delete(e),t}
  function Ww (line 21) | function Ww(e){return typeof e=="string"||e&&typeof e=="object"}
  function Xv (line 21) | function Xv(e){return typeof e=="string"||typeof e=="symbol"}
  function zo (line 21) | function zo(e,t){return We(new Error,{type:e,[Zv]:!0},t)}
  function Jn (line 21) | function Jn(e,t){return e instanceof Error&&Zv in e&&(t==null||!!(e.type...
  function Yw (line 21) | function Yw(e){if(typeof e=="string")return e;if(e.path!=null)return e.p...
  function Jw (line 21) | function Jw(e){const t={};if(e===""||e==="?")return t;const n=(e[0]==="?...
  function Jf (line 21) | function Jf(e){let t="";for(let n in e){const r=e[n];if(n=Pw(n),r==null)...
  function Xw (line 21) | function Xw(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[...
  function ds (line 21) | function ds(){let e=[];function t(r){return e.push(r),()=>{const o=e.ind...
  function Zw (line 21) | function Zw(e,t,n){const r=()=>{e[t].delete(n)};kr(r),oc(r),Ka(()=>{e[t]...
  function yN (line 21) | function yN(e){const t=Ee(Qv,{}).value;t&&Zw(t,"leaveGuards",e)}
  function Ir (line 21) | function Ir(e,t,n,r,o,s=i=>i()){const i=r&&(r.enterCallbacks[o]=r.enterC...
  function Nl (line 21) | function Nl(e,t,n,r,o=s=>s()){const s=[];for(const i of e)for(const a in...
  function Qw (line 21) | function Qw(e,t){const n=[],r=[],o=[],s=Math.max(t.matched.length,e.matc...
  function tm (line 25) | function tm(e,t){const{pathname:n,search:r,hash:o}=t,s=e.indexOf("#");if...
  function t1 (line 25) | function t1(e,t,n,r){let o=[],s=[],i=null;const a=({state:d})=>{const v=...
  function Zf (line 25) | function Zf(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:...
  function n1 (line 25) | function n1(e){const{history:t,location:n}=window,r={value:tm(e,n)},o={v...
  function r1 (line 25) | function r1(e){e=Vw(e);const t=n1(e),n=t1(e,t.state,t.location,t.replace...
  function wN (line 25) | function wN(e){return e=location.host?e||location.pathname+location.sear...
  function i1 (line 25) | function i1(e){if(!e)return[[]];if(e==="/")return[[o1]];if(!e.startsWith...
  function u1 (line 25) | function u1(e,t){const n=We({},a1,t),r=[];let o=n.start?"^":"";const s=[...
  function c1 (line 25) | function c1(e,t){let n=0;for(;n<e.length&&n<t.length;){const r=t[n]-e[n]...
  function nm (line 25) | function nm(e,t){let n=0;const r=e.score,o=t.score;for(;n<r.length&&n<o....
  function ed (line 25) | function ed(e){const t=e[e.length-1];return e.length>0&&t[t.length-1]<0}
  function d1 (line 25) | function d1(e,t,n){const r=u1(i1(e.path),n),o=We(r,{record:e,parent:t,ch...
  function p1 (line 25) | function p1(e,t){const n=[],r=new Map;t=qf(f1,t);function o(f){return r....
  function td (line 25) | function td(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}
  function nd (line 25) | function nd(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta...
  function h1 (line 25) | function h1(e){const t={},n=e.props||!1;if("component"in e)t.default=n;e...
  function rd (line 25) | function rd(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}
  function v1 (line 25) | function v1(e){return e.reduce((t,n)=>We(t,n.meta),{})}
  function m1 (line 25) | function m1(e,t){let n=0,r=t.length;for(;n!==r;){const s=n+r>>1;nm(e,t[s...
  function g1 (line 25) | function g1(e){let t=e;for(;t=t.parent;)if(rm(t)&&nm(e,t)===0)return t}
  function rm (line 25) | function rm({record:e}){return!!(e.name||e.components&&Object.keys(e.com...
  function od (line 25) | function od(e){const t=Ee(Ja),n=Ee(em),r=C(()=>{const l=g(e.to);return t...
  function b1 (line 25) | function b1(e){return e.length===1?e[0]:e}
  method setup (line 25) | setup(e,{slots:t}){const n=wt(od(e)),{options:r}=Ee(Ja),o=C(()=>({[id(e....
  function S1 (line 25) | function S1(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defa...
  function E1 (line 25) | function E1(e,t){for(const n in t){const r=t[n],o=e[n];if(typeof r=="str...
  function sd (line 25) | function sd(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}
  method setup (line 25) | setup(e,{attrs:t,slots:n}){const r=Ee(mu),o=C(()=>e.route||r.value),s=Ee...
  function ad (line 25) | function ad(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}
  function SN (line 25) | function SN(e){const t=p1(e.routes,e),n=e.parseQuery||Jw,r=e.stringifyQu...
  function EN (line 25) | function EN(){return Ee(Ja)}
  function fd (line 25) | function fd(e,t){var n;const r=ir();return Ha(()=>{r.value=e()},M1(L1({}...
  function Ks (line 25) | function Ks(e){return typeof e=="function"?e():g(e)}
  function k1 (line 25) | function k1(e,t){function n(...r){return new Promise((o,s)=>{Promise.res...
  function F1 (line 25) | function F1(e,t={}){let n,r,o=Sa;const s=a=>{clearTimeout(a),o(),o=Sa};r...
  function B1 (line 25) | function B1(e){return e}
  function ui (line 25) | function ui(e){return Fa()?(Ba(e),!0):!1}
  function D1 (line 25) | function D1(e,t=200,n={}){return k1(F1(t,n),e)}
  function V1 (line 25) | function V1(e,t=200,n={}){const r=V(e.value),o=D1(()=>{r.value=e.value},...
  function j1 (line 25) | function j1(e,t=!0){Ge()?Ke(e):t?e():Ie(e)}
  function bu (line 25) | function bu(e,t,n={}){const{immediate:r=!0}=n,o=V(!1);let s=null;functio...
  function sr (line 25) | function sr(e){var t;const n=Ks(e);return(t=n==null?void 0:n.$el)!=null?...
  function tn (line 25) | function tn(...e){let t,n,r,o;if($1(e[0])||Array.isArray(e[0])?([n,r,o]=...
  function H1 (line 25) | function H1(e,t,n={}){const{window:r=ci,ignore:o=[],capture:s=!0,detectI...
  function om (line 25) | function om(e,t=!1){const n=V(),r=()=>n.value=!!e();return r(),j1(r,t),n}
  function U1 (line 25) | function U1({document:e=z1}={}){if(!e)return V("visible");const t=V(e.vi...
  function Dt (line 25) | function Dt(e,t,n={}){const r=n,{window:o=ci}=r,s=W1(r,["window"]);let i...
  function X1 (line 25) | function X1(e,t,n={}){const r=n,{window:o=ci}=r,s=J1(r,["window"]);let i...
  function rS (line 25) | function rS({window:e=ci}={}){if(!e)return V(!1);const t=V(e.document.ha...
  function lS (line 25) | function lS(e){var t=iS.call(e,ps),n=e[ps];try{e[ps]=void 0;var r=!0}cat...
  function fS (line 25) | function fS(e){return cS.call(e)}
  function Qo (line 25) | function Qo(e){return e==null?e===void 0?pS:dS:Sd&&Sd in Object(e)?lS(e)...
  function $r (line 25) | function $r(e){return e!=null&&typeof e=="object"}
  function Xa (line 25) | function Xa(e){return typeof e=="symbol"||$r(e)&&Qo(e)==hS}
  function vS (line 25) | function vS(e,t){for(var n=-1,r=e==null?0:e.length,o=Array(r);++n<r;)o[n...
  function am (line 25) | function am(e){if(typeof e=="string")return e;if(dn(e))return vS(e,am)+"...
  function gS (line 25) | function gS(e){for(var t=e.length;t--&&mS.test(e.charAt(t)););return t}
  function yS (line 25) | function yS(e){return e&&e.slice(0,gS(e)+1).replace(bS,"")}
  function xn (line 25) | function xn(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}
  function Td (line 25) | function Td(e){if(typeof e=="number")return e;if(Xa(e))return Cd;if(xn(e...
  function lm (line 25) | function lm(e){return e}
  function um (line 25) | function um(e){if(!xn(e))return!1;var t=Qo(e);return t==TS||t==OS||t==CS...
  function RS (line 25) | function RS(e){return!!Od&&Od in e}
  function bo (line 25) | function bo(e){if(e!=null){try{return IS.call(e)}catch{}try{return e+""}...
  function BS (line 25) | function BS(e){if(!xn(e)||RS(e))return!1;var t=um(e)?FS:NS;return t.test...
  function DS (line 25) | function DS(e,t){return e==null?void 0:e[t]}
  function yo (line 25) | function yo(e,t){var n=DS(e,t);return BS(n)?n:void 0}
  function e (line 25) | function e(){}
  function jS (line 25) | function jS(e,t,n){switch(n.length){case 0:return e.call(t);case 1:retur...
  function zS (line 25) | function zS(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n...
  function qS (line 25) | function qS(e){var t=0,n=0;return function(){var r=KS(),o=US-(r-n);if(n=...
  function WS (line 25) | function WS(e){return function(){return e}}
  function JS (line 25) | function JS(e,t){for(var n=-1,r=e==null?0:e.length;++n<r&&t(e[n],n,e)!==...
  function XS (line 25) | function XS(e,t,n,r){e.length;for(var o=n+1;o--;)if(t(e[o],o,e))return o...
  function pc (line 25) | function pc(e,t){var n=typeof e;return t=t??ZS,!!t&&(n=="number"||n!="sy...
  function cm (line 25) | function cm(e,t,n){t=="__proto__"&&Ea?Ea(e,t,{configurable:!0,enumerable...
  function hc (line 25) | function hc(e,t){return e===t||e!==e&&t!==t}
  function vc (line 25) | function vc(e,t,n){var r=e[t];(!(tE.call(e,t)&&hc(r,n))||n===void 0&&!(t...
  function Za (line 25) | function Za(e,t,n,r){var o=!n;n||(n={});for(var s=-1,i=t.length;++s<i;){...
  function nE (line 25) | function nE(e,t,n){return t=Rd(t===void 0?e.length-1:t,0),function(){for...
  function mc (line 25) | function mc(e){return typeof e=="number"&&e>-1&&e%1==0&&e<=rE}
  function fm (line 25) | function fm(e){return e!=null&&mc(e.length)&&!um(e)}
  function gc (line 25) | function gc(e){var t=e&&e.constructor,n=typeof t=="function"&&t.prototyp...
  function sE (line 25) | function sE(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}
  function xd (line 25) | function xd(e){return $r(e)&&Qo(e)==iE}
  function uE (line 25) | function uE(){return!1}
  function kE (line 25) | function kE(e){return $r(e)&&mc(e.length)&&!!it[Qo(e)]}
  function yc (line 25) | function yc(e){return function(t){return e(t)}}
  function mm (line 25) | function mm(e,t){var n=dn(e),r=!n&&bc(e),o=!n&&!r&&_a(e),s=!n&&!r&&!o&&v...
  function gm (line 25) | function gm(e,t){return function(n){return e(t(n))}}
  function HE (line 25) | function HE(e){if(!gc(e))return VE(e);var t=[];for(var n in Object(e))zE...
  function wc (line 25) | function wc(e){return fm(e)?mm(e):HE(e)}
  function UE (line 25) | function UE(e){var t=[];if(e!=null)for(var n in Object(e))t.push(n);retu...
  function WE (line 25) | function WE(e){if(!xn(e))return UE(e);var t=gc(e),n=[];for(var r in e)r=...
  function GE (line 25) | function GE(e){return fm(e)?mm(e,!0):WE(e)}
  function Sc (line 25) | function Sc(e,t){if(dn(e))return!1;var n=typeof e;return n=="number"||n=...
  function XE (line 25) | function XE(){this.__data__=qs?qs(null):{},this.size=0}
  function ZE (line 25) | function ZE(e){var t=this.has(e)&&delete this.__data__[e];return this.si...
  function n2 (line 25) | function n2(e){var t=this.__data__;if(qs){var n=t[e];return n===QE?void ...
  function s2 (line 25) | function s2(e){var t=this.__data__;return qs?t[e]!==void 0:o2.call(t,e)}
  function a2 (line 25) | function a2(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n...
  function co (line 25) | function co(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){va...
  function l2 (line 25) | function l2(){this.__data__=[],this.size=0}
  function Qa (line 25) | function Qa(e,t){for(var n=e.length;n--;)if(hc(e[n][0],t))return n;retur...
  function f2 (line 25) | function f2(e){var t=this.__data__,n=Qa(t,e);if(n<0)return!1;var r=t.len...
  function d2 (line 25) | function d2(e){var t=this.__data__,n=Qa(t,e);return n<0?void 0:t[n][1]}
  function p2 (line 25) | function p2(e){return Qa(this.__data__,e)>-1}
  function h2 (line 25) | function h2(e,t){var n=this.__data__,r=Qa(n,e);return r<0?(++this.size,n...
  function gr (line 25) | function gr(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){va...
  function v2 (line 25) | function v2(){this.size=0,this.__data__={hash:new co,map:new(Ws||gr),str...
  function m2 (line 25) | function m2(e){var t=typeof e;return t=="string"||t=="number"||t=="symbo...
  function el (line 25) | function el(e,t){var n=e.__data__;return m2(t)?n[typeof t=="string"?"str...
  function g2 (line 25) | function g2(e){var t=el(this,e).delete(e);return this.size-=t?1:0,t}
  function b2 (line 25) | function b2(e){return el(this,e).get(e)}
  function y2 (line 25) | function y2(e){return el(this,e).has(e)}
  function w2 (line 25) | function w2(e,t){var n=el(this,e),r=n.size;return n.set(e,t),this.size+=...
  function br (line 25) | function br(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){va...
  function Ec (line 25) | function Ec(e,t){if(typeof e!="function"||t!=null&&typeof t!="function")...
  function _2 (line 25) | function _2(e){var t=Ec(e,function(r){return n.size===E2&&n.clear(),r}),...
  function A2 (line 25) | function A2(e){return e==null?"":am(e)}
  function tl (line 25) | function tl(e,t){return dn(e)?e:Sc(e,t)?[e]:O2(A2(e))}
  function fi (line 25) | function fi(e){if(typeof e=="string"||Xa(e))return e;var t=e+"";return t...
  function _c (line 25) | function _c(e,t){t=tl(t,e);for(var n=0,r=t.length;e!=null&&n<r;)e=e[fi(t...
  function zn (line 25) | function zn(e,t,n){var r=e==null?void 0:_c(e,t);return r===void 0?n:r}
  function Cc (line 25) | function Cc(e,t){for(var n=-1,r=t.length,o=e.length;++n<r;)e[o+n]=t[n];r...
  function R2 (line 25) | function R2(e){return dn(e)||bc(e)||!!(Ld&&e&&e[Ld])}
  function x2 (line 25) | function x2(e,t,n,r,o){var s=-1,i=e.length;for(n||(n=R2),o||(o=[]);++s<i...
  function I2 (line 25) | function I2(e){var t=e==null?0:e.length;return t?x2(e):[]}
  function P2 (line 25) | function P2(e){return YS(nE(e,void 0,I2),e+"")}
  function yn (line 25) | function yn(){if(!arguments.length)return[];var e=arguments[0];return dn...
  function N2 (line 25) | function N2(){this.__data__=new gr,this.size=0}
  function L2 (line 25) | function L2(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}
  function M2 (line 25) | function M2(e){return this.__data__.get(e)}
  function $2 (line 25) | function $2(e){return this.__data__.has(e)}
  function F2 (line 25) | function F2(e,t){var n=this.__data__;if(n instanceof gr){var r=n.__data_...
  function Kn (line 25) | function Kn(e){var t=this.__data__=new gr(e);this.size=t.size}
  function B2 (line 25) | function B2(e,t){return e&&Za(t,wc(t),e)}
  function D2 (line 25) | function D2(e,t){return e&&Za(t,GE(t),e)}
  function j2 (line 25) | function j2(e,t){var n=e.length,r=kd?kd(n):new e.constructor(n);return e...
  function z2 (line 25) | function z2(e,t){for(var n=-1,r=e==null?0:e.length,o=0,s=[];++n<r;){var ...
  function wm (line 25) | function wm(){return[]}
  function K2 (line 25) | function K2(e,t){return Za(e,Tc(e),t)}
  function G2 (line 25) | function G2(e,t){return Za(e,W2(e),t)}
  function Y2 (line 25) | function Y2(e,t,n){var r=t(e);return dn(e)?r:Cc(r,n(e))}
  function wu (line 25) | function wu(e){return Y2(e,wc,Tc)}
  function o_ (line 25) | function o_(e){var t=e.length,n=new e.constructor(t);return t&&typeof e[...
  function s_ (line 25) | function s_(e){var t=new e.constructor(e.byteLength);return new Ca(t).se...
  function i_ (line 25) | function i_(e,t){var n=e.buffer;return new e.constructor(n,e.byteOffset,...
  function l_ (line 25) | function l_(e){var t=new e.constructor(e.source,a_.exec(e));return t.las...
  function u_ (line 25) | function u_(e){return Ud?Object(Ud.call(e)):{}}
  function c_ (line 25) | function c_(e,t){var n=e.buffer;return new e.constructor(n,e.byteOffset,...
  function I_ (line 25) | function I_(e,t,n){var r=e.constructor;switch(t){case y_:return s_(e);ca...
  function P_ (line 25) | function P_(e){return typeof e.constructor=="function"&&!gc(e)?VS(bm(e))...
  function L_ (line 25) | function L_(e){return $r(e)&&bn(e)==N_}
  function k_ (line 25) | function k_(e){return $r(e)&&bn(e)==$_}
  function Xi (line 25) | function Xi(e,t,n,r,o,s){var i,a=t&B_;if(i!==void 0)return i;if(!xn(e))r...
  function Wd (line 25) | function Wd(e){return Xi(e,lC)}
  function cC (line 25) | function cC(e){return this.__data__.set(e,uC),this}
  function fC (line 25) | function fC(e){return this.__data__.has(e)}
  function Ta (line 25) | function Ta(e){var t=-1,n=e==null?0:e.length;for(this.__data__=new br;++...
  function dC (line 25) | function dC(e,t){for(var n=-1,r=e==null?0:e.length;++n<r;)if(t(e[n],n,e)...
  function pC (line 25) | function pC(e,t){return e.has(t)}
  function Cm (line 25) | function Cm(e,t,n,r,o,s){var i=n&hC,a=e.length,l=t.length;if(a!=l&&!(i&&...
  function mC (line 25) | function mC(e){var t=-1,n=Array(e.size);return e.forEach(function(r,o){n...
  function gC (line 25) | function gC(e){var t=-1,n=Array(e.size);return e.forEach(function(r){n[+...
  function PC (line 25) | function PC(e,t,n,r,o,s,i){switch(n){case IC:if(e.byteLength!=t.byteLeng...
  function $C (line 25) | function $C(e,t,n,r,o,s){var i=n&NC,a=wu(e),l=a.length,u=wu(t),c=u.lengt...
  function BC (line 25) | function BC(e,t,n,r,o,s){var i=dn(e),a=dn(t),l=i?Jd:bn(e),u=a?Jd:bn(t);l...
  function nl (line 25) | function nl(e,t,n,r,o){return e===t?!0:e==null||t==null||!$r(e)&&!$r(t)?...
  function jC (line 25) | function jC(e,t,n,r){var o=n.length,s=o;if(e==null)return!s;for(e=Object...
  function Tm (line 25) | function Tm(e){return e===e&&!xn(e)}
  function zC (line 25) | function zC(e){for(var t=wc(e),n=t.length;n--;){var r=t[n],o=e[r];t[n]=[...
  function Om (line 25) | function Om(e,t){return function(n){return n==null?!1:n[e]===t&&(t!==voi...
  function HC (line 25) | function HC(e){var t=zC(e);return t.length==1&&t[0][2]?Om(t[0][0],t[0][1...
  function UC (line 25) | function UC(e,t){return e!=null&&t in Object(e)}
  function KC (line 25) | function KC(e,t,n){t=tl(t,e);for(var r=-1,o=t.length,s=!1;++r<o;){var i=...
  function Am (line 25) | function Am(e,t){return e!=null&&KC(e,t,UC)}
  function GC (line 25) | function GC(e,t){return Sc(e)&&Tm(t)?Om(fi(e),t):function(n){var r=zn(n,...
  function YC (line 25) | function YC(e){return function(t){return t==null?void 0:t[e]}}
  function JC (line 25) | function JC(e){return function(t){return _c(t,e)}}
  function XC (line 25) | function XC(e){return Sc(e)?YC(fi(e)):JC(e)}
  function ZC (line 25) | function ZC(e){return typeof e=="function"?e:e==null?lm:typeof e=="objec...
  function nT (line 25) | function nT(e,t,n){var r,o,s,i,a,l,u=0,c=!1,f=!1,d=!0;if(typeof e!="func...
  function rT (line 25) | function rT(e,t,n){var r=e==null?0:e.length;if(!r)return-1;var o=r-1;ret...
  function Oa (line 25) | function Oa(e){for(var t=-1,n=e==null?0:e.length,r={};++t<n;){var o=e[t]...
  function Aa (line 25) | function Aa(e,t){return nl(e,t)}
  function qn (line 25) | function qn(e){return e==null}
  function Rm (line 25) | function Rm(e){return e===void 0}
  function xm (line 25) | function xm(e,t,n,r){if(!xn(e))return e;t=tl(t,e);for(var o=-1,s=t.lengt...
  function oT (line 25) | function oT(e,t,n){for(var r=-1,o=t.length,s={};++r<o;){var i=t[r],a=_c(...
  function sT (line 25) | function sT(e,t){return oT(e,t,function(n,r){return Am(e,r)})}
  function iT (line 25) | function iT(e,t,n){return e==null?e:xm(e,t,n)}
  method value (line 25) | get value(){return zn(e,t,n)}
  method value (line 25) | set value(r){iT(e,t,r)}
  class uT (line 25) | class uT extends Error{constructor(t){super(t),this.name="ElementPlusErr...
    method constructor (line 25) | constructor(t){super(t),this.name="ElementPlusError"}
  function Br (line 25) | function Br(e,t){throw new uT(`[${e}] ${t}`)}
  function pn (line 25) | function pn(e,t="px"){if(!e)return"";if(je(e)||aT(e))return`${e}${t}`;if...
  function fT (line 25) | function fT(e,t){if(!st)return;if(!t){e.scrollTop=0;return}const n=[];le...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  method setup (line 25) | setup(e){return(t,n)=>(L(),ee("svg",{xmlns:"http://www.w3.org/2000/svg",...
  function Gn (line 25) | function Gn(e){return e?(e.nodeName||"").toLowerCase():null}
  function nn (line 25) | function nn(e){if(e==null)return window;if(e.toString()!=="[object Windo...
  function po (line 25) | function po(e){var t=nn(e).Element;return e instanceof t||e instanceof E...
  function un (line 25) | function un(e){var t=nn(e).HTMLElement;return e instanceof t||e instance...
  function xc (line 25) | function xc(e){if(typeof ShadowRoot>"u")return!1;var t=nn(e).ShadowRoot;...
  function gO (line 25) | function gO(e){var t=e.state;Object.keys(t.elements).forEach(function(n)...
  function bO (line 25) | function bO(e){var t=e.state,n={popper:{position:t.options.strategy,left...
  function Wn (line 25) | function Wn(e){return e.split("-")[0]}
  function Ou (line 25) | function Ou(){var e=navigator.userAgentData;return e!=null&&e.brands&&Ar...
  function Ym (line 25) | function Ym(){return!/^((?!chrome|android).)*safari/i.test(Ou())}
  function qo (line 25) | function qo(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!1);var r=e.getBoun...
  function Ic (line 25) | function Ic(e){var t=qo(e),n=e.offsetWidth,r=e.offsetHeight;return Math....
  function Jm (line 25) | function Jm(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))r...
  function dr (line 25) | function dr(e){return nn(e).getComputedStyle(e)}
  function yO (line 25) | function yO(e){return["table","td","th"].indexOf(Gn(e))>=0}
  function Dr (line 25) | function Dr(e){return((po(e)?e.ownerDocument:e.document)||window.documen...
  function al (line 25) | function al(e){return Gn(e)==="html"?e:e.assignedSlot||e.parentNode||(xc...
  function tp (line 25) | function tp(e){return!un(e)||dr(e).position==="fixed"?null:e.offsetParent}
  function wO (line 25) | function wO(e){var t=/firefox/i.test(Ou()),n=/Trident/i.test(Ou());if(n&...
  function pi (line 25) | function pi(e){for(var t=nn(e),n=tp(e);n&&yO(n)&&dr(n).position==="stati...
  function Pc (line 25) | function Pc(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}
  function Ps (line 25) | function Ps(e,t,n){return ao(e,xa(t,n))}
  function SO (line 25) | function SO(e,t,n){var r=Ps(e,t,n);return r>n?n:r}
  function Xm (line 25) | function Xm(){return{top:0,right:0,bottom:0,left:0}}
  function Zm (line 25) | function Zm(e){return Object.assign({},Xm(),e)}
  function Qm (line 25) | function Qm(e,t){return t.reduce(function(n,r){return n[r]=e,n},{})}
  function _O (line 25) | function _O(e){var t,n=e.state,r=e.name,o=e.options,s=n.elements.arrow,i...
  function CO (line 25) | function CO(e){var t=e.state,n=e.options,r=n.element,o=r===void 0?"[data...
  function Wo (line 25) | function Wo(e){return e.split("-")[1]}
  function AO (line 25) | function AO(e,t){var n=e.x,r=e.y,o=t.devicePixelRatio||1;return{x:Ko(n*o...
  function np (line 25) | function np(e){var t,n=e.popper,r=e.popperRect,o=e.placement,s=e.variati...
  function RO (line 25) | function RO(e){var t=e.state,n=e.options,r=n.gpuAcceleration,o=r===void ...
  function xO (line 25) | function xO(e){var t=e.state,n=e.instance,r=e.options,o=r.scroll,s=o===v...
  function ea (line 25) | function ea(e){return e.replace(/left|right|bottom|top/g,function(t){ret...
  function rp (line 25) | function rp(e){return e.replace(/start|end/g,function(t){return PO[t]})}
  function Nc (line 25) | function Nc(e){var t=nn(e),n=t.pageXOffset,r=t.pageYOffset;return{scroll...
  function Lc (line 25) | function Lc(e){return qo(Dr(e)).left+Nc(e).scrollLeft}
  function NO (line 25) | function NO(e,t){var n=nn(e),r=Dr(e),o=n.visualViewport,s=r.clientWidth,...
  function LO (line 25) | function LO(e){var t,n=Dr(e),r=Nc(e),o=(t=e.ownerDocument)==null?void 0:...
  function Mc (line 25) | function Mc(e){var t=dr(e),n=t.overflow,r=t.overflowX,o=t.overflowY;retu...
  function ng (line 25) | function ng(e){return["html","body","#document"].indexOf(Gn(e))>=0?e.own...
  function Ns (line 25) | function Ns(e,t){var n;t===void 0&&(t=[]);var r=ng(e),o=r===((n=e.ownerD...
  function Au (line 25) | function Au(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.w...
  function MO (line 25) | function MO(e,t){var n=qo(e,!1,t==="fixed");return n.top=n.top+e.clientT...
  function op (line 25) | function op(e,t,n){return t===Wm?Au(NO(e,n)):po(t)?MO(t,n):Au(LO(Dr(e)))}
  function $O (line 25) | function $O(e){var t=Ns(al(e)),n=["absolute","fixed"].indexOf(dr(e).posi...
  function kO (line 25) | function kO(e,t,n,r){var o=t==="clippingParents"?$O(e):[].concat(t),s=[]...
  function rg (line 25) | function rg(e){var t=e.reference,n=e.element,r=e.placement,o=r?Wn(r):nul...
  function Zs (line 25) | function Zs(e,t){t===void 0&&(t={});var n=t,r=n.placement,o=r===void 0?e...
  function FO (line 25) | function FO(e,t){t===void 0&&(t={});var n=t,r=n.placement,o=n.boundary,s...
  function BO (line 25) | function BO(e){if(Wn(e)===Rc)return[];var t=ea(e);return[rp(e),t,rp(t)]}
  function DO (line 25) | function DO(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]...
  function sp (line 25) | function sp(e,t,n){return n===void 0&&(n={x:0,y:0}),{top:e.top-t.height-...
  function ip (line 25) | function ip(e){return[zt,vn,hn,Ht].some(function(t){return e[t]>=0})}
  function jO (line 25) | function jO(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popp...
  function HO (line 25) | function HO(e,t,n){var r=Wn(e),o=[Ht,zt].indexOf(r)>=0?-1:1,s=typeof n==...
  function UO (line 25) | function UO(e){var t=e.state,n=e.options,r=e.name,o=n.offset,s=o===void ...
  function qO (line 25) | function qO(e){var t=e.state,n=e.name;t.modifiersData[n]=rg({reference:t...
  function WO (line 25) | function WO(e){return e==="x"?"y":"x"}
  function GO (line 25) | function GO(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=o===voi...
  function JO (line 25) | function JO(e){return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}}
  function XO (line 25) | function XO(e){return e===nn(e)||!un(e)?Nc(e):JO(e)}
  function ZO (line 25) | function ZO(e){var t=e.getBoundingClientRect(),n=Ko(t.width)/e.offsetWid...
  function QO (line 25) | function QO(e,t,n){n===void 0&&(n=!1);var r=un(t),o=un(t)&&ZO(t),s=Dr(t)...
  function eA (line 25) | function eA(e){var t=new Map,n=new Set,r=[];e.forEach(function(s){t.set(...
  function tA (line 25) | function tA(e){var t=eA(e);return mO.reduce(function(n,r){return n.conca...
  function nA (line 25) | function nA(e){var t;return function(){return t||(t=new Promise(function...
  function rA (line 25) | function rA(e){var t=e.reduce(function(n,r){var o=n[r.name];return n[r.n...
  function lp (line 25) | function lp(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]...
  function $c (line 25) | function $c(e){e===void 0&&(e={});var t=e,n=t.defaultModifiers,r=n===voi...
  function lA (line 25) | function lA(e){const t=Object.keys(e.elements),n=Oa(t.map(o=>[o,e.styles...
  function up (line 25) | function up(){let e;const t=(r,o)=>{n(),e=window.setTimeout(r,o)},n=()=>...
  method mounted (line 25) | mounted(t){e(t)}
  method updated (line 25) | updated(t){e(t)}
  method unmounted (line 25) | unmounted(){e(null)}
  function gA (line 25) | function gA(e){let t;function n(){if(e.value==null)return;const{selectio...
  function fg (line 25) | function fg(e,{beforeFocus:t,afterFocus:n,beforeBlur:r,afterBlur:o}={}){...
  function dg (line 25) | function dg({afterComposition:e,emit:t}){const n=V(!1),r=a=>{t==null||t(...
  function ll (line 25) | function ll(e,t=void 0){const n=Ge()?Ee(vg,Ia):Ia;return e?C(()=>{var r,...
  function Bc (line 25) | function Bc(e,t){const n=ll(),r=$e(e,C(()=>{var a;return((a=n.value)==nu...
  method setup (line 25) | setup(e){const t=e,n=$e("icon"),r=C(()=>{const{size:o,color:s}=t;return!...
  function MA (line 25) | function MA(){const e=V([]),t=C(()=>{if(!e.value.length)return"0";const ...
  method setup (line 25) | setup(e,{expose:t,emit:n}){const r=e,o=[],s=In(),i=$e("form"),a=C(()=>{c...
  function eo (line 25) | function eo(){return eo=Object.assign?Object.assign.bind():function(e){f...
  function DA (line 25) | function DA(e,t){e.prototype=Object.create(t.prototype),e.prototype.cons...
  function Ru (line 25) | function Ru(e){return Ru=Object.setPrototypeOf?Object.getPrototypeOf.bin...
  function Qs (line 25) | function Qs(e,t){return Qs=Object.setPrototypeOf?Object.setPrototypeOf.b...
  function VA (line 25) | function VA(){if(typeof Reflect>"u"||!Reflect.construct||Reflect.constru...
  function ta (line 25) | function ta(e,t,n){return VA()?ta=Reflect.construct.bind():ta=function(o...
  function jA (line 25) | function jA(e){return Function.toString.call(e).indexOf("[native code]")...
  function xu (line 25) | function xu(e){var t=typeof Map=="function"?new Map:void 0;return xu=fun...
  function Iu (line 25) | function Iu(e){if(!e||!e.length)return null;var t={};return e.forEach(fu...
  function Zt (line 25) | function Zt(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t...
  function UA (line 25) | function UA(e){return e==="string"||e==="url"||e==="hex"||e==="email"||e...
  function bt (line 25) | function bt(e,t){return!!(e==null||t==="array"&&Array.isArray(e)&&!e.len...
  function KA (line 25) | function KA(e,t,n){var r=[],o=0,s=e.length;function i(a){r.push.apply(r,...
  function vp (line 25) | function vp(e,t,n){var r=0,o=e.length;function s(i){if(i&&i.length){n(i)...
  function qA (line 25) | function qA(e){var t=[];return Object.keys(e).forEach(function(n){t.push...
  function t (line 25) | function t(n,r){var o;return o=e.call(this,"Async Validation Error")||th...
  function WA (line 25) | function WA(e,t,n,r,o){if(t.first){var s=new Promise(function(d,v){var p...
  function GA (line 25) | function GA(e){return!!(e&&e.message!==void 0)}
  function YA (line 25) | function YA(e,t){for(var n=e,r=0;r<t.length;r++){if(n==null)return n;n=n...
  function gp (line 25) | function gp(e,t){return function(n){var r;return e.fullFields?r=YA(t,e.f...
  function bp (line 25) | function bp(e,t){if(t){for(var n in t)if(t.hasOwnProperty(n)){var r=t[n]...
  function Pu (line 36) | function Pu(){return{default:"Validation error on field %s",required:"%s...
  function e (line 36) | function e(n){this.rules=null,this._messages=Nu,this.define(n)}
  function c (line 36) | function c(h){var b=[],m={};function S(w){if(Array.isArray(w)){var y;b=(...
  function _ (line 36) | function _(A,R){return eo({},R,{fullField:m.fullField+"."+A,fullFields:m...
  function w (line 36) | function w(A){A===void 0&&(A=[]);var R=Array.isArray(A)?A:[A];!l.suppres...
  method setup (line 36) | setup(e,{slots:t}){const n=Ee(ts,void 0),r=Ee(ho);r||Br(wp,"usage: <el-f...
  method setup (line 36) | setup(e,{expose:t}){const n=e,r=go(),o=Ee(ts,void 0),s=Ee(ho,void 0),i=I...
  function C4 (line 44) | function C4(e){const t=window.getComputedStyle(e),n=t.getPropertyValue("...
  function Sp (line 44) | function Sp(e,t=1,n){var r;mn||(mn=document.createElement("textarea"),do...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,o=Zy(),s=go(),i=C(()=>{const z={};r...
  method setup (line 44) | setup(e){const t=e,n=Ee(Dc),r=$e("scrollbar");n||Br(L4,"can not inject s...
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=Ee(Dc),o=V(0),s=V(0),i=V(""),a=V(""),l=V...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,o=$e("scrollbar");let s,i,a=0,l=0;c...
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=V(),o=V(),s=V(),i=V(),a=C(()=>n.role),l=...
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=$e("popper"),{arrowOffset:o,arrowRef:s,a...
  method setup (line 44) | setup(e,{slots:t,attrs:n}){var r;const o=Ee(ag),s=mA((r=o==null?void 0:o...
  function Eg (line 44) | function Eg(e){if(!e)return null;const t=e;for(const n of t){if(Oe(n))sw...
  function _p (line 44) | function _p(e){const t=$e("only-child");return re("span",{class:t.e("con...
  method setup (line 44) | setup(e,{expose:t}){const n=e,{role:r,triggerRef:o}=Ee(Vc,void 0);vA(o);...
  function Rp (line 44) | function Rp(e,t){const n=[...e],r=e.indexOf(t);return r!==-1&&n.splice(r...
  method setup (line 44) | setup(e,{emit:t}){const n=V();let r,o;const{focusReason:s}=fR();cA(p=>{e...
  function pR (line 44) | function pR(e,t,n,r,o,s){return de(e.$slots,"default",{handleKeydown:e.o...
  function yR (line 44) | function yR(e){const{offset:t,gpuAcceleration:n,fallbackPlacements:r}=e;...
  function wR (line 44) | function wR(e,t){t&&(e.modifiers=[...e.modifiers,...t??[]])}
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,{focusStartRef:o,trapped:s,onFocusA...
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=$e("tooltip"),{controlled:o,id:s,open:i,...
  method setup (line 44) | setup(e){return(t,n)=>t.disabled?de(t.$slots,"default",{key:0}):(L(),fe(...
  method setup (line 44) | setup(e,{expose:t}){const n=e,{selector:r}=ig(),o=$e("tooltip"),s=V(null...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e;dA();const o=pr(),s=V(),i=V(),a=()=...
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=$e("badge"),o=C(()=>n.isDot?"":je(n.valu...
  function Tt (line 44) | function Tt(e,t){nx(e)&&(e="100%");var n=rx(e);return e=t===360?e:Math.m...
  function ki (line 44) | function ki(e){return Math.min(1,Math.max(0,e))}
  function nx (line 44) | function nx(e){return typeof e=="string"&&e.indexOf(".")!==-1&&parseFloa...
  function rx (line 44) | function rx(e){return typeof e=="string"&&e.indexOf("%")!==-1}
  function Ig (line 44) | function Ig(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}
  function Fi (line 44) | function Fi(e){return e<=1?"".concat(Number(e)*100,"%"):e}
  function to (line 44) | function to(e){return e.length===1?"0"+e:String(e)}
  function ox (line 44) | function ox(e,t,n){return{r:Tt(e,255)*255,g:Tt(t,255)*255,b:Tt(n,255)*255}}
  function Pp (line 44) | function Pp(e,t,n){e=Tt(e,255),t=Tt(t,255),n=Tt(n,255);var r=Math.max(e,...
  function jl (line 44) | function jl(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*(6*n):n<...
  function sx (line 44) | function sx(e,t,n){var r,o,s;if(e=Tt(e,360),t=Tt(t,100),n=Tt(n,100),t===...
  function Np (line 44) | function Np(e,t,n){e=Tt(e,255),t=Tt(t,255),n=Tt(n,255);var r=Math.max(e,...
  function ix (line 44) | function ix(e,t,n){e=Tt(e,360)*6,t=Tt(t,100),n=Tt(n,100);var r=Math.floo...
  function Lp (line 44) | function Lp(e,t,n,r){var o=[to(Math.round(e).toString(16)),to(Math.round...
  function ax (line 44) | function ax(e,t,n,r,o){var s=[to(Math.round(e).toString(16)),to(Math.rou...
  function lx (line 44) | function lx(e){return Math.round(parseFloat(e)*255).toString(16)}
  function Mp (line 44) | function Mp(e){return Wt(e)/255}
  function Wt (line 44) | function Wt(e){return parseInt(e,16)}
  function ux (line 44) | function ux(e){return{r:e>>16,g:(e&65280)>>8,b:e&255}}
  function cx (line 44) | function cx(e){var t={r:0,g:0,b:0},n=1,r=null,o=null,s=null,i=!1,a=!1;re...
  function px (line 44) | function px(e){if(e=e.trim().toLowerCase(),e.length===0)return!1;var t=!...
  function Xn (line 44) | function Xn(e){return!!gn.CSS_UNIT.exec(String(e))}
  function e (line 44) | function e(t,n){t===void 0&&(t=""),n===void 0&&(n={});var r;if(t instanc...
  function _r (line 44) | function _r(e,t=20){return e.mix("#141414",t).toString()}
  function vx (line 44) | function vx(e){const t=ns(),n=$e("button");return C(()=>{let r={},o=e.co...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,o=vx(r),s=$e("button"),{_ref:i,_siz...
  method setup (line 44) | setup(e){const t=e;ft(xg,wt({size:Jt(t,"size"),type:Jt(t,"type")}));cons...
  function $p (line 44) | function $p(e,t){let n=[];return Array.isArray(t.arg)?n=t.arg:ar(t.arg)&...
  method beforeMount (line 44) | beforeMount(e,t){Or.has(e)||Or.set(e,[]),Or.get(e).push({documentHandler...
  method updated (line 44) | updated(e,t){Or.has(e)||Or.set(e,[]);const n=Or.get(e),r=n.findIndex(s=>...
  method unmounted (line 44) | unmounted(e){Or.delete(e)}
  method beforeMount (line 44) | beforeMount(e,t){const n=t.value,{interval:r=Cx,delay:o=Tx}=ve(n)?{}:n;l...
  method beforeMount (line 44) | beforeMount(e){e[$u]=ld(e),no.push(e),no.length<=1&&document.addEventLis...
  method updated (line 44) | updated(e){Ie(()=>{e[$u]=ld(e)})}
  method unmounted (line 44) | unmounted(){no.shift(),no.length===0&&document.removeEventListener("keyd...
  function u (line 44) | function u(p){var h,b,m,S;return[!0,e.trueValue,e.trueLabel].includes(p)...
  function c (line 44) | function c(p,h){l("change",u(p),h)}
  function f (line 44) | function f(p){if(n.value)return;const h=p.target;l("change",u(h.checked)...
  function d (line 44) | async function d(p){n.value||!r.value&&!o.value&&s.value&&(p.composedPat...
  method get (line 44) | get(){var a,l;return o.value?(a=r==null?void 0:r.modelValue)==null?void ...
  method set (line 44) | set(a){var l,u;o.value&&pe(a)?(s.value=((l=r==null?void 0:r.max)==null?v...
  function S (line 44) | function S(){var _,w;pe(r.value)&&!r.value.includes(f.value)?r.value.pus...
  method setup (line 44) | setup(e){const t=e,n=go(),{inputId:r,isLabeledByFormItem:o,isChecked:s,i...
  method setup (line 44) | setup(e){const t=e,n=go(),{isFocused:r,isChecked:o,isDisabled:s,checkbox...
  method setup (line 44) | setup(e,{emit:t}){const n=e,r=$e("checkbox"),{formItem:o}=Vr(),{inputId:...
  method setup (line 44) | setup(e,{emit:t}){const n=e,r=In(),o=$e("tag"),s=C(()=>{const{type:u,hit...
  method setup (line 44) | setup(e,{slots:t,emit:n}){const r=$e(Wx),o=l=>{n("click",l)},{onClick:s,...
  method setup (line 44) | setup(e,{expose:t}){const n=e,{t:r}=sl(),{Close:o}=HT,{dialogRef:s,heade...
  function S (line 44) | function S(){o("opened")}
  function _ (line 44) | function _(){o("closed"),o(rt,!1),e.destroyOnClose&&(f.value=!1)}
  function w (line 44) | function w(){o("close")}
  function y (line 44) | function y(){p==null||p(),v==null||v(),e.openDelay&&e.openDelay>0?{stop:...
  function A (line 44) | function A(){v==null||v(),p==null||p(),e.closeDelay&&e.closeDelay>0?{sto...
  function R (line 44) | function R(){function P(O){O||(c.value=!0,u.value=!1)}e.beforeClose?e.be...
  function N (line 44) | function N(){e.closeOnClickModal&&R()}
  function I (line 44) | function I(){st&&(u.value=!0)}
  function x (line 44) | function x(){u.value=!1}
  function k (line 44) | function k(){o("openAutoFocus")}
  function $ (line 44) | function $(){o("closeAutoFocus")}
  function F (line 44) | function F(P){var O;((O=P.detail)==null?void 0:O.focusReason)==="pointer...
  function Y (line 44) | function Y(){e.closeOnPressEscape&&R()}
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=go();xs({scope:"el-dialog",from:"the tit...
  function i3 (line 44) | function i3(e,t,n,r,o,s){return de(e.$slots,"default")}
  function u3 (line 44) | function u3(e,t,n,r,o,s){return de(e.$slots,"default")}
  method setup (line 44) | setup(){const a=V(null),l=new Map;ft(r,{itemMap:l,getItems:()=>{const c=...
  method setup (line 44) | setup(a,{attrs:l}){const u=V(null),c=Ee(r,void 0);ft(o,{collectionItemRe...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,{t:o}=sl(),s=$e("input-number"),i=V...
  method setup (line 44) | setup(e,{emit:t}){const n=e,r=$e("link"),o=C(()=>[r.b(),r.m(n.type),r.is...
  function _3 (line 44) | function _3(e,t){const n=Ee(cl),r=Ee(Vg,{disabled:!1}),o=C(()=>c(yn(n.pr...
  method setup (line 44) | setup(e){const t=$e("select"),n=pr(),r=C(()=>[t.be("dropdown","item"),t....
  function T3 (line 44) | function T3(e,t,n,r,o,s){return ct((L(),ee("li",{id:e.id,class:U(e.conta...
  method setup (line 44) | setup(){const e=Ee(cl),t=$e("select"),n=C(()=>e.props.popperClass),r=C((...
  function A3 (line 44) | function A3(e,t,n,r,o,s){return L(),ee("div",{class:U([e.ns.b("dropdown"...
  method beforeFocus (line 44) | beforeFocus(){return j.value}
  method afterFocus (line 44) | afterFocus(){e.automaticDropdown&&!x.value&&(x.value=!0,i.menuVisibleOnF...
  method beforeBlur (line 44) | beforeBlur(H){var ie,Fe;return((ie=u.value)==null?void 0:ie.isFocusInsid...
  method afterBlur (line 44) | afterBlur(){x.value=!1,i.menuVisibleOnFocus=!1}
  method get (line 44) | get(){return x.value&&ze.value!==!1}
  method set (line 44) | set(H){x.value=H}
  method isDisabled (line 44) | get isDisabled(){return Ln.isDisabled}
  method setup (line 44) | setup(e,{slots:t}){const n=Ee(cl);let r=[];return()=>{var o,s;const i=(o...
  method setup (line 44) | setup(e,{emit:t}){const n=C(()=>{const{modelValue:i,multiple:a}=e,l=a?[]...
  function M3 (line 44) | function M3(e,t,n,r,o,s){const i=Yt("el-tag"),a=Yt("el-tooltip"),l=Yt("e...
  method setup (line 44) | setup(e){const t=$e("select"),n=V(null),r=Ge(),o=V([]);ft(Vg,wt({...vr(e...
  function F3 (line 44) | function F3(e,t,n,r,o,s){return ct((L(),ee("ul",{ref:"groupRef",class:U(...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,o=C(()=>r[V3]),s=$e("popover"),i=V(...
  method mounted (line 44) | mounted(e,t){Dp(e,t)}
  method updated (line 44) | updated(e,t){Dp(e,t)}
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=e,{formItem:o}=Vr(),s=In(),i=$e("swit...
  method setup (line 44) | setup(e,{expose:t}){const n=e,r=Ge(),o=Ee(fl);o||Br(Hg,"<el-tabs><el-tab...
  method setup (line 44) | setup(e,{expose:t,emit:n}){const r=Ee(fl);r||Br(Vp,"<el-tabs><tab-nav />...
  method setup (line 44) | setup(e,{emit:t,slots:n,expose:r}){var o;const s=$e("tabs"),i=C(()=>["le...
  method setup (line 44) | setup(e){const t=e,n=Ge(),r=go(),o=Ee(fl);o||Br(Ug,"usage: <el-tabs><el-...
  method setup (line 44) | setup(e){const t=e,n=In(),r=$e("text"),o=C(()=>[r.b(),r.m(t.type),r.m(n....
  function vI (line 44) | function vI(e){let t;const n=V(!1),r=wt({...e,originalPosition:"",origin...
  method mounted (line 44) | mounted(e,t){t.value&&zp(e,t)}
  method updated (line 44) | updated(e,t){const n=e[na];t.oldValue!==t.value&&(t.value&&!t.oldValue?z...
  method unmounted (line 44) | unmounted(e){var t;(t=e[na])==null||t.instance.close(),e[na]=null}
  method install (line 44) | install(e){e.directive("loading",Hp),e.config.globalProperties.$loading=Fu}
  method setup (line 44) | setup(e,{expose:t}){const n=e,{Close:r}=Dm,{ns:o,zIndex:s}=Bc("message")...
  function II (line 44) | function II(e){for(const t of wn)(!e||e===t.props.type)&&t.handler.close()}
  method setup (line 44) | setup(e,{emit:t}){const{locale:n,zIndex:r,ns:o,size:s}=Bc("message-box",...
  function NI (line 44) | function NI(e,t,n,r,o,s){const i=Yt("el-icon"),a=Yt("close"),l=Yt("el-in...
  function os (line 44) | function os(e,t=null){if(!st)return Promise.reject();let n;return Ae(e)|...
  function VI (line 44) | function VI(e){return(t,n,r,o)=>{let s="";return Oe(n)?(r=n,s=""):Lt(n)?...
  function Gg (line 44) | function Gg(e,t){return function(){return e.apply(t,arguments)}}
  function mi (line 44) | function mi(e){return e!==null&&!Yo(e)&&e.constructor!==null&&!Yo(e.cons...
  function zI (line 44) | function zI(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t...
  function QI (line 44) | function QI(){return typeof globalThis<"u"?globalThis:typeof self<"u"?se...
  function bi (line 44) | function bi(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;l...
  function Zg (line 44) | function Zg(e,t){if(mi(e))return null;t=t.toLowerCase();const n=Object.k...
  function Bu (line 44) | function Bu(){const{caseless:e,skipUndefined:t}=Qg(this)&&this||{},n={},...
  function _P (line 44) | function _P(e){return!!(e&&Ut(e.append)&&e[Yg]==="FormData"&&e[dl])}
  method from (line 44) | static from(t,n,r,o,s,i){const a=new nb(t.message,n||t.code,r,o,s);retur...
  method constructor (line 44) | constructor(t,n,r,o,s){super(t),Object.defineProperty(this,"message",{va...
  method toJSON (line 44) | toJSON(){return{message:this.message,name:this.name,description:this.des...
  function Du (line 44) | function Du(e){return D.isPlainObject(e)||D.isArray(e)}
  function rb (line 44) | function rb(e){return D.endsWith(e,"[]")?e.slice(0,-2):e}
  function ql (line 44) | function ql(e,t,n){return e?e.concat(t).map(function(o,s){return o=rb(o)...
  function IP (line 44) | function IP(e){return D.isArray(e)&&!e.some(Du)}
  function vl (line 44) | function vl(e,t,n){if(!D.isObject(e))throw new TypeError("target must be...
  function Wp (line 44) | function Wp(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E...
  function Wc (line 44) | function Wc(e,t){this._pairs=[],e&&vl(e,this,t)}
  function NP (line 44) | function NP(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace...
  function sb (line 44) | function sb(e,t,n){if(!t)return e;const r=n&&n.encode||NP,o=D.isFunction...
  class Gp (line 44) | class Gp{constructor(){this.handlers=[]}use(t,n,r){return this.handlers....
    method constructor (line 44) | constructor(){this.handlers=[]}
    method use (line 44) | use(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchrono...
    method eject (line 44) | eject(t){this.handlers[t]&&(this.handlers[t]=null)}
    method clear (line 44) | clear(){this.handlers&&(this.handlers=[])}
    method forEach (line 44) | forEach(t){D.forEach(this.handlers,function(r){r!==null&&t(r)})}
  function jP (line 44) | function jP(e,t){return vl(e,new Nt.classes.URLSearchParams,{visitor:fun...
  function zP (line 44) | function zP(e){return D.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"...
  function HP (line 44) | function HP(e){const t={},n=Object.keys(e);let r;const o=n.length;let s;...
  function ib (line 44) | function ib(e){function t(n,r,o,s){let i=n[s++];if(i==="__proto__")retur...
  function UP (line 44) | function UP(e,t,n){if(D.isString(e))try{return(t||JSON.parse)(e),D.trim(...
  function vs (line 45) | function vs(e){return e&&String(e).trim().toLowerCase()}
  function oa (line 45) | function oa(e){return e===!1||e==null?e:D.isArray(e)?e.map(oa):String(e)}
  function WP (line 45) | function WP(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;...
  function Wl (line 45) | function Wl(e,t,n,r,o){if(D.isFunction(r))return r.call(this,t,n);if(o&&...
  function YP (line 45) | function YP(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(...
  function JP (line 45) | function JP(e,t){const n=D.toCamelCase(" "+t);["get","set","has"].forEac...
  method constructor (line 45) | constructor(t){t&&this.set(t)}
  method set (line 45) | set(t,n,r){const o=this;function s(a,l,u){const c=vs(l);if(!c)throw new ...
  method get (line 45) | get(t,n){if(t=vs(t),t){const r=D.findKey(this,t);if(r){const o=this[r];i...
  method has (line 45) | has(t,n){if(t=vs(t),t){const r=D.findKey(this,t);return!!(r&&this[r]!==v...
  method delete (line 45) | delete(t,n){const r=this;let o=!1;function s(i){if(i=vs(i),i){const a=D....
  method clear (line 45) | clear(t){const n=Object.keys(this);let r=n.length,o=!1;for(;r--;){const ...
  method normalize (line 45) | normalize(t){const n=this,r={};return D.forEach(this,(o,s)=>{const i=D.f...
  method concat (line 45) | concat(...t){return this.constructor.concat(this,...t)}
  method toJSON (line 45) | toJSON(t){const n=Object.create(null);return D.forEach(this,(r,o)=>{r!=n...
  method [Symbol.iterator] (line 45) | [Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator...
  method toString (line 45) | toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).j...
  method getSetCookie (line 46) | getSetCookie(){return this.get("set-cookie")||[]}
  method [Symbol.toStringTag] (line 46) | get[Symbol.toStringTag](){return"AxiosHeaders"}
  method from (line 46) | static from(t){return t instanceof this?t:new this(t)}
  method concat (line 46) | static concat(t,...n){const r=new this(t);return n.forEach(o=>r.set(o)),r}
  method accessor (line 46) | static accessor(t){const r=(this[Yp]=this[Yp]={accessors:{}}).accessors,...
  method set (line 46) | set(r){this[n]=r}
  function Gl (line 46) | function Gl(e,t){const n=this||yi,r=t||n,o=Kt.from(r.headers);let s=r.da...
  function ab (line 46) | function ab(e){return!!(e&&e.__CANCEL__)}
  method constructor (line 46) | constructor(t,n,r){super(t??"canceled",Te.ERR_CANCELED,n,r),this.name="C...
  function lb (line 46) | function lb(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.st...
  function XP (line 46) | function XP(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1...
  function ZP (line 46) | function ZP(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o=0,s=0...
  function QP (line 46) | function QP(e,t){let n=0,r=1e3/t,o,s;const i=(u,c=Date.now())=>{n=c,o=nu...
  method write (line 46) | write(e,t,n,r,o,s,i){if(typeof document>"u")return;const a=[`${e}=${enco...
  method read (line 46) | read(e){if(typeof document>"u")return null;const t=document.cookie.match...
  method remove (line 46) | remove(e){this.write(e,"",Date.now()-864e5,"/")}
  method write (line 46) | write(){}
  method read (line 46) | read(){return null}
  method remove (line 46) | remove(){}
  function n8 (line 46) | function n8(e){return typeof e!="string"?!1:/^([a-z][a-z\d+\-.]*:)?\/\//...
  function r8 (line 46) | function r8(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""...
  function ub (line 46) | function ub(e,t,n){let r=!n8(t);return e&&(r||n==!1)?r8(e,t):t}
  function vo (line 46) | function vo(e,t){t=t||{};const n={};function r(u,c,f,d){return D.isPlain...
  function h (line 46) | function h(){v&&v(),p&&p(),o.cancelToken&&o.cancelToken.unsubscribe(c),o...
  function m (line 46) | function m(){if(!b)return;const _=Kt.from("getAllResponseHeaders"in b&&b...
  method pull (line 46) | async pull(l){try{const{done:u,value:c}=await o.next();if(u){a(),l.close...
  method cancel (line 46) | cancel(l){return a(l),o.return()}
  method duplex (line 46) | get duplex(){return p=!0,"half"}
  function h8 (line 46) | function h8(e,t){e=D.isArray(e)?e:[e];const{length:n}=e;let r,o;const s=...
  function Yl (line 48) | function Yl(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.sign...
  function sh (line 48) | function sh(e){return Yl(e),e.headers=Kt.from(e.headers),e.data=Gl.call(...
  function o (line 48) | function o(s,i){return"[Axios v"+pb+"] Transitional option '"+s+"'"+i+(r...
  function v8 (line 48) | function v8(e,t,n){if(typeof e!="object")throw new Te("options must be a...
  method constructor (line 48) | constructor(t){this.defaults=t||{},this.interceptors={request:new Gp,res...
  method request (line 48) | async request(t,n){try{return await this._request(t,n)}catch(r){if(r ins...
  method _request (line 49) | _request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=vo(this.def...
  method getUri (line 49) | getUri(t){t=vo(this.defaults,t);const n=ub(t.baseURL,t.url,t.allowAbsolu...
  function n (line 49) | function n(r){return function(s,i,a){return this.request(vo(a||{},{metho...
  method constructor (line 49) | constructor(t){if(typeof t!="function")throw new TypeError("executor mus...
  method throwIfRequested (line 49) | throwIfRequested(){if(this.reason)throw this.reason}
  method subscribe (line 49) | subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this....
  method unsubscribe (line 49) | unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexO...
  method toAbortSignal (line 49) | toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return thi...
  method source (line 49) | static source(){let t;return{token:new hb(function(o){t=o}),cancel:t}}
  function g8 (line 49) | function g8(e){return function(n){return e.apply(null,n)}}
  function b8 (line 49) | function b8(e){return D.isObject(e)&&e.isAxiosError===!0}
  function vb (line 49) | function vb(e){const t=new lo(e),n=Gg(lo.prototype.request,t);return D.e...
  function mb (line 49) | function mb(e){return Fa()?(Ba(e),!0):!1}
  function ln (line 49) | function ln(e){return typeof e=="function"?e():g(e)}
  function Xc (line 49) | function Xc(e,t){function n(...r){return new Promise((o,s)=>{Promise.res...
  function E8 (line 49) | function E8(e,t={}){let n,r,o=Jo;const s=a=>{clearTimeout(a),o(),o=Jo};r...
  function _8 (line 49) | function _8(...e){let t=0,n,r=!0,o=Jo,s,i,a,l,u;!Ue(e[0])&&typeof e[0]==...
  function C8 (line 49) | function C8(e=gb){const t=V(!0);function n(){t.value=!1}function r(){t.v...
  function T8 (line 49) | function T8(e){return Ge()}
  function O8 (line 49) | function O8(...e){if(e.length!==1)return Jt(...e);const t=e[0];return ty...
  function dL (line 49) | function dL(e,t=200,n={}){return Xc(E8(t,n),e)}
  function pL (line 49) | function pL(e,t=200,n=!1,r=!0,o=!1){return Xc(_8(t,n,r,o),e)}
  function A8 (line 49) | function A8(e,t,n={}){const{eventFilter:r=gb,...o}=n;return he(e,Xc(r,t)...
  function R8 (line 49) | function R8(e,t,n={}){const{eventFilter:r,...o}=n,{eventFilter:s,pause:i...
  function bb (line 49) | function bb(e,t=!0,n){T8()?Ke(e,n):t?e():Ie(e)}
  function I8 (line 49) | function I8(e,t,n,r){let o=e<12?"AM":"PM";return r&&(o=o.split("").reduc...
  function Gr (line 49) | function Gr(e){const t=["th","st","nd","rd"],n=e%100;return e+(t[(n-20)%...
  function hL (line 49) | function hL(e,t,n={}){var r;const o=e.getFullYear(),s=e.getMonth(),i=e.g...
  function zu (line 53) | function zu(e){return e&&typeof e=="object"&&Object.prototype.toString.c...
  function vL (line 53) | function vL(){const e=Th(!0),t=e.run(()=>V({}));let n=[],r=[];const o=Ds...
  function ah (line 53) | function ah(e,t,n,r=Sb){e.push(t);const o=()=>{const s=e.indexOf(t);s>-1...
  function Ao (line 53) | function Ao(e,...t){e.slice().forEach(n=>{n(...t)})}
  function Hu (line 53) | function Hu(e,t){e instanceof Map&&t instanceof Map?t.forEach((n,r)=>e.s...
  function L8 (line 53) | function L8(e){return!zu(e)||!e.hasOwnProperty(N8)}
  function M8 (line 53) | function M8(e){return!!(Ue(e)&&e.effect)}
  function $8 (line 53) | function $8(e,t,n,r){const{state:o,actions:s,getters:i}=t,a=n.state.valu...
  function Eb (line 53) | function Eb(e,t,n={},r,o,s){let i;const a=Rr({actions:{}},n),l={deep:!0}...
  function mL (line 53) | function mL(e,t,n){let r,o;const s=typeof t=="function";typeof e=="strin...
  function gL (line 53) | function gL(e){{const t=Me(e),n={};for(const r in t){const o=t[r];o.effe...
  function uh (line 53) | function uh(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){v...
  function Vi (line 53) | function Vi(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=n...
  function k8 (line 53) | function k8(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a...
  function F8 (line 53) | function F8(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.e...
  function B8 (line 53) | function B8(e,t,n){return t&&F8(e.prototype,t),e}
  function D8 (line 53) | function D8(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enum...
  function V8 (line 53) | function V8(e){return j8(e)||z8(e)||H8(e)||U8()}
  function j8 (line 53) | function j8(e){if(Array.isArray(e))return Uu(e)}
  function z8 (line 53) | function z8(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iter...
  function H8 (line 53) | function H8(e,t){if(e){if(typeof e=="string")return Uu(e,t);var n=Object...
  function Uu (line 53) | function Uu(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new A...
  function U8 (line 53) | function U8(){throw new TypeError(`Invalid attempt to spread non-iterabl...
  function e (line 54) | function e(t,n){k8(this,e),this.init(t,n)}
  function Zl (line 54) | function Zl(e,t,n,r){e.addEventListener?e.addEventListener(t,n,r):e.atta...
  function ms (line 54) | function ms(e,t,n,r){e.removeEventListener?e.removeEventListener(t,n,r):...
  function Cb (line 54) | function Cb(e,t){const n=t.slice(0,t.length-1);for(let r=0;r<n.length;r+...
  function Tb (line 54) | function Tb(e){typeof e!="string"&&(e=""),e=e.replace(/\s/g,"");const t=...
  function J8 (line 54) | function J8(e,t){const n=e.length>=t.length?e:t,r=e.length>=t.length?t:e...
  function Ab (line 54) | function Ab(e){Ob=e||"all"}
  function ri (line 54) | function ri(){return Ob||"all"}
  function Q8 (line 54) | function Q8(){return at.slice(0)}
  function eN (line 54) | function eN(){return at.map(e=>X8(e)||Z8(e)||String.fromCharCode(e))}
  function tN (line 54) | function tN(){const e=[];return Object.keys(lt).forEach(t=>{lt[t].forEac...
  function nN (line 54) | function nN(e){const t=e.target||e.srcElement,{tagName:n}=t;let r=!0;con...
  function rN (line 54) | function rN(e){return typeof e=="string"&&(e=is(e)),at.indexOf(e)!==-1}
  function oN (line 54) | function oN(e,t){let n,r;e||(e=ri());for(const o in lt)if(Object.prototy...
  function sN (line 54) | function sN(e){let t=e.keyCode||e.which||e.charCode;e.key&&e.key.toLower...
  function Rb (line 54) | function Rb(e){if(typeof e>"u")Object.keys(lt).forEach(o=>{Array.isArray...
  function dh (line 54) | function dh(e,t,n,r){if(t.element!==r)return;let o;if(t.scope===n||t.sco...
  function ph (line 54) | function ph(e,t){const n=lt["*"];let r=e.keyCode||e.which||e.charCode;if...
  function Lr (line 54) | function Lr(e,t,n){at=[];const r=Tb(e);let o=[],s="all",i=document,a=0,l...
  function iN (line 54) | function iN(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments...
  function Zc (line 54) | function Zc(e){const t=Object.values(lt).flat();if(t.findIndex(r=>{let{e...
  function xb (line 54) | function xb(e){var t;const n=ln(e);return(t=n==null?void 0:n.$el)!=null?...
  function hh (line 54) | function hh(...e){let t,n,r,o;if(typeof e[0]=="string"||Array.isArray(e[...
  function aN (line 54) | function aN(){const e=V(!1),t=Ge();return t&&Ke(()=>{e.value=!0},t),e}
  function lN (line 54) | function lN(e){const t=aN();return C(()=>(t.value,!!e()))}
  function uN (line 54) | function uN(e,t={}){const{window:n=Xo}=t,r=lN(()=>n&&"matchMedia"in n&&t...
  function fN (line 54) | function fN(){return Hi in zi||(zi[Hi]=zi[Hi]||{}),zi[Hi]}
  function Ib (line 54) | function Ib(e,t){return cN[e]||t}
  function Pb (line 54) | function Pb(e){return uN("(prefers-color-scheme: dark)",e)}
  function dN (line 54) | function dN(e){return e==null?"any":e instanceof Set?"set":e instanceof ...
  function hN (line 54) | function hN(e,t,n,r={}){var o;const{flush:s="pre",deep:i=!0,listenToStor...
  function mN (line 54) | function mN(e={}){const{selector:t="html",attribute:n="class",initialVal...
  function yL (line 54) | function yL(e={}){const{valueDark:t="dark",valueLight:n="",window:r=Xo}=...

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetDetector.java
  class CharsetDetector (line 47) | @SuppressWarnings({"JavaDoc", "unused", "RedundantSuppression"})
    method CharsetDetector (line 65) | public CharsetDetector() {
    method setDeclaredEncoding (line 83) | public CharsetDetector setDeclaredEncoding(String encoding) {
    method setText (line 95) | public CharsetDetector setText(@NonNull byte[] in) {
    method setText (line 102) | public CharsetDetector setText(@NonNull ParcelFileDescriptor pfd) {
    method setText (line 130) | public CharsetDetector setText(@NonNull InputStream in) throws IOExcep...
    method detect (line 171) | @Nullable
    method detectAll (line 200) | public CharsetMatch[] detectAll() {
    method getReader (line 245) | public Reader getReader(InputStream in, String declaredEncoding) {
    method getString (line 277) | public String getString(byte[] in, String declaredEncoding) {
    method getAllDetectableCharsets (line 310) | public static String[] getAllDetectableCharsets() {
    method inputFilterEnabled (line 325) | public boolean inputFilterEnabled() {
    method enableInputFilter (line 338) | public boolean enableInputFilter(boolean filter) {
    method MungeInput (line 350) | private void MungeInput() {
    class CSRecognizerInfo (line 464) | private static class CSRecognizerInfo {
      method CSRecognizerInfo (line 468) | CSRecognizerInfo(CharsetRecognizer recognizer, boolean isDefaultEnab...
    method getDetectableCharsets (line 527) | @Deprecated
    method setDetectableCharset (line 554) | @Deprecated

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetMatch.java
  class CharsetMatch (line 31) | @SuppressWarnings({"JavaDoc", "unused"})
    method getReader (line 47) | public Reader getReader() {
    method getString (line 69) | public String getString() throws java.io.IOException {
    method getString (line 87) | public String getString(int maxLength) throws java.io.IOException {
    method getConfidence (line 130) | public int getConfidence() {
    method getName (line 147) | public String getName() {
    method getLanguage (line 157) | public String getLanguage() {
    method compareTo (line 174) | @Override
    method CharsetMatch (line 188) | CharsetMatch(CharsetDetector det, CharsetRecognizer rec, int conf) {
    method CharsetMatch (line 208) | CharsetMatch(CharsetDetector det, CharsetRecognizer rec, int conf, Str...

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetRecog_2022.java
  class CharsetRecog_2022 (line 19) | abstract class CharsetRecog_2022 extends CharsetRecognizer {
    method match (line 33) | int match(byte[] text, int textLen, byte[][] escapeSequences) {
    class CharsetRecog_2022JP (line 97) | static class CharsetRecog_2022JP extends CharsetRecog_2022 {
      method getName (line 113) | @Override
      method match (line 118) | @Override
    class CharsetRecog_2022KR (line 125) | static class CharsetRecog_2022KR extends CharsetRecog_2022 {
      method getName (line 130) | @Override
      method match (line 135) | @Override
    class CharsetRecog_2022CN (line 142) | static class CharsetRecog_2022CN extends CharsetRecog_2022 {
      method getName (line 157) | @Override
      method match (line 162) | @Override

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetRecog_UTF8.java
  class CharsetRecog_UTF8 (line 14) | class CharsetRecog_UTF8 extends CharsetRecognizer {
    method getName (line 16) | @Override
    method match (line 24) | @Override

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetRecog_Unicode.java
  class CharsetRecog_Unicode (line 17) | abstract class CharsetRecog_Unicode extends CharsetRecognizer {
    method getName (line 22) | @Override
    method match (line 28) | @Override
    method codeUnit16FromBytes (line 31) | static int codeUnit16FromBytes(byte hi, byte lo) {
    method adjustConfidence (line 40) | static int adjustConfidence(int codeUnit, int confidence) {
    class CharsetRecog_UTF_16_BE (line 54) | static class CharsetRecog_UTF_16_BE extends CharsetRecog_Unicode {
      method getName (line 55) | @Override
      method match (line 60) | @Override
    class CharsetRecog_UTF_16_LE (line 87) | static class CharsetRecog_UTF_16_LE extends CharsetRecog_Unicode {
      method getName (line 88) | @Override
      method match (line 93) | @Override
    class CharsetRecog_UTF_32 (line 120) | static abstract class CharsetRecog_UTF_32 extends CharsetRecog_Unicode {
      method getChar (line 121) | abstract int getChar(byte[] input, int index);
      method getName (line 123) | @Override
      method match (line 126) | @Override
    class CharsetRecog_UTF_32_BE (line 172) | static class CharsetRecog_UTF_32_BE extends CharsetRecog_UTF_32 {
      method getChar (line 173) | @Override
      method getName (line 179) | @Override
    class CharsetRecog_UTF_32_LE (line 186) | static class CharsetRecog_UTF_32_LE extends CharsetRecog_UTF_32 {
      method getChar (line 187) | @Override
      method getName (line 193) | @Override

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetRecog_mbcs.java
  class CharsetRecog_mbcs (line 26) | abstract class CharsetRecog_mbcs extends CharsetRecognizer {
    method getName (line 33) | @Override
    method match (line 49) | int match(CharsetDetector det, int[] commonChars) {
    class iteratedChar (line 144) | static class iteratedChar {
      method reset (line 150) | void reset() {
      method nextByte (line 157) | int nextByte(CharsetDetector det) {
    method nextChar (line 179) | abstract boolean nextChar(iteratedChar it, CharsetDetector det);
    class CharsetRecog_sjis (line 185) | static class CharsetRecog_sjis extends CharsetRecog_mbcs {
      method nextChar (line 197) | @Override
      method match (line 222) | @Override
      method getName (line 228) | @Override
      method getLanguage (line 233) | @Override
    class CharsetRecog_big5 (line 245) | static class CharsetRecog_big5 extends CharsetRecog_mbcs {
      method nextChar (line 261) | @Override
      method match (line 289) | @Override
      method getName (line 295) | @Override
      method getLanguage (line 301) | @Override
    class CharsetRecog_euc (line 313) | abstract static class CharsetRecog_euc extends CharsetRecog_mbcs {
      method nextChar (line 321) | @Override
      class CharsetRecog_euc_jp (line 383) | static class CharsetRecog_euc_jp extends CharsetRecog_euc {
        method getName (line 399) | @Override
        method match (line 404) | @Override
        method getLanguage (line 410) | @Override
      class CharsetRecog_euc_kr (line 420) | static class CharsetRecog_euc_kr extends CharsetRecog_euc {
        method getName (line 436) | @Override
        method match (line 441) | @Override
        method getLanguage (line 447) | @Override
    class CharsetRecog_gb_18030 (line 457) | static class CharsetRecog_gb_18030 extends CharsetRecog_mbcs {
      method nextChar (line 465) | @Override
      method getName (line 534) | @Override
      method match (line 539) | @Override
      method getLanguage (line 545) | @Override

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetRecog_sbcs.java
  class CharsetRecog_sbcs (line 17) | abstract class CharsetRecog_sbcs extends CharsetRecognizer {
    method getName (line 22) | @Override
    class NGramParser (line 25) | static class NGramParser {
      method NGramParser (line 40) | public NGramParser(int[] theNgramList, byte[] theByteMap) {
      method search (line 52) | private static int search(int[] table, int value) {
      method lookup (line 90) | private void lookup(int thisNgram) {
      method addByte (line 99) | protected void addByte(int b) {
      method nextByte (line 104) | private int nextByte(CharsetDetector det) {
      method parseCharacters (line 112) | protected void parseCharacters(CharsetDetector det) {
      method parse (line 131) | public int parse(CharsetDetector det) {
      method parse (line 135) | public int parse(CharsetDetector det, byte spaceCh) {
    class NGramParser_IBM420 (line 160) | static class NGramParser_IBM420 extends NGramParser {
      method NGramParser_IBM420 (line 184) | public NGramParser_IBM420(int[] theNgramList, byte[] theByteMap) {
      method isLamAlef (line 188) | private byte isLamAlef(byte b) {
      method nextByte (line 206) | private int nextByte(CharsetDetector det) {
      method parseCharacters (line 223) | @Override
    method match (line 257) | int match(CharsetDetector det, int[] ngrams, byte[] byteMap) {
    method match (line 261) | int match(CharsetDetector det, int[] ngrams, byte[] byteMap, byte spac...
    method matchIBM420 (line 266) | @SuppressWarnings("SameParameterValue")
    class NGramsPlusLang (line 272) | static class NGramsPlusLang {
      method NGramsPlusLang (line 276) | NGramsPlusLang(String la, int[] ng) {
    class CharsetRecog_8859_1 (line 282) | static class CharsetRecog_8859_1 extends CharsetRecog_sbcs {
      method match (line 412) | @Override
      method getName (line 428) | @Override
    class CharsetRecog_8859_2 (line 435) | static class CharsetRecog_8859_2 extends CharsetRecog_sbcs {
      method match (line 506) | @Override
      method getName (line 521) | @Override
    class CharsetRecog_8859_5 (line 529) | abstract static class CharsetRecog_8859_5 extends CharsetRecog_sbcs {
      method getName (line 565) | @Override
    class CharsetRecog_8859_5_ru (line 571) | static class CharsetRecog_8859_5_ru extends CharsetRecog_8859_5 {
      method getLanguage (line 579) | @Override
      method match (line 584) | @Override
    class CharsetRecog_8859_6 (line 591) | abstract static class CharsetRecog_8859_6 extends CharsetRecog_sbcs {
      method getName (line 627) | @Override
    class CharsetRecog_8859_6_ar (line 633) | static class CharsetRecog_8859_6_ar extends CharsetRecog_8859_6 {
      method getLanguage (line 641) | @Override
      method match (line 646) | @Override
    class CharsetRecog_8859_7 (line 653) | abstract static class CharsetRecog_8859_7 extends CharsetRecog_sbcs {
      method getName (line 689) | @Override
    class CharsetRecog_8859_7_el (line 695) | static class CharsetRecog_8859_7_el extends CharsetRecog_8859_7 {
      method getLanguage (line 703) | @Override
      method match (line 708) | @Override
    class CharsetRecog_8859_8 (line 716) | abstract static class CharsetRecog_8859_8 extends CharsetRecog_sbcs {
      method getName (line 752) | @Override
    class CharsetRecog_8859_8_I_he (line 758) | static class CharsetRecog_8859_8_I_he extends CharsetRecog_8859_8 {
      method getName (line 766) | @Override
      method getLanguage (line 771) | @Override
      method match (line 776) | @Override
    class CharsetRecog_8859_8_he (line 784) | static class CharsetRecog_8859_8_he extends CharsetRecog_8859_8 {
      method getLanguage (line 792) | @Override
      method match (line 797) | @Override
    class CharsetRecog_8859_9 (line 806) | abstract static class CharsetRecog_8859_9 extends CharsetRecog_sbcs {
      method getName (line 842) | @Override
    class CharsetRecog_8859_9_tr (line 848) | static class CharsetRecog_8859_9_tr extends CharsetRecog_8859_9 {
      method getLanguage (line 856) | @Override
      method match (line 861) | @Override
    class CharsetRecog_windows_1251 (line 869) | static class CharsetRecog_windows_1251 extends CharsetRecog_sbcs {
      method getName (line 912) | @Override
      method getLanguage (line 917) | @Override
      method match (line 922) | @Override
    class CharsetRecog_windows_1256 (line 929) | static class CharsetRecog_windows_1256 extends CharsetRecog_sbcs {
      method getName (line 972) | @Override
      method getLanguage (line 977) | @Override
      method match (line 982) | @Override
    class CharsetRecog_KOI8_R (line 989) | static class CharsetRecog_KOI8_R extends CharsetRecog_sbcs {
      method getName (line 1032) | @Override
      method getLanguage (line 1037) | @Override
      method match (line 1042) | @Override
    class CharsetRecog_IBM424_he (line 1049) | abstract static class CharsetRecog_IBM424_he extends CharsetRecog_sbcs {
      method getLanguage (line 1070) | @Override
    class CharsetRecog_IBM424_he_rtl (line 1076) | static class CharsetRecog_IBM424_he_rtl extends CharsetRecog_IBM424_he {
      method getName (line 1077) | @Override
      method match (line 1089) | @Override
    class CharsetRecog_IBM424_he_ltr (line 1096) | static class CharsetRecog_IBM424_he_ltr extends CharsetRecog_IBM424_he {
      method getName (line 1097) | @Override
      method match (line 1110) | @Override
    class CharsetRecog_IBM420_ar (line 1117) | abstract static class CharsetRecog_IBM420_ar extends CharsetRecog_sbcs {
      method getLanguage (line 1140) | @Override
    class CharsetRecog_IBM420_ar_rtl (line 1147) | static class CharsetRecog_IBM420_ar_rtl extends CharsetRecog_IBM420_ar {
      method getName (line 1155) | @Override
      method match (line 1160) | @Override
    class CharsetRecog_IBM420_ar_ltr (line 1168) | static class CharsetRecog_IBM420_ar_ltr extends CharsetRecog_IBM420_ar {
      method getName (line 1176) | @Override
      method match (line 1181) | @Override

FILE: app/src/main/java/io/legado/app/lib/icu4j/CharsetRecognizer.java
  class CharsetRecognizer (line 25) | abstract class CharsetRecognizer {
    method getName (line 31) | abstract String getName();
    method getLanguage (line 38) | public String getLanguage() {
    method match (line 51) | abstract CharsetMatch match(CharsetDetector det);

FILE: app/src/main/java/io/legado/app/model/analyzeRule/QueryTTF.java
  class QueryTTF (line 11) | @Keep
    class Header (line 19) | private static class Header {
    class Directory (line 45) | private static class Directory {
    class NameLayout (line 64) | private static class NameLayout {
    class NameRecord (line 71) | private static class NameRecord {
    class HeadLayout (line 83) | private static class HeadLayout {
    class MaxpLayout (line 162) | private static class MaxpLayout {
    class CmapLayout (line 228) | private static class CmapLayout {
    class CmapRecord (line 244) | private static class CmapRecord {
    class CmapFormat (line 276) | private static class CmapFormat {
    class GlyfLayout (line 384) | private static class GlyfLayout {
    class GlyphTableBySimple (line 418) | private static class GlyphTableBySimple {
    class GlyphTableComponent (line 458) | private static class GlyphTableComponent {
    class BufferReader (line 509) | private static class BufferReader {
      method BufferReader (line 512) | public BufferReader(byte[] buffer, int index) {
      method position (line 518) | public void position(int index) {
      method position (line 522) | public int position() {
      method ReadUInt64 (line 526) | public long ReadUInt64() {
      method ReadUInt32 (line 530) | public int ReadUInt32() {
      method ReadInt32 (line 534) | public int ReadInt32() {
      method ReadUInt16 (line 538) | public int ReadUInt16() {
      method ReadInt16 (line 542) | public short ReadInt16() {
      method ReadUInt8 (line 546) | public short ReadUInt8() {
      method ReadInt8 (line 550) | public byte ReadInt8() {
      method ReadByteArray (line 554) | public byte[] ReadByteArray(int len) {
      method ReadUInt8Array (line 561) | public int[] ReadUInt8Array(int len) {
      method ReadInt16Array (line 568) | public int[] ReadInt16Array(int len) {
      method ReadUInt16Array (line 575) | public int[] ReadUInt16Array(int len) {
      method ReadInt32Array (line 582) | public int[] ReadInt32Array(int len) {
    method readNameTable (line 598) | private void readNameTable(byte[] buffer) {
    method readHeadTable (line 617) | private void readHeadTable(byte[] buffer) {
    method readLocaTable (line 648) | private void readLocaTable(byte[] buffer) {
    method readCmapTable (line 661) | private void readCmapTable(byte[] buffer) {
    method readMaxpTable (line 753) | private void readMaxpTable(byte[] buffer) {
    method readGlyfTable (line 779) | private void readGlyfTable(byte[] buffer) {
    method getGlyfById (line 913) | public String getGlyfById(int glyfId) {
    method QueryTTF (line 949) | public QueryTTF(final byte[] buffer) {
    method getGlyfIdByUnicode (line 1003) | public int getGlyfIdByUnicode(int unicode) {
    method getGlyfByUnicode (line 1015) | public String getGlyfByUnicode(int unicode) {
    method getUnicodeByGlyf (line 1025) | public int getUnicodeByGlyf(String glyph) {
    method isBlankUnicode (line 1037) | public boolean isBlankUnicode(int unicode) {

FILE: app/src/main/java/io/legado/app/ui/file/utils/FilePickerIcon.java
  class FilePickerIcon (line 9) | public class FilePickerIcon {
    method getFile (line 11) | public static byte[] getFile() {
    method getFolder (line 15) | public static byte[] getFolder() {
    method getHome (line 19) | public static byte[] getHome() {
    method getUpDir (line 23) | public static byte[] getUpDir() {
    method getArrow (line 27) | public static byte[] getArrow() {

FILE: modules/book/src/main/java/me/ag2s/base/PfdHelper.java
  class PfdHelper (line 15) | @SuppressWarnings("unused")
    method seek (line 23) | public static void seek(ParcelFileDescriptor pfd, long pos) throws IOE...
    method getFilePointer (line 32) | public static long getFilePointer(ParcelFileDescriptor pfd) throws IOE...
    method length (line 40) | public static long length(ParcelFileDescriptor pfd) throws IOException {
    method readBytes (line 48) | private static int readBytes(ParcelFileDescriptor pfd, byte[] b, int o...
    method read (line 56) | public static int read(ParcelFileDescriptor pfd) throws IOException {
    method read (line 60) | public static int read(ParcelFileDescriptor pfd, byte[] b, int off, in...
    method read (line 64) | public static int read(ParcelFileDescriptor pfd, byte[] b) throws IOEx...
    method readFully (line 68) | public static void readFully(ParcelFileDescriptor pfd, byte[] b) throw...
    method readFully (line 72) | public static void readFully(ParcelFileDescriptor pfd, byte[] b, int o...
    method skipBytes (line 83) | public static int skipBytes(ParcelFileDescriptor pfd, int n) throws IO...

FILE: modules/book/src/main/java/me/ag2s/base/ThrowableUtils.java
  class ThrowableUtils (line 7) | public class ThrowableUtils {
    method rethrowAsIOException (line 10) | public static @NonNull

FILE: modules/book/src/main/java/me/ag2s/epublib/Constants.java
  type Constants (line 4) | public interface Constants {

FILE: modules/book/src/main/java/me/ag2s/epublib/browsersupport/NavigationEvent.java
  class NavigationEvent (line 15) | @SuppressWarnings("unused")
    method NavigationEvent (line 27) | public NavigationEvent(Object source) {
    method NavigationEvent (line 31) | public NavigationEvent(Object source, Navigator navigator) {
    method getOldSectionPos (line 46) | public int getOldSectionPos() {
    method getNavigator (line 50) | public Navigator getNavigator() {
    method getOldFragmentId (line 54) | public String getOldFragmentId() {
    method setOldFragmentId (line 59) | void setOldFragmentId(String oldFragmentId) {
    method getOldBook (line 63) | public EpubBook getOldBook() {
    method setOldPagePos (line 68) | void setOldPagePos(int oldPagePos) {
    method getCurrentSectionPos (line 72) | public int getCurrentSectionPos() {
    method getOldSpinePos (line 76) | public int getOldSpinePos() {
    method getCurrentSpinePos (line 80) | public int getCurrentSpinePos() {
    method getCurrentFragmentId (line 84) | public String getCurrentFragmentId() {
    method isBookChanged (line 88) | public boolean isBookChanged() {
    method isSpinePosChanged (line 95) | public boolean isSpinePosChanged() {
    method isFragmentChanged (line 99) | public boolean isFragmentChanged() {
    method getOldResource (line 103) | public Resource getOldResource() {
    method getCurrentResource (line 107) | public Resource getCurrentResource() {
    method setOldResource (line 111) | public void setOldResource(Resource oldResource) {
    method setOldSpinePos (line 116) | public void setOldSpinePos(int oldSpinePos) {
    method setNavigator (line 121) | public void setNavigator(Navigator navigator) {
    method setOldBook (line 126) | public void setOldBook(EpubBook oldBook) {
    method getCurrentBook (line 130) | public EpubBook getCurrentBook() {
    method isResourceChanged (line 134) | public boolean isResourceChanged() {
    method toString (line 138) | @SuppressWarnings("NullableProblems")
    method isSectionPosChanged (line 154) | public boolean isSectionPosChanged() {

FILE: modules/book/src/main/java/me/ag2s/epublib/browsersupport/NavigationEventListener.java
  type NavigationEventListener (line 9) | public interface NavigationEventListener {
    method navigationPerformed (line 16) | void navigationPerformed(NavigationEvent navigationEvent);

FILE: modules/book/src/main/java/me/ag2s/epublib/browsersupport/NavigationHistory.java
  class NavigationHistory (line 14) | public class NavigationHistory implements NavigationEventListener {
    class Location (line 19) | private static class Location {
      method Location (line 23) | public Location(String href) {
      method setHref (line 28) | @SuppressWarnings("unused")
      method getHref (line 33) | public String getHref() {
    method NavigationHistory (line 46) | public NavigationHistory(Navigator navigator) {
    method getCurrentPos (line 52) | public int getCurrentPos() {
    method getCurrentSize (line 57) | public int getCurrentSize() {
    method initBook (line 61) | public void initBook(EpubBook book) {
    method getHistoryWaitTime (line 82) | public long getHistoryWaitTime() {
    method setHistoryWaitTime (line 86) | public void setHistoryWaitTime(long historyWaitTime) {
    method addLocation (line 90) | public void addLocation(Resource resource) {
    method addLocation (line 110) | public void addLocation(Location location) {
    method checkHistorySize (line 130) | private void checkHistorySize() {
    method addLocation (line 138) | public void addLocation(String href) {
    method getLocationHref (line 142) | private String getLocationHref(int pos) {
    method move (line 159) | public boolean move(int delta) {
    method navigationPerformed (line 174) | @Override
    method getCurrentHref (line 193) | public String getCurrentHref() {
    method setMaxHistorySize (line 200) | public void setMaxHistorySize(int maxHistorySize) {
    method getMaxHistorySize (line 204) | public int getMaxHistorySize() {

FILE: modules/book/src/main/java/me/ag2s/epublib/browsersupport/Navigator.java
  class Navigator (line 19) | public class Navigator implements Serializable {
    method Navigator (line 30) | public Navigator() {
    method Navigator (line 34) | public Navigator(EpubBook book) {
    method handleEventListeners (line 43) | private synchronized void handleEventListeners(
    method addNavigationEventListener (line 51) | public boolean addNavigationEventListener(
    method removeNavigationEventListener (line 56) | public boolean removeNavigationEventListener(
    method gotoFirstSpineSection (line 61) | public int gotoFirstSpineSection(Object source) {
    method gotoPreviousSpineSection (line 65) | public int gotoPreviousSpineSection(Object source) {
    method gotoPreviousSpineSection (line 69) | public int gotoPreviousSpineSection(int pagePos, Object source) {
    method hasNextSpineSection (line 77) | public boolean hasNextSpineSection() {
    method hasPreviousSpineSection (line 81) | public boolean hasPreviousSpineSection() {
    method gotoNextSpineSection (line 85) | public int gotoNextSpineSection(Object source) {
    method gotoResource (line 93) | public int gotoResource(String resourceHref, Object source) {
    method gotoResource (line 99) | public int gotoResource(Resource resource, Object source) {
    method gotoResource (line 103) | public int gotoResource(Resource resource, String fragmentId, Object s...
    method gotoResource (line 107) | public int gotoResource(Resource resource, int pagePos, Object source) {
    method gotoResource (line 111) | public int gotoResource(Resource resource, int pagePos, String fragmen...
    method gotoResourceId (line 126) | public int gotoResourceId(String resourceId, Object source) {
    method gotoSpineSection (line 131) | public int gotoSpineSection(int newSpinePos, Object source) {
    method gotoSpineSection (line 143) | public int gotoSpineSection(int newSpinePos, int newPagePos, Object so...
    method gotoLastSpineSection (line 158) | public int gotoLastSpineSection(Object source) {
    method gotoBook (line 162) | public void gotoBook(EpubBook book, Object source) {
    method getCurrentSpinePos (line 177) | public int getCurrentSpinePos() {
    method getCurrentResource (line 181) | public Resource getCurrentResource() {
    method setCurrentSpinePos (line 192) | public void setCurrentSpinePos(int currentIndex) {
    method getBook (line 197) | public EpubBook getBook() {
    method setCurrentResource (line 206) | public int setCurrentResource(Resource currentResource) {
    method getCurrentFragmentId (line 212) | public String getCurrentFragmentId() {
    method getCurrentSectionPos (line 216) | public int getCurrentSectionPos() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Author.java
  class Author (line 13) | public class Author implements Serializable {
    method Author (line 21) | public Author(String singleName) {
    method Author (line 25) | public Author(String firstname, String lastname) {
    method getFirstname (line 30) | public String getFirstname() {
    method setFirstname (line 34) | public void setFirstname(String firstname) {
    method getLastname (line 38) | public String getLastname() {
    method setLastname (line 42) | public void setLastname(String lastname) {
    method toString (line 47) | @Override
    method hashCode (line 53) | public int hashCode() {
    method equals (line 57) | public boolean equals(Object authorObject) {
    method setRole (line 72) | public void setRole(String code) {
    method getRelator (line 80) | public Relator getRelator() {
    method setRelator (line 85) | public void setRelator(Relator relator) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Date.java
  class Date (line 16) | public class Date implements Serializable {
    type Event (line 20) | public enum Event {
      method Event (line 27) | Event(String v) {
      method fromValue (line 31) | public static Event fromValue(String v) {
      method toString (line 40) | @Override
    method Date (line 51) | public Date() {
    method Date (line 55) | public Date(java.util.Date date) {
    method Date (line 59) | public Date(String dateString) {
    method Date (line 63) | public Date(java.util.Date date, Event event) {
    method Date (line 68) | public Date(String dateString, Event event) {
    method Date (line 73) | public Date(java.util.Date date, String event) {
    method Date (line 78) | public Date(String dateString, String event) {
    method checkDate (line 83) | private static String checkDate(String dateString) {
    method getValue (line 91) | public String getValue() {
    method getEvent (line 95) | public Event getEvent() {
    method setEvent (line 99) | public void setEvent(Event event) {
    method toString (line 103) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/EpubBook.java
  class EpubBook (line 43) | public class EpubBook implements Serializable {
    method getVersion (line 59) | public String getVersion() {
    method setVersion (line 63) | public void setVersion(String version) {
    method isEpub3 (line 67) | public boolean isEpub3() {
    method addSection (line 71) | @SuppressWarnings("UnusedReturnValue")
    method addSection (line 87) | public TOCReference addSection(
    method addSection (line 98) | public TOCReference addSection(String title, Resource resource) {
    method addSection (line 111) | public TOCReference addSection(
    method generateSpineFromTableOfContents (line 122) | @SuppressWarnings("unused")
    method getMetadata (line 137) | public Metadata getMetadata() {
    method setMetadata (line 141) | public void setMetadata(Metadata metadata) {
    method setResources (line 146) | public void setResources(Resources resources) {
    method addResource (line 150) | @SuppressWarnings("unused")
    method getResources (line 162) | public Resources getResources() {
    method getSpine (line 173) | public Spine getSpine() {
    method setSpine (line 178) | public void setSpine(Spine spine) {
    method getTableOfContents (line 188) | public TableOfContents getTableOfContents() {
    method setTableOfContents (line 193) | public void setTableOfContents(TableOfContents tableOfContents) {
    method getCoverPage (line 203) | public Resource getCoverPage() {
    method setCoverPage (line 212) | public void setCoverPage(Resource coverPage) {
    method getTitle (line 227) | public String getTitle() {
    method getCoverImage (line 237) | public Resource getCoverImage() {
    method setCoverImage (line 241) | public void setCoverImage(Resource coverImage) {
    method getGuide (line 258) | public Guide getGuide() {
    method getContents (line 280) | public List<Resource> getContents() {
    method addToContentsResult (line 299) | private static void addToContentsResult(Resource resource,
    method getOpfResource (line 307) | public Resource getOpfResource() {
    method setOpfResource (line 311) | public void setOpfResource(Resource opfResource) {
    method setNcxResource (line 315) | public void setNcxResource(Resource ncxResource) {
    method getNcxResource (line 319) | public Resource getNcxResource() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/EpubResourceProvider.java
  class EpubResourceProvider (line 14) | public class EpubResourceProvider implements LazyResourceProvider {
    method EpubResourceProvider (line 20) | public EpubResourceProvider(ZipFileWrapper zipFileWrapper) {
    method getResourceStream (line 25) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/FileResourceProvider.java
  class FileResourceProvider (line 12) | public class FileResourceProvider implements LazyResourceProvider {
    method FileResourceProvider (line 21) | public FileResourceProvider(String parentDir) {
    method FileResourceProvider (line 30) | @SuppressWarnings("unused")
    method getResourceStream (line 42) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Guide.java
  class Guide (line 18) | public class Guide implements Serializable {
    method getReferences (line 33) | public List<GuideReference> getReferences() {
    method setReferences (line 37) | public void setReferences(List<GuideReference> references) {
    method uncheckCoverPage (line 42) | private void uncheckCoverPage() {
    method getCoverReference (line 46) | public GuideReference getCoverReference() {
    method setCoverReference (line 54) | @SuppressWarnings("UnusedReturnValue")
    method checkCoverPage (line 65) | private void checkCoverPage() {
    method initCoverPage (line 72) | private void initCoverPage() {
    method getCoverPage (line 89) | public Resource getCoverPage() {
    method setCoverPage (line 97) | public void setCoverPage(Resource coverPage) {
    method addReference (line 103) | @SuppressWarnings("UnusedReturnValue")
    method getGuideReferencesByType (line 118) | public List<GuideReference> getGuideReferencesByType(

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/GuideReference.java
  class GuideReference (line 14) | public class GuideReference extends TitledResourceReference
    method GuideReference (line 75) | public GuideReference(Resource resource) {
    method GuideReference (line 79) | public GuideReference(Resource resource, String title) {
    method GuideReference (line 83) | public GuideReference(Resource resource, String type, String title) {
    method GuideReference (line 87) | public GuideReference(Resource resource, String type, String title,
    method getType (line 93) | public String getType() {
    method setType (line 97) | public void setType(String type) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Identifier.java
  class Identifier (line 16) | public class Identifier implements Serializable {
    type Scheme (line 20) | @SuppressWarnings("unused")
    method Identifier (line 36) | public Identifier() {
    method Identifier (line 41) | public Identifier(String scheme, String value) {
    method getBookIdIdentifier (line 57) | public static Identifier getBookIdIdentifier(List<Identifier> identifi...
    method getScheme (line 77) | public String getScheme() {
    method setScheme (line 81) | public void setScheme(String scheme) {
    method getValue (line 85) | public String getValue() {
    method setValue (line 89) | public void setValue(String value) {
    method setBookId (line 94) | public void setBookId(boolean bookId) {
    method isBookId (line 108) | public boolean isBookId() {
    method hashCode (line 112) | public int hashCode() {
    method equals (line 117) | public boolean equals(Object otherIdentifier) {
    method toString (line 125) | @SuppressWarnings("NullableProblems")

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/LazyResource.java
  class LazyResource (line 15) | public class LazyResource extends Resource {
    method LazyResource (line 29) | public LazyResource(LazyResourceProvider resourceProvider, String href) {
    method LazyResource (line 33) | public LazyResource(LazyResourceProvider resourceProvider, String href...
    method LazyResource (line 46) | public LazyResource(
    method LazyResource (line 53) | public LazyResource(
    method getInputStream (line 66) | public InputStream getInputStream() throws IOException {
    method initialize (line 79) | public void initialize() throws IOException {
    method getData (line 92) | public byte[] getData() throws IOException {
    method close (line 118) | public void close() {
    method isInitialized (line 129) | public boolean isInitialized() {
    method getSize (line 138) | public long getSize() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/LazyResourceProvider.java
  type LazyResourceProvider (line 9) | public interface LazyResourceProvider {
    method getResourceStream (line 11) | InputStream getResourceStream(String href) throws IOException;

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/ManifestItemProperties.java
  type ManifestItemProperties (line 3) | @SuppressWarnings("unused")
    method ManifestItemProperties (line 15) | ManifestItemProperties(String name) {
    method getName (line 19) | public String getName() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/ManifestItemRefProperties.java
  type ManifestItemRefProperties (line 3) | @SuppressWarnings("unused")
    method ManifestItemRefProperties (line 10) | ManifestItemRefProperties(String name) {
    method getName (line 14) | public String getName() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/ManifestProperties.java
  type ManifestProperties (line 3) | public interface ManifestProperties {
    method getName (line 5) | String getName();

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/MediaType.java
  class MediaType (line 17) | public class MediaType implements Serializable {
    method MediaType (line 24) | public MediaType(String name, String defaultExtension) {
    method MediaType (line 28) | public MediaType(String name, String defaultExtension,
    method hashCode (line 33) | public int hashCode() {
    method MediaType (line 40) | public MediaType(String name, String defaultExtension,
    method getName (line 48) | public String getName() {
    method getDefaultExtension (line 53) | public String getDefaultExtension() {
    method getExtensions (line 58) | public Collection<String> getExtensions() {
    method equals (line 62) | public boolean equals(Object otherMediaType) {
    method toString (line 69) | @SuppressWarnings("NullableProblems")

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/MediaTypes.java
  class MediaTypes (line 14) | public class MediaTypes {
    method isBitmapImage (line 73) | public static boolean isBitmapImage(MediaType mediaType) {
    method isImage (line 77) | public static boolean isImage(MediaType mediaType) {
    method determineMediaType (line 88) | public static MediaType determineMediaType(String filename) {
    method getMediaTypeByName (line 99) | public static MediaType getMediaTypeByName(String mediaTypeName) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Metadata.java
  class Metadata (line 20) | public class Metadata implements Serializable {
    method Metadata (line 42) | public Metadata() {
    method isAutoGeneratedId (line 47) | @SuppressWarnings("unused")
    method getOtherProperties (line 57) | public Map<QName, String> getOtherProperties() {
    method setOtherProperties (line 61) | public void setOtherProperties(Map<QName, String> otherProperties) {
    method addDate (line 65) | @SuppressWarnings("unused")
    method getDates (line 71) | public List<Date> getDates() {
    method setDates (line 75) | public void setDates(List<Date> dates) {
    method addAuthor (line 79) | @SuppressWarnings("UnusedReturnValue")
    method getAuthors (line 85) | public List<Author> getAuthors() {
    method setAuthors (line 89) | public void setAuthors(List<Author> authors) {
    method addContributor (line 93) | @SuppressWarnings("UnusedReturnValue")
    method getContributors (line 99) | public List<Author> getContributors() {
    method setContributors (line 103) | public void setContributors(List<Author> contributors) {
    method getLanguage (line 107) | public String getLanguage() {
    method setLanguage (line 111) | public void setLanguage(String language) {
    method getSubjects (line 115) | public List<String> getSubjects() {
    method setSubjects (line 119) | public void setSubjects(List<String> subjects) {
    method setRights (line 123) | public void setRights(List<String> rights) {
    method getRights (line 127) | public List<String> getRights() {
    method getFirstTitle (line 138) | public String getFirstTitle() {
    method addTitle (line 150) | public String addTitle(String title) {
    method setTitles (line 155) | public void setTitles(List<String> titles) {
    method getTitles (line 159) | public List<String> getTitles() {
    method addPublisher (line 163) | @SuppressWarnings("UnusedReturnValue")
    method setPublishers (line 169) | public void setPublishers(List<String> publishers) {
    method getPublishers (line 173) | public List<String> getPublishers() {
    method addDescription (line 177) | @SuppressWarnings("UnusedReturnValue")
    method setDescriptions (line 183) | public void setDescriptions(List<String> descriptions) {
    method getDescriptions (line 187) | public List<String> getDescriptions() {
    method addIdentifier (line 191) | @SuppressWarnings("unused")
    method setIdentifiers (line 202) | public void setIdentifiers(List<Identifier> identifiers) {
    method getIdentifiers (line 207) | public List<Identifier> getIdentifiers() {
    method setFormat (line 211) | public void setFormat(String format) {
    method getFormat (line 215) | public String getFormat() {
    method addType (line 219) | @SuppressWarnings("UnusedReturnValue")
    method getTypes (line 225) | public List<String> getTypes() {
    method setTypes (line 229) | public void setTypes(List<String> types) {
    method getMetaAttribute (line 233) | @SuppressWarnings("unused")
    method setMetaAttributes (line 238) | public void setMetaAttributes(Map<String, String> metaAttributes) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Relator.java
  type Relator (line 14) | public enum Relator {
    method Relator (line 1121) | Relator(String code, String name) {
    method getCode (line 1126) | public String getCode() {
    method getName (line 1130) | public String getName() {
    method byCode (line 1134) | public static Relator byCode(String code) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Resource.java
  class Resource (line 20) | public class Resource implements Serializable {
    method Resource (line 41) | public Resource(String href) {
    method Resource (line 54) | public Resource(byte[] data, MediaType mediaType) {
    method Resource (line 68) | public Resource(byte[] data, String href) {
    method Resource (line 81) | public Resource(Reader in, String href) throws IOException {
    method Resource (line 101) | public Resource(InputStream in, String href) throws IOException {
    method Resource (line 115) | public Resource(String id, byte[] data, String href, MediaType mediaTy...
    method Resource (line 119) | public Resource(String id, byte[] data, String href, String originalHr...
    method Resource (line 134) | public Resource(String id, byte[] data, String href, MediaType mediaType,
    method Resource (line 144) | public Resource(String id, byte[] data, String href, String originalHr...
    method getInputStream (line 160) | public InputStream getInputStream() throws IOException {
    method getData (line 169) | public byte[] getData() throws IOException {
    method close (line 178) | public void close() {
    method setData (line 187) | public void setData(byte[] data) {
    method getSize (line 196) | public long getSize() {
    method getTitle (line 205) | public String getTitle() {
    method setId (line 214) | public void setId(String id) {
    method getId (line 225) | public String getId() {
    method getHref (line 238) | public String getHref() {
    method setHref (line 247) | public void setHref(String href) {
    method getInputEncoding (line 257) | public String getInputEncoding() {
    method setInputEncoding (line 266) | public void setInputEncoding(String encoding) {
    method getReader (line 278) | public Reader getReader() throws IOException {
    method hashCode (line 286) | public int hashCode() {
    method equals (line 295) | public boolean equals(Object resourceObject) {
    method getMediaType (line 307) | public MediaType getMediaType() {
    method setMediaType (line 311) | public void setMediaType(MediaType mediaType) {
    method setTitle (line 315) | public void setTitle(String title) {
    method getProperties (line 319) | public String getProperties() {
    method setProperties (line 323) | public void setProperties(String properties) {
    method toString (line 327) | @SuppressWarnings("NullableProblems")

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/ResourceInputStream.java
  class ResourceInputStream (line 13) | public class ResourceInputStream extends FilterInputStream {
    method ResourceInputStream (line 22) | public ResourceInputStream(InputStream in) {
    method close (line 27) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/ResourceReference.java
  class ResourceReference (line 5) | public class ResourceReference implements Serializable {
    method ResourceReference (line 11) | public ResourceReference(Resource resource) {
    method getResource (line 16) | public Resource getResource() {
    method setResource (line 25) | public void setResource(Resource resource) {
    method getResourceId (line 37) | public String getResourceId() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Resources.java
  class Resources (line 24) | public class Resources implements Serializable {
    method add (line 44) | public Resource add(Resource resource) {
    method fixResourceId (line 57) | public void fixResourceId(Resource resource) {
    method makeValidId (line 81) | private String makeValidId(String resourceId, Resource resource) {
    method getResourceItemPrefix (line 89) | private String getResourceItemPrefix(Resource resource) {
    method createUniqueResourceId (line 105) | private String createUniqueResourceId(Resource resource) {
    method containsId (line 131) | public boolean containsId(String id) {
    method getById (line 144) | public Resource getById(String id) {
    method getByProperties (line 151) | public Resource getByProperties(String properties) {
    method remove (line 169) | public Resource remove(String href) {
    method fixResourceHref (line 173) | private void fixResourceHref(Resource resource) {
    method createHref (line 192) | private String createHref(MediaType mediaType, int counter) {
    method isEmpty (line 201) | public boolean isEmpty() {
    method size (line 210) | public int size() {
    method getResourceMap (line 220) | @SuppressWarnings("unused")
    method getAll (line 225) | public Collection<Resource> getAll() {
    method notContainsByHref (line 236) | public boolean notContainsByHref(String href) {
    method containsByHref (line 251) | @SuppressWarnings("unused")
    method set (line 261) | public void set(Collection<Resource> resources) {
    method addAll (line 272) | public void addAll(Collection<Resource> resources) {
    method set (line 283) | public void set(Map<String, Resource> resources) {
    method getByIdOrHref (line 299) | public Resource getByIdOrHref(String idOrHref) {
    method getByHref (line 315) | public Resource getByHref(String href) {
    method findFirstResourceByMediaType (line 344) | public Resource findFirstResourceByMediaType(MediaType mediaType) {
    method findFirstResourceByMediaType (line 356) | public static Resource findFirstResourceByMediaType(
    method getResourcesByMediaType (line 372) | public List<Resource> getResourcesByMediaType(MediaType mediaType) {
    method getResourcesByMediaTypes (line 391) | @SuppressWarnings("unused")
    method getAllHrefs (line 415) | public Collection<String> getAllHrefs() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/Spine.java
  class Spine (line 18) | public class Spine implements Serializable {
    method Spine (line 24) | public Spine() {
    method Spine (line 33) | public Spine(TableOfContents tableOfContents) {
    method Spine (line 38) | public Spine(List<SpineReference> spineReferences) {
    method createSpineReferences (line 42) | public static List<SpineReference> createSpineReferences(
    method getSpineReferences (line 52) | public List<SpineReference> getSpineReferences() {
    method setSpineReferences (line 56) | public void setSpineReferences(List<SpineReference> spineReferences) {
    method getResource (line 67) | public Resource getResource(int index) {
    method findFirstResourceById (line 82) | public int findFirstResourceById(String resourceId) {
    method addSpineReference (line 102) | public SpineReference addSpineReference(SpineReference spineReference) {
    method addResource (line 115) | @SuppressWarnings("unused")
    method size (line 125) | public int size() {
    method setTocResource (line 136) | public void setTocResource(Resource tocResource) {
    method getTocResource (line 146) | public Resource getTocResource() {
    method getResourceIndex (line 156) | public int getResourceIndex(Resource currentResource) {
    method getResourceIndex (line 168) | public int getResourceIndex(String resourceHref) {
    method isEmpty (line 187) | public boolean isEmpty() {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/SpineReference.java
  class SpineReference (line 12) | public class SpineReference extends ResourceReference implements Seriali...
    method SpineReference (line 17) | public SpineReference(Resource resource) {
    method SpineReference (line 22) | public SpineReference(Resource resource, boolean linear) {
    method isLinear (line 44) | public boolean isLinear() {
    method setLinear (line 48) | public void setLinear(boolean linear) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/TOCReference.java
  class TOCReference (line 14) | public class TOCReference extends TitledResourceReference
    method TOCReference (line 21) | @Deprecated
    method TOCReference (line 26) | public TOCReference(String name, Resource resource) {
    method TOCReference (line 30) | public TOCReference(String name, Resource resource, String fragmentId) {
    method TOCReference (line 34) | public TOCReference(String title, Resource resource, String fragmentId,
    method getComparatorByTitleIgnoreCase (line 40) | @SuppressWarnings("unused")
    method getChildren (line 45) | public List<TOCReference> getChildren() {
    method addChildSection (line 49) | public TOCReference addChildSection(TOCReference childSection) {
    method setChildren (line 54) | public void setChildren(List<TOCReference> children) {

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/TableOfContents.java
  class TableOfContents (line 22) | public class TableOfContents implements Serializable {
    method TableOfContents (line 30) | public TableOfContents() {
    method TableOfContents (line 34) | public TableOfContents(List<TOCReference> tocReferences) {
    method getTocReferences (line 38) | public List<TOCReference> getTocReferences() {
    method setTocReferences (line 42) | public void setTocReferences(List<TOCReference> tocReferences) {
    method addSection (line 51) | @SuppressWarnings("unused")
    method addSection (line 64) | public TOCReference addSection(Resource resource, String path,
    method findTocReferenceByTitle (line 77) | private static TOCReference findTocReferenceByTitle(String title,
    method addSection (line 103) | public TOCReference addSection(Resource resource, String[] pathElement...
    method addSection (line 137) | @SuppressWarnings("unused")
    method paddTOCReferences (line 164) | private void paddTOCReferences(List<TOCReference> currentTocReferences,
    method createSectionTitle (line 175) | private String createSectionTitle(int[] pathElements, int pathPos,
    method addTOCReference (line 192) | public TOCReference addTOCReference(TOCReference tocReference) {
    method getAllUniqueResources (line 205) | public List<Resource> getAllUniqueResources() {
    method getAllUniqueResources (line 212) | private static void getAllUniqueResources(
    method size (line 232) | public int size() {
    method getTotalSize (line 236) | private static int getTotalSize(Collection<TOCReference> tocReferences) {
    method calculateDepth (line 249) | public int calculateDepth() {
    method calculateDepth (line 253) | private int calculateDepth(List<TOCReference> tocReferences,

FILE: modules/book/src/main/java/me/ag2s/epublib/domain/TitledResourceReference.java
  class TitledResourceReference (line 8) | public class TitledResourceReference extends ResourceReference
    method TitledResourceReference (line 20) | @Deprecated
    method TitledResourceReference (line 26) | public TitledResourceReference(Resource resource, String title) {
    method TitledResourceReference (line 30) | public TitledResourceReference(Resource resource, String title,
    method getFragmentId (line 37) | public String getFragmentId() {
    method setFragmentId (line 41) | public void setFragmentId(String fragmentId) {
    method getTitle (line 45) | public String getTitle() {
    method setTitle (line 49) | public void setTitle(String title) {
    method getCompleteHref (line 61) | public String getCompleteHref() {
    method getResource (line 70) | @Override
    method setResource (line 80) | public void setResource(Resource resource, String fragmentId) {
    method setResource (line 88) | public void setResource(Resource resource) {

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/BookProcessor.java
  type BookProcessor (line 12) | public interface BookProcessor {
    method processBook (line 19) | EpubBook processBook(EpubBook book);

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/BookProcessorPipeline.java
  class BookProcessorPipeline (line 19) | @SuppressWarnings("unused declaration")
    method BookProcessorPipeline (line 25) | public BookProcessorPipeline() {
    method BookProcessorPipeline (line 29) | public BookProcessorPipeline(List<BookProcessor> bookProcessingPipelin...
    method processBook (line 33) | @Override
    method addBookProcessor (line 48) | public void addBookProcessor(BookProcessor bookProcessor) {
    method addBookProcessors (line 55) | public void addBookProcessors(Collection<BookProcessor> bookProcessors) {
    method getBookProcessors (line 63) | public List<BookProcessor> getBookProcessors() {
    method setBookProcessingPipeline (line 68) | public void setBookProcessingPipeline(

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/DOMUtil.java
  class DOMUtil (line 20) | class DOMUtil {
    method getAttribute (line 30) | public static String getAttribute(Element element, String namespace,
    method getElementsTextChild (line 47) | public static List<String> getElementsTextChild(Element parentElement,
    method getFindAttributeValue (line 71) | public static String getFindAttributeValue(Document document,
    method getElementsByTagNameNS (line 95) | public static NodeList getElementsByTagNameNS(Element parentElement,
    method getElementsByTagNameNS (line 116) | public static NodeList getElementsByTagNameNS(Document parentElement,
    method getFirstElementByTagNameNS (line 137) | public static Element getFirstElementByTagNameNS(Element parentElement,
    method getTextChildrenContent (line 161) | public static String getTextChildrenContent(Element parentElement) {

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/EpubProcessorSupport.java
  class EpubProcessorSupport (line 30) | public class EpubProcessorSupport {
    class EntityResolverImpl (line 40) | static class EntityResolverImpl implements EntityResolver {
      method resolveEntity (line 44) | @Override
    method init (line 71) | private static void init() {
    method createXmlSerializer (line 78) | public static XmlSerializer createXmlSerializer(OutputStream out)
    method createXmlSerializer (line 84) | public static XmlSerializer createXmlSerializer(Writer out) {
    method getEntityResolver (line 115) | public static EntityResolver getEntityResolver() {
    method getDocumentBuilderFactory (line 119) | @SuppressWarnings("unused")
    method createDocumentBuilder (line 129) | public static DocumentBuilder createDocumentBuilder() {

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/EpubReader.java
  class EpubReader (line 33) | @SuppressWarnings("ALL")
    method readEpub (line 39) | public EpubBook readEpub(InputStream in) throws IOException {
    method readEpub (line 43) | public EpubBook readEpub(ZipInputStream in) throws IOException {
    method readEpub (line 47) | public EpubBook readEpub(ZipFile zipfile) throws IOException {
    method readEpub (line 59) | public EpubBook readEpub(InputStream in, String encoding) throws IOExc...
    method readEpubLazy (line 72) | public EpubBook readEpubLazy(@NonNull ZipFile zipFile, @NonNull String...
    method readEpubLazy (line 77) | public EpubBook readEpubLazy(@NonNull AndroidZipFile zipFile, @NonNull...
    method readEpub (line 82) | public EpubBook readEpub(@NonNull ZipInputStream in, @NonNull String e...
    method readEpub (line 86) | public EpubBook readEpub(ZipFile in, String encoding) throws IOExcepti...
    method readEpubLazy (line 99) | public EpubBook readEpubLazy(@NonNull ZipFile zipFile, @NonNull String...
    method readEpubLazy (line 106) | public EpubBook readEpubLazy(@NonNull AndroidZipFile zipFile, @NonNull...
    method readEpub (line 113) | public EpubBook readEpub(Resources resources) {
    method readEpub (line 117) | public EpubBook readEpub(Resources resources, EpubBook result) {
    method postProcessBook (line 131) | private EpubBook postProcessBook(EpubBook book) {
    method processNcxResource (line 138) | private Resource processNcxResource(Resource packageResource, EpubBook...
    method processPackageResource (line 148) | private Resource processPackageResource(String packageResourceHref, Ep...
    method getPackageResourceHref (line 159) | private String getPackageResourceHref(Resources resources) {
    method handleMimeType (line 182) | private void handleMimeType(EpubBook result, Resources resources) {

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/EpubWriter.java
  class EpubWriter (line 27) | public class EpubWriter {
    method EpubWriter (line 36) | public EpubWriter() {
    method EpubWriter (line 46) | public EpubWriter(BookProcessor bookProcessor) {
    method setCallback (line 50) | public EpubWriter setCallback(EpubWriterProcessor.Callback callback) {
    method write (line 55) | public void write(EpubBook book, OutputStream out) throws IOException {
    method processBook (line 77) | private EpubBook processBook(EpubBook book) {
    method initTOCResource (line 84) | private void initTOCResource(EpubBook book) {
    method writeResources (line 105) | private void writeResources(EpubBook book, ZipOutputStream resultStrea...
    method writeResource (line 118) | private void writeResource(Resource resource, ZipOutputStream resultSt...
    method writePackageDocument (line 134) | private void writePackageDocument(EpubBook book, ZipOutputStream resul...
    method writeContainer (line 149) | private void writeContainer(ZipOutputStream resultStream) throws IOExc...
    method writeMimeType (line 167) | private void writeMimeType(ZipOutputStream resultStream) throws IOExce...
    method calculateCrc (line 177) | private long calculateCrc(byte[] data) {
    method getNcxId (line 183) | String getNcxId() {
    method getNcxHref (line 187) | String getNcxHref() {
    method getNcxMediaType (line 191) | String getNcxMediaType() {
    method getBookProcessor (line 196) | @SuppressWarnings("unused")
    method setBookProcessor (line 201) | @SuppressWarnings("unused")

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/EpubWriterProcessor.java
  class EpubWriterProcessor (line 12) | public class EpubWriterProcessor {
    method getCurrentProgress (line 17) | public int getCurrentProgress() {
    method getTotalProgress (line 21) | public int getTotalProgress() {
    method setTotalProgress (line 25) | public void setTotalProgress(int totalProgress) {
    method setCallback (line 29) | public void setCallback(Callback callback) {
    method updateCurrentProgress (line 33) | protected void updateCurrentProgress(int current) {
    method getCallback (line 41) | protected Callback getCallback() {
    type Callback (line 45) | @SuppressWarnings("unused")
      method onStart (line 47) | default void onStart(EpubBook epubBook) {
      method onProgressing (line 50) | default void onProgressing(int total, int progress) {
      method onEnd (line 53) | default void onEnd(EpubBook epubBook) {

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/HtmlProcessor.java
  type HtmlProcessor (line 7) | @SuppressWarnings("unused")
    method processHtmlResource (line 10) | void processHtmlResource(Resource resource, OutputStream out);

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java
  class NCXDocumentV2 (line 36) | public class NCXDocumentV2 {
    type NCXTags (line 47) | private interface NCXTags {
    type NCXAttributes (line 61) | private interface NCXAttributes {
    type NCXAttributeValues (line 72) | private interface NCXAttributeValues {
    method read (line 79) | @SuppressWarnings("unused")
    method readTOCReferences (line 109) | static List<TOCReference> readTOCReferences(NodeList navpoints,
    method readTOCReference (line 130) | static TOCReference readTOCReference(Element navpointElement, EpubBook...
    method readNavReference (line 161) | private static String readNavReference(Element navpointElement) {
    method readNavLabel (line 178) | private static String readNavLabel(Element navpointElement) {
    method write (line 188) | @SuppressWarnings("unused")
    method write (line 208) | public static void write(XmlSerializer xmlSerializer, EpubBook book)
    method createNCXResource (line 214) | public static Resource createNCXResource(EpubBook book)
    method createNCXResource (line 221) | public static Resource createNCXResource(List<Identifier> identifiers,
    method write (line 231) | public static void write(XmlSerializer serializer,
    method writeMetaElement (line 282) | private static void writeMetaElement(String dtbName, String content,
    method writeNavPoints (line 294) | private static int writeNavPoints(List<TOCReference> tocReferences,
    method writeNavPointStart (line 316) | private static void writeNavPointStart(TOCReference tocReference,
    method writeNavPointEnd (line 338) | @SuppressWarnings("unused")

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java
  class NCXDocumentV3 (line 36) | public class NCXDocumentV3 {
    type XHTMLTgs (line 49) | private interface XHTMLTgs {
    type XHTMLAttributes (line 65) | private interface XHTMLAttributes {
    type XHTMLAttributeValues (line 81) | private interface XHTMLAttributeValues {
    method read (line 98) | @SuppressWarnings("unused")
    method doToc (line 138) | private static List<TOCReference> doToc(Node n, EpubBook book) {
    method readTOCReferences (line 154) | static List<TOCReference> readTOCReferences(NodeList navpoints,
    method readTOCReference (line 181) | static TOCReference readTOCReference(Element navpointElement, EpubBook...
    method readNavReference (line 224) | private static String readNavReference(Element navpointElement) {
    method readNavLabel (line 252) | private static String readNavLabel(Element navpointElement) {
    method createNCXResource (line 272) | public static Resource createNCXResource(EpubBook book)
    method createNCXResource (line 279) | public static Resource createNCXResource(List<Identifier> identifiers,
    method write (line 301) | public static void write(XmlSerializer xmlSerializer, EpubBook book)
    method write (line 316) | @SuppressWarnings("unused")
    method writeNavPoints (line 360) | private static int writeNavPoints(List<TOCReference> tocReferences,
    method writeNavPointStart (line 386) | private static void writeNavPointStart(TOCReference tocReference, XmlS...
    method writeNavPointEnd (line 397) | @SuppressWarnings("unused")
    method writeLabel (line 403) | protected static void writeLabel(String title, String href, XmlSeriali...
    method writeLabel (line 412) | protected static void writeLabel(String title, XmlSerializer serialize...
    method writeLiStart (line 418) | private static void writeLiStart(XmlSerializer serializer) throws IOEx...
    method writeLiEnd (line 423) | private static void writeLiEnd(XmlSerializer serializer) throws IOExce...
    method writeOlStart (line 428) | private static void writeOlStart(XmlSerializer serializer) throws IOEx...
    method writeOlSEnd (line 433) | private static void writeOlSEnd(XmlSerializer serializer) throws IOExc...
    method writeHead (line 438) | private static void writeHead(String title, XmlSerializer serializer) ...

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentBase.java
  class PackageDocumentBase (line 9) | public class PackageDocumentBase {
    type DCTags (line 24) | protected interface DCTags {
    type DCAttributes (line 43) | protected interface DCAttributes {
    type OPFTags (line 49) | protected interface OPFTags {
    type OPFAttributes (line 62) | protected interface OPFAttributes {
    type OPFValues (line 88) | protected interface OPFValues {

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentMetadataReader.java
  class PackageDocumentMetadataReader (line 31) | class PackageDocumentMetadataReader extends PackageDocumentBase {
    method readMetadata (line 35) | public static Metadata readMetadata(Document packageDocument) {
    method readOtherProperties (line 85) | private static Map<QName, String> readOtherProperties(
    method readMetaProperties (line 111) | private static Map<String, String> readMetaProperties(
    method getBookIdId (line 126) | private static String getBookIdId(Document document) {
    method readCreators (line 137) | private static List<Author> readCreators(Element metadataElement) {
    method readContributors (line 141) | private static List<Author> readContributors(Element metadataElement) {
    method readAuthors (line 145) | private static List<Author> readAuthors(String authorTag,
    method readDates (line 161) | private static List<Date> readDates(Element metadataElement) {
    method createAuthor (line 180) | private static Author createAuthor(Element authorElement) {
    method readIdentifiers (line 199) | private static List<Identifier> readIdentifiers(Element metadataElemen...

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentMetadataWriter.java
  class PackageDocumentMetadataWriter (line 18) | public class PackageDocumentMetadataWriter extends PackageDocumentBase {
    method writeMetaData (line 29) | public static void writeMetaData(EpubBook book, XmlSerializer serializer)
    method writeSimpleMetdataElements (line 135) | private static void writeSimpleMetdataElements(String tagName,
    method writeIdentifiers (line 160) | private static void writeIdentifiers(List<Identifier> identifiers,

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java
  class PackageDocumentReader (line 45) | public class PackageDocumentReader extends PackageDocumentBase {
    method read (line 53) | public static void read(
    method ensureImageInfo (line 100) | private static ArrayList<Element> ensureImageInfo(Resources resources,
    method readManifest (line 159) | @SuppressWarnings("unused")
    method readGuide (line 219) | @SuppressWarnings("unused")
    method fixHrefs (line 275) | static Resources fixHrefs(String packageHref,
    method readSpine (line 300) | private static Spine readSpine(Document packageDocument, Resources res...
    method generateSpineFromResources (line 357) | private static Spine generateSpineFromResources(Resources resources) {
    method findTableOfContentsResource (line 383) | static Resource findTableOfContentsResource(
    method findCoverHrefs (line 439) | static Set<String> findCoverHrefs(Document packageDocument, URI packag...
    method resolvePath (line 473) | private static String resolvePath(URI parentPath, String href) {
    method readCover (line 490) | private static void readCover(Document packageDocument, URI packagePat...

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentWriter.java
  class PackageDocumentWriter (line 27) | public class PackageDocumentWriter extends PackageDocumentBase {
    method write (line 31) | public static void write(EpubWriter epubWriter, XmlSerializer serializer,
    method writeSpine (line 68) | @SuppressWarnings("unused")
    method writeManifest (line 96) | private static void writeManifest(EpubBook book, EpubWriter epubWriter,
    method getAllResourcesSortById (line 127) | private static List<Resource> getAllResourcesSortById(EpubBook book) {
    method writeItem (line 143) | private static void writeItem(EpubBook book, Resource resource,
    method writeSpineItems (line 184) | @SuppressWarnings("unused")
    method writeGuide (line 201) | private static void writeGuide(EpubBook book, EpubWriter epubWriter,
    method ensureCoverPageGuideReferenceWritten (line 213) | @SuppressWarnings("unused")
    method writeGuideReference (line 229) | private static void writeGuideReference(GuideReference reference,

FILE: modules/book/src/main/java/me/ag2s/epublib/epub/ResourcesLoader.java
  class ResourcesLoader (line 32) | public class ResourcesLoader {
    method loadResources (line 50) | public static Resources loadResources(
    method shouldLoadLazy (line 98) | private static boolean shouldLoadLazy(String href,
    method loadResources (line 119) | public static Resources loadResources(ZipInputStream zipInputStream,
    method getNextZipEntry (line 143) | private static ZipEntry getNextZipEntry(ZipInputStream zipInputStream)
    method loadResources (line 173) | public static Resources loadResources(ZipFileWrapper zipFile, String d...

FILE: modules/book/src/main/java/me/ag2s/epublib/util/CollectionUtil.java
  class CollectionUtil (line 8) | public class CollectionUtil {
    class IteratorEnumerationAdapter (line 16) | private static class IteratorEnumerationAdapter<T> implements Enumerat...
      method IteratorEnumerationAdapter (line 20) | public IteratorEnumerationAdapter(Iterator<T> iter) {
      method hasMoreElements (line 24) | @Override
      method nextElement (line 29) | @Override
    method createEnumerationFromIterator (line 42) | @SuppressWarnings("unused")
    method first (line 56) | public static <T> T first(List<T> list) {
    method isEmpty (line 69) | public static boolean isEmpty(Collection<?> collection) {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/IOUtil.java
  class IOUtil (line 30) | public class IOUtil {
    method toByteArray (line 65) | public static byte[] toByteArray(Reader in, String encoding)
    method toByteArray (line 80) | public static byte[] toByteArray(InputStream in) throws IOException {
    method toByteArray (line 99) | public static byte[] toByteArray(InputStream in, int size)
    method calcNewNrReadSize (line 133) | protected static int calcNewNrReadSize(int nrRead, int totalNrNread) {
    method copy (line 145) | public static void copy(InputStream in, OutputStream result) throws IO...
    method copy (line 164) | public static long copy(final InputStream input, final OutputStream ou...
    method copy (line 185) | @Deprecated
    method copy (line 207) | public static void copy(final InputStream input, final Writer output, ...
    method copy (line 235) | public static void copy(final InputStream input, final Writer output, ...
    method copy (line 258) | public static long copy(final Reader input, final Appendable output) t...
    method copy (line 277) | public static long copy(final Reader input, final Appendable output, f...
    method copy (line 308) | @Deprecated
    method copy (line 337) | public static void copy(final Reader input, final OutputStream output,...
    method copy (line 372) | public static void copy(final Reader input, final OutputStream output,...
    method copy (line 395) | public static int copy(final Reader input, final Writer output) throws...
    method copyLarge (line 421) | public static long copyLarge(final InputStream input, final OutputStre...
    method copyLarge (line 441) | public static long copyLarge(final InputStream input, final OutputStre...
    method copyLarge (line 479) | public static long copyLarge(final InputStream input, final OutputStre...
    method copyLarge (line 508) | public static long copyLarge(final InputStream input, final OutputStre...
    method copyLarge (line 549) | public static long copyLarge(final Reader input, final Writer output) ...
    method copyLarge (line 568) | public static long copyLarge(final Reader input, final Writer output, ...
    method copyLarge (line 597) | public static long copyLarge(final Reader input, final Writer output, ...
    method copyLarge (line 621) | public static long copyLarge(final Reader input, final Writer output, ...
    method skip (line 668) | public static long skip(final InputStream input, final long toSkip) th...
    method skip (line 702) | public static long skip(final ReadableByteChannel input, final long to...
    method skip (line 741) | public static long skip(final Reader input, final long toSkip) throws ...
    method skipFully (line 784) | public static void skipFully(final InputStream input, final long toSki...
    method skipFully (line 804) | public static void skipFully(final ReadableByteChannel input, final lo...
    method skipFully (line 833) | public static void skipFully(final Reader input, final long toSkip) th...
    method length (line 847) | public static int length(final byte[] array) {
    method length (line 858) | public static int length(final char[] array) {
    method length (line 869) | public static int length(final CharSequence csq) {
    method length (line 880) | public static int length(final Object[] array) {
    method close (line 891) | public static void close(final Closeable closeable) throws IOException {
    method close (line 904) | public static void close(final Closeable... closeables) throws IOExcep...
    method close (line 920) | public static void close(final Closeable closeable, final IOConsumer<I...
    method close (line 938) | public static void close(final URLConnection conn) {
    method Stream2String (line 944) | @SuppressWarnings("unused")

FILE: modules/book/src/main/java/me/ag2s/epublib/util/NoCloseOutputStream.java
  class NoCloseOutputStream (line 14) | @SuppressWarnings("unused")
    method NoCloseOutputStream (line 19) | public NoCloseOutputStream(OutputStream outputStream) {
    method write (line 23) | @Override
    method close (line 31) | public void close() {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/NoCloseWriter.java
  class NoCloseWriter (line 14) | @SuppressWarnings("unused")
    method NoCloseWriter (line 19) | public NoCloseWriter(Writer writer) {
    method close (line 23) | @Override
    method flush (line 27) | @Override
    method write (line 32) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/util/ResourceUtil.java
  class ResourceUtil (line 28) | public class ResourceUtil {
    method createChapterResource (line 37) | public static Resource createChapterResource(String title, String txt,...
    method createPublicResource (line 57) | public static Resource createPublicResource(String name, String author...
    method createResource (line 74) | @SuppressWarnings("unused")
    method createResource (line 92) | @SuppressWarnings("unused")
    method createResource (line 109) | public static Resource createResource(String name,
    method createResource (line 115) | public static Resource createResource(String name,
    method recode (line 130) | @SuppressWarnings("unused")
    method getInputSource (line 139) | @SuppressWarnings("unused")
    method getAsDocument (line 156) | public static Document getAsDocument(Resource resource)
    method getAsDocument (line 172) | public static Document getAsDocument(Resource resource,

FILE: modules/book/src/main/java/me/ag2s/epublib/util/StringUtil.java
  class StringUtil (line 17) | public class StringUtil {
    method collapsePathDots (line 27) | public static String collapsePathDots(String path) {
    method isNotBlank (line 61) | public static boolean isNotBlank(String text) {
    method isBlank (line 70) | public static boolean isBlank(String text) {
    method isEmpty (line 88) | public static boolean isEmpty(String text) {
    method endsWithIgnoreCase (line 100) | public static boolean endsWithIgnoreCase(String source, String suffix) {
    method startsWithIgnoreCase (line 114) | public static boolean startsWithIgnoreCase(String source, String prefi...
    method defaultIfNull (line 134) | public static String defaultIfNull(String text) {
    method defaultIfNull (line 145) | public static String defaultIfNull(String text, String defaultValue) {
    method equals (line 159) | public static boolean equals(String text1, String text2) {
    method toString (line 172) | public static String toString(Object... keyValues) {
    method hashCode (line 197) | public static int hashCode(String... values) {
    method substringBefore (line 215) | public static String substringBefore(String text, char separator) {
    method substringBeforeLast (line 237) | public static String substringBeforeLast(String text, char separator) {
    method substringAfterLast (line 258) | public static String substringAfterLast(String text, char separator) {
    method substringAfter (line 278) | public static String substringAfter(String text, char c) {
    method formatHtml (line 289) | public static String formatHtml(String text) {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/URLEncodeUtil.java
  class URLEncodeUtil (line 10) | public class URLEncodeUtil {
    method encode (line 37) | public static String encode(String s, Charset charset) {
    method encode (line 114) | public static String encode(String s) {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/commons/io/BOMInputStream.java
  class BOMInputStream (line 92) | public class BOMInputStream extends ProxyInputStream {
    method BOMInputStream (line 110) | @SuppressWarnings("unused")
    method BOMInputStream (line 121) | @SuppressWarnings("unused")
    method BOMInputStream (line 132) | @SuppressWarnings("unused")
    method BOMInputStream (line 153) | public BOMInputStream(final InputStream delegate, final boolean includ...
    method hasBOM (line 174) | @SuppressWarnings("unused")
    method hasBOM (line 187) | @SuppressWarnings("unused")
    method getBOM (line 202) | public ByteOrderMark getBOM() throws IOException {
    method getBOMCharsetName (line 237) | public String getBOMCharsetName() throws IOException {
    method readFirstBytes (line 250) | private int readFirstBytes() throws IOException {
    method find (line 260) | private ByteOrderMark find() {
    method matches (line 275) | private boolean matches(final ByteOrderMark bom) {
    method read (line 298) | @Override
    method read (line 313) | @Override
    method read (line 336) | @Override
    method mark (line 346) | @Override
    method reset (line 358) | @Override
    method skip (line 375) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/util/commons/io/ByteOrderMark.java
  class ByteOrderMark (line 32) | public class ByteOrderMark implements Serializable {
    method ByteOrderMark (line 87) | public ByteOrderMark(final String charsetName, final int... bytes) {
    method getCharsetName (line 104) | public String getCharsetName() {
    method length (line 113) | public int length() {
    method get (line 123) | public int get(final int pos) {
    method getBytes (line 132) | public byte[] getBytes() {
    method equals (line 147) | @Override
    method hashCode (line 170) | @Override
    method toString (line 184) | @Override

FILE: modules/book/src/main/java/me/ag2s/epublib/util/commons/io/IOConsumer.java
  type IOConsumer (line 30) | @FunctionalInterface
    method accept (line 39) | void accept(T t) throws IOException;
    method andThen (line 51) | @SuppressWarnings("unused")

FILE: modules/book/src/main/java/me/ag2s/epublib/util/commons/io/ProxyInputStream.java
  class ProxyInputStream (line 44) | public abstract class ProxyInputStream extends FilterInputStream {
    method ProxyInputStream (line 51) | public ProxyInputStream(final InputStream proxy) {
    method read (line 62) | @Override
    method read (line 82) | @Override
    method read (line 104) | @Override
    method skip (line 124) | @Override
    method available (line 140) | @Override
    method close (line 155) | @Override
    method mark (line 165) | @Override
    method reset (line 175) | @Override
    method markSupported (line 189) | @Override
    method beforeRead (line 211) | @SuppressWarnings("unused")
    method afterRead (line 233) | @SuppressWarnings("unused")
    method handleIOException (line 248) | protected void handleIOException(final IOException e) throws IOExcepti...

FILE: modules/book/src/main/java/me/ag2s/epublib/util/commons/io/XmlStreamReader.java
  class XmlStreamReader (line 75) | public class XmlStreamReader extends Reader {
    method getDefaultEncoding (line 130) | public String getDefaultEncoding() {
    method XmlStreamReader (line 146) | @SuppressWarnings("unused")
    method XmlStreamReader (line 162) | public XmlStreamReader(final InputStream inputStream) throws IOExcepti...
    method XmlStreamReader (line 193) | public XmlStreamReader(final InputStream inputStream, final boolean le...
    method XmlStreamReader (line 225) | public XmlStreamReader(final InputStream inputStream, final boolean le...
    method XmlStreamReader (line 252) | @SuppressWarnings("unused")
    method XmlStreamReader (line 276) | public XmlStreamReader(final URLConnection conn, final String defaultE...
    method XmlStreamReader (line 309) | public XmlStreamReader(final InputStream inputStream, final String htt...
    method XmlStreamReader (line 348) | public XmlStreamReader(final InputStream inputStream, final String htt...
    method XmlStreamReader (line 391) | public XmlStreamReader(final InputStream inputStream, final String htt...
    method getEncoding (line 401) | public String getEncoding() {
    method read (line 414) | @Override
    method close (line 424) | @Override
    method doRawStream (line 439) | private String doRawStream(final BOMInputStream bom, final BOMInputStr...
    method processHttpStream (line 465) | private String processHttpStream(final BOMInputStream bom, final BOMIn...
    method doLenientDetection (line 489) | private String doLenientDetection(String httpContentType,
    method calculateRawEncoding (line 520) | String calculateRawEncoding(final String bomEnc, final String xmlGuess...
    method calculateHttpEncoding (line 592) | String calculateHttpEncoding(final String httpContentType,
    method getContentTypeMime (line 666) | static String getContentTypeMime(final String httpContentType) {
    method getContentTypeEncoding (line 690) | static String getContentTypeEncoding(final String httpContentType) {
    method getXmlProlog (line 719) | private static String getXmlProlog(final InputStream inputStream, fina...
    method isAppXml (line 782) | static boolean isAppXml(final String mime) {
    method isTextXml (line 797) | static boolean isTextXml(final String mime) {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/commons/io/XmlStreamReaderException.java
  class XmlStreamReaderException (line 35) | public class XmlStreamReaderException extends IOException {
    method XmlStreamReaderException (line 61) | public XmlStreamReaderException(final String msg, final String bomEnc,
    method XmlStreamReaderException (line 80) | public XmlStreamReaderException(final String msg, final String ctMime,...
    method getBomEncoding (line 95) | public String getBomEncoding() {
    method getXmlGuessEncoding (line 104) | public String getXmlGuessEncoding() {
    method getXmlEncoding (line 113) | public String getXmlEncoding() {
    method getContentTypeMime (line 124) | public String getContentTypeMime() {
    method getContentTypeEncoding (line 136) | public String getContentTypeEncoding() {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/zip/AndroidZipEntry.java
  class AndroidZipEntry (line 18) | public class AndroidZipEntry implements ZipConstants, Cloneable {
    method AndroidZipEntry (line 58) | public AndroidZipEntry(String name, int nameLen) {
    method AndroidZipEntry (line 72) | public AndroidZipEntry(AndroidZipEntry e) {
    method setDOSTime (line 85) | final void setDOSTime(int dostime) {
    method getDOSTime (line 90) | final int getDOSTime() {
    method clone (line 103) | public Object clone() {
    method getName (line 119) | public String getName() {
    method getNameLen (line 123) | public int getNameLen() {
    method setTime (line 132) | public void setTime(long time) {
    method getTime (line 152) | public long getTime() {
    method getCalendar (line 176) | private static synchronized Calendar getCalendar() {
    method setSize (line 188) | public void setSize(long size) {
    method getSize (line 200) | public long getSize() {
    method setCompressedSize (line 209) | public void setCompressedSize(long csize) {
    method getCompressedSize (line 221) | public long getCompressedSize() {
    method setCrc (line 230) | public void setCrc(long crc) {
    method getCrc (line 242) | public long getCrc() {
    method setMethod (line 254) | public void setMethod(int method) {
    method getMethod (line 266) | public int getMethod() {
    method setExtra (line 275) | public void setExtra(byte[] extra) {
    method getExtra (line 315) | public byte[] getExtra() {
    method setComment (line 324) | public void setComment(String comment) {
    method getComment (line 335) | public String getComment() {
    method isDirectory (line 343) | public boolean isDirectory() {
    method toString (line 352) | public String toString() {
    method hashCode (line 360) | public int hashCode() {

FILE: modules/book/src/main/java/me/ag2s/epublib/util/zip/AndroidZipFile.java
  class AndroidZipFile (line 38) | public class AndroidZipFile implements ZipConstants {
    method AndroidZipFile (line 70) | public AndroidZipFile(@NonNull ParcelFileDescriptor pfd, String name) ...
    method AndroidZipFile (line 82) | public AndroidZipFile(File file) throws ZipException, IOException {
    method readLeShort (line 123) | private final int readLeShort(DataInput di, byte[] b) throws IOExcepti...
    method readLeShort (line 128) | private final int readLeShort(ParcelFileDescriptor pfd, byte[] b) thro...
    method readLeInt (line 143) | private final int readLeInt(DataInput di, byte[] b) throws IOException {
    method readLeInt (line 149) | private final int readLeInt(ParcelFileDescriptor pfd, byte[] b) throws...
    method readLeShort (line 164) | private final int readLeShort(byte[] b, int off) {
    method readLeInt (line 176) | private final int readLeInt(byte[] b, int off) {
    method readEntries (line 190) | private void readEntries() throws ZipException, IOException {
    method close (line 277) | public void close() throws IOException {
    method finalize (line 289) | protected void finalize() throws IOException {
    method entries (line 296) | public Enumeration<AndroidZipEntry> entries() {
    method getEntries (line 310) | private HashMap<String, AndroidZipEntry> getEntries() throws IOExcepti...
    method getEntry (line 329) | public AndroidZipEntry getEntry(String name) {
    method checkLocalHeader (line 353) | private long checkLocalHeader(AndroidZipEntry entry) throws IOException {
    method getInputStream (line 382) | public InputStream getInputStream(AndroidZipEntry entry) throws IOExce...
    method getName (line 406) | public String getName() {
    method size (line 413) | public int size() {
    class ZipEntryEnumeration (line 421) | private static class ZipEntryEnumeration implements Enumeration<Androi...
      method ZipEntryEnumeration (line 424) | public ZipEntryEnumeration(Iterator<AndroidZipEntry> elements) {
      method hasMoreElements (line 428) | public boolean hasMoreElements() {
      method nextElement (line 432) | public AndroidZipEntry nextElement() {
    class PartialInputStream (line 440) | private static class PartialInputStream extends InputStream {
      method PartialInputStream (line 444) | public PartialInputStream(ParcelFileDescriptor pfd, long start, long...
      method available (line 450) | public int available() {
      method read (line 457) | public int read() throws IOException {
      method read (line 466) | public int read(
Copy disabled (too large) Download .json
Condensed preview — 1746 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (12,399K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/01-bugReport.yml",
    "chars": 1949,
    "preview": "name: BUG提交 / BUG Report\ndescription: Report bugs to developers\nlabels: [\"BUG\"]\nbody:\n  - type: checkboxes\n    attribute"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/02-featureRequest.yml",
    "chars": 1096,
    "preview": "name: 功能请求 / Features\ndescription: Request new features\nlabels: [\"需求\"]\nbody:\n  - type: checkboxes\n    attributes:\n      "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 417,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: 简繁转化\n    url: https://github.com/liuyueyi/quick-chinese-transfer/is"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 1264,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/scripts/cronet.sh",
    "chars": 3308,
    "preview": "#!/usr/bin/env bash\n\n#分支Stable Dev Beta\nbranch=$1\n#api 最大偏移\nmax_offset=$2\n\n[ -z $1 ] && branch=Stable\n[ -z $2 ] && max_o"
  },
  {
    "path": ".github/scripts/lzy_web.py",
    "chars": 2828,
    "preview": "import requests, os, datetime, sys\n\n# Cookie 中 phpdisk_info 的值\ncookie_phpdisk_info = os.environ.get('phpdisk_info')\n# Co"
  },
  {
    "path": ".github/scripts/tg_bot.py",
    "chars": 1163,
    "preview": "import os, sys, telebot\n\n# 上传文件\ndef upload_file(tb, chat_id, file_dir):\n    doc = open(file_dir, 'rb')\n    tb.send_docum"
  },
  {
    "path": ".github/workflows/autoupdatefork.yml",
    "chars": 689,
    "preview": "#更新fork\nname: update fork\n\non: \n  schedule:\n    - cron: '0 16 * * *' #0点定时任务\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n"
  },
  {
    "path": ".github/workflows/cronet.yml",
    "chars": 1329,
    "preview": "name: Update Cronet\n\non:\n  schedule:\n  # 周一北京时间9点\n    - cron: 0 1 * * 1\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 4930,
    "preview": "name: Release Build\n\non:\n#  push:\n#    branches:\n#      - master\n#    paths:\n#      - 'CHANGELOG.md'\n  workflow_dispatch"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 721,
    "preview": "# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.\n#\n# You c"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 9435,
    "preview": "name: Test Build\n\non:\n  push:\n    branches:\n      - master\n    paths:\n      - '**'\n      # - '!**/assets/**'\n      # - '"
  },
  {
    "path": ".github/workflows/web.yml",
    "chars": 1581,
    "preview": "name: Build Web\n\non:\n  push:\n    branches:\n      - master\n    paths:\n      - '**/modules/web/**'\n  pull_request:\n    pat"
  },
  {
    "path": ".gitignore",
    "chars": 205,
    "preview": "*.iml\n.gradle\nlocal.properties\n.DS_Store\n/build\nbuild/\n/captures\n.externalNativeBuild\n/release\n/tmp\nnode_modules/\n/app/a"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 289,
    "preview": "**2022/10/02**\n\n* 更新cronet: 106.0.5249.79\n* 正文选择菜单朗读按钮长按可切换朗读选择内容和从选择开始处一直朗读\n* 源编辑输入框设置最大行数12,在行数特别多的时候更容易滚动到其它输入\n* 修复某些"
  },
  {
    "path": "English.md",
    "chars": 8263,
    "preview": "# [English](English.md) [中文](README.md)\n\n[![icon_android](https://github.com/gedoor/gedoor.github.io/blob/master/static/"
  },
  {
    "path": "LICENSE",
    "chars": 35139,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 5532,
    "preview": "# [English](English.md) [中文](README.md)\n\n[![icon_android](https://github.com/gedoor/gedoor.github.io/blob/master/static/"
  },
  {
    "path": "api.md",
    "chars": 5006,
    "preview": "# 阅读[API](/app/src/main/java/io/legado/app/api/controller)\n\n## 对于[Web](/app/src/main/java/io/legado/app/web/)的配置\n\n您需要先在设"
  },
  {
    "path": "app/.gitignore",
    "chars": 10,
    "preview": "/build\n/so"
  },
  {
    "path": "app/build.gradle",
    "chars": 8874,
    "preview": "plugins {\n//    id \"com.android.application\"\n//    id 'org.jetbrains.kotlin.android'\n//    id 'kotlin-parcelize'\n//    /"
  },
  {
    "path": "app/cronet-proguard-rules.pro",
    "chars": 10013,
    "preview": "# -------- Config Path: base/android/proguard/shared_with_cronet.flags --------\n# Copyright 2016 The Chromium Authors\n# "
  },
  {
    "path": "app/download.gradle",
    "chars": 3002,
    "preview": "import java.security.MessageDigest\n\napply plugin: 'de.undercouch.download'\n\ndef BASE_PATH = \"https://storage.googleapis."
  },
  {
    "path": "app/google-services.json",
    "chars": 4383,
    "preview": "{\n  \"project_info\": {\n    \"project_number\": \"453392274790\",\n    \"firebase_url\": \"https://legado-fca69.firebaseio.com\",\n "
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 3963,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/1.json",
    "chars": 30977,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 1,\n    \"identityHash\": \"d9ed367fc7241a61e9f770d416c4f887\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/10.json",
    "chars": 35400,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 10,\n    \"identityHash\": \"a9744f575dad6d4774cccc433921973b\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/11.json",
    "chars": 35570,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 11,\n    \"identityHash\": \"d3019908fa3212a7ac8eb87ac2f33369\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/12.json",
    "chars": 35739,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 12,\n    \"identityHash\": \"fa238e7524c215177f66110c847d327d\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/13.json",
    "chars": 35943,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 13,\n    \"identityHash\": \"da04f8cb7f257482f105b1274a7a351b\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/14.json",
    "chars": 35953,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 14,\n    \"identityHash\": \"139ff0cc002ac7be67a60912cd26bac7\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/15.json",
    "chars": 36145,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 15,\n    \"identityHash\": \"07a0976a08cbae60a16550af5663cde5\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/16.json",
    "chars": 36877,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 16,\n    \"identityHash\": \"ce9320370930dec28d85e2a77fad95e2\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/17.json",
    "chars": 36877,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 17,\n    \"identityHash\": \"ce9320370930dec28d85e2a77fad95e2\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/18.json",
    "chars": 37735,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 18,\n    \"identityHash\": \"ec3badfc86fb8187260ab26fb78a2d3f\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/19.json",
    "chars": 37962,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 19,\n    \"identityHash\": \"c58916ed4a4aece6092e21acf99845a1\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/2.json",
    "chars": 31158,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 2,\n    \"identityHash\": \"8164f697c57c68c7b82ec8e427214a88\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/20.json",
    "chars": 38167,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 20,\n    \"identityHash\": \"2c443ea987b87d8daf2a6161a98d2d5c\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/21.json",
    "chars": 38519,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 21,\n    \"identityHash\": \"eac4e5b7fdad840e82c1f607a3a8a46a\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/22.json",
    "chars": 38321,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 22,\n    \"identityHash\": \"9cf4f754700355578a8b8bf045c0e8e1\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/23.json",
    "chars": 38504,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 23,\n    \"identityHash\": \"874aa30f88921306741b488dbad38536\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/24.json",
    "chars": 39648,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 24,\n    \"identityHash\": \"55416d5a8a8530659ae3e7f948c0058b\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/25.json",
    "chars": 40890,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 25,\n    \"identityHash\": \"469ee9861faf7f562d7c60bc15a4a58b\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/26.json",
    "chars": 41656,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 26,\n    \"identityHash\": \"e20aa63032efb23c9e9c269afd64e7d7\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/27.json",
    "chars": 41656,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 27,\n    \"identityHash\": \"e20aa63032efb23c9e9c269afd64e7d7\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/28.json",
    "chars": 42012,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 28,\n    \"identityHash\": \"f77119a40a8930665af834d03c8c5d25\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/29.json",
    "chars": 42205,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 29,\n    \"identityHash\": \"85f1e7146f650af82aac6f9137eff815\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/3.json",
    "chars": 31438,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 3,\n    \"identityHash\": \"a3ccd8882307290a450c49e09a4435f6\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/30.json",
    "chars": 44506,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 30,\n    \"identityHash\": \"d9c8ef97ef4ffe0c1dbd57ca74bc4de4\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/31.json",
    "chars": 42592,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 31,\n    \"identityHash\": \"d1c390e708a1e89c7d016cdd2e0b2e88\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/32.json",
    "chars": 42592,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 32,\n    \"identityHash\": \"d1c390e708a1e89c7d016cdd2e0b2e88\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/33.json",
    "chars": 42483,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 33,\n    \"identityHash\": \"6dad1518f359667b4d740fc6a1f44a21\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/34.json",
    "chars": 42652,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 34,\n    \"identityHash\": \"2e519f1f67ca16091cbc3891c1b71c66\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/35.json",
    "chars": 43213,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 35,\n    \"identityHash\": \"25948a8defe4d091514bb725b4db7683\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/36.json",
    "chars": 43213,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 36,\n    \"identityHash\": \"25948a8defe4d091514bb725b4db7683\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/37.json",
    "chars": 43756,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 37,\n    \"identityHash\": \"11ebd6a72eb3f9ccd6ca46bc5535bca5\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/38.json",
    "chars": 43957,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 38,\n    \"identityHash\": \"5211699415b40f58b06d4136d14173d1\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/39.json",
    "chars": 44153,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 39,\n    \"identityHash\": \"8cfa1fb6bb9a65c04bfe563680126a4f\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/4.json",
    "chars": 33063,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 4,\n    \"identityHash\": \"3b81b2e900be34b8ceb48aaacc6b1004\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/40.json",
    "chars": 44519,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 40,\n    \"identityHash\": \"09617e0520cd8ec1671d812a866b45a4\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/41.json",
    "chars": 45430,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 41,\n    \"identityHash\": \"6fbd1d1b3918bcc6db113ad108e6b924\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/42.json",
    "chars": 45617,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 42,\n    \"identityHash\": \"5bef05ac6abeaa4b82c3ff6e9e6bd7b3\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/43.json",
    "chars": 46121,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 43,\n    \"identityHash\": \"b97eb5297faaacb44c2274233f52d250\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/44.json",
    "chars": 46873,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 44,\n    \"identityHash\": \"fdfaa67979c13dd76db0a1b594bc5904\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/45.json",
    "chars": 48932,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 45,\n    \"identityHash\": \"63272539e04e405abfd79e27ea55db75\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/46.json",
    "chars": 48932,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 46,\n    \"identityHash\": \"63272539e04e405abfd79e27ea55db75\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/47.json",
    "chars": 49203,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 47,\n    \"identityHash\": \"985b7a8fbf3f49e6eb444e4f4472bdee\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/48.json",
    "chars": 49503,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 48,\n    \"identityHash\": \"6348b1307bb9fb4f5482fb94a723338a\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/49.json",
    "chars": 50256,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 49,\n    \"identityHash\": \"2a6f5ee3d0ed9ac13f15183a04a4af45\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/5.json",
    "chars": 33051,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 5,\n    \"identityHash\": \"a355f8e02ebe0b13464573b1420a7b90\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/50.json",
    "chars": 50654,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 50,\n    \"identityHash\": \"524cf3564400bd897a49355afd984ac1\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/51.json",
    "chars": 50932,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 51,\n    \"identityHash\": \"028c189be828501449b61b32ab47a36f\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/52.json",
    "chars": 51107,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 52,\n    \"identityHash\": \"0221c385ed7393f47afe9579d3106541\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/53.json",
    "chars": 51490,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 53,\n    \"identityHash\": \"c55dac79aa9cc3dcdb72e91da4282005\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/54.json",
    "chars": 52129,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 54,\n    \"identityHash\": \"2b32177325d903e84445cc80ad7cbce8\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/55.json",
    "chars": 52145,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 55,\n    \"identityHash\": \"7dc698b0bf395df06befb13d41df87b9\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/56.json",
    "chars": 52145,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 56,\n    \"identityHash\": \"7dc698b0bf395df06befb13d41df87b9\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/57.json",
    "chars": 52323,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 57,\n    \"identityHash\": \"ae968e35603fe39a0141d0983d993de1\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/58.json",
    "chars": 52560,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 58,\n    \"identityHash\": \"dce5917572677d2b19bbc43809efb40c\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/59.json",
    "chars": 53136,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 59,\n    \"identityHash\": \"ddae0fd3a6b7ec874a028754a8cdd528\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/6.json",
    "chars": 34136,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 6,\n    \"identityHash\": \"af70ea583587e17c968d29f41bb3c0d6\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/60.json",
    "chars": 54213,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 60,\n    \"identityHash\": \"19e1f66252eb41afc0990f202fe4527a\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/61.json",
    "chars": 54497,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 61,\n    \"identityHash\": \"9e424026dc2c4dba847b0d9a5f3f788e\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/62.json",
    "chars": 55728,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 62,\n    \"identityHash\": \"965c5f1d4c60d25b4b46efb17c575c85\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/63.json",
    "chars": 56021,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 63,\n    \"identityHash\": \"5763792a4d08dc4cd7ebec9fb3215458\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/64.json",
    "chars": 56343,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 64,\n    \"identityHash\": \"c9b9979578e5ae84c1b424b1aa590efa\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/65.json",
    "chars": 56482,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 65,\n    \"identityHash\": \"ccfe4ad59c8caef014b1c754b69e6d05\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/66.json",
    "chars": 56651,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 66,\n    \"identityHash\": \"ef55cf538ab8076ccaf821cbc7f6582f\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/67.json",
    "chars": 57372,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 67,\n    \"identityHash\": \"48855e5272b008e4c6b202a41654b575\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/68.json",
    "chars": 57562,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 68,\n    \"identityHash\": \"9b6070f339f55e90e4cceaeb89b4a698\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/69.json",
    "chars": 57562,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 69,\n    \"identityHash\": \"9b6070f339f55e90e4cceaeb89b4a698\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/7.json",
    "chars": 34136,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 7,\n    \"identityHash\": \"af70ea583587e17c968d29f41bb3c0d6\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/70.json",
    "chars": 57788,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 70,\n    \"identityHash\": \"ab3b8675fe5c3152003e20a73f022b0c\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/71.json",
    "chars": 58023,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 71,\n    \"identityHash\": \"6e17b5366286b868f2912c12d6d8e467\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/72.json",
    "chars": 58483,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 72,\n    \"identityHash\": \"53d960f1fdc04a6f157a25b269a0d93b\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/73.json",
    "chars": 58664,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 73,\n    \"identityHash\": \"63617164079ebbdaf82176384c39bba5\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/74.json",
    "chars": 59017,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 74,\n    \"identityHash\": \"c492bca5d9c4b4b34a0808d8cce9e7ba\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/75.json",
    "chars": 59425,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 75,\n    \"identityHash\": \"e22b36ff0280a224a30d08dd6e9bd7be\",\n    \""
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/8.json",
    "chars": 34850,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 8,\n    \"identityHash\": \"0c09d0b5970a01069c4381648f793da7\",\n    \"e"
  },
  {
    "path": "app/schemas/io.legado.app.data.AppDatabase/9.json",
    "chars": 35051,
    "preview": "{\n  \"formatVersion\": 1,\n  \"database\": {\n    \"version\": 9,\n    \"identityHash\": \"8da976febbd44e9e028b951b42583f9a\",\n    \"e"
  },
  {
    "path": "app/src/androidTest/java/io/legado/app/AndroidJsTest.kt",
    "chars": 3473,
    "preview": "package io.legado.app\n\nimport cn.hutool.core.lang.JarClassLoader\nimport com.script.ScriptBindings\nimport com.script.rhin"
  },
  {
    "path": "app/src/androidTest/java/io/legado/app/ExampleInstrumentedTest.kt",
    "chars": 941,
    "preview": "package io.legado.app\n\nimport android.content.Context\nimport android.net.Uri\nimport android.util.Log\nimport androidx.tes"
  },
  {
    "path": "app/src/androidTest/java/io/legado/app/HttpTest.kt",
    "chars": 3492,
    "preview": "package io.legado.app\n\nimport android.app.DownloadManager\nimport android.net.Uri\nimport android.os.Environment\nimport an"
  },
  {
    "path": "app/src/androidTest/java/io/legado/app/HttpTtsTest.kt",
    "chars": 815,
    "preview": "package io.legado.app\n\nimport io.legado.app.help.config.AppConfig\nimport io.legado.app.model.analyzeRule.AnalyzeUrl\nimpo"
  },
  {
    "path": "app/src/androidTest/java/io/legado/app/MigrationTest.kt",
    "chars": 1479,
    "preview": "package io.legado.app\n\nimport androidx.room.Room\nimport androidx.room.migration.Migration\nimport androidx.room.testing.M"
  },
  {
    "path": "app/src/androidTest/java/io/legado/app/UpdateTest.kt",
    "chars": 1805,
    "preview": "package io.legado.app\n\nimport com.google.gson.Gson\nimport io.legado.app.exception.NoStackTraceException\nimport io.legado"
  },
  {
    "path": "app/src/debug/res/values/strings.xml",
    "chars": 137,
    "preview": "<resources>\n    <string name=\"app_name\">legado·D</string>\n    <string name=\"receiving_shared_label\">legado·D·search</str"
  },
  {
    "path": "app/src/debug/res/values-zh/strings.xml",
    "chars": 125,
    "preview": "<resources>\n    <string name=\"app_name\">阅读·D</string>\n    <string name=\"receiving_shared_label\">阅读·D·搜索</string>\n</resou"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 23375,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "app/src/main/assets/18PlusList.txt",
    "chars": 3607,
    "preview": "OGN5dS5jb20=\nc2cwMC54eXo=\naXRyYWZmaWNuZXQuY29t\neGlhb3FpYW5nNTIw\nMTIzeGlhb3FpYW5n\neGlhb3FpYW5neHM=\neGlhb3FpYW5nNTIw\nMzM1e"
  },
  {
    "path": "app/src/main/assets/LICENSE.md",
    "chars": 34764,
    "preview": "GNU GENERAL PUBLIC LICENSE\nVersion 3, 29 June 2007\n\nCopyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>"
  },
  {
    "path": "app/src/main/assets/cronet.json",
    "chars": 208,
    "preview": "{\"x86\":\"2288814a4d9d4ee24154f52abf227fa0\",\"armeabi-v7a\":\"ac8190c5e795d1a754b7bf2d477119c5\",\"x86_64\":\"116f2d0f8e6363caacb"
  },
  {
    "path": "app/src/main/assets/defaultData/bookSources.json",
    "chars": 5231,
    "preview": "[\n  {\n    \"bookSourceComment\": \"\",\n    \"bookSourceGroup\": \"听书\",\n    \"bookSourceName\": \"消消乐听书\",\n    \"bookSourceType\": 1,\n"
  },
  {
    "path": "app/src/main/assets/defaultData/coverRule.json",
    "chars": 59,
    "preview": "{\n  \"enable\": false,\n  \"searchUrl\": \"\",\n  \"coverRule\": \"\"\n}"
  },
  {
    "path": "app/src/main/assets/defaultData/dictRules.json",
    "chars": 823,
    "preview": "[\n  {\n    \"name\": \"百度汉语\",\n    \"urlRule\": \"https://dict.baidu.com/s?wd={{key}}\",\n    \"showRule\": \"@js:var jsoup = org.jso"
  },
  {
    "path": "app/src/main/assets/defaultData/directLinkUpload.json",
    "chars": 900,
    "preview": "[\n  {\n    \"uploadUrl\": \"https://sy.nyasama.net/shuyuan,{\\\"method\\\":\\\"POST\\\",\\\"body\\\": {\\\"file\\\": \\\"fileRequest\\\"},\\\"type"
  },
  {
    "path": "app/src/main/assets/defaultData/httpTTS.json",
    "chars": 3183,
    "preview": "[\n  {\n    \"id\": -100,\n    \"name\": \"1.百度\",\n    \"url\": \"http://tts.baidu.com/text2audio,{\\n    \\\"method\\\": \\\"POST\\\",\\n    "
  },
  {
    "path": "app/src/main/assets/defaultData/keyboardAssists.json",
    "chars": 2101,
    "preview": "[\n  {\n    \"key\": \"@css:\",\n    \"value\": \"@css:\",\n    \"serialNo\": 0\n  },\n  {\n    \"key\": \"<js>\",\n    \"value\": \"<js></js>\",\n"
  },
  {
    "path": "app/src/main/assets/defaultData/readConfig.json",
    "chars": 2418,
    "preview": "[\n  {\n    \"bgStr\": \"#ffc0edc6\",\n    \"bgStrEInk\": \"#FFFFFF\",\n    \"bgStrNight\": \"#000000\",\n    \"bgType\": 0,\n    \"bgTypeEIn"
  },
  {
    "path": "app/src/main/assets/defaultData/rssSources.json",
    "chars": 1284,
    "preview": "[\n  {\n    \"customOrder\": 2,\n    \"enableJs\": true,\n    \"enabled\": true,\n    \"singleUrl\": true,\n    \"sourceGroup\": \"legado"
  },
  {
    "path": "app/src/main/assets/defaultData/themeConfig.json",
    "chars": 754,
    "preview": "[\n  {\n    \"themeName\": \"默认\",\n    \"isNightTheme\": false,\n    \"primaryColor\": \"#795548\",\n    \"accentColor\": \"#E53935\",\n   "
  },
  {
    "path": "app/src/main/assets/defaultData/txtTocRule.json",
    "chars": 6239,
    "preview": "[\n  {\n    \"id\": -1,\n    \"enable\": true,\n    \"name\": \"目录(去空白)\",\n    \"rule\": \"(?<=[ \\\\s])(?:序章|楔子|正文(?!完|结)|终章|后记|尾声|番外|第\\"
  },
  {
    "path": "app/src/main/assets/disclaimer.md",
    "chars": 794,
    "preview": "# 免责声明(Disclaimer)\n\n* 阅读是一款解析指定规则并获取内容的工具,为广大网络文学爱好者提供一种方便、快捷舒适的试读体验。\n* 当您搜索一本书的时,阅读会您所使用的规则将该书的书名以关键词的形式提交到各个第三方网络文学网站。"
  },
  {
    "path": "app/src/main/assets/epub/chapter.html",
    "chars": 347,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <title>Cha"
  },
  {
    "path": "app/src/main/assets/epub/cover.html",
    "chars": 644,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <title>Cov"
  },
  {
    "path": "app/src/main/assets/epub/fonts.css",
    "chars": 11010,
    "preview": "@charset \"utf-8\";\n/*---常用---*/\n\n@font-face {\n    font-family: \"zw\";\n    src:\n\tlocal(\"宋体\"),local(\"明体\"),local(\"明朝\"),\n\tloca"
  },
  {
    "path": "app/src/main/assets/epub/intro.html",
    "chars": 384,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"zh-CN\">\n<hea"
  },
  {
    "path": "app/src/main/assets/epub/main.css",
    "chars": 10261,
    "preview": "@charset \"utf-8\";\n@import url(\"../Styles/fonts.css\");\nbody {\n    padding: 0%;\n    margin-top: 0%;\n    margin-bottom: 0%;"
  },
  {
    "path": "app/src/main/assets/privacyPolicy.md",
    "chars": 180,
    "preview": "* 本应用没有服务端,不收集任何用户信息,只采用了Google Firebase收集崩溃报告和性能报告.\n* 本应用网络同步和备份采用webDav协议,由用户自己提供同步服务.\n* 存储权限用来打开本地文件和本地备份恢复.\n* 其它一些权限"
  },
  {
    "path": "app/src/main/assets/storageHelp.md",
    "chars": 109,
    "preview": "* 由于安卓的存储访问限制,阅读需要设置**公共目录下的子目录**来实现书籍拷贝、下载,例如Documents/Books、Download/Books\n* 如不设置,将无法正常使用本地书籍、webDav书籍的相关功能"
  },
  {
    "path": "app/src/main/assets/updateLog.md",
    "chars": 921,
    "preview": "# 更新日志\n\n* 关注公众号 **[开源阅读]** 菜单•软件下载 提前享受新版本。\n* 关注合作公众号 **[小说拾遗]** 获取好看的小说。\n\n## cronet版本: 128.0.6613.40\n\n## **必读**\n\n【温馨提醒】"
  },
  {
    "path": "app/src/main/assets/web/assets/css/main.css",
    "chars": 71823,
    "preview": " /*\n\tForty by HTML5 UP\n\thtml5up.net | @ajlkn\n\tFree for personal and commercial use under the CCA 3.0 license (html5up.ne"
  },
  {
    "path": "app/src/main/assets/web/assets/js/dist.js",
    "chars": 105537,
    "preview": "/*!\n * Powered by uglifiyJS v2.6.1, Build by http://tool.uis.cc/jsmin/\n * build time: Sun Jul 25 2021 19:58:00 GMT+0800 "
  },
  {
    "path": "app/src/main/assets/web/assets/js/md5.js",
    "chars": 8571,
    "preview": "/*\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321"
  },
  {
    "path": "app/src/main/assets/web/help/index.html",
    "chars": 488,
    "preview": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>help</title>\n\t\t<link rel=\"stylesheet\" href=\"css/githu"
  },
  {
    "path": "app/src/main/assets/web/help/js/main.js",
    "chars": 1127,
    "preview": "require.config({\n    baseUrl: 'js',\n    paths: {\n        marked: 'marked.min',\n        markedHighlight: 'marked-highligh"
  },
  {
    "path": "app/src/main/assets/web/help/js/marked-highlight.umd.js",
    "chars": 2258,
    "preview": "(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports):typeof define==='funct"
  },
  {
    "path": "app/src/main/assets/web/help/js/require.js",
    "chars": 17695,
    "preview": "/** vim: et:ts=4:sw=4:sts=4\n * @license RequireJS 2.3.6 Copyright jQuery Foundation and other contributors.\n * Released "
  },
  {
    "path": "app/src/main/assets/web/help/md/ExtensionContentType.md",
    "chars": 4308,
    "preview": "```java\npublic enum MimeTypeEnum {\n\n    AAC(\"acc\", \"AAC音频\", \"audio/aac\"),\n\n    ABW(\"abw\", \"AbiWord文件\", \"application/x-ab"
  },
  {
    "path": "app/src/main/assets/web/help/md/SourceMBookHelp.md",
    "chars": 464,
    "preview": "# 书源管理界面帮助\n\n* 书源右上角标志\n  * 绿点表示书源有发现,且启用了发现\n  * 红点表示书源有发现,但是未启用\n  * 没有标志表示此书源没有发现\n* 右上角有分组菜单,可以按分组筛选书源\n* 右上角更多菜单里包含\n  * 新"
  },
  {
    "path": "app/src/main/assets/web/help/md/SourceMRssHelp.md",
    "chars": 260,
    "preview": "# 订阅源管理界面帮助\n\n* 订阅源可以通过规则订阅一些网络内容\n* 书源右上角标志\n  * 绿点表示书源有发现,且启用了发现\n  * 红点表示书源有发现,但是未启用\n  * 没有标志表示此书源没有发现\n* 右上角有分组菜单,可以按分组筛选"
  },
  {
    "path": "app/src/main/assets/web/help/md/appHelp.md",
    "chars": 5495,
    "preview": "# 帮助文档\n\n【温馨提醒】 *本帮助可以在“**我的**”——右上角帮助按钮再次打开,更新前一定要做好备份,以免数据丢失!*\n\n## 新人必读 \n\n### 1. 为什么第一次安装好之后什么东西都没有?\n阅读只是一个转码工具,不提供内容。\n"
  },
  {
    "path": "app/src/main/assets/web/help/md/debugHelp.md",
    "chars": 336,
    "preview": "# 书源调试\n\n* 调试搜索>>输入关键字,如:\n```\n系统\n```\n* 调试发现>>输入发现URL,如:\n```\n月票榜::https://www.qidian.com/rank/yuepiao?page={{page}}\n```\n* "
  },
  {
    "path": "app/src/main/assets/web/help/md/dictRuleHelp.md",
    "chars": 107,
    "preview": "## 字典规则说明\n\n* 字典规则是用在正文文字选择菜单字典里的规则,通常用来做翻译或者查找\n* urlRule\n    * 同书源的url规则\n* showRule\n    * 用来提取显示到对话框里面内容的规则"
  },
  {
    "path": "app/src/main/assets/web/help/md/httpTTSHelp.md",
    "chars": 356,
    "preview": "# 在线朗读规则说明\n\n* 在线朗读规则为url规则,同书源url\n* js参数\n```\nspeakText //朗读文本\nspeakSpeed //朗读速度,5-50\n```\n* 例:\n```\nhttp://tts.baidu.com/t"
  },
  {
    "path": "app/src/main/assets/web/help/md/jsHelp.md",
    "chars": 12085,
    "preview": "# js变量和函数\n> 阅读使用[Rhino v1.8.0](https://github.com/mozilla/rhino) 作为JavaScript引擎以便于[调用Java类和方法](https://m.jb51.net/articl"
  },
  {
    "path": "app/src/main/assets/web/help/md/readMenuHelp.md",
    "chars": 742,
    "preview": "# 阅读界面帮助文档\n\n## 阅读界面主菜单\n* 顶部操作\n  * 章节名称:点击可编辑书源\n  * 章节url:点击可打开浏览器浏览\n  * 菜单:**不同类型的书籍显示的菜单不同**。详情请查看菜单文字,长按菜单图标可显示文字\n* 中间"
  },
  {
    "path": "app/src/main/assets/web/help/md/regexHelp.md",
    "chars": 9094,
    "preview": "# 正则表达式学习\n\n- [基本匹配]\n- [元字符]\n  - [英文句号]\n  - [字符集]\n    - [否定字符集]\n  - [重复]\n    - [星号]\n    - [加号]\n    - [问号]\n  - [花括号]\n  - ["
  },
  {
    "path": "app/src/main/assets/web/help/md/replaceRuleHelp.md",
    "chars": 70,
    "preview": "# 替换管理界面帮助\n\n* 替换规则是用来替换正文内容的一种规则\n  * 菜单可以新建和导入规则\n  * 可以拖动排序\n  * 可以选择操作"
  },
  {
    "path": "app/src/main/assets/web/help/md/ruleHelp.md",
    "chars": 5973,
    "preview": "# 源规则帮助\n\n* [阅读3.0(Legado)规则说明](https://mgz0227.github.io/The-tutorial-of-Legado/)\n* [书源帮助文档](https://mgz0227.github.io/T"
  },
  {
    "path": "app/src/main/assets/web/help/md/txtTocRuleHelp.md",
    "chars": 66333,
    "preview": "## Txt目录正则说明\n\n### 菜单区\n\n- 新增目录规则,当Legado自带的规则不能够满足需求时,用户可根据自己的情况自定义目录规则\n- 导入默认规则 在旧版本中,Legado自带的规则不会随着软件的更新而更新。用户需要使用最新规则"
  },
  {
    "path": "app/src/main/assets/web/help/md/webDavBookHelp.md",
    "chars": 1799,
    "preview": "# WebDav 书籍简明使用教程\n\n> 本帮助页会在第一次进入时弹出,后续则不再出现,如想查看,请点击右上角 “**⁝**” > 帮助 查看此页。\n\n虽然阅读主要是用来看网络小说的工具,但为了方便书友,也提供了一些本地书籍阅读的简单支持("
  },
  {
    "path": "app/src/main/assets/web/help/md/webDavHelp.md",
    "chars": 403,
    "preview": "# WebDav备份教程\n\n### 阅读支持云备份,采用WebDav协议,所有支持WebDav的云盘都可以,建议采用坚果云,每月免费1G流量,用来备份阅读足够了,下面就采用坚果云来讲解配置步骤.\n\n1. 打开坚果云网站 https://ww"
  },
  {
    "path": "app/src/main/assets/web/help/md/xpathHelp.md",
    "chars": 7531,
    "preview": "# xpath 路径表达式详解\n\n_注:本文所有代码均通过 Chrome(版本 123.0.6312.86) 验证_\n\n> XPath 规范中定义了 13 种不同的轴(axes)。  \n> 轴表示与元素的关系,并用于定位元素树上相对于该元素"
  },
  {
    "path": "app/src/main/assets/web/index.html",
    "chars": 2158,
    "preview": "<!DOCTYPE HTML>\n<!--\n\tForty by HTML5 UP\n\thtml5up.net | @ajlkn\n\tFree for personal and commercial use under the CCA 3.0 li"
  },
  {
    "path": "app/src/main/assets/web/uploadBook/css/wifi_send.css",
    "chars": 7234,
    "preview": "@charset \"utf-8\";\n/*reset*/\nhtml{-webkit-text-size-adjust:100%}\nbody,p,blockquote,ul,ol,li,h1,h2,h3,h4,h5,h6,dl,dd,input"
  },
  {
    "path": "app/src/main/assets/web/uploadBook/index.html",
    "chars": 114129,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n    \n    <meta"
  },
  {
    "path": "app/src/main/assets/web/uploadBook/js/common.js",
    "chars": 3877,
    "preview": "/**\n * 公共函数\n */\n//全局的配置文件 \nvar config = {\n\tfileTypes: \"txt|epub|umd|pdf|mobi|azw3|azw\", //允许上传的文件格式 \"txt|epub\" // |doc|d"
  },
  {
    "path": "app/src/main/assets/web/uploadBook/js/html5_fun.js",
    "chars": 5435,
    "preview": "/**\n * 处理拖拽上传\n */\n\tvar isDragOver\t\t= false;//拖拽触发点\n\tvar fileNumber\t\t= -1; //上传文件编号\n\tvar fileNumberPex\t= \"zyFileUpload_\";"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/BookChapter-BsiFtdIw.css",
    "chars": 13151,
    "preview": "@charset \"UTF-8\";.title[data-v-d8efefe3]{margin-bottom:57px;font:24px/32px PingFangSC-Regular,HelveticaNeue-Light,Helvet"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/BookChapter-Cs3stH93.js",
    "chars": 40430,
    "preview": "import{d as ce,a4 as Je,U as Fe,a9 as Pe,o as g,e as p,F as se,h as t,z as K,R as le,u as a,aa as Z,C as l,M as D,ab as "
  },
  {
    "path": "app/src/main/assets/web/vue/assets/BookShelf-00b2QCsd.css",
    "chars": 5951,
    "preview": "@charset \"UTF-8\";.books-wrapper[data-v-0f5f0160]{overflow:auto}.books-wrapper .wrapper[data-v-0f5f0160]{display:grid;gri"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/BookShelf-DIQtBULC.js",
    "chars": 7742,
    "preview": "import{d as H,a4 as j,o as d,e as h,h as e,F as N,R as W,z as p,c as $,w as M,g as P,a5 as J,P as x,u as o,C as V,Q as e"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/index-CrxHVQK7.css",
    "chars": 2304,
    "preview": ".el-link[data-v-085627fb]{padding:4px}.el-text[data-v-085627fb]{padding-top:20px}[data-v-d8dae8d3] .el-checkbox__label{f"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/index-Wr40-hHf.js",
    "chars": 35892,
    "preview": "const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=[\"./BookShelf-DIQtBULC.js\",\"./vendor-KSDcS24u.js\",\"./vendor-CXe1"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/loading-C4J6hIxs.js",
    "chars": 514,
    "preview": "import{ak as i,N as g,a9 as c,M as d,al as f,u as m}from\"./vendor-KSDcS24u.js\";const L=(s,t,l=i)=>{const a=d(!1);let r=n"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/loading-DkQYEuap.css",
    "chars": 107,
    "preview": ".el-loading-spinner{font-size:36px;color:#b5b5b5}.el-loading-text{font-weight:500;color:#b5b5b5!important}\n"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/vendor-CXe1BRiH.css",
    "chars": 107780,
    "preview": "@charset \"UTF-8\";:root{--el-color-white:#ffffff;--el-color-black:#000000;--el-color-primary-rgb:64,158,255;--el-color-su"
  },
  {
    "path": "app/src/main/assets/web/vue/assets/vendor-KSDcS24u.js",
    "chars": 430573,
    "preview": "/**\n* @vue/shared v3.5.30\n* (c) 2018-present Yuxi (Evan) You and Vue contributors\n* @license MIT\n**/function Ku(e){const"
  },
  {
    "path": "app/src/main/assets/web/vue/index.html",
    "chars": 613,
    "preview": "<!DOCTYPE html>\r\n<html lang=\"zh\" class=\"\">\r\n    <head>\r\n        <meta charset=\"UTF-8\" />\r\n        <link rel=\"icon\" href="
  },
  {
    "path": "app/src/main/java/io/legado/app/App.kt",
    "chars": 9714,
    "preview": "package io.legado.app\n\nimport android.app.Application\nimport android.app.Notification\nimport android.app.NotificationCha"
  },
  {
    "path": "app/src/main/java/io/legado/app/README.md",
    "chars": 162,
    "preview": "# 文件结构介绍\n\n* api 提供的接口\n* base 基类\n* constant 常量\n* data 数据\n* exception 错误类型\n* help 帮助\n* lib 库\n* model 解析\n* receiver 广播侦听\n* "
  },
  {
    "path": "app/src/main/java/io/legado/app/api/ReaderProvider.kt",
    "chars": 6913,
    "preview": "/*\n * Copyright (C) 2020 w568w\n */\npackage io.legado.app.api\n\nimport android.content.ContentProvider\nimport android.cont"
  },
  {
    "path": "app/src/main/java/io/legado/app/api/ReturnData.kt",
    "chars": 546,
    "preview": "package io.legado.app.api\n\nimport androidx.annotation.Keep\n\n@Keep\nclass ReturnData {\n\n    var isSuccess: Boolean = false"
  },
  {
    "path": "app/src/main/java/io/legado/app/api/ShortCuts.kt",
    "chars": 2601,
    "preview": "package io.legado.app.api\n\nimport android.content.Context\nimport android.content.Intent\nimport androidx.core.content.pm."
  },
  {
    "path": "app/src/main/java/io/legado/app/api/controller/BookController.kt",
    "chars": 11783,
    "preview": "package io.legado.app.api.controller\n\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport an"
  },
  {
    "path": "app/src/main/java/io/legado/app/api/controller/BookSourceController.kt",
    "chars": 2867,
    "preview": "package io.legado.app.api.controller\n\n\nimport android.text.TextUtils\nimport io.legado.app.api.ReturnData\nimport io.legad"
  },
  {
    "path": "app/src/main/java/io/legado/app/api/controller/ReplaceRuleController.kt",
    "chars": 3002,
    "preview": "package io.legado.app.api.controller\n\nimport io.legado.app.api.ReturnData\nimport io.legado.app.data.appDb\nimport io.lega"
  },
  {
    "path": "app/src/main/java/io/legado/app/api/controller/RssSourceController.kt",
    "chars": 2725,
    "preview": "package io.legado.app.api.controller\n\n\nimport android.text.TextUtils\nimport io.legado.app.api.ReturnData\nimport io.legad"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/AppContextWrapper.kt",
    "chars": 2963,
    "preview": "package io.legado.app.base\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/BaseActivity.kt",
    "chars": 7215,
    "preview": "package io.legado.app.base\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/BaseDialogFragment.kt",
    "chars": 4185,
    "preview": "package io.legado.app.base\n\nimport android.content.DialogInterface\nimport android.content.DialogInterface.OnDismissListe"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/BaseFragment.kt",
    "chars": 2289,
    "preview": "package io.legado.app.base\n\nimport android.annotation.SuppressLint\nimport android.content.res.Configuration\nimport andro"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/BasePrefDialogFragment.kt",
    "chars": 1639,
    "preview": "package io.legado.app.base\n\nimport android.view.Gravity\nimport android.view.WindowManager\nimport androidx.fragment.app.D"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/BaseService.kt",
    "chars": 3229,
    "preview": "package io.legado.app.base\n\nimport android.content.Intent\nimport android.os.Build\nimport android.os.IBinder\nimport andro"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/BaseViewModel.kt",
    "chars": 1790,
    "preview": "package io.legado.app.base\n\nimport android.app.Application\nimport android.content.Context\nimport androidx.lifecycle.Andr"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/README.md",
    "chars": 4,
    "preview": "# 基类"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/VMBaseActivity.kt",
    "chars": 491,
    "preview": "package io.legado.app.base\n\nimport androidx.lifecycle.ViewModel\nimport androidx.viewbinding.ViewBinding\nimport io.legado"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/VMBaseFragment.kt",
    "chars": 198,
    "preview": "package io.legado.app.base\n\nimport androidx.lifecycle.ViewModel\n\nabstract class VMBaseFragment<VM : ViewModel>(layoutID:"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt",
    "chars": 6930,
    "preview": "package io.legado.app.base.adapter\n\nimport android.content.Context\nimport android.os.Parcelable\nimport android.view.Layo"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/ItemAnimation.kt",
    "chars": 2287,
    "preview": "package io.legado.app.base.adapter\n\nimport android.view.animation.Interpolator\nimport android.view.animation.LinearInter"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/ItemViewHolder.kt",
    "chars": 302,
    "preview": "package io.legado.app.base.adapter\n\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.viewbinding.ViewBin"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt",
    "chars": 15868,
    "preview": "package io.legado.app.base.adapter\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/animations/AlphaInAnimation.kt",
    "chars": 477,
    "preview": "package io.legado.app.base.adapter.animations\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/animations/BaseAnimation.kt",
    "chars": 214,
    "preview": "package io.legado.app.base.adapter.animations\n\nimport android.animation.Animator\nimport android.view.View\n\n/**\n * adapte"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/animations/ScaleInAnimation.kt",
    "chars": 599,
    "preview": "package io.legado.app.base.adapter.animations\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/animations/SlideInBottomAnimation.kt",
    "chars": 356,
    "preview": "package io.legado.app.base.adapter.animations\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/animations/SlideInLeftAnimation.kt",
    "chars": 356,
    "preview": "package io.legado.app.base.adapter.animations\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator"
  },
  {
    "path": "app/src/main/java/io/legado/app/base/adapter/animations/SlideInRightAnimation.kt",
    "chars": 356,
    "preview": "package io.legado.app.base.adapter.animations\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator"
  },
  {
    "path": "app/src/main/java/io/legado/app/constant/AppConst.kt",
    "chars": 3655,
    "preview": "package io.legado.app.constant\n\nimport android.annotation.SuppressLint\nimport android.content.pm.PackageManager\nimport a"
  }
]

// ... and 1546 more files (download for full content)

About this extraction

This page contains the full source code of the gedoor/legado GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1746 files (11.0 MB), approximately 3.0M tokens, and a symbol index with 2427 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!