Showing preview only (8,448K chars total). Download the full file or copy to clipboard to get everything.
Repository: koodo-reader/koodo-reader
Branch: dev
Commit: fb4d83699220
Files: 621
Total size: 8.0 MB
Directory structure:
gitextract_j5v1h9cg/
├── .coderabbit.yaml
├── .eslintrc.js
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ └── submit_translation.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ ├── docker-publish.yml
│ ├── release-appx.yml
│ ├── release.yml
│ └── upload.yml
├── .gitignore
├── .prettierrc
├── .yarnrc
├── Dockerfile
├── LICENSE
├── README.md
├── README_cn.md
├── README_hi.md
├── README_id.md
├── README_pt.md
├── assets/
│ ├── icons/
│ │ ├── azw3.icns
│ │ ├── comic.icns
│ │ ├── epub.icns
│ │ ├── fb2.icns
│ │ ├── icon.icns
│ │ ├── mobi.icns
│ │ └── pdf.icns
│ ├── macos/
│ │ └── entitlements.mac.plist
│ └── windows/
│ └── installer.nsh
├── docker-compose-secret.yml
├── docker-compose.yml
├── electron-builder.env
├── httpServer.js
├── main.js
├── package.json
├── public/
│ ├── LICENSE
│ ├── assets/
│ │ └── styles/
│ │ ├── dark.css
│ │ └── default.css
│ ├── index.html
│ ├── lib/
│ │ ├── 7z-wasm/
│ │ │ ├── 7zz.umd.js
│ │ │ ├── 7zz.wasm
│ │ │ └── License.txt
│ │ ├── esearch-ocr/
│ │ │ └── esearch-ocr.umd.js
│ │ ├── libunrar/
│ │ │ ├── libunrar.js
│ │ │ ├── libunrar.wasm
│ │ │ ├── rpc.js
│ │ │ └── worker.js
│ │ ├── pdfjs/
│ │ │ ├── annotation_layer_builder.css
│ │ │ ├── cmaps/
│ │ │ │ ├── 78-EUC-H.bcmap
│ │ │ │ ├── 78-EUC-V.bcmap
│ │ │ │ ├── 78-H.bcmap
│ │ │ │ ├── 78-RKSJ-H.bcmap
│ │ │ │ ├── 78-RKSJ-V.bcmap
│ │ │ │ ├── 78-V.bcmap
│ │ │ │ ├── 78ms-RKSJ-H.bcmap
│ │ │ │ ├── 78ms-RKSJ-V.bcmap
│ │ │ │ ├── 83pv-RKSJ-H.bcmap
│ │ │ │ ├── 90ms-RKSJ-H.bcmap
│ │ │ │ ├── 90ms-RKSJ-V.bcmap
│ │ │ │ ├── 90msp-RKSJ-H.bcmap
│ │ │ │ ├── 90msp-RKSJ-V.bcmap
│ │ │ │ ├── 90pv-RKSJ-H.bcmap
│ │ │ │ ├── 90pv-RKSJ-V.bcmap
│ │ │ │ ├── Add-H.bcmap
│ │ │ │ ├── Add-RKSJ-H.bcmap
│ │ │ │ ├── Add-RKSJ-V.bcmap
│ │ │ │ ├── Add-V.bcmap
│ │ │ │ ├── Adobe-CNS1-0.bcmap
│ │ │ │ ├── Adobe-CNS1-1.bcmap
│ │ │ │ ├── Adobe-CNS1-2.bcmap
│ │ │ │ ├── Adobe-CNS1-3.bcmap
│ │ │ │ ├── Adobe-CNS1-4.bcmap
│ │ │ │ ├── Adobe-CNS1-5.bcmap
│ │ │ │ ├── Adobe-CNS1-6.bcmap
│ │ │ │ ├── Adobe-CNS1-UCS2.bcmap
│ │ │ │ ├── Adobe-GB1-0.bcmap
│ │ │ │ ├── Adobe-GB1-1.bcmap
│ │ │ │ ├── Adobe-GB1-2.bcmap
│ │ │ │ ├── Adobe-GB1-3.bcmap
│ │ │ │ ├── Adobe-GB1-4.bcmap
│ │ │ │ ├── Adobe-GB1-5.bcmap
│ │ │ │ ├── Adobe-GB1-UCS2.bcmap
│ │ │ │ ├── Adobe-Japan1-0.bcmap
│ │ │ │ ├── Adobe-Japan1-1.bcmap
│ │ │ │ ├── Adobe-Japan1-2.bcmap
│ │ │ │ ├── Adobe-Japan1-3.bcmap
│ │ │ │ ├── Adobe-Japan1-4.bcmap
│ │ │ │ ├── Adobe-Japan1-5.bcmap
│ │ │ │ ├── Adobe-Japan1-6.bcmap
│ │ │ │ ├── Adobe-Japan1-UCS2.bcmap
│ │ │ │ ├── Adobe-Korea1-0.bcmap
│ │ │ │ ├── Adobe-Korea1-1.bcmap
│ │ │ │ ├── Adobe-Korea1-2.bcmap
│ │ │ │ ├── Adobe-Korea1-UCS2.bcmap
│ │ │ │ ├── B5-H.bcmap
│ │ │ │ ├── B5-V.bcmap
│ │ │ │ ├── B5pc-H.bcmap
│ │ │ │ ├── B5pc-V.bcmap
│ │ │ │ ├── CNS-EUC-H.bcmap
│ │ │ │ ├── CNS-EUC-V.bcmap
│ │ │ │ ├── CNS1-H.bcmap
│ │ │ │ ├── CNS1-V.bcmap
│ │ │ │ ├── CNS2-H.bcmap
│ │ │ │ ├── CNS2-V.bcmap
│ │ │ │ ├── ETHK-B5-H.bcmap
│ │ │ │ ├── ETHK-B5-V.bcmap
│ │ │ │ ├── ETen-B5-H.bcmap
│ │ │ │ ├── ETen-B5-V.bcmap
│ │ │ │ ├── ETenms-B5-H.bcmap
│ │ │ │ ├── ETenms-B5-V.bcmap
│ │ │ │ ├── EUC-H.bcmap
│ │ │ │ ├── EUC-V.bcmap
│ │ │ │ ├── Ext-H.bcmap
│ │ │ │ ├── Ext-RKSJ-H.bcmap
│ │ │ │ ├── Ext-RKSJ-V.bcmap
│ │ │ │ ├── Ext-V.bcmap
│ │ │ │ ├── GB-EUC-H.bcmap
│ │ │ │ ├── GB-EUC-V.bcmap
│ │ │ │ ├── GB-H.bcmap
│ │ │ │ ├── GB-V.bcmap
│ │ │ │ ├── GBK-EUC-H.bcmap
│ │ │ │ ├── GBK-EUC-V.bcmap
│ │ │ │ ├── GBK2K-H.bcmap
│ │ │ │ ├── GBK2K-V.bcmap
│ │ │ │ ├── GBKp-EUC-H.bcmap
│ │ │ │ ├── GBKp-EUC-V.bcmap
│ │ │ │ ├── GBT-EUC-H.bcmap
│ │ │ │ ├── GBT-EUC-V.bcmap
│ │ │ │ ├── GBT-H.bcmap
│ │ │ │ ├── GBT-V.bcmap
│ │ │ │ ├── GBTpc-EUC-H.bcmap
│ │ │ │ ├── GBTpc-EUC-V.bcmap
│ │ │ │ ├── GBpc-EUC-H.bcmap
│ │ │ │ ├── GBpc-EUC-V.bcmap
│ │ │ │ ├── H.bcmap
│ │ │ │ ├── HKdla-B5-H.bcmap
│ │ │ │ ├── HKdla-B5-V.bcmap
│ │ │ │ ├── HKdlb-B5-H.bcmap
│ │ │ │ ├── HKdlb-B5-V.bcmap
│ │ │ │ ├── HKgccs-B5-H.bcmap
│ │ │ │ ├── HKgccs-B5-V.bcmap
│ │ │ │ ├── HKm314-B5-H.bcmap
│ │ │ │ ├── HKm314-B5-V.bcmap
│ │ │ │ ├── HKm471-B5-H.bcmap
│ │ │ │ ├── HKm471-B5-V.bcmap
│ │ │ │ ├── HKscs-B5-H.bcmap
│ │ │ │ ├── HKscs-B5-V.bcmap
│ │ │ │ ├── Hankaku.bcmap
│ │ │ │ ├── Hiragana.bcmap
│ │ │ │ ├── KSC-EUC-H.bcmap
│ │ │ │ ├── KSC-EUC-V.bcmap
│ │ │ │ ├── KSC-H.bcmap
│ │ │ │ ├── KSC-Johab-H.bcmap
│ │ │ │ ├── KSC-Johab-V.bcmap
│ │ │ │ ├── KSC-V.bcmap
│ │ │ │ ├── KSCms-UHC-H.bcmap
│ │ │ │ ├── KSCms-UHC-HW-H.bcmap
│ │ │ │ ├── KSCms-UHC-HW-V.bcmap
│ │ │ │ ├── KSCms-UHC-V.bcmap
│ │ │ │ ├── KSCpc-EUC-H.bcmap
│ │ │ │ ├── KSCpc-EUC-V.bcmap
│ │ │ │ ├── Katakana.bcmap
│ │ │ │ ├── LICENSE
│ │ │ │ ├── NWP-H.bcmap
│ │ │ │ ├── NWP-V.bcmap
│ │ │ │ ├── RKSJ-H.bcmap
│ │ │ │ ├── RKSJ-V.bcmap
│ │ │ │ ├── Roman.bcmap
│ │ │ │ ├── UniCNS-UCS2-H.bcmap
│ │ │ │ ├── UniCNS-UCS2-V.bcmap
│ │ │ │ ├── UniCNS-UTF16-H.bcmap
│ │ │ │ ├── UniCNS-UTF16-V.bcmap
│ │ │ │ ├── UniCNS-UTF32-H.bcmap
│ │ │ │ ├── UniCNS-UTF32-V.bcmap
│ │ │ │ ├── UniCNS-UTF8-H.bcmap
│ │ │ │ ├── UniCNS-UTF8-V.bcmap
│ │ │ │ ├── UniGB-UCS2-H.bcmap
│ │ │ │ ├── UniGB-UCS2-V.bcmap
│ │ │ │ ├── UniGB-UTF16-H.bcmap
│ │ │ │ ├── UniGB-UTF16-V.bcmap
│ │ │ │ ├── UniGB-UTF32-H.bcmap
│ │ │ │ ├── UniGB-UTF32-V.bcmap
│ │ │ │ ├── UniGB-UTF8-H.bcmap
│ │ │ │ ├── UniGB-UTF8-V.bcmap
│ │ │ │ ├── UniJIS-UCS2-H.bcmap
│ │ │ │ ├── UniJIS-UCS2-HW-H.bcmap
│ │ │ │ ├── UniJIS-UCS2-HW-V.bcmap
│ │ │ │ ├── UniJIS-UCS2-V.bcmap
│ │ │ │ ├── UniJIS-UTF16-H.bcmap
│ │ │ │ ├── UniJIS-UTF16-V.bcmap
│ │ │ │ ├── UniJIS-UTF32-H.bcmap
│ │ │ │ ├── UniJIS-UTF32-V.bcmap
│ │ │ │ ├── UniJIS-UTF8-H.bcmap
│ │ │ │ ├── UniJIS-UTF8-V.bcmap
│ │ │ │ ├── UniJIS2004-UTF16-H.bcmap
│ │ │ │ ├── UniJIS2004-UTF16-V.bcmap
│ │ │ │ ├── UniJIS2004-UTF32-H.bcmap
│ │ │ │ ├── UniJIS2004-UTF32-V.bcmap
│ │ │ │ ├── UniJIS2004-UTF8-H.bcmap
│ │ │ │ ├── UniJIS2004-UTF8-V.bcmap
│ │ │ │ ├── UniJISPro-UCS2-HW-V.bcmap
│ │ │ │ ├── UniJISPro-UCS2-V.bcmap
│ │ │ │ ├── UniJISPro-UTF8-V.bcmap
│ │ │ │ ├── UniJISX0213-UTF32-H.bcmap
│ │ │ │ ├── UniJISX0213-UTF32-V.bcmap
│ │ │ │ ├── UniJISX02132004-UTF32-H.bcmap
│ │ │ │ ├── UniJISX02132004-UTF32-V.bcmap
│ │ │ │ ├── UniKS-UCS2-H.bcmap
│ │ │ │ ├── UniKS-UCS2-V.bcmap
│ │ │ │ ├── UniKS-UTF16-H.bcmap
│ │ │ │ ├── UniKS-UTF16-V.bcmap
│ │ │ │ ├── UniKS-UTF32-H.bcmap
│ │ │ │ ├── UniKS-UTF32-V.bcmap
│ │ │ │ ├── UniKS-UTF8-H.bcmap
│ │ │ │ ├── UniKS-UTF8-V.bcmap
│ │ │ │ ├── V.bcmap
│ │ │ │ └── WP-Symbol.bcmap
│ │ │ ├── pdf.mjs
│ │ │ ├── pdf.worker.mjs
│ │ │ ├── standard_fonts/
│ │ │ │ ├── FoxitDingbats.pfb
│ │ │ │ ├── FoxitFixed.pfb
│ │ │ │ ├── FoxitFixedBold.pfb
│ │ │ │ ├── FoxitFixedBoldItalic.pfb
│ │ │ │ ├── FoxitFixedItalic.pfb
│ │ │ │ ├── FoxitSerif.pfb
│ │ │ │ ├── FoxitSerifBold.pfb
│ │ │ │ ├── FoxitSerifBoldItalic.pfb
│ │ │ │ ├── FoxitSerifItalic.pfb
│ │ │ │ ├── FoxitSymbol.pfb
│ │ │ │ ├── LICENSE_FOXIT
│ │ │ │ └── LICENSE_LIBERATION
│ │ │ └── text_layer_builder.css
│ │ └── sqljs-wasm/
│ │ ├── sql-wasm.js
│ │ └── sql-wasm.wasm
│ └── robots.txt
├── src/
│ ├── assets/
│ │ ├── lib/
│ │ │ └── kookit-extra.min.mjs
│ │ ├── locales/
│ │ │ ├── am/
│ │ │ │ └── translation.json
│ │ │ ├── ar/
│ │ │ │ └── translation.json
│ │ │ ├── bg/
│ │ │ │ └── translation.json
│ │ │ ├── bn/
│ │ │ │ └── translation.json
│ │ │ ├── bo/
│ │ │ │ └── translation.json
│ │ │ ├── cs/
│ │ │ │ └── translation.json
│ │ │ ├── da/
│ │ │ │ └── translation.json
│ │ │ ├── de/
│ │ │ │ └── translation.json
│ │ │ ├── el/
│ │ │ │ └── translation.json
│ │ │ ├── en/
│ │ │ │ └── translation.json
│ │ │ ├── es/
│ │ │ │ └── translation.json
│ │ │ ├── fa/
│ │ │ │ └── translation.json
│ │ │ ├── fi/
│ │ │ │ └── translation.json
│ │ │ ├── fr/
│ │ │ │ └── translation.json
│ │ │ ├── ga/
│ │ │ │ └── translation.json
│ │ │ ├── hi/
│ │ │ │ └── translation.json
│ │ │ ├── hu/
│ │ │ │ └── translation.json
│ │ │ ├── hy/
│ │ │ │ └── translation.json
│ │ │ ├── id/
│ │ │ │ └── translation.json
│ │ │ ├── ie/
│ │ │ │ └── translation.json
│ │ │ ├── it/
│ │ │ │ └── translation.json
│ │ │ ├── ja/
│ │ │ │ └── translation.json
│ │ │ ├── ko/
│ │ │ │ └── translation.json
│ │ │ ├── nl/
│ │ │ │ └── translation.json
│ │ │ ├── pl/
│ │ │ │ └── translation.json
│ │ │ ├── pt/
│ │ │ │ └── translation.json
│ │ │ ├── pt-BR/
│ │ │ │ └── translation.json
│ │ │ ├── ro/
│ │ │ │ └── translation.json
│ │ │ ├── ru/
│ │ │ │ └── translation.json
│ │ │ ├── sl/
│ │ │ │ └── translation.json
│ │ │ ├── sr/
│ │ │ │ └── translation.json
│ │ │ ├── sv/
│ │ │ │ └── translation.json
│ │ │ ├── ta/
│ │ │ │ └── translation.json
│ │ │ ├── th/
│ │ │ │ └── translation.json
│ │ │ ├── tl/
│ │ │ │ └── translation.json
│ │ │ ├── tr/
│ │ │ │ └── translation.json
│ │ │ ├── uk/
│ │ │ │ └── translation.json
│ │ │ ├── vi/
│ │ │ │ └── translation.json
│ │ │ ├── zh-CN/
│ │ │ │ └── translation.json
│ │ │ ├── zh-MO/
│ │ │ │ └── translation.json
│ │ │ └── zh-TW/
│ │ │ └── translation.json
│ │ ├── lotties/
│ │ │ ├── exit.json
│ │ │ ├── message.json
│ │ │ ├── new.json
│ │ │ ├── safe.json
│ │ │ ├── success.json
│ │ │ └── support.json
│ │ └── styles/
│ │ ├── global.css
│ │ ├── reset.css
│ │ └── style.css
│ ├── components/
│ │ ├── arrow/
│ │ │ ├── arrow.css
│ │ │ └── index.tsx
│ │ ├── background/
│ │ │ ├── background.css
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── bookCardItem/
│ │ │ ├── bookCardItem.css
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── bookCoverItem/
│ │ │ ├── bookCoverItem.css
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── bookListItem/
│ │ │ ├── bookListItem.css
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── colorOption/
│ │ │ ├── colorOption.css
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── deleteIcon/
│ │ │ ├── component.tsx
│ │ │ ├── deleteIcon.css
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── dialogs/
│ │ │ ├── aboutDialog/
│ │ │ │ ├── aboutDialog.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── actionDialog/
│ │ │ │ ├── actionDialog.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── addDialog/
│ │ │ │ ├── addDialog.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── backupDialog/
│ │ │ │ ├── backupDialog.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── convertDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── convertDialog.css
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── deleteDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── deleteDialog.css
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── deletePopup/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── detailDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── updateInfo.css
│ │ │ ├── editDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── editDialog.css
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── importDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── importDialog.css
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── loadingDialog/
│ │ │ │ ├── index.tsx
│ │ │ │ └── loadingDialog.css
│ │ │ ├── localFileDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── localFileDialog.css
│ │ │ ├── moreAction/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── moreAction.css
│ │ │ ├── settingDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── settingDialog.css
│ │ │ ├── sortBookDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── sortDialog.css
│ │ │ ├── sortShelfDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── sortShelfDialog.css
│ │ │ ├── speechDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── speechDialog.css
│ │ │ ├── supportDialog/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── supportDialog.css
│ │ │ └── updateDialog/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── updateInfo.css
│ │ ├── emptyCover/
│ │ │ ├── emptyCover.css
│ │ │ └── index.tsx
│ │ ├── imageViewer/
│ │ │ ├── component.tsx
│ │ │ ├── imageViewer.css
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── importLocal/
│ │ │ ├── component.tsx
│ │ │ ├── importLocal.css
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── noteTag/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── noteTag.css
│ │ ├── popups/
│ │ │ ├── popupAssist/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupAssist.css
│ │ │ ├── popupBox/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupMenu.css
│ │ │ ├── popupDict/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupDict.css
│ │ │ ├── popupMenu/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupMenu.css
│ │ │ ├── popupNote/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupNote.css
│ │ │ ├── popupOption/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupOption.css
│ │ │ ├── popupRefer/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── popupRefer.css
│ │ │ └── popupTrans/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── popupTrans.css
│ │ ├── readerSettings/
│ │ │ ├── dropdownList/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── dropdownList.css
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── modeControl/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── modeControl.css
│ │ │ ├── settingSwitch/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── sliderList/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── sliderList.css
│ │ │ └── themeList/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── themeList.css
│ │ ├── searchBox/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── searchBox.css
│ │ ├── selectBook/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── selectBook.css
│ │ ├── textToSpeech/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── textToSpeech.css
│ │ └── viewMode/
│ │ ├── component.tsx
│ │ ├── index.tsx
│ │ ├── interface.tsx
│ │ └── viewMode.css
│ ├── constants/
│ │ ├── driveList.tsx
│ │ ├── dropdownList.tsx
│ │ ├── emptyList.tsx
│ │ ├── loginList.tsx
│ │ ├── mimetype.tsx
│ │ ├── popupList.tsx
│ │ ├── settingList.tsx
│ │ ├── sideMenu.tsx
│ │ ├── themeList.tsx
│ │ ├── ttsList.tsx
│ │ └── viewMode.tsx
│ ├── containers/
│ │ ├── emptyPage/
│ │ │ ├── component.tsx
│ │ │ ├── emptyPage.css
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── header/
│ │ │ ├── component.tsx
│ │ │ ├── header.css
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── lists/
│ │ │ ├── bookList/
│ │ │ │ ├── booklist.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── cardList/
│ │ │ │ ├── cardList.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── contentList/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── contentList.css
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── deletedBookList/
│ │ │ │ ├── booklist.css
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── navList/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── navList.css
│ │ │ └── noteList/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── noteList.css
│ │ ├── pageWidget/
│ │ │ ├── background.css
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── panels/
│ │ │ ├── navigationPanel/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── navigationPanel.css
│ │ │ ├── operationPanel/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── operationPanel.css
│ │ │ ├── progressPanel/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── interface.tsx
│ │ │ │ └── progressPanel.css
│ │ │ └── settingPanel/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── settingPanel.css
│ │ ├── settings/
│ │ │ ├── accountSetting/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── generalSetting/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ ├── pluginSetting/
│ │ │ │ ├── component.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── interface.tsx
│ │ │ └── syncSetting/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ ├── sidebar/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── sidebar.css
│ │ └── viewer/
│ │ ├── component.tsx
│ │ ├── index.css
│ │ ├── index.tsx
│ │ └── interface.tsx
│ ├── i18n-script.js
│ ├── i18n.tsx
│ ├── index.tsx
│ ├── models/
│ │ ├── Book.ts
│ │ ├── BookLocation.ts
│ │ ├── Bookmark.ts
│ │ ├── DictHistory.ts
│ │ ├── HtmlBook.ts
│ │ ├── Note.ts
│ │ └── Plugin.ts
│ ├── pages/
│ │ ├── login/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── login.css
│ │ ├── manager/
│ │ │ ├── component.tsx
│ │ │ ├── index.tsx
│ │ │ ├── interface.tsx
│ │ │ └── manager.css
│ │ ├── reader/
│ │ │ ├── component.tsx
│ │ │ ├── index.css
│ │ │ ├── index.tsx
│ │ │ └── interface.tsx
│ │ └── redirect/
│ │ ├── component.tsx
│ │ ├── index.tsx
│ │ ├── interface.tsx
│ │ └── manager.css
│ ├── react-app-env.d.ts
│ ├── router/
│ │ ├── index.tsx
│ │ └── routes.tsx
│ ├── store/
│ │ ├── actions/
│ │ │ ├── backupPage.tsx
│ │ │ ├── book.tsx
│ │ │ ├── index.tsx
│ │ │ ├── manager.tsx
│ │ │ ├── progressPanel.tsx
│ │ │ ├── reader.tsx
│ │ │ ├── sidebar.tsx
│ │ │ └── viewArea.tsx
│ │ ├── index.tsx
│ │ └── reducers/
│ │ ├── backupPage.tsx
│ │ ├── book.tsx
│ │ ├── index.tsx
│ │ ├── manager.tsx
│ │ ├── progressPanel.tsx
│ │ ├── reader.tsx
│ │ ├── sidebar.tsx
│ │ └── viewArea.tsx
│ ├── upload.sh
│ └── utils/
│ ├── common.ts
│ ├── file/
│ │ ├── backup.ts
│ │ ├── bookUtil.ts
│ │ ├── common.ts
│ │ ├── configUtil.ts
│ │ ├── coverUtil.ts
│ │ ├── export.ts
│ │ ├── googlePicker.ts
│ │ ├── localFile.ts
│ │ ├── restore.ts
│ │ └── sqlUtil.ts
│ ├── reader/
│ │ ├── docUtil.ts
│ │ ├── launchUtil.ts
│ │ ├── mouseEvent.ts
│ │ ├── styleUtil.ts
│ │ ├── themeUtil.ts
│ │ └── ttsUtil.ts
│ ├── request/
│ │ ├── common.ts
│ │ ├── reader.ts
│ │ ├── thirdparty.ts
│ │ └── user.ts
│ └── storage/
│ ├── databaseService.ts
│ └── syncService.ts
├── tsconfig.json
├── types/
│ └── index.d.ts
└── webpack.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .coderabbit.yaml
================================================
reviews:
auto_review:
path_filters:
- "!src/assets/**" # Exclude all files in the 'test_files' directory
================================================
FILE: .eslintrc.js
================================================
module.exports = {
// 其他配置
rules: {
"no-unused-expressions": "off",
"@typescript-eslint/ban-types": "off",
},
};
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: General Inquiry
url: https://koodoreader.com/en/support
about: Have questions or need help using Koodo Reader.
- name: 问题咨询
url: https://koodoreader.com/zh/support
about: 有疑问或需要帮助
- name: Report Issue
url: https://koodoreader.com/en/support
about: Encountered a bug or technical problem
- name: 报告问题
url: https://koodoreader.com/zh/support
about: 遇到错误或技术问题
- name: Feature Request
url: https://koodoreader.com/en/support
about: Have an idea for a new feature or improvement
- name: 功能建议
url: https://koodoreader.com/zh/support
about: 希望添加新功能或觉得需要改进
================================================
FILE: .github/ISSUE_TEMPLATE/submit_translation.yml
================================================
name: Submit Translation
description: Edit current translation or add new languages
labels: "submit translation"
body:
- type: checkboxes
id: guide
attributes:
label: I've read the translation guide
description: https://github.com/koodo-reader/koodo-reader#translation
options:
- label: "Yes"
required: true
- type: input
id: code
attributes:
label: Language code (Check out this website for more info)
description: http://www.lingoes.net/en/translator/langcode.htm
placeholder: Language code for the translation
validations:
required: true
- type: input
id: native
attributes:
label: The name of this language in your native language
placeholder: How to say this language in your native language
validations:
required: true
- type: textarea
id: translation
attributes:
label: Translation snippets or file
placeholder: You can paste the translation snippets or drag and drop the translation json file here
validations:
required: true
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
## Description
<!-- Note that we only accept pull request related to translations -->
<!-- 请注意,我们只接受翻译相关的 Pull Request -->
================================================
FILE: .github/workflows/docker-publish.yml
================================================
name: Docker
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on: workflow_dispatch
env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0
with:
cosign-release: "v2.2.4"
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
================================================
FILE: .github/workflows/release-appx.yml
================================================
name: Build/release-appx
on: workflow_dispatch
jobs:
release:
runs-on: ${{ matrix.os }}
# Platforms to build on/for
strategy:
matrix:
os: [windows-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v2
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 22
- name: Set environment variable USE_HARD_LINKS
run: echo "USE_HARD_LINKS=false" >> $GITHUB_ENV
- name: Modify package.json for Windows Store build
if: startsWith(matrix.os, 'windows')
run: |
$packageJson = Get-Content package.json -Raw | ConvertFrom-Json
$packageJson.build.win.target = @(
@{
target = "appx"
arch = @("x64", "arm64", "ia32")
}
)
$packageJson | ConvertTo-Json -Depth 10 | Set-Content package.json
- name: Build/release for Windows Store
if: startsWith(matrix.os, 'windows')
uses: samuelmeuli/action-electron-builder@v1.6.0
with:
build_script_name: "build"
# GitHub token, automatically provided to the action
# (No need to define this secret in the repo settings)
github_token: ${{ secrets.github_token }}
================================================
FILE: .github/workflows/release.yml
================================================
name: Build/release
on: workflow_dispatch
jobs:
release:
runs-on: ${{ matrix.os }}
# Platforms to build on/for
strategy:
matrix:
os: [macos-latest, ubuntu-22.04, windows-latest, ubuntu-24.04-arm]
steps:
- name: Check out Git repository
uses: actions/checkout@v2
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 22
- name: Install Snapcraft
uses: samuelmeuli/action-snapcraft@v1.2.0
# Only install Snapcraft on Ubuntu
if: startsWith(matrix.os, 'ubuntu-22.04')
with:
# Log in to Snap Store
snapcraft_token: ${{ secrets.snapcraft_token }}
- name: Install Gcc
if: startsWith(matrix.os, 'ubuntu-22.04')
run: |
sudo apt update
sudo apt-get install gcc-multilib g++-multilib
- name: Install FPM
if: startsWith(matrix.os, 'ubuntu-24.04-arm')
run: |
sudo apt update
sudo apt-get install -y ruby-full build-essential zlib1g-dev liblzma-dev
sudo gem install --no-document fpm
- name: Prepare for app notarization (macOS)
if: startsWith(matrix.os, 'macos')
# Import Apple API key for app notarization on macOS
run: |
mkdir -p ~/private_keys/
echo ${{ github.ref }}
echo '${{ secrets.API_KEY }}' > ~/private_keys/AuthKey_${{ secrets.API_KEY_ID }}.p8
brew install python-setuptools
- name: Set environment variable USE_SYSTEM_FPM
if: startsWith(matrix.os, 'ubuntu-24.04-arm')
run: echo "USE_SYSTEM_FPM=true" >> $GITHUB_ENV
- name: Set environment variable USE_HARD_LINKS
run: echo "USE_HARD_LINKS=false" >> $GITHUB_ENV
- name: Modify package.json for dev branch
if: github.ref == 'refs/heads/dev'
shell: bash
run: |
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
powershell -Command "(Get-Content package.json) -replace '\"productName\": \"Koodo Reader\"', '\"productName\": \"Koodo Reader DEV\"' | Set-Content package.json"
else
sed -i.bak 's/"productName": "Koodo Reader"/"productName": "Koodo Reader DEV"/' package.json
fi
- name: Modify package.json for Linux arm64 build
if: startsWith(matrix.os, 'ubuntu-24.04-arm')
run: |
jq '.build.linux.target = [
{
"target": "deb",
"arch": ["arm64"]
},
{
"target": "AppImage",
"arch": ["arm64"]
}
]' package.json > package.json.tmp && mv package.json.tmp package.json
- name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1.6.0
with:
build_script_name: "build"
# GitHub token, automatically provided to the action
# (No need to define this secret in the repo settings)
github_token: ${{ secrets.github_token }}
# macOS code signing certificate
mac_certs: ${{ secrets.MAC_CERTS }}
mac_certs_password: ${{ secrets.MAC_CERTS_PASSWORD }}
# If the commit is tagged with a version (e.g. "v1.0.0"),
# release the app after building
release: ${{ startsWith(github.ref, 'refs/tags/v') }}
env:
# macOS notarization API key
API_KEY_ID: ${{ secrets.API_KEY_ID }}
API_KEY_ISSUER_ID: ${{ secrets.API_KEY_ISSUER_ID }}
================================================
FILE: .github/workflows/upload.yml
================================================
name: Download/upload
on: workflow_dispatch
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Run custom script
run: |
curl -O https://raw.githubusercontent.com/koodo-reader/koodo-reader/master/src/upload.sh
chmod +x ./upload.sh
./upload.sh ${{ secrets.R2_ACCOUNT_ID }} ${{ secrets.R2_APPLICATION_KEY }} ${{ secrets.R2_ENDPOINT }}
shell: bash
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
#/build
dist/
/build/*
/.vscode
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
#.env
npm-debug.log*
yarn-debug.log*
yarn-error.log*
config.js*
rewrite.sh
bfg.jar
kookit.js
kookit.mjs
kookit-extra.js
kookit-extra.mjs
kookit-extra-browser.js
kookit-extra-browser.mjs
================================================
FILE: .prettierrc
================================================
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"useTabs": false,
"printWidth": 80,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf",
"jsxSingleQuote": false,
"bracketSameLine": false,
"proseWrap": "preserve"
}
================================================
FILE: .yarnrc
================================================
network-timeout 600000
================================================
FILE: Dockerfile
================================================
FROM node:20-slim as builder
RUN apt-get update && apt-get install -y jq curl wget python3 git
WORKDIR /app
### Get the latest release source code tarball
# RUN tarball_url=$(curl -s https://api.github.com/repos/koodo-reader/koodo-reader/releases/latest | jq -r ".tarball_url") \
# && wget -qO- $tarball_url \
# | tar xvfz - --strip 1
RUN git clone https://github.com/koodo-reader/koodo-reader.git . && \
git checkout master
### --network-timeout 1000000 as a workaround for slow devices
### when the package being installed is too large, Yarn assumes it's a network problem and throws an error
RUN yarn --ignore-scripts --network-timeout 1000000
### Separate `yarn build` layer as a workaround for devices with low RAM.
### If build fails due to OOM, `yarn install` layer will be already cached.
RUN yarn --ignore-scripts\
&& yarn build
### Nginx or Apache can also be used, Caddy is just smaller in size
FROM caddy:latest
# Install Node.js in the Caddy image
RUN apk add --no-cache nodejs npm
# Copy built website files to Caddy
COPY --from=builder /app/build /usr/share/caddy
# Copy httpServer.js
COPY --from=builder /app/httpServer.js /app/httpServer.js
# Create uploads directory with proper permissions
RUN mkdir -p /app/uploads && \
chmod 755 /app/uploads
# Expose both Caddy (80) and httpServer (8080) ports
EXPOSE 80 8080
# Create startup script to run both services
RUN echo '#!/bin/sh' > /start.sh && \
echo 'cd /app' >> /start.sh && \
echo 'node httpServer.js &' >> /start.sh && \
echo 'caddy run --config /etc/caddy/Caddyfile' >> /start.sh && \
chmod +x /start.sh
# Set default environment variables (can be overridden at runtime)
ENV SERVER_USERNAME=admin
ENV SERVER_PASSWORD=securePass123
ENV SERVER_PASSWORD_FILE=my_secret
# Define volume for uploads directory
VOLUME ["/app/uploads"]
CMD ["/start.sh"]
================================================
FILE: LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are 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.
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.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
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 Affero 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. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
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 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 work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
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 AGPL, see
<http://www.gnu.org/licenses/>.
================================================
FILE: README.md
================================================
<div align="left">
[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [हिंदी](https://github.com/koodo-reader/koodo-reader/blob/master/README_hi.md)
|[Português](https://github.com/koodo-reader/koodo-reader/blob/master/README_pt.md) | [Indonesian](https://github.com/koodo-reader/koodo-reader/blob/master/README_id.md) | English
</div>
<div align="center" >
<img src="https://dl.koodoreader.com/screenshots/logo.png" width="96px" height="96px"/>
</div>
<h1 align="center">
Koodo Reader
</h1>
<h3 align="center">
A cross-platform ebook reader
</h3>
<div align="center">
[Download](https://koodoreader.com/en) | [Preview](https://web.koodoreader.com) | [Roadmap](https://koodoreader.com/en/roadmap) | [Document](https://koodoreader.com/en/document) | [Plugins](https://koodoreader.com/en/plugin)
</div>
## Preview
<div align="center">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/7.png" width="800px">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/8.png" width="800px">
<br/>
<br/>
</div>
## Features
- Format support:
- EPUB (**.epub**)
- PDF (**.pdf**)
- DRM-free Mobipocket (**.mobi**) and Kindle (**.azw3**, **.azw**)
- Plain-text (**.txt**)
- FictionBook (**.fb2**)
- Comic book archive (**.cbr**, **.cbz**, **.cbt**, **.cb7**)
- Rich text (**.md**, **.docx**)
- HyperText (**.html**, **.xml**, **.xhtml**, **.mhtml**, **.htm**)
- Platform support: **Windows**, **macOS**, **Linux**, **Android**, **iOS** and **Web**
- Sync and backup your data with **OneDrive**, **Google Drive**, **Dropbox**, **MEGA**, **pCloud**, **Yandex Disk**, **Box**, **FTP**, **SFTP**, **WebDAV**, **SMB**, or **Object Storage**
- Easily import books from **OneDrive**, **Google Drive**, **MEGA**, **Yandex Disk**, **Box**, **FTP**, **SFTP**, **WebDAV**, **SMB**, or **Object Storage**
- AI dictionary, summarization, and translation
- Single-column, two-column or continuous scrolling layouts
- Text-to-speech, translation, dictionary, touch screen support, and batch import
- Add bookmarks, notes, and highlights to your books
- Adjust font size, font family, line-spacing, paragraph spacing, background color, text color, margins, and brightness
- Night mode and theme color
- Text highlighting, underline, boldness, italics, and shadow
## Installation
### Desktop version: [Download](https://koodoreader.com/en/download)
### Web version:[Visit](https://web.koodoreader.com)
### Android version:[Download](https://koodoreader.com/en/download)
### iOS version:[Download](https://koodoreader.com/en/download)
### Install with Scoop:
```shell
scoop bucket add extras
scoop install extras/koodo-reader
```
### Install with Homebrew:
```shell
brew install --cask koodo-reader
```
### Install with Docker:
[Installation Guide](https://koodoreader.com/en/deploy-docker)
## Screenshot
<div align="center">
<b>Book list</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/1.png" width="800px"></kbd>
<br/>
<br/>
<b>Book display</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/5.png" width="800px"></kbd>
<br/>
<br/>
<b>List mode</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/2.png" width="800px"></kbd>
<br/>
<br/>
<b>Cover mode</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/3.png" width="800px"></kbd>
<br/>
<br/>
<b>Reader menu</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/6.png" width="800px"></kbd>
<br/>
<br/>
<b>Dark mode</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/4.png" width="800px"></kbd>
<br/>
</div>
## Develop
Make sure that you have installed yarn and git
1. Download the repo
```
git clone https://github.com/koodo-reader/koodo-reader.git
```
2. Enter desktop mode
```
yarn
yarn dev
```
3. Enter web mode
```
yarn
yarn start
```
## Translation
### Edit current language
1. Select your target language from the following list.
2. Click the view button to examine the source file. The untranslated terms are listed at the bottom of each file.
3. Translate the terms to your target language based on the given English reference
4. Submit the translation file or just translation snippets based on the amount of your translation to [this link](https://github.com/koodo-reader/koodo-reader/issues/new?assignees=&labels=submit+translation&projects=&template=submit_translation.yml). Pull request is also welcomed.
| Language(A-Z) | Code | View |
| --------------- | ----- | --------------------------------------------------- |
| Amharic | am | [View](./src/assets/locales/am/translation.json) |
| Arabic | ar | [View](./src/assets/locales/ar/translation.json) |
| Armenian | hy | [View](./src/assets/locales/hy/translation.json) |
| Bengali | bn | [View](./src/assets/locales/bn/translation.json) |
| Bulgarian | bg | [View](./src/assets/locales/bg/translation.json) |
| Chinese (CN) | zh-CN | [View](./src/assets/locales/zh-CN/translation.json) |
| Chinese (MO) | zh-MO | [View](./src/assets/locales/zh-MO/translation.json) |
| Chinese (TW) | zh-TW | [View](./src/assets/locales/zh-TW/translation.json) |
| Czech | cs | [View](./src/assets/locales/cs/translation.json) |
| Danish | da | [View](./src/assets/locales/da/translation.json) |
| Dutch | nl | [View](./src/assets/locales/nl/translation.json) |
| English | en | [View](./src/assets/locales/en/translation.json) |
| Finnish | fi | [View](./src/assets/locales/fi/translation.json) |
| French | fr | [View](./src/assets/locales/fr/translation.json) |
| German | de | [View](./src/assets/locales/de/translation.json) |
| Greek | el | [View](./src/assets/locales/el/translation.json) |
| Hindi | hi | [View](./src/assets/locales/hi/translation.json) |
| Hungarian | hu | [View](./src/assets/locales/hu/translation.json) |
| Indonesian | id | [View](./src/assets/locales/id/translation.json) |
| Interlingue | ie | [View](./src/assets/locales/ie/translation.json) |
| Irish | ga | [View](./src/assets/locales/ga/translation.json) |
| Italian | it | [View](./src/assets/locales/it/translation.json) |
| Japanese | ja | [View](./src/assets/locales/ja/translation.json) |
| Korean | ko | [View](./src/assets/locales/ko/translation.json) |
| Persian | fa | [View](./src/assets/locales/fa/translation.json) |
| Polish | pl | [View](./src/assets/locales/pl/translation.json) |
| Portuguese | pt | [View](./src/assets/locales/pt/translation.json) |
| Portuguese (BR) | pt-BR | [View](./src/assets/locales/pt-BR/translation.json) |
| Romanian | ro | [View](./src/assets/locales/ro/translation.json) |
| Russian | ru | [View](./src/assets/locales/ru/translation.json) |
| Slovenian | sl | [View](./src/assets/locales/sl/translation.json) |
| Spanish | es | [View](./src/assets/locales/es/translation.json) |
| Swedish | sv | [View](./src/assets/locales/sv/translation.json) |
| Tamil | ta | [View](./src/assets/locales/ta/translation.json) |
| Thai | th | [View](./src/assets/locales/th/translation.json) |
| Tagalog | tl | [View](./src/assets/locales/tl/translation.json) |
| Tibetan | bo | [View](./src/assets/locales/bo/translation.json) |
| Turkish | tr | [View](./src/assets/locales/tr/translation.json) |
| Ukrainian | uk | [View](./src/assets/locales/uk/translation.json) |
| Vietnamese | vi | [View](./src/assets/locales/vi/translation.json) |
### Add new language
1. If you can't find your target language from the above list, download the English source file from [this link](./src/assets/locales/en/translation.json).
2. When you're finished translating, submit the source file to [this link](https://github.com/koodo-reader/koodo-reader/issues/new?assignees=&labels=submit+translation&projects=&template=submit_translation.yml). Pull requests are also welcome.
================================================
FILE: README_cn.md
================================================
<div align="left">
简体中文 | [हिंदी](https://github.com/koodo-reader/koodo-reader/blob/master/README_hi.md) |[Português](https://github.com/koodo-reader/koodo-reader/blob/master/README_pt.md) | [English](https://github.com/koodo-reader/koodo-reader/blob/master/README.md) | [Indonesian](https://github.com/koodo-reader/koodo-reader/blob/master/README_id.md)
</div>
<div align="center">
<img src="https://dl.koodoreader.com/screenshots/logo.png" width="96px" height="96px"/>
</div>
<h1 align="center">
Koodo Reader
</h1>
<h3 align="center">
一个跨平台的电子书阅读器
</h3>
<div align="center">
[下载客户端](https://koodoreader.com/zh) | [在线预览](https://web.koodoreader.com) | [开发计划](https://koodoreader.com/zh/roadmap) | [帮助文档](https://koodoreader.com/zh/document) | [插件列表](https://koodoreader.com/zh/plugin)
</div>
## 预览
<div align="center">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/7.png" width="800px">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/8.png" width="800px">
<br/>
<br/>
</div>
## 特色
- 支持阅读格式:
- EPUB (**.epub**)
- PDF (**.pdf**)
- Kindle (**.azw3**, **.mobi**, **.azw**)
- 纯文本 (**.txt**)
- 漫画 (**.cbr**, **.cbz**, **.cbt**, **.cb7**)
- 富文本 (**.md**, **.docx**)
- FB2 (**.fb2**)
- 超文本 (**.html**, **.xml**, **.xhtml**, **.mhtml**, **.htm**)
- 支持 **Windows**,**macOS**,**Linux** ,**安卓** ,**iOS** 和 **网页版**
- 利用 **OneDrive**, **Google Drive**, **Dropbox**, **MEGA**, **pCloud**, **阿里云盘**, **百度网盘**, **115 网盘**, **Box**, **Yandex Disk**, **FTP**, **SFTP**, **SMB**, **Docker**, **WebDAV**, **对象存储** 实现数据多端同步和备份
- 轻松从 **OneDrive**, **Google Drive**, **MEGA**, **阿里云盘**, **百度网盘**, **115 网盘**, **Box**, **Yandex Disk**, **FTP**, **SFTP**, **SMB**, **WebDAV**, **对象存储** 导入图书
- AI 翻译,AI 词典,AI 总结
- 双页模式,单页模式,滚动模式
- 听书功能,翻译功能,词典功能,触控屏支持,批量导入图书
- 支持目录,书签,笔记,高亮,书架,标签
- 自定义字体,字体大小,行间距,段落间距,阅读背景色,文字颜色,屏幕亮度,文字下划线、斜体、文字阴影、字体粗细
- 黑夜模式和主题色设置
## 使用方法
### 桌面端:[下载](https://koodoreader.com/zh/download)
### 网页版:[前往](https://web.koodoreader.com)
### 安卓版:[下载](https://koodoreader.com/zh/download)
### iOS 版:[下载](https://koodoreader.com/zh/download)
### 使用 Scoop 安装:
```shell
scoop bucket add extras
scoop install extras/koodo-reader
```
### 使用 Homebrew 安装:
```shell
brew install --cask koodo-reader
```
### 使用 Docker 安装:
[部署教程](https://koodoreader.com/zh/deploy-docker)
## 截图
<div align="center">
<b>图书列表</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/1.png" width="800px"></kbd>
<br/>
<br/>
<b>图书展示</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/5.png" width="800px"></kbd>
<br/>
<br/>
<b>列表模式</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/2.png" width="800px"></kbd>
<br/>
<br/>
<b>封面模式</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/3.png" width="800px"></kbd>
<br/>
<br/>
<b>阅读菜单</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/6.png" width="800px"></kbd>
<br/>
<br/>
<b>黑夜模式</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/4.png" width="800px"></kbd>
<br/>
<br/>
</div>
## 运行源码
请确保您电脑已配置好 yarn,git 的运行环境。
1. 将项目源码下载到本地
```
git clone https://github.com/koodo-reader/koodo-reader.git
```
2. cd 到项目文件夹,运行以下代码进入客户端模式
```
yarn
yarn dev
```
3. 运行以下代码进入网页模式
```
yarn
yarn start
```
================================================
FILE: README_hi.md
================================================
<div align="left">
[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [English](https://github.com/koodo-reader/koodo-reader/blob/master/README.md) | हिंदी |[Português](https://github.com/koodo-reader/koodo-reader/blob/master/README_pt.md) | [Indonesian](https://github.com/koodo-reader/koodo-reader/blob/master/README_id.md)
</div>
<div align="center" >
<img src="https://dl.koodoreader.com/screenshots/logo.png" width="96px" height="96px"/>
</div>
<h1 align="center">
कूडो रीडर
</h1>
<h3 align="center">
एक क्रॉस-प्लेटफ़ॉर्म ईबुक रीडर
</h3>
<div align="center">
[डाउनलोड](https://koodoreader.com/en) | [समीक्षा](https://web.koodoreader.com) | [रोडमैप](https://koodoreader.com/en/roadmap) | [आलेख](https://koodoreader.com/en/document)
</div>
## समीक्षा
<div align="center">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/7.png" width="800px">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/8.png" width="800px">
<br/>
<br/>
</div>
## विशेषता
- प्रारूप:
- EPUB (**.epub**)
- PDF (**.pdf**)
- डीआरएम मुक्त मोबिपॉकेट (**.mobi**) और Kindle (**.azw3**, **.azw**)
- प्लेन टेक्स्ट (**.txt**)
- उपन्यास पुस्तक (**.fb2**)
- हास्य पुस्तक पुरालेख (**.cbr**, **.cbz**, **.cbt**, **.cb7**)
- रिच टेक्स्ट (**.md**, **.docx**)
- हाइपरटेक्सट (**.html**, **.xml**, **.xhtml**, **.mhtml**, **.htm**)
- प्लेटफार्म: **Windows**, **macOS**, **Linux** and **Web**
- अपना डेटा यहां सहेजें **OneDrive**, **Google Drive**, **Dropbox**, **Yandex Disk**, **FTP**, **SFTP**, **SMB**, **WebDAV**, **S3**, **S3 Compatible**
- स्रोत फ़ोल्डर को कस्टमाइज़ करें और वनड्राइव, आईक्लाउड, ड्रॉपबॉक्स आदि का उपयोग करके कई डिवाइसों के बीच सिंक्रनाइज़ करें।
- एकल-स्तंभ, दो-स्तंभ, या निरंतर स्क्रॉलिंग लेआउट
- टेक्स्ट-टू-स्पीच, अनुवाद, शब्दकोश, टच स्क्रीन समर्थन, बैच आयात
- अपनी पुस्तकों में बुकमार्क, नोट्स, हाइलाइट्स जोड़ें
- फ़ॉन्ट आकार, फ़ॉन्ट परिवार, लाइन-स्पेसिंग, पैराग्राफ़ रिक्ति, पृष्ठभूमि रंग, टेक्स्ट रंग, मार्जिन और द्य्रुति समायोजित करें
- रात्रि मोड और थीम रंग
- टेक्स्ट हाइलाइट, अंडरलाइन, बोल्डनेस, इटैलिक और शैडो
## इंस्टालेशन
- डेस्कटॉप संस्करण:
- स्थिर संस्करण (अनुशंसित): [डाउनलोड](https://koodoreader.com/en)
- डेवलपर संस्करण: [डाउनलोड](https://github.com/koodo-reader/koodo-reader/releases/latest) ( नई सुविधा और बग फिक्स के साथ, लेकिन कुछ अज्ञात बग उत्पन्न हो सकते हैं)
- वेब संस्करण:[समीक्षा](https://web.koodoreader.com)
- स्कूप के साथ इंस्टाल करें:
```shell
scoop bucket add extras
scoop install extras/koodo-reader
```
- होमब्रू के साथ इंस्टॉल करें:
```shell
brew install --cask koodo-reader
```
- डॉकर के साथ इंस्टॉल करें:
[Installation Guide](https://koodoreader.com/en/deploy-docker)
## स्क्रीनशॉट
<div align="center">
<b>पुस्तक सूची</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/1.png" width="800px"></kbd>
<br/>
<br/>
<b>पुस्तक प्रदर्शन</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/5.png" width="800px"></kbd>
<br/>
<br/>
<b>सूची मोड</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/2.png" width="800px"></kbd>
<br/>
<br/>
<b>कवर मोड</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/3.png" width="800px"></kbd>
<br/>
<br/>
<b>पाठक मेनू</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/6.png" width="800px"></kbd>
<br/>
<br/>
<b>डार्क मोड</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/4.png" width="800px"></kbd>
<br/>
</div>
## विकास
सुनिश्चित करें कि आपने यार्न और गिट इंस्टॉल किया है
1. रेपो डाउनलोड करें
```
git clone https://github.com/koodo-reader/koodo-reader.git
```
2. डेस्कटॉप मोड में प्रवेश करें
```
yarn
yarn dev
```
3. वेब मोड में प्रवेश करें
```
yarn
yarn start
```
================================================
FILE: README_id.md
================================================
<div align="left">
[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [हिंदी](https://github.com/koodo-reader/koodo-reader/blob/master/README_hi.md) |[Português](https://github.com/koodo-reader/koodo-reader/blob/master/README_pt.md) | [English](https://github.com/koodo-reader/koodo-reader/blob/master/README.md) | Indonesian
</div>
<div align="center">
<img src="https://dl.koodoreader.com/screenshots/logo.png" width="96px" height="96px"/>
</div>
<h1 align="center">
Koodo Reader
</h1>
<h3 align="center">
Pembaca buku digital lintas platform
</h3>
<div align="center">
[Unduh](https://koodoreader.com/en) | [Pratinjau](https://web.koodoreader.com) | [Roadmap](https://koodoreader.com/en/roadmap) | [Dokumentasi](https://koodoreader.com/en/document)
</div>
## Pratinjau
<div align="center">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/7.png" width="800px">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/8.png" width="800px">
<br/>
<br/>
</div>
## Fitur
- Format yang didukung:
- EPUB (**.epub**)
- PDF (**.pdf**)
- Format bebas DRM (**.mobi**) dan Kindle (**.azw3**, **.azw**)
- Teks biasa (**.txt**)
- FictionBook (**.fb2**)
- Arsip komik (**.cbr**, **.cbz**, **.cbt**, **.cb7**)
- Teks kaya (**.md**, **.docx**)
- Hiperteks (**.html**, **.xml**, **.xhtml**, **.mhtml**, **.htm**)
- Platform yang didukung: **Windows**, **macOS**, **Linux**, dan **Web**
- Simpan data Anda di **OneDrive**, **Google Drive**, **Dropbox**, **Yandex Disk**, **FTP**, **SFTP**, **WebDAV**, **SMB**, **S3**, **S3 Compatible**
- Sesuaikan folder sumber dan sinkronkan antar perangkat menggunakan OneDrive, iCloud, Dropbox, dll.
- Tata letak satu kolom, dua kolom, atau gulir kontinu
- Text-to-speech, terjemahan, bilah kemajuan, dukungan layar sentuh, impor massal
- Tambahkan penanda, catatan, dan sorotan ke buku Anda
- Sesuaikan ukuran font, jenis font, jarak baris, jarak paragraf, warna latar belakang, warna teks, margin, dan kecerahan
- Mode malam dan tema warna
- Sorotan teks, garis bawah, tebal, miring, dan bayangan
## Instalasi
- Versi Desktop:
- Versi stabil (Disarankan): [Unduh](https://koodoreader.com/en)
- Versi pengembang: [Unduh](https://github.com/koodo-reader/koodo-reader/releases/latest) (Memiliki fitur baru dan perbaikan bug, tetapi mungkin masih mengandung beberapa masalah yang belum diketahui)
- Versi Web: [Pratinjau](https://web.koodoreader.com)
- Instal dengan Scoop:
```shell
scoop bucket add extras
scoop install extras/koodo-reader
```
- Instal dengan Homebrew:
```shell
brew install --cask koodo-reader
```
- Instal dengan Docker:
[Installation Guide](https://koodoreader.com/en/deploy-docker)
## Tangkapan Layar
<div align="center">
<b>Daftar buku</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/1.png" width="800px"></kbd>
<br/>
<br/>
<b>tampilan buku</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/5.png" width="800px"></kbd>
<br/>
<br/>
<b>Mode daftar</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/2.png" width="800px"></kbd>
<br/>
<br/>
<b>Mode sampul</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/3.png" width="800px"></kbd>
<br/>
<br/>
<b>Opsi membaca</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/6.png" width="800px"></kbd>
<br/>
<br/>
<b>Mode gelap dan warna tema</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/4.png" width="800px"></kbd>
<br/>
<br/>
</div>
## Pengembangan
Pastikan Anda telah menginstal yarn dan git.
1. Unduh repositori:
```
git clone https://github.com/koodo-reader/koodo-reader.git
```
2. Masuk ke mode desktop:
```
yarn
yarn dev
```
3. Masuk ke mode web:
```
yarn
yarn start
```
================================================
FILE: README_pt.md
================================================
<div align="left">
[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [हिंदी](https://github.com/koodo-reader/koodo-reader/blob/master/README_hi.md) | Português | [English](https://github.com/koodo-reader/koodo-reader/blob/master/README.md) | [Indonesian](https://github.com/koodo-reader/koodo-reader/blob/master/README_id.md)
</div>
<div align="center" >
<img src="https://dl.koodoreader.com/screenshots/logo.png" width="96px" height="96px"/>
</div>
<h1 align="center">
Koodo Reader
</h1>
<h3 align="center">
Um leitor de livros digitais multiplataforma
</h3>
<div align="center">
[Baixar](https://koodoreader.com/en) | [Pré-visualizar](https://web.koodoreader.com) | [Roadmap](https://koodoreader.com/en/roadmap) | [Documento](https://koodoreader.com/en/document)
</div>
## Pré-visualizar
<div align="center">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/7.png" width="800px">
<br/>
<br/>
<img src="https://dl.koodoreader.com/screenshots/8.png" width="800px">
<br/>
<br/>
</div>
## Características
- Formatos suportados:
- EPUB (**.epub**)
- PDF (**.pdf**)
- Formato sem DRM (**.mobi**) e Kindle (**.azw3**, **.azw**)
- Texto puro (**.txt**)
- FictionBook (**.fb2**)
- Arquivo de quadrinhos (**.cbr**, **.cbz**, **.cbt**, **.cb7**)
- Texto rico (**.md**, **.docx**)
- Hiper texto (**.html**, **.xml**, **.xhtml**, **.mhtml**, **.htm**)
- Plataformas suportadas: **Windows**, **macOS**, **Linux** e **Web**
- Guarde seus dados no **OneDrive**, **Google Drive**, **Dropbox**, **Yandex Disk**, **FTP**, **SFTP**, **WebDAV**, **SMB**, **S3**, **S3 Compatible**
- Personalize a pasta de origem e sincronize entre varios dispositivos usando OneDrive, iCloud, Dropbox, etc..
- Layouts de uma coluna, duas colunas ou de rolagem continua
- Text para fala, tradução, controles deslizante de progresso, suporte a tela sensível ao toque, importação em lote
- Adicione marcadores, notas e destaques aos seus livros
- Ajuste o tamanho da fonte, tipo da fonte, espaçamento entre linhas, espaçamento entre parágrafos, cor de fundo, cor do texto, margens e brilho
- Modo noturno e cores nos temas
- Destaque de texto, sublinhado, negrito, itálico e sombra
## Instalação
- Versão para computador:
- Versão estável (Recomendada): [Baixar](https://koodoreader.com/en)
- Versão do desenvolvedor: [Baixar](https://github.com/koodo-reader/koodo-reader/releases/latest) (Com novos recursos e correção de bugs, mas podendo ainda conter alguns problemas desconhecidos)
- Versão para Web:[Pré-visualizar](https://web.koodoreader.com)
- Instalar com o Scoop:
```shell
scoop bucket add extras
scoop install extras/koodo-reader
```
- Instalar com o Homebrew:
```shell
brew install --cask koodo-reader
```
- Instalar com o Docker:
[Installation Guide](https://koodoreader.com/en/deploy-docker)
## Capturas de tela
<div align="center">
<b>Lista de livros</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/1.png" width="800px"></kbd>
<br/>
<br/>
<b>exposição de livro</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/5.png" width="800px"></kbd>
<br/>
<br/>
<b>Modo em lista</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/2.png" width="800px"></kbd>
<br/>
<br/>
<b>Modo de capa</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/3.png" width="800px"></kbd>
<br/>
<br/>
<b>Opções de leitura</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/6.png" width="800px"></kbd>
<br/>
<br/>
<b>Modo escuro e cores do tema</b>
<br/>
<br/>
<kbd><img src="https://dl.koodoreader.com/screenshots/4.png" width="800px"></kbd>
<br/>
<br/>
</div>
## Desenvolver
Certifique-se de ter instalado yarn e git, a versão.
1. Baixe o repositório
```
git clone https://github.com/koodo-reader/koodo-reader.git
```
2. Entre no modo de desktop
```
yarn
yarn dev
```
3. Entre no modo web
```
yarn
yarn start
```
================================================
FILE: assets/macos/entitlements.mac.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
================================================
FILE: assets/windows/installer.nsh
================================================
!macro customUnInstall
MessageBox MB_YESNO "Do you want to delete all your data including books, notes, highlights, bookmarks, configurations?" /SD IDNO IDNO SkipRemoval
SetShellVarContext current
RMDir /r "$APPDATA\koodo-reader"
SkipRemoval:
!macroend
================================================
FILE: docker-compose-secret.yml
================================================
# This docker-compose file uses secrets to manage sensitive information like passwords.
services:
koodo-reader:
image: ghcr.io/koodo-reader/koodo-reader:master
container_name: koodo-reader
restart: unless-stopped
ports:
- "80:80"
- "8080:8080"
environment:
- SERVER_USERNAME=${SERVER_USERNAME:-admin}
- SERVER_PASSWORD_FILE=${SERVER_PASSWORD_FILE:-my_secret}
- ENABLE_HTTP_SERVER=false
volumes:
# 使用主机目录(推荐)
- /opt/uploads:/app/uploads
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt
================================================
FILE: docker-compose.yml
================================================
version: "3.8"
services:
koodo-reader:
build: .
container_name: koodo-reader
restart: unless-stopped
ports:
- "80:80"
- "8080:8080"
environment:
- SERVER_USERNAME=${SERVER_USERNAME:-admin}
- SERVER_PASSWORD=${SERVER_PASSWORD:-securePass123}
- ENABLE_HTTP_SERVER=false
volumes:
# 使用主机目录(推荐)
- /opt/uploads:/app/uploads
# 或者使用命名卷
# - uploads_data:/app/uploads
# 如果使用命名卷,取消注释以下内容
# volumes:
# uploads_data:
# driver: local
================================================
FILE: electron-builder.env
================================================
USE_HARD_LINKS=false
================================================
FILE: httpServer.js
================================================
const http = require("http");
const fs = require("fs");
const path = require("path");
const url = require("url");
// 从 Docker Secrets 读取密码的函数
function getDockerSecret(secretName) {
try {
const secretPath = `/run/secrets/${secretName}`;
if (fs.existsSync(secretPath)) {
return fs.readFileSync(secretPath, "utf8").trim();
}
} catch (err) {
console.warn(`Failed to read Docker secret '${secretName}':`, err.message);
}
return null;
}
// 配置信息
const UPLOAD_DIR = path.resolve("./uploads"); // 使用绝对路径
const PORT = process.env.PORT || 8080;
const SERVER_ENABLED = process.env.ENABLE_HTTP_SERVER === "true"; // 新增:控制服务器是否启用
// 优先从 Docker Secrets 读取密码,如果没有则回退到环境变量
const SERVER_PASSWORD_FILE = process.env.SERVER_PASSWORD_FILE || "my_secret";
const SERVER_PASSWORD =
getDockerSecret(SERVER_PASSWORD_FILE) ||
process.env.SERVER_PASSWORD ||
"securePass123";
const VALID_CREDENTIALS = {
username: process.env.SERVER_USERNAME || "admin",
password: SERVER_PASSWORD,
};
// 验证密码来源
if (getDockerSecret(SERVER_PASSWORD_FILE)) {
console.log("Using password from Docker Secret");
} else if (process.env.SERVER_PASSWORD) {
console.warn("Using password from environment variable (less secure)");
} else {
console.warn(
"Warning: Using default password. Set Docker Secret or SERVER_PASSWORD environment variable for production."
);
}
if (!process.env.SERVER_USERNAME) {
console.warn(
"Warning: Using default username. Set SERVER_USERNAME environment variable for production."
);
}
// 检查服务器是否启用
if (!SERVER_ENABLED) {
console.log(
"HTTP Server is disabled. Set ENABLE_HTTP_SERVER=true to enable it."
);
process.exit(0);
}
// 创建上传目录(如果不存在)
if (!fs.existsSync(UPLOAD_DIR)) {
fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}
const server = http.createServer((req, res) => {
// 设置CORS头部
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
res.setHeader("Access-Control-Allow-Credentials", "true");
// 处理预检请求
if (req.method === "OPTIONS") {
res.writeHead(200);
return res.end();
}
// 认证检查
if (!authenticate(req)) {
res.writeHead(401, {
"WWW-Authenticate": 'Basic realm="Secure File Server"',
"Content-Type": "text/plain",
});
return res.end("Unauthorized");
}
// 路由处理
const parsedUrl = url.parse(req.url, true);
if (req.method === "POST" && parsedUrl.pathname === "/upload") {
handleUpload(req, res, parsedUrl.query.dir || "");
} else if (req.method === "GET" && parsedUrl.pathname === "/download") {
handleDownload(req, res, parsedUrl.query.dir || "");
} else if (req.method === "DELETE" && parsedUrl.pathname === "/delete") {
handleDelete(req, res, parsedUrl.query.dir || "");
} else if (req.method === "GET" && parsedUrl.pathname === "/list") {
handleList(req, res, parsedUrl.query.dir || "");
} else {
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("Not Found");
}
});
// 基本认证验证
function authenticate(req) {
const authHeader = req.headers["authorization"];
if (!authHeader) return false;
const [scheme, credentials] = authHeader.split(" ");
if (scheme !== "Basic") return false;
const [username, password] = Buffer.from(credentials, "base64")
.toString()
.split(":");
return (
username === VALID_CREDENTIALS.username &&
password === VALID_CREDENTIALS.password
);
}
// 安全处理文件名
function sanitizeFilename(originalName) {
// 移除路径部分,只保留文件名
const base = path.basename(originalName);
// 替换非法字符(Windows文件系统非法字符)
return base.replace(/[\\/:*?"<>|]/g, "_");
}
// 安全路径解析(防止目录遍历攻击)
function resolveSafePath(...pathSegments) {
const targetPath = path.resolve(UPLOAD_DIR, ...pathSegments);
const relativePath = path.relative(UPLOAD_DIR, targetPath);
// 检查路径是否试图访问UPLOAD_DIR之外
if (relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
throw new Error("Invalid path");
}
return targetPath;
}
// 文件上传处理
function handleUpload(req, res, dirParam) {
const contentType = req.headers["content-type"];
if (!contentType || !contentType.includes("multipart/form-data")) {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Invalid Content-Type. Expected multipart/form-data");
}
const boundaryMatch = contentType.match(/boundary=(.+)$/);
if (!boundaryMatch) {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Missing boundary in Content-Type");
}
const boundary = boundaryMatch[1];
let body = [];
req.on("data", (chunk) => body.push(chunk));
req.on("end", () => {
try {
const buffer = Buffer.concat(body);
const parts = parseMultipart(buffer, boundary);
if (!parts.file || !parts.filename) {
console.log("Parsed parts:", Object.keys(parts)); // 调试信息
throw new Error("No valid file uploaded");
}
// 安全处理文件名
const safeFilename = sanitizeFilename(parts.filename);
// 验证文件名
if (!safeFilename || safeFilename === "." || safeFilename === "..") {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Invalid filename");
}
// 解析并验证目标路径
const targetDir = resolveSafePath(dirParam);
const filePath = resolveSafePath(dirParam, safeFilename);
// 确保目标目录存在
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
fs.writeFile(filePath, parts.file, (err) => {
if (err) {
console.error("File write error:", err);
res.writeHead(500, { "Content-Type": "text/plain" });
return res.end("Internal Server Error");
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(
JSON.stringify({
success: true,
filename: safeFilename,
directory: dirParam,
message: "File uploaded successfully",
})
);
});
} catch (err) {
console.error("Upload error:", err);
res.writeHead(400, { "Content-Type": "text/plain" });
res.end(err.message);
}
});
}
// 解析multipart数据 - 改进版本
function parseMultipart(buffer, boundary) {
const result = {};
const boundaryBuffer = Buffer.from(`--${boundary}`);
const parts = [];
let start = 0;
let end = buffer.indexOf(boundaryBuffer, start);
while (end !== -1) {
if (start !== 0) {
// 跳过第一个边界前的内容
parts.push(buffer.slice(start, end));
}
start = end + boundaryBuffer.length;
end = buffer.indexOf(boundaryBuffer, start);
}
for (const part of parts) {
if (part.length === 0) continue;
// 查找头部结束位置
const headerEndIndex = part.indexOf("\r\n\r\n");
if (headerEndIndex === -1) continue;
const headers = part.slice(0, headerEndIndex).toString();
const content = part.slice(headerEndIndex + 4);
// 移除结尾的 \r\n
const actualContent = content.slice(0, content.length - 2);
const nameMatch = headers.match(/name="([^"]+)"/);
const filenameMatch = headers.match(/filename="([^"]+)"/);
if (nameMatch) {
const name = nameMatch[1];
if (filenameMatch && filenameMatch[1]) {
result.filename = filenameMatch[1];
result.file = actualContent;
console.log(
`Found file: ${result.filename}, size: ${actualContent.length} bytes`
); // 调试信息
} else {
result[name] = actualContent.toString();
}
}
}
return result;
}
// 文件下载处理
function handleDownload(req, res, dirParam) {
try {
const parsedUrl = url.parse(req.url, true);
const filename = parsedUrl.query.filename;
if (!filename) {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Missing filename parameter");
}
// 安全处理文件名
const safeFilename = sanitizeFilename(filename);
// 验证文件名
if (!safeFilename || safeFilename === "." || safeFilename === "..") {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Invalid filename");
}
// 解析并验证文件路径
const filePath = resolveSafePath(dirParam, safeFilename);
// 检查文件是否存在
if (!fs.existsSync(filePath)) {
res.writeHead(404, { "Content-Type": "text/plain" });
return res.end("File not found");
}
const stat = fs.statSync(filePath);
// 设置下载文件名
const encodedFilename = encodeURIComponent(safeFilename);
res.writeHead(200, {
"Content-Type": "application/octet-stream",
"Content-Length": stat.size,
"Content-Disposition": `attachment; filename="${encodedFilename}"; filename*=UTF-8''${encodedFilename}`,
});
fs.createReadStream(filePath).pipe(res);
} catch (err) {
console.error("Download error:", err);
res.writeHead(400, { "Content-Type": "text/plain" });
res.end(err.message);
}
}
function handleDelete(req, res, dirParam) {
try {
const parsedUrl = url.parse(req.url, true);
const filename = parsedUrl.query.filename;
if (!filename) {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Missing filename parameter");
}
// 安全处理文件名
const safeFilename = sanitizeFilename(filename);
// 验证文件名
if (!safeFilename || safeFilename === "." || safeFilename === "..") {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Invalid filename");
}
// 解析并验证文件路径
const filePath = resolveSafePath(dirParam, safeFilename);
// 检查文件是否存在
if (!fs.existsSync(filePath)) {
res.writeHead(404, { "Content-Type": "text/plain" });
return res.end("File not found");
}
// 检查是否为文件(非目录)
const stat = fs.statSync(filePath);
if (!stat.isFile()) {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Target is not a file");
}
// 删除文件
fs.unlink(filePath, (err) => {
if (err) {
console.error("File delete error:", err);
res.writeHead(500, { "Content-Type": "text/plain" });
return res.end("Internal Server Error");
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(
JSON.stringify({
success: true,
filename: safeFilename,
directory: dirParam,
message: "File deleted successfully",
})
);
});
} catch (err) {
console.error("Delete error:", err);
res.writeHead(400, { "Content-Type": "text/plain" });
res.end(err.message);
}
}
// 目录列表处理
function handleList(req, res, dirParam) {
try {
// 解析并验证目录路径
const targetDir = resolveSafePath(dirParam);
// 检查目录是否存在
if (!fs.existsSync(targetDir)) {
res.writeHead(404, { "Content-Type": "text/plain" });
return res.end("Directory not found");
}
// 检查是否为目录
const stat = fs.statSync(targetDir);
if (!stat.isDirectory()) {
res.writeHead(400, { "Content-Type": "text/plain" });
return res.end("Target is not a directory");
}
// 读取目录内容
fs.readdir(targetDir, { withFileTypes: true }, (err, entries) => {
if (err) {
console.error("Directory read error:", err);
res.writeHead(500, { "Content-Type": "text/plain" });
return res.end("Internal Server Error");
}
const fileList = entries.map((entry) => {
const stat = fs.statSync(path.join(targetDir, entry.name));
return {
name: entry.name,
type: entry.isDirectory() ? "directory" : "file",
size: entry.isFile() ? stat.size : null,
modifiedTime: stat.mtime.toISOString(),
createdTime: stat.birthtime.toISOString(),
};
});
// 按类型和名称排序(目录在前,然后按名称排序)
fileList.sort((a, b) => {
if (a.type !== b.type) {
return a.type === "directory" ? -1 : 1;
}
return a.name.localeCompare(b.name);
});
res.writeHead(200, { "Content-Type": "application/json" });
res.end(
JSON.stringify({
success: true,
directory: dirParam,
files: fileList,
totalCount: fileList.length,
})
);
});
} catch (err) {
console.error("List error:", err);
res.writeHead(400, { "Content-Type": "text/plain" });
res.end(err.message);
}
}
// 启动服务器
server.listen(PORT, () => {
console.log(`Secure File Server running at http://localhost:${PORT}`);
console.log(`Username: ${VALID_CREDENTIALS.username}`);
console.log("Password: [HIDDEN FOR SECURITY]");
});
================================================
FILE: main.js
================================================
const {
app,
BrowserWindow,
WebContentsView,
Menu,
ipcMain,
dialog,
powerSaveBlocker,
nativeTheme,
protocol,
screen,
} = require("electron");
const path = require("path");
const isDev = require("electron-is-dev");
const Store = require("electron-store");
const log = require("electron-log/main");
const os = require("os");
const store = new Store();
const fs = require("fs");
const configDir = app.getPath("userData");
const dirPath = path.join(configDir, "uploads");
const packageJson = require("./package.json");
let mainWin;
let readerWindow;
let readerWindowList = [];
let dictWindow;
let transWindow;
let linkWindow;
let mainView;
//multi tab
// let mainViewList = []
let chatWindow;
let dbConnection = {};
let syncUtilCache = {};
let pickerUtilCache = {};
let downloadRequest = null;
const singleInstance = app.requestSingleInstanceLock();
var filePath = null;
if (process.platform != "darwin" && process.argv.length >= 2) {
filePath = process.argv[1];
}
log.transports.file.fileName = "debug.log";
log.transports.file.maxSize = 1024 * 1024; // 1MB
log.initialize();
store.set("appVersion", packageJson.version);
store.set("appPlatform", os.platform() + " " + os.release());
const mainWinDisplayScale = store.get("mainWinDisplayScale") || 1;
let options = {
width: parseInt(store.get("mainWinWidth") || 1050) / mainWinDisplayScale,
height: parseInt(store.get("mainWinHeight") || 660) / mainWinDisplayScale,
x: parseInt(store.get("mainWinX")),
y: parseInt(store.get("mainWinY")),
backgroundColor: "#fff",
minWidth: 400,
minHeight: 300,
webPreferences: {
webSecurity: false,
nodeIntegration: true,
contextIsolation: false,
nativeWindowOpen: true,
nodeIntegrationInSubFrames: false,
allowRunningInsecureContent: false,
enableRemoteModule: true,
sandbox: false,
},
};
const Database = require("better-sqlite3");
if (os.platform() === "linux") {
options = Object.assign({}, options, {
icon: path.join(__dirname, "./build/assets/icon.png"),
});
}
// Single Instance Lock
if (!singleInstance) {
app.quit();
} else {
app.on("second-instance", (event, argv, workingDir) => {
if (mainWin) {
if (!mainWin.isVisible()) mainWin.show();
mainWin.focus();
}
});
}
if (filePath && fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
// Make sure the directory exists
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
fs.writeFileSync(
path.join(dirPath, "log.json"),
JSON.stringify({ filePath }),
"utf-8"
);
}
const getDBConnection = (dbName, storagePath, sqlStatement) => {
if (!dbConnection[dbName]) {
if (!fs.existsSync(path.join(storagePath, "config"))) {
fs.mkdirSync(path.join(storagePath, "config"), { recursive: true });
}
dbConnection[dbName] = new Database(
path.join(storagePath, "config", `${dbName}.db`),
{}
);
dbConnection[dbName].pragma("journal_mode = WAL");
dbConnection[dbName].exec(sqlStatement["createTableStatement"][dbName]);
}
return dbConnection[dbName];
};
const getSyncUtil = async (config, isUseCache = true) => {
if (!isUseCache || !syncUtilCache[config.service]) {
const { SyncUtil } = await import("./src/assets/lib/kookit-extra.min.mjs");
syncUtilCache[config.service] = new SyncUtil(config.service, config);
}
return syncUtilCache[config.service];
};
const removeSyncUtil = (config) => {
delete syncUtilCache[config.service];
};
const getPickerUtil = async (config, isUseCache = true) => {
if (!isUseCache || !pickerUtilCache[config.service]) {
const { SyncUtil } = await import("./src/assets/lib/kookit-extra.min.mjs");
pickerUtilCache[config.service] = new SyncUtil(config.service, config);
}
return pickerUtilCache[config.service];
};
const removePickerUtil = (config) => {
if (pickerUtilCache[config.service]) {
pickerUtilCache[config.service] = null;
}
};
// Simple encryption function
const encrypt = (text, key) => {
let result = "";
for (let i = 0; i < text.length; i++) {
const charCode = text.charCodeAt(i) ^ key.charCodeAt(i % key.length);
result += String.fromCharCode(charCode);
}
return Buffer.from(result).toString("base64");
};
// Simple decryption function
const decrypt = (encryptedText, key) => {
const buff = Buffer.from(encryptedText, "base64").toString();
let result = "";
for (let i = 0; i < buff.length; i++) {
const charCode = buff.charCodeAt(i) ^ key.charCodeAt(i % key.length);
result += String.fromCharCode(charCode);
}
return result;
};
// Helper to check if two rectangles intersect (for partial visibility)
const rectanglesIntersect = (rect1, rect2) => {
return !(
rect1.x + rect1.width <= rect2.x ||
rect1.y + rect1.height <= rect2.y ||
rect1.x >= rect2.x + rect2.width ||
rect1.y >= rect2.y + rect2.height
);
};
// Check if the window is at least partially visible on any display
const isWindowPartiallyVisible = (bounds) => {
const displays = screen.getAllDisplays();
for (const display of displays) {
if (rectanglesIntersect(bounds, display.workArea)) {
return true;
}
}
return false;
};
const createMainWin = () => {
const isMainWindVisible = isWindowPartiallyVisible({
width: parseInt(store.get("mainWinWidth") || 1050) / mainWinDisplayScale,
height: parseInt(store.get("mainWinHeight") || 660) / mainWinDisplayScale,
x: parseInt(store.get("mainWinX")),
y: parseInt(store.get("mainWinY")),
});
if (!isMainWindVisible) {
delete options.x;
delete options.y;
}
mainWin = new BrowserWindow(options);
if (store.get("isAlwaysOnTop") === "yes") {
mainWin.setAlwaysOnTop(true);
}
if (store.get("isAutoMaximizeWin") === "yes") {
mainWin.maximize();
}
if (!isDev) {
Menu.setApplicationMenu(null);
}
const urlLocation = isDev
? "http://localhost:3000"
: `file://${path.join(__dirname, "./build/index.html")}`;
mainWin.loadURL(urlLocation);
mainWin.on("close", () => {
if (mainWin && !mainWin.isDestroyed()) {
let bounds = mainWin.getBounds();
const currentDisplay = screen.getDisplayMatching(bounds);
const primaryDisplay = screen.getPrimaryDisplay();
if (bounds.width > 0 && bounds.height > 0) {
store.set({
mainWinWidth: bounds.width,
mainWinHeight: bounds.height,
mainWinX: mainWin.isMaximized() ? 0 : bounds.x,
mainWinY: mainWin.isMaximized() ? 0 : bounds.y,
mainWinDisplayScale:
currentDisplay.scaleFactor / primaryDisplay.scaleFactor,
});
}
}
mainWin = null;
});
mainWin.on("resize", () => {
if (mainView) {
if (!mainWin) return;
let { width, height } = mainWin.getContentBounds();
mainView.setBounds({ x: 0, y: 0, width: width, height: height });
}
});
mainWin.on("maximize", () => {
if (mainView) {
let { width, height } = mainWin.getContentBounds();
mainView.setBounds({ x: 0, y: 0, width: width, height: height });
}
});
mainWin.on("unmaximize", () => {
if (mainView) {
let { width, height } = mainWin.getContentBounds();
mainView.setBounds({ x: 0, y: 0, width: width, height: height });
}
});
mainWin.webContents.on(
"console-message",
(event, level, message, line, sourceId) => {
console.log(`[Renderer Console] Message: ${message}`);
}
);
//cancel-download-app
ipcMain.handle("cancel-download-app", (event, arg) => {
// Implement cancellation logic here
// Note: In this example, we are not keeping a reference to the request,
// so we cannot actually abort it. This is a placeholder for demonstration.
if (downloadRequest) {
downloadRequest.abort();
downloadRequest = null;
}
event.returnValue = "cancelled";
});
ipcMain.handle("update-win-app", (event, config) => {
let fileName = `koodo-reader-installer.exe`;
let supportedArchs = ["x64", "ia32", "arm64"];
//get system arch
let arch = os.arch();
if (!supportedArchs.includes(arch)) {
return;
}
let url = `https://dl.koodoreader.com/v${config.version}/Koodo-Reader-${config.version}-${arch}.exe`;
const https = require("https");
const { spawn } = require("child_process");
const file = fs.createWriteStream(path.join(app.getPath("temp"), fileName));
downloadRequest = https.get(url, (res) => {
const totalSize = parseInt(res.headers["content-length"], 10);
let downloadedSize = 0;
res.on("data", (chunk) => {
downloadedSize += chunk.length;
const progress = ((downloadedSize / totalSize) * 100).toFixed(2);
const downloadedMB = (downloadedSize / 1024 / 1024).toFixed(2);
const totalMB = (totalSize / 1024 / 1024).toFixed(2);
mainWin.webContents.send("download-app-progress", {
progress,
downloadedMB,
totalMB,
});
});
res.pipe(file);
file.on("finish", () => {
console.log("\n下载完成!");
file.close();
let updateExePath = path.join(app.getPath("temp"), fileName);
if (!fs.existsSync(updateExePath)) {
console.error("更新包不存在:", updateExePath);
return;
}
// 验证文件可执行性
try {
fs.accessSync(updateExePath, fs.constants.X_OK);
console.info("更新包可执行性验证通过");
} catch (err) {
console.error("更新包不可执行:", err.message);
return;
}
try {
// 使用 spawn 执行非静默安装
const child = spawn(updateExePath, [], {
stdio: ["ignore", "pipe", "pipe"], // 捕获 stdout 和 stderr 以便调试
detached: true, // 独立进程
shell: true, // 确保 UAC 提示
windowsHide: false, // 确保窗口可见
});
setTimeout(() => {
app.quit();
}, 1000);
child.unref();
} catch (err) {
console.error(`spawn 执行异常: ${err.message}`);
}
});
});
});
ipcMain.handle("open-book", (event, config) => {
let { url, isMergeWord, isAutoFullscreen, isAutoMaximize, isPreventSleep } =
config;
options.webPreferences.nodeIntegrationInSubFrames = true;
if (isMergeWord) {
delete options.backgroundColor;
}
store.set({
url,
isMergeWord: isMergeWord || "no",
isAutoFullscreen: isAutoFullscreen || "no",
isAutoMaximize: isAutoMaximize || "no",
isPreventSleep: isPreventSleep || "no",
});
let id;
if (isPreventSleep === "yes") {
id = powerSaveBlocker.start("prevent-display-sleep");
console.log(powerSaveBlocker.isStarted(id));
}
if (readerWindow) {
readerWindowList.push(readerWindow);
}
if (isAutoFullscreen === "yes" || isAutoMaximize === "yes") {
readerWindow = new BrowserWindow(options);
readerWindow.loadURL(url);
if (isAutoFullscreen === "yes") {
readerWindow.setFullScreen(true);
} else if (isAutoMaximize === "yes") {
readerWindow.maximize();
}
} else {
const scaleRatio = store.get("windowDisplayScale") || 1;
const isWindowVisible = isWindowPartiallyVisible({
x: parseInt(store.get("windowX")),
y: parseInt(store.get("windowY")),
width: parseInt(store.get("windowWidth") || 1050) / scaleRatio,
height: parseInt(store.get("windowHeight") || 660) / scaleRatio,
});
readerWindow = new BrowserWindow({
...options,
width: parseInt(store.get("windowWidth") || 1050) / scaleRatio,
height: parseInt(store.get("windowHeight") || 660) / scaleRatio,
x: isWindowVisible ? parseInt(store.get("windowX")) : undefined,
y: isWindowVisible ? parseInt(store.get("windowY")) : undefined,
frame: isMergeWord === "yes" ? false : true,
hasShadow: isMergeWord === "yes" ? false : true,
transparent: isMergeWord === "yes" ? true : false,
});
readerWindow.loadURL(url);
// readerWindow.webContents.openDevTools();
}
if (store.get("isAlwaysOnTop") === "yes") {
readerWindow.setAlwaysOnTop(true);
}
readerWindow.on("close", (event) => {
if (readerWindow && !readerWindow.isDestroyed()) {
let bounds = readerWindow.getBounds();
const currentDisplay = screen.getDisplayMatching(bounds);
const primaryDisplay = screen.getPrimaryDisplay();
if (bounds.width > 0 && bounds.height > 0) {
store.set({
windowWidth: bounds.width,
windowHeight: bounds.height,
windowX:
readerWindow.isMaximized() &&
currentDisplay.id === primaryDisplay.id
? 0
: bounds.x,
windowY:
readerWindow.isMaximized() &&
currentDisplay.id === primaryDisplay.id
? 0
: bounds.y < 0
? 0
: bounds.y,
windowDisplayScale:
currentDisplay.scaleFactor / primaryDisplay.scaleFactor,
});
}
}
if (isPreventSleep && !readerWindow.isDestroyed()) {
id && powerSaveBlocker.stop(id);
}
if (mainWin && !mainWin.isDestroyed()) {
mainWin.webContents.send("reading-finished", {});
}
});
event.returnValue = "success";
});
ipcMain.handle("generate-tts", async (event, voiceConfig) => {
let { text, speed, plugin, config } = voiceConfig;
let voiceFunc = plugin.script;
// eslint-disable-next-line no-eval
eval(voiceFunc);
return global.getAudioPath(text, speed, dirPath, config);
});
ipcMain.handle("cloud-upload", async (event, config) => {
let syncUtil = await getSyncUtil(config, config.isUseCache);
let result = await syncUtil.uploadFile(
config.fileName,
config.fileName,
config.type
);
return result;
});
ipcMain.handle("cloud-download", async (event, config) => {
let syncUtil = await getSyncUtil(config);
let result = await syncUtil.downloadFile(
config.fileName,
(config.isTemp ? "temp-" : "") + config.fileName,
config.type
);
return result;
});
ipcMain.handle("cloud-progress", async (event, config) => {
let syncUtil = await getSyncUtil(config);
let result = syncUtil.getDownloadedSize();
return result;
});
ipcMain.handle("picker-download", async (event, config) => {
let pickerUtil = await getPickerUtil(config);
let result = await pickerUtil.remote.downloadFile(
config.sourcePath,
config.destPath
);
return result;
});
ipcMain.handle("picker-progress", async (event, config) => {
let pickerUtil = await getPickerUtil(config);
let result = await pickerUtil.getDownloadedSize();
return result;
});
ipcMain.handle("cloud-reset", async (event, config) => {
let syncUtil = await getSyncUtil(config);
let result = syncUtil.resetCounters();
return result;
});
ipcMain.handle("cloud-stats", async (event, config) => {
let syncUtil = await getSyncUtil(config);
let result = syncUtil.getStats();
return result;
});
ipcMain.handle("cloud-delete", async (event, config) => {
try {
let syncUtil = await getSyncUtil(config, config.isUseCache);
let result = await syncUtil.deleteFile(config.fileName, config.type);
return result;
} catch (error) {
console.error("Error deleting file:", error);
}
return false;
});
ipcMain.handle("cloud-list", async (event, config) => {
let syncUtil = await getSyncUtil(config);
let result = await syncUtil.listFiles(config.type);
return result;
});
ipcMain.handle("picker-list", async (event, config) => {
let pickerUtil = await getPickerUtil(config);
let result = await pickerUtil.listFileInfos(config.currentPath);
return result;
});
ipcMain.handle("cloud-exist", async (event, config) => {
let syncUtil = await getSyncUtil(config);
let result = await syncUtil.isExist(config.fileName, config.type);
return result;
});
ipcMain.handle("cloud-close", async (event, config) => {
removeSyncUtil(config);
return "pong";
});
ipcMain.handle("clear-tts", async (event, config) => {
if (!fs.existsSync(path.join(dirPath, "tts"))) {
return "pong";
} else {
const fsExtra = require("fs-extra");
try {
await fsExtra.remove(path.join(dirPath, "tts"));
await fsExtra.mkdir(path.join(dirPath, "tts"));
return "pong";
} catch (err) {
console.error(err);
return "pong";
}
}
});
ipcMain.handle("select-path", async (event) => {
var path = await dialog.showOpenDialog({
properties: ["openDirectory"],
});
return path.filePaths[0];
});
ipcMain.handle("encrypt-data", async (event, config) => {
const { TokenService } =
await import("./src/assets/lib/kookit-extra.min.mjs");
let fingerprint = await TokenService.getFingerprint();
let encrypted = encrypt(config.token, fingerprint);
store.set("encryptedToken", encrypted);
return "pong";
});
ipcMain.handle("decrypt-data", async (event) => {
let encrypted = store.get("encryptedToken");
if (!encrypted) return "";
const { TokenService } =
await import("./src/assets/lib/kookit-extra.min.mjs");
let fingerprint = await TokenService.getFingerprint();
let decrypted = decrypt(encrypted, fingerprint);
if (decrypted.startsWith("{") && decrypted.endsWith("}")) {
return decrypted;
} else {
try {
const { safeStorage } = require("electron");
decrypted = safeStorage.decryptString(Buffer.from(encrypted, "base64"));
let newEncrypted = encrypt(decrypted, fingerprint);
store.set("encryptedToken", newEncrypted);
return decrypted;
} catch (error) {
console.error("Decryption failed:", error);
return "{}";
}
}
});
ipcMain.handle("get-mac", async (event, config) => {
const { machineIdSync } = require("node-machine-id");
return machineIdSync();
});
ipcMain.handle("get-store-value", async (event, config) => {
return store.get(config.key);
});
ipcMain.handle("reset-reader-position", async (event) => {
store.delete("windowX");
store.delete("windowY");
return "success";
});
ipcMain.handle("reset-main-position", async (event) => {
store.delete("mainWinX");
store.delete("mainWinY");
app.relaunch();
app.exit();
return "success";
});
ipcMain.handle("select-file", async (event, config) => {
const result = await dialog.showOpenDialog({
properties: ["openFile"],
filters: [{ name: "Zip Files", extensions: ["zip"] }],
});
if (result.canceled) {
return "";
} else {
const filePath = result.filePaths[0];
return filePath;
}
});
ipcMain.handle("select-book", async (event, config) => {
const result = await dialog.showOpenDialog({
properties: ["openFile", "multiSelections"],
filters: [
{
name: "Books",
extensions: [
"epub",
"pdf",
"txt",
"mobi",
"azw3",
"azw",
"htm",
"html",
"xml",
"xhtml",
"mhtml",
"docx",
"md",
"fb2",
"cbz",
"cbt",
"cbr",
"cb7",
],
},
],
});
if (result.canceled) {
console.log("User canceled the file selection");
return [];
} else {
const filePaths = result.filePaths;
console.log("Selected file path:", filePaths);
return filePaths;
}
});
ipcMain.handle("custom-database-command", async (event, config) => {
const { SqlStatement } =
await import("./src/assets/lib/kookit-extra.min.mjs");
let { query, storagePath, data, dbName, executeType } = config;
let db = getDBConnection(dbName, storagePath, SqlStatement.sqlStatement);
const row = db.prepare(query);
let result;
if (data && data.length > 0) {
result = row[executeType](...data);
} else {
result = row[executeType]();
}
return result;
});
ipcMain.handle("database-command", async (event, config) => {
const { SqlStatement } =
await import("./src/assets/lib/kookit-extra.min.mjs");
let { statement, statementType, executeType, dbName, data, storagePath } =
config;
let db = getDBConnection(dbName, storagePath, SqlStatement.sqlStatement);
let sql = "";
if (statementType === "string") {
sql = SqlStatement.sqlStatement[statement][dbName];
} else if (statementType === "function") {
sql = SqlStatement.sqlStatement[statement][dbName](data);
}
const row = db.prepare(sql);
let result;
if (data) {
if (statement.startsWith("save") || statement.startsWith("update")) {
data = SqlStatement.jsonToSqlite[dbName](data);
}
result = row[executeType](data);
} else {
result = row[executeType]();
}
if (executeType === "all") {
return result.map((item) => SqlStatement.sqliteToJson[dbName](item));
} else if (executeType === "get") {
return SqlStatement.sqliteToJson[dbName](result);
} else {
return result;
}
});
ipcMain.handle("close-database", async (event, config) => {
const { SqlStatement } =
await import("./src/assets/lib/kookit-extra.min.mjs");
let { dbName, storagePath } = config;
let db = getDBConnection(dbName, storagePath, SqlStatement.sqlStatement);
delete dbConnection[dbName];
db.close();
});
ipcMain.handle("set-always-on-top", async (event, config) => {
store.set("isAlwaysOnTop", config.isAlwaysOnTop);
if (mainWin && !mainWin.isDestroyed()) {
if (config.isAlwaysOnTop === "yes") {
mainWin.setAlwaysOnTop(true);
} else {
mainWin.setAlwaysOnTop(false);
}
}
if (readerWindow && !readerWindow.isDestroyed()) {
if (config.isAlwaysOnTop === "yes") {
readerWindow.setAlwaysOnTop(true);
} else {
readerWindow.setAlwaysOnTop(false);
}
}
return "pong";
});
ipcMain.handle("set-auto-maximize", async (event, config) => {
store.set("isAutoMaximizeWin", config.isAutoMaximizeWin);
if (mainWin && !mainWin.isDestroyed()) {
if (config.isAutoMaximizeWin === "yes") {
mainWin.maximize();
} else {
mainWin.unmaximize();
}
}
if (readerWindow && !readerWindow.isDestroyed()) {
if (config.isAlwaysOnTop === "yes") {
readerWindow.setAlwaysOnTop(true);
} else {
readerWindow.setAlwaysOnTop(false);
}
}
return "pong";
});
ipcMain.handle("toggle-auto-launch", async (event, config) => {
app.setLoginItemSettings({
openAtLogin: config.isAutoLaunch === "yes",
});
return "pong";
});
ipcMain.handle("open-explorer-folder", async (event, config) => {
const { shell } = require("electron");
if (config.isFolder) {
shell.openPath(config.path);
} else {
shell.showItemInFolder(config.path);
}
return "pong";
});
ipcMain.handle("get-debug-logs", async (event, config) => {
const { shell } = require("electron");
const file = log.transports.file.getFile();
shell.showItemInFolder(file.path);
return "pong";
});
ipcMain.on("user-data", (event, arg) => {
event.returnValue = dirPath;
});
ipcMain.handle("hide-reader", (event, arg) => {
if (
readerWindow &&
!readerWindow.isDestroyed() &&
readerWindow.isFocused()
) {
readerWindow.minimize();
event.returnvalue = true;
} else if (mainWin && mainWin.isFocused()) {
mainWin.minimize();
event.returnvalue = true;
} else {
event.returnvalue = false;
}
});
ipcMain.handle("open-console", (event, arg) => {
mainWin.webContents.openDevTools();
event.returnvalue = true;
});
ipcMain.handle("reload-reader", (event, arg) => {
if (readerWindowList.length > 0) {
readerWindowList.forEach((win) => {
if (
win &&
!win.isDestroyed() &&
win.webContents.getURL().indexOf(arg.bookKey) > -1
) {
win.reload();
}
});
}
if (
readerWindow &&
!readerWindow.isDestroyed() &&
readerWindow.webContents.getURL().indexOf(arg.bookKey) > -1
) {
readerWindow.reload();
}
});
ipcMain.handle("reload-main", (event, arg) => {
if (mainWin) {
mainWin.reload();
}
});
ipcMain.handle("new-chat", (event, config) => {
if (!chatWindow && mainWin) {
let bounds = mainWin.getBounds();
chatWindow = new BrowserWindow({
...options,
width: 450,
height: bounds.height,
x: bounds.x + (bounds.width - 450),
y: bounds.y,
frame: true,
hasShadow: true,
transparent: false,
});
chatWindow.loadURL(config.url);
chatWindow.on("close", (event) => {
chatWindow && chatWindow.destroy();
chatWindow = null;
});
} else if (chatWindow && !chatWindow.isDestroyed()) {
chatWindow.show();
chatWindow.focus();
}
});
ipcMain.handle("clear-all-data", (event, config) => {
store.clear();
});
ipcMain.handle("new-tab", (event, config) => {
if (mainWin) {
mainView = new WebContentsView(options);
mainWin.contentView.addChildView(mainView);
let { width, height } = mainWin.getContentBounds();
mainView.setBounds({ x: 0, y: 0, width: width, height: height });
mainView.webContents.loadURL(config.url);
}
});
ipcMain.handle("reload-tab", (event, config) => {
if (mainWin && mainView) {
mainView.webContents.reload();
}
});
ipcMain.handle("adjust-tab-size", (event, config) => {
if (mainWin && mainView) {
let { width, height } = mainWin.getContentBounds();
mainView.setBounds({ x: 0, y: 0, width: width, height: height });
}
});
ipcMain.handle("exit-tab", (event, message) => {
if (mainWin && mainView) {
mainWin.contentView.removeChildView(mainView);
}
});
ipcMain.handle("enter-tab-fullscreen", () => {
if (mainWin && mainView) {
mainWin.setFullScreen(true);
console.log("enter full");
}
});
ipcMain.handle("exit-tab-fullscreen", () => {
if (mainWin && mainView) {
mainWin.setFullScreen(false);
console.log("exit full");
}
});
ipcMain.handle("enter-fullscreen", () => {
if (readerWindow) {
readerWindow.setFullScreen(true);
console.log("enter full");
}
});
ipcMain.handle("exit-fullscreen", () => {
if (readerWindow) {
readerWindow.setFullScreen(false);
console.log("exit full");
}
});
ipcMain.handle("open-url", (event, config) => {
if (config.type === "dict") {
if (!dictWindow || dictWindow.isDestroyed()) {
dictWindow = new BrowserWindow();
}
dictWindow.loadURL(config.url);
dictWindow.focus();
} else if (config.type === "trans") {
if (!transWindow || transWindow.isDestroyed()) {
transWindow = new BrowserWindow();
}
transWindow.loadURL(config.url);
transWindow.focus();
} else {
if (!linkWindow || linkWindow.isDestroyed()) {
linkWindow = new BrowserWindow();
}
linkWindow.loadURL(config.url);
linkWindow.focus();
}
event.returnvalue = true;
});
ipcMain.handle("switch-moyu", (event, arg) => {
let id;
if (store.get("isPreventSleep") === "yes") {
id = powerSaveBlocker.start("prevent-display-sleep");
console.log(powerSaveBlocker.isStarted(id));
}
if (readerWindow) {
readerWindow.close();
if (store.get("isMergeWord") === "yes") {
delete options.backgroundColor;
}
const scaleRatio = store.get("windowDisplayScale") || 1;
Object.assign(options, {
width: parseInt(store.get("windowWidth") || 1050) / scaleRatio,
height: parseInt(store.get("windowHeight") || 660) / scaleRatio,
x: parseInt(store.get("windowX")),
y: parseInt(store.get("windowY")),
frame: store.get("isMergeWord") !== "yes" ? false : true,
hasShadow: store.get("isMergeWord") !== "yes" ? false : true,
transparent: store.get("isMergeWord") !== "yes" ? true : false,
});
options.webPreferences.nodeIntegrationInSubFrames = true;
store.set(
"isMergeWord",
store.get("isMergeWord") !== "yes" ? "yes" : "no"
);
if (readerWindow) {
readerWindowList.push(readerWindow);
}
readerWindow = new BrowserWindow(options);
if (store.get("isAlwaysOnTop") === "yes") {
readerWindow.setAlwaysOnTop(true);
}
readerWindow.loadURL(store.get("url"));
readerWindow.on("close", (event) => {
if (!readerWindow.isDestroyed()) {
let bounds = readerWindow.getBounds();
const currentDisplay = screen.getDisplayMatching(bounds);
const primaryDisplay = screen.getPrimaryDisplay();
if (bounds.width > 0 && bounds.height > 0) {
store.set({
windowWidth: bounds.width,
windowHeight: bounds.height,
windowX:
readerWindow.isMaximized() &&
currentDisplay.id === primaryDisplay.id
? 0
: bounds.x,
windowY:
readerWindow.isMaximized() &&
currentDisplay.id === primaryDisplay.id
? 0
: bounds.y < 0
? 0
: bounds.y,
});
}
}
if (store.get("isPreventSleep") && !readerWindow.isDestroyed()) {
id && powerSaveBlocker.stop(id);
}
if (mainWin && !mainWin.isDestroyed()) {
mainWin.webContents.send("reading-finished", {});
}
});
}
event.returnvalue = false;
});
ipcMain.on("storage-location", (event, config) => {
event.returnValue = path.join(dirPath, "data");
});
ipcMain.on("url-window-status", (event, config) => {
if (config.type === "dict") {
event.returnValue =
dictWindow && !dictWindow.isDestroyed() ? true : false;
} else if (config.type === "trans") {
event.returnValue =
transWindow && !transWindow.isDestroyed() ? true : false;
} else {
event.returnValue =
linkWindow && !linkWindow.isDestroyed() ? true : false;
}
});
ipcMain.on("get-dirname", (event, arg) => {
event.returnValue = __dirname;
});
ipcMain.on("system-color", (event, arg) => {
event.returnValue = nativeTheme.shouldUseDarkColors || false;
});
ipcMain.on("check-main-open", (event, arg) => {
event.returnValue = mainWin ? true : false;
});
ipcMain.on("get-file-data", function (event) {
if (fs.existsSync(path.join(dirPath, "log.json"))) {
try {
const _data = JSON.parse(
fs.readFileSync(path.join(dirPath, "log.json"), "utf-8") || "{}"
);
if (_data && _data.filePath) {
filePath = _data.filePath;
setTimeout(() => {
fs.writeFileSync(path.join(dirPath, "log.json"), "{}", "utf-8");
}, 1000);
}
} catch (error) {
console.error("Error reading log.json:", error);
}
}
event.returnValue = filePath;
filePath = null;
});
ipcMain.on("check-file-data", function (event) {
if (fs.existsSync(path.join(dirPath, "log.json"))) {
try {
const _data = JSON.parse(
fs.readFileSync(path.join(dirPath, "log.json"), "utf-8") || "{}"
);
if (_data && _data.filePath) {
filePath = _data.filePath;
}
} catch (error) {
console.error("Error reading log.json:", error);
}
}
event.returnValue = filePath;
filePath = null;
});
};
app.on("ready", () => {
createMainWin();
});
app.on("window-all-closed", () => {
app.quit();
});
app.on("open-file", (e, pathToFile) => {
filePath = pathToFile;
});
// Register protocol handler
app.setAsDefaultProtocolClient("koodo-reader");
// Handle deep linking
app.on("second-instance", (event, commandLine) => {
const url = commandLine.pop();
if (url) {
handleCallback(url);
}
});
const serializeArg = (arg) => {
if (arg === null) return "null";
if (arg === undefined) return "undefined";
if (typeof arg === "object") {
try {
return JSON.stringify(arg);
} catch {
return String(arg);
}
}
return String(arg);
};
const originalConsoleLog = console.log;
console.log = function (...args) {
originalConsoleLog(...args); // 保留原日志
log.info(args.map(serializeArg).join(" ")); // 写入日志文件
};
const originalConsoleError = console.error;
console.error = function (...args) {
originalConsoleError(...args); // 保留原错误日志
log.error(args.map(serializeArg).join(" ")); // 写入错误日志文件
};
const originalConsoleWarn = console.warn;
console.warn = function (...args) {
originalConsoleWarn(...args); // 保留原警告日志
log.warn(args.map(serializeArg).join(" ")); // 写入警告日志文件
};
const originalConsoleInfo = console.info;
console.info = function (...args) {
originalConsoleInfo(...args); // 保留原信息日志
log.info(args.map(serializeArg).join(" ")); // 写入信息日志文件
};
// Handle MacOS deep linking
app.on("open-url", (event, url) => {
event.preventDefault();
handleCallback(url);
});
const handleCallback = (url) => {
try {
// 检查 URL 是否有效
if (!url.startsWith("koodo-reader://")) {
console.error("Invalid URL format:", url);
return;
}
// 解析 URL
const parsedUrl = new URL(url);
const code = parsedUrl.searchParams.get("code");
const state = parsedUrl.searchParams.get("state");
const pickerData = parsedUrl.searchParams.get("pickerData");
if (code && mainWin) {
mainWin.webContents.send("oauth-callback", { code, state });
}
if (pickerData && mainWin) {
let config = JSON.parse(decodeURIComponent(pickerData));
mainWin.webContents.send("picker-finished", config);
}
} catch (error) {
console.error("Error handling callback URL:", error);
console.log("Problematic URL:", url);
}
};
================================================
FILE: package.json
================================================
{
"name": "koodo-reader",
"main": "main.js",
"version": "2.3.0",
"description": "Koodo Reader is a cross-platform ebook reader",
"author": {
"name": "App by Troye",
"email": "feedback@koodoreader.com"
},
"engines": {
"node": ">=20.0.0",
"npm": ">=6.0.0"
},
"repository": "https://github.com/koodo-reader/koodo-reader",
"private": false,
"resolutions": {
"//": "See https://github.com/facebook/create-react-app/issues/11773",
"react-error-overlay": "6.0.9"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.485.0",
"adm-zip": "^0.5.2",
"axios": "^0.19.2",
"basic-ftp": "^5.0.5",
"better-sqlite3": "^11.6.0",
"buffer": "^6.0.3",
"chardet": "^2.0.0",
"copy-text-to-clipboard": "^2.2.0",
"dompurify": "^3.2.4",
"electron-is-dev": "^1.1.0",
"electron-log": "^5.4.3",
"electron-store": "^8.0.1",
"fflate": "^0.8.2",
"file-saver": "^2.0.5",
"form-data": "^4.0.2",
"fs-extra": "^9.1.0",
"hammerjs": "^2.0.8",
"howler": "^2.2.3",
"js-untar": "^2.0.0",
"jszip": "^3.10.1",
"localforage": "^1.10.0",
"mammoth": "^1.8.0",
"marked": "^15.0.11",
"megajs": "^1.3.9",
"mhtml2html": "^3.0.0",
"node-machine-id": "^1.1.12",
"qs": "^6.11.2",
"rangy": "1.3.0",
"react-hot-toast": "^2.1.1",
"react-sortablejs": "^6.1.4",
"react-tooltip": "^5.28.0",
"sortablejs": "^1.15.6",
"sse.js": "^2.6.0",
"ssh2-sftp-client": "^11.0.0",
"underscore": "^1.13.7",
"uuid": "^11.0.5",
"webdav": "^5.7.1"
},
"devDependencies": {
"@types/copy-text-to-clipboard": "^2.0.4",
"@types/file-saver": "^2.0.7",
"@types/hammerjs": "^2.0.46",
"@types/i18next": "^13.0.0",
"@types/node": "^13.13.2",
"@types/react": "17.0.2",
"@types/react-dom": "17.0.2",
"@types/react-i18next": "^8.1.0",
"@types/react-lottie": "^1.2.5",
"@types/react-redux": "^7.1.7",
"@types/react-router-dom": "^5.1.6",
"@types/react-tooltip": "^4.2.4",
"@types/spark-md5": "^3.0.2",
"@types/underscore": "^1.13.0",
"@types/ws": "^8.5.5",
"classnames": "^2.2.6",
"concurrently": "^5.0.1",
"cross-env": "^6.0.3",
"electron": "^34.0.1",
"electron-builder": "^26.0.12",
"electron-rebuild": "^3.2.9",
"hard-source-webpack-plugin": "^0.13.1",
"html-react-parser": "^5.1.10",
"i18next": "^20.2.4",
"nodemon": "^3.1.3",
"rc-color-picker": "^1.2.6",
"react": "^17.0.2",
"react-device-detect": "^1.12.1",
"react-dom": "^17.0.2",
"react-dropzone": "^11.3.0",
"react-hot-loader": "^4.13.1",
"react-i18next": "^11.8.15",
"react-lottie": "^1.2.3",
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"source-map-explorer": "^2.5.2",
"spark-md5": "^3.0.1",
"typescript": "^5.9.3",
"wait-on": "^7.0.1"
},
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"ele": "electron .",
"dev": "concurrently \"cross-env BROWSER=none npm start\" \"wait-on http://127.0.0.1:3000/ && nodemon --watch main.js --exec electron .\"",
"release": "electron-builder",
"prerelease": "react-scripts build",
"postinstall": "sed 's/^#include .nan_scriptorigin\\.h./\\/\\/ #include nan_scriptorigin.h/' ./node_modules/nan/nan.h > ./node_modules/nan/nan.h.new && mv ./node_modules/nan/nan.h.new ./node_modules/nan/nan.h && electron-builder install-app-deps",
"rebuild": "electron-rebuild -f -w better-sqlite3"
},
"homepage": "./",
"build": {
"appId": "xyz.960960.koodo",
"productName": "Koodo Reader",
"copyright": "Copyright (c) 2020-2025 ${author}",
"files": [
"build/**/*",
"node_modules/**/*",
"package.json",
"src/assets/lib/kookit-extra.min.mjs",
"main.js"
],
"protocols": {
"name": "KoodoReader",
"schemes": [
"koodo-reader"
]
},
"directories": {
"buildResources": "assets"
},
"publish": {
"provider": "github",
"repo": "koodo-reader",
"owner": "koodo-reader"
},
"buildDependenciesFromSource": false,
"nodeGypRebuild": false,
"fileAssociations": [
{
"ext": "epub",
"icon": "assets/icons/epub",
"role": "Viewer",
"mimeType": "application/epub+zip"
},
{
"ext": "pdf",
"icon": "assets/icons/pdf",
"role": "Viewer",
"mimeType": "application/pdf"
},
{
"ext": "mobi",
"icon": "assets/icons/mobi",
"role": "Viewer",
"mimeType": "application/x-mobipocket-ebook"
},
{
"ext": "azw3",
"icon": "assets/icons/azw3",
"role": "Viewer",
"mimeType": "application/vnd.amazon.ebook"
},
{
"ext": "azw",
"icon": "assets/icons/azw3",
"role": "Viewer",
"mimeType": "application/vnd.amazon.ebook"
},
{
"ext": "cbz",
"icon": "assets/icons/comic",
"role": "Viewer",
"mimeType": "application/x-cbz"
},
{
"ext": "cbr",
"icon": "assets/icons/comic",
"role": "Viewer",
"mimeType": "application/x-cbr"
},
{
"ext": "cbt",
"icon": "assets/icons/comic",
"role": "Viewer",
"mimeType": "application/x-cbt"
},
{
"ext": "cb7",
"icon": "assets/icons/comic",
"role": "Viewer",
"mimeType": "application/x-cb7"
},
{
"ext": "fb2",
"icon": "assets/icons/fb2",
"role": "Viewer",
"mimeType": "application/x-fictionbook+xml"
}
],
"extends": null,
"dmg": {
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"mac": {
"darkModeSupport": true,
"entitlements": "assets/macos/entitlements.mac.plist",
"entitlementsInherit": "assets/macos/entitlements.mac.plist",
"identity": "Liang Guo",
"gatekeeperAssess": false,
"hardenedRuntime": true,
"notarize": true,
"target": [
{
"target": "dmg",
"arch": [
"x64",
"arm64"
]
}
],
"icon": "assets/icons/icon.icns",
"category": "public.app-category.productivity",
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64",
"ia32",
"arm64"
]
},
{
"target": "zip",
"arch": [
"x64"
]
},
{
"target": "portable",
"arch": [
"x64"
]
}
],
"icon": "assets/icons/icon.ico",
"artifactName": "${productName}-${version}-${arch}-Win.${ext}"
},
"linux": {
"icon": "assets/icons",
"category": "Office",
"target": [
{
"target": "snap",
"arch": [
"x64"
]
},
{
"target": "deb",
"arch": [
"x64"
]
},
{
"target": "rpm",
"arch": [
"x64"
]
},
{
"target": "AppImage",
"arch": [
"x64"
]
}
],
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"portable": {
"artifactName": "${productName}-${version}-${arch}-Portable.${ext}"
},
"appx": {
"applicationId": "com.koodoreader.electron",
"identityName": "AppbyTroye.KoodoReader",
"publisher": "CN=0AEAD7C6-DF4A-4D05-8FA0-D816D7DE37FF",
"publisherDisplayName": "App by Troye",
"artifactName": "${productName}-${version}-${arch}.${ext}",
"displayName": "Koodo Reader",
"backgroundColor": "transparent"
},
"nsis": {
"artifactName": "${productName}-${version}-${arch}.${ext}",
"oneClick": true,
"allowToChangeInstallationDirectory": false,
"buildUniversalInstaller": false,
"include": "assets/windows/installer.nsh"
},
"snap": {
"publish": [
{
"provider": "github"
}
]
}
},
"eslintConfig": {
"extends": "react-app",
"rules": {
"no-unused-vars": 2
}
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"babel": {
"presets": [
"react-app"
],
"plugins": [
[
"react-hot-loader/babel"
]
]
}
}
================================================
FILE: public/LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: public/assets/styles/dark.css
================================================
body {
-webkit-tap-highlight-color: transparent;
background: rgba(47, 52, 55, 1);
color: rgba(235, 235, 235, 1);
}
a {
color: lightskyblue;
text-decoration: none;
}
.booklist-shelf-list,
.lang-setting-dropdown,
.delete-tag-container,
.setting-subtitle,
.more-option-text,
.book-subcontent-name {
color: rgba(235, 235, 235, 1);
}
.add-dialog-shelf-list-box,
.add-dialog-new-shelf-box,
.add-dialog-cancel,
.delete-dialog-cancel,
.edit-dialog-book-name-box,
.edit-dialog-book-author-box,
.edit-dialog-input,
.edit-dialog-textarea,
.edit-dialog-cancel,
.tag-list-item,
.token-dialog-cancel,
.voice-add-cancel,
.lang-setting-dropdown,
.tag-list-item-new,
.input-value,
.import-from-cloud,
.booklist-shelf-list,
.token-dialog-token-box,
.voice-add-content-box,
.token-dialog-username-box,
.feedback-dialog-content-box,
.token-dialog-url-box,
.token-dialog-username-box,
.token-dialog-password-box,
.general-setting-dropdown,
.delete-dialog-uncheck-icon,
.next-chapter,
.progress-slide-circle,
.setting-dialog-location-title,
.delete-dialog-uncheck-icon,
.previous-chapter,
.color-option,
.line-option,
.token-dialog-link-text,
.token-dialog-token-text,
.nav-search-page-item {
border: 1.5px solid rgba(235, 235, 235, 1);
}
.header-search-box,
.header-search-box::placeholder,
.feedback-dialog-content-box::placeholder,
.voice-add-content-box::placeholder,
.token-dialog-username-box::placeholder,
.token-dialog-token-box::placeholder,
.header-search-text {
color: rgba(235, 235, 235, 0.8);
}
.delete-digest-button,
.add-dialog-confirm,
.backup-page-backup-selector,
.delete-dialog-confirm,
.book-item-config,
.book-cover-item-config,
.download-desk-button,
.edit-dialog-confirm,
.change-location-button,
.token-dialog-confirm,
.add-dialog-shelf-list-option,
.voice-add-confirm,
.new-version-open,
.update-dialog-container-button,
.import-from-local,
.side-menu-selector-container,
.previous-chapter-single-container,
.next-chapter-single-container,
.book-bookmark-link,
.message-box-container,
.only-local-icon,
.voice-add-content-box,
.token-dialog-username-box,
.token-dialog-token-box,
.backup-source-dropdown,
.popup-close {
background-color: rgba(71, 76, 80, 1);
color: rgba(235, 235, 235, 1);
}
.header-search-box,
#jumpPage,
#jumpChapter,
#newTag {
background-color: rgba(235, 235, 235, 0.1);
}
.backup-page-close-icon:hover,
.sidebar-list-icon:hover,
.nav-close-icon:hover,
.setting-close-container:hover,
.side-menu-hover-container,
.setting-dialog-location-title,
.note-option:hover,
.digest-option:hover,
.translation-option:hover,
.speaker-option:hover,
.search-book-option:hover,
.dict-option:hover,
.wikipedia-option:hover,
.browser-option:hover,
.header-search-text:hover,
.reader-setting-icon-container:hover,
.setting-icon-container:hover,
.animation-mask,
.animation-mask-local,
.sort-by-category-list:hover,
.more-option-item:hover,
.sort-by-order-list:hover,
.backup-page-backup:hover,
.action-dialog-add:hover,
.action-dialog-delete:hover,
.action-dialog-edit:hover,
.backup-page-next:hover,
.book-manage-title:hover,
.backup-page-list-item:hover,
.restore-file:hover,
.copy-option:hover {
background-color: rgba(235, 235, 235, 0.035);
}
.drag-background {
background: hsla(0, 0%, 100%, 0.2);
}
.action-dialog-container,
.select-more-actions,
.add-dialog-container,
.backup-page-container,
.delete-dialog-container,
.download-desk-container,
.edit-dialog-container,
.loading-dialog,
.setting-dialog-container,
.feedback-dialog-container,
.token-dialog-container,
.new-version,
.sort-dialog-container,
.popup-menu-box,
.popup-box-container,
.loading-page-cover,
.loading-page-cover,
.navigation-panel,
.book-operation-panel,
.progress-panel,
.input-value,
.tag-list-item-new,
.tag-list-item,
.more-options-dropdown,
.setting-panel-parent {
background: rgba(47, 52, 55, 1);
box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.2);
}
.plugin-tab-bar {
background: rgba(47, 52, 55, 1);
}
.plugin-tab-item-active {
background: rgba(255, 255, 255, 0.12);
}
.book-item-image,
.book-item-cover,
.book-cover,
.detail-cover,
.detail-cover-background-container,
.book-cover-item-cover {
background: rgba(235, 235, 235, 0.1);
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.18);
}
.backup-page-backup-selector,
.message-box-container {
box-shadow: 0px 0px 12px rgba(75, 75, 75, 1);
}
.add-bookmark-button,
.exit-reading-button,
.add-bookmark-button,
.enter-fullscreen-button,
.navigation-header {
box-shadow: 0px 0px 5px rgba(30, 30, 30, 1);
}
.background-color-circle,
.background-box1,
.background-box2,
.background-box3 {
box-shadow: 0px 0px 2px rgba(235, 235, 235, 0.18);
}
.book-spine,
.background-box1,
.background-box2,
.background-box3 {
border: 1px solid rgba(191, 191, 191, 0.3);
}
.add-dialog-cancel,
.delete-dialog-cancel,
.edit-dialog-cancel,
.loading-dialog,
.lang-setting-dropdown,
.token-dialog-cancel,
.voice-add-cancel,
.new-version,
.popup-menu-box,
.popup-box-container,
.general-setting-dropdown,
.card-list-item-card,
.import-from-cloud,
.only-local-slider,
.single-control-button,
.add-dialog-shelf-list-box,
.add-dialog-new-shelf-box,
.edit-dialog-book-name-box,
.edit-dialog-book-author-box,
.edit-dialog-input,
.edit-dialog-textarea,
.setting-dialog-pro-button,
.booklist-shelf-list,
.progress-slide-circle {
background: rgba(47, 52, 55, 1);
}
.single-control-switch,
::-webkit-scrollbar-thumb,
::-webkit-scrollbar-thumb:hover,
.active-tag,
.active-page,
.sk-chase-dot:before {
background-color: rgba(235, 235, 235, 0.5);
}
@-moz-document url-prefix() {
.single-control-switch {
border: 1.5px solid rgba(235, 235, 235, 0.3);
background-color: rgba(71, 76, 80, 1);
}
}
.exit-reading-text,
.add-bookmark-text,
.token-dialog-token-text,
.enter-fullscreen-text,
.image-operation,
.add-bookmark-icon,
.exit-reading-icon,
.message-box-icon,
.active-icon,
.active-selector,
.enter-fullscreen-icon,
.icon-popup,
.token-dialog-link-text,
.token-dialog-token-text,
.delete-dialog-uncheck-icon,
.book-bookmark-link,
.general-setting-dropdown,
.trans-lang-selector,
.original-lang-selector,
.editor-box,
#jumpPage,
#jumpChapter,
.add-dialog-shelf-list-box,
.add-dialog-new-shelf-box,
.edit-dialog-book-name-box,
.edit-dialog-book-author-box,
.edit-dialog-input,
.edit-dialog-textarea,
.card-list-item-show-more,
.cover-banner,
.book-more-action,
.reading-progress-icon,
.book-love-icon,
input,
.input-value {
color: rgba(235, 235, 235, 1);
}
.book-content-name,
.book-subcontent-name,
.book-content-header,
.book-bookmark-list,
.nav-search-list-item,
.sort-dialog-seperator {
border-bottom: 1px solid rgba(235, 235, 235, 0.1);
}
.card-list-item-card {
border: 1px solid rgba(235, 235, 235, 0.1);
}
.popup-menu-triangle-up,
.active-tag,
.active-page,
.popup-menu-triangle-down {
color: rgba(47, 52, 55, 1) !important;
}
================================================
FILE: public/assets/styles/default.css
================================================
body {
-webkit-tap-highlight-color: transparent;
background: rgba(255, 255, 255, 1);
color: rgba(75, 75, 75, 1);
}
a {
color: blue;
text-decoration: none;
}
.delete-tag-container,
.setting-subtitle,
.book-more-action,
.reading-progress-icon,
.more-option-text,
.book-subcontent-name {
color: rgba(75, 75, 75, 1);
}
.book-love-icon,
.book-loved-icon,
.zoom-in-icon,
.zoom-out-icon,
.save-icon,
.clockwise-icon,
.counterclockwise-icon {
text-shadow: 0px 0px 5px rgba(75, 75, 75, 0.3);
}
.add-dialog-shelf-list-box,
.add-dialog-shelf-list-option,
.add-dialog-new-shelf-box,
.add-dialog-cancel,
.delete-dialog-cancel,
.edit-dialog-book-name-box,
.edit-dialog-book-author-box,
.edit-dialog-input,
.edit-dialog-textarea,
.edit-dialog-cancel,
.tag-list-item,
.token-dialog-cancel,
.voice-add-cancel,
.lang-setting-dropdown,
.tag-list-item-new,
.input-value,
.import-from-cloud,
.booklist-shelf-list,
.token-dialog-token-box,
.feedback-dialog-content-box,
.voice-add-content-box,
.token-dialog-url-box,
.token-dialog-username-box,
.token-dialog-password-box,
.general-setting-dropdown,
.delete-dialog-uncheck-icon,
.next-chapter,
.progress-slide-circle,
.setting-dialog-location-title,
.delete-dialog-uncheck-icon,
.previous-chapter,
.color-option,
.line-option,
.token-dialog-link-text,
.token-dialog-token-text,
.nav-search-page-item {
border: 2px solid rgba(75, 75, 75, 1);
}
.header-search-box,
.header-search-box::placeholder,
.feedback-dialog-content-box::placeholder,
.header-search-text,
.card-list-item-show-more,
.token-dialog-link-text,
.token-dialog-token-text {
color: rgba(75, 75, 75, 0.8);
}
::-webkit-scrollbar-thumb,
::-webkit-scrollbar-thumb:hover {
background-color: rgba(75, 75, 75, 0.3);
}
.delete-digest-button,
.add-dialog-confirm,
.backup-page-backup-selector,
.delete-dialog-confirm,
.book-item-config,
.book-cover-item-config,
.download-desk-button,
.edit-dialog-confirm,
.change-location-button,
.token-dialog-confirm,
.voice-add-confirm,
.new-version-open,
.update-dialog-container-button,
.import-from-local,
.active-tag,
.single-control-switch,
.side-menu-selector-container,
.previous-chapter-single-container,
.next-chapter-single-container,
.book-bookmark-link,
.message-box-container,
.popup-close,
.only-local-icon,
.popup-close,
.active-page,
.sk-chase-dot:before {
background-color: rgba(75, 75, 75, 1) !important;
color: rgba(255, 255, 255, 1) !important;
}
.header-search-box,
#jumpPage,
#jumpChapter,
#newTag {
background-color: rgba(75, 75, 75, 0.1);
}
.backup-page-close-icon:hover,
.sidebar-list-icon:hover,
.nav-close-icon:hover,
.setting-close-container:hover,
.side-menu-hover-container,
.setting-dialog-location-title,
.note-option:hover,
.digest-option:hover,
.translation-option:hover,
.speaker-option:hover,
.backup-page-backup:hover,
.search-book-option:hover,
.dict-option:hover,
.wikipedia-option:hover,
.browser-option:hover,
.header-search-text:hover,
.reader-setting-icon-container:hover,
.setting-icon-container:hover,
.animation-mask,
.animation-mask-local,
.sort-by-category-list:hover,
.more-option-item:hover,
.sort-by-order-list:hover,
.action-dialog-add:hover,
.action-dialog-delete:hover,
.action-dialog-edit:hover,
.backup-page-next:hover,
.backup-page-list-item:hover,
.restore-file:hover,
.book-manage-title:hover,
.copy-option:hover {
background-color: rgba(75, 75, 75, 0.035);
}
.drag-background {
background: hsla(0, 0%, 0%, 0.4);
}
.action-dialog-container,
.add-dialog-container,
.select-more-actions,
.backup-page-container,
.delete-dialog-container,
.download-desk-container,
.edit-dialog-container,
.loading-dialog,
.setting-dialog-container,
.feedback-dialog-container,
.token-dialog-container,
.new-version,
.sort-dialog-container,
.popup-menu-box,
.popup-box-container,
.loading-page-cover,
.loading-page-cover,
.navigation-panel,
.book-operation-panel,
.progress-panel,
.setting-panel-parent {
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.2);
}
.plugin-tab-bar {
background: rgba(255, 255, 255, 1);
}
.plugin-tab-item-active {
background: rgba(0, 0, 0, 0.08);
}
.book-item-image,
.book-item-cover,
.book-cover,
.detail-cover,
.more-options-dropdown,
.detail-cover-background-container,
.book-cover-item-cover {
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.18);
}
.book-item-list {
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.18);
}
.backup-page-backup-selector,
.message-box-container {
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.3);
}
.tag-list-item {
background-color: white;
}
.add-bookmark-button,
.exit-reading-button,
.add-bookmark-button,
.enter-fullscreen-button,
.navigation-header,
.book-cover {
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.18);
}
.book-spine,
.background-box1,
.background-box2,
.background-box3 {
border: 1px solid rgba(191, 191, 191, 1);
}
.background-color-circle,
.background-box1,
.background-box2,
.background-box3 {
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.18);
}
.add-dialog-cancel,
.delete-dialog-cancel,
.edit-dialog-cancel,
.loading-dialog,
.lang-setting-dropdown,
.token-dialog-cancel,
.voice-add-cancel,
.new-version,
.popup-menu-box,
.popup-box-container,
.general-setting-dropdown,
.card-list-item-card,
.import-from-cloud,
.only-local-slider,
.single-control-button,
.setting-dialog-pro-button,
.progress-slide-circle {
background: rgba(255, 255, 255, 1);
}
.cover-banner,
.exit-reading-text,
.add-bookmark-text,
.enter-fullscreen-text,
.book-love-icon,
.image-operation,
.popup-menu-triangle-up,
.popup-menu-triangle-down,
.add-bookmark-icon,
.active-page,
.exit-reading-icon,
.message-box-icon,
.active-icon,
.active-selector,
.enter-fullscreen-icon,
.icon-popup,
.delete-dialog-uncheck-icon,
.book-bookmark-link {
color: rgba(255, 255, 255, 1);
}
.book-content-name,
.book-content-header,
.book-subcontent-name,
.book-bookmark-list,
.nav-search-list-item,
.sort-dialog-seperator {
border-bottom: 1px solid rgba(75, 75, 75, 0.1);
}
.card-list-item-card {
border: 2px solid rgba(75, 75, 75, 0.15);
}
================================================
FILE: public/index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.png" />
<link rel="dns-prefetch" href="https://web.koodoreader.com" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
#root {
height: 100%;
width: 100%;
position: fixed;
top: 0px;
left: 0px;
}
</style>
<title>Koodo Reader</title>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/7z-wasm/7zz.umd.js"
></script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/libunrar/rpc.js"
></script>
<script type="module">
import "%PUBLIC_URL%/lib/pdfjs/pdf.mjs";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"%PUBLIC_URL%/lib/pdfjs/pdf.worker.mjs";
</script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/sqljs-wasm/sql-wasm.js"
></script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/tesseractjs/tesseract.min.js"
></script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/onnxruntime-web/ort.min.js"
></script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/esearch-ocr/esearch-ocr.umd.js"
></script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/jspdf/jspdf.umd.min.js"
></script>
<script
type="text/javascript"
src="%PUBLIC_URL%/lib/jspdf/html2canvas.min.js"
></script>
<script src="%PUBLIC_URL%/lib/vex-js/vex.combined.min.js"></script>
<script>
vex.defaultOptions.className = "vex-theme-wireframe";
</script>
<link rel="stylesheet" href="%PUBLIC_URL%/lib/vex-js/vex.min.css" />
<link
rel="stylesheet"
href="%PUBLIC_URL%/lib/vex-js/vex-theme-wireframe.min.css"
/>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<canvas id="the-canvas"></canvas>
</body>
</html>
================================================
FILE: public/lib/7z-wasm/7zz.umd.js
================================================
var SevenZip = (function() {
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
return (
function(SevenZip) {
SevenZip = SevenZip || {};
// The Module object: Our interface to the outside world. We import
// and export values on it. There are various ways Module can be used:
// 1. Not defined. We create it here
// 2. A function parameter, function(Module) { ..generated code.. }
// 3. pre-run appended it, var Module = {}; ..generated code..
// 4. External script tag defines var Module.
// We need to check if Module already exists (e.g. case 3 above).
// Substitution will be replaced with actual code on later stage of the build,
// this way Closure Compiler will not mangle it (e.g. case 4. above).
// Note that if you want to run closure, and also to use Module
// after the generated code, you will need to define var Module = {};
// before the code. Then that object will be used in the code, and you
// can continue to use Module afterwards as well.
var Module = typeof SevenZip !== 'undefined' ? SevenZip : {};
// Set up the promise that indicates the Module is initialized
var readyPromiseResolve, readyPromiseReject;
Module['ready'] = new Promise(function(resolve, reject) {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_main')) {
Object.defineProperty(Module['ready'], '_main', { configurable: true, get: function() { abort('You are getting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_main', { configurable: true, set: function() { abort('You are setting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_end')) {
Object.defineProperty(Module['ready'], '_emscripten_stack_get_end', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_emscripten_stack_get_end', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_free')) {
Object.defineProperty(Module['ready'], '_emscripten_stack_get_free', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_emscripten_stack_get_free', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_init')) {
Object.defineProperty(Module['ready'], '_emscripten_stack_init', { configurable: true, get: function() { abort('You are getting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_emscripten_stack_init', { configurable: true, set: function() { abort('You are setting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackSave')) {
Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, get: function() { abort('You are getting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, set: function() { abort('You are setting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackRestore')) {
Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, get: function() { abort('You are getting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, set: function() { abort('You are setting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackAlloc')) {
Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, get: function() { abort('You are getting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, set: function() { abort('You are setting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '___wasm_call_ctors')) {
Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, get: function() { abort('You are getting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, set: function() { abort('You are setting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_fflush')) {
Object.defineProperty(Module['ready'], '_fflush', { configurable: true, get: function() { abort('You are getting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_fflush', { configurable: true, set: function() { abort('You are setting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '___errno_location')) {
Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, get: function() { abort('You are getting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, set: function() { abort('You are setting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '_malloc')) {
Object.defineProperty(Module['ready'], '_malloc', { configurable: true, get: function() { abort('You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '_malloc', { configurable: true, set: function() { abort('You are setting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '__get_tzname')) {
Object.defineProperty(Module['ready'], '__get_tzname', { configurable: true, get: function() { abort('You are getting __get_tzname on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '__get_tzname', { configurable: true, set: function() { abort('You are setting __get_tzname on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '__get_daylight')) {
Object.defineProperty(Module['ready'], '__get_daylight', { configurable: true, get: function() { abort('You are getting __get_daylight on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '__get_daylight', { configurable: true, set: function() { abort('You are setting __get_daylight on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], '__get_timezone')) {
Object.defineProperty(Module['ready'], '__get_timezone', { configurable: true, get: function() { abort('You are getting __get_timezone on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], '__get_timezone', { configurable: true, set: function() { abort('You are setting __get_timezone on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
if (!Object.getOwnPropertyDescriptor(Module['ready'], 'onRuntimeInitialized')) {
Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, get: function() { abort('You are getting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, set: function() { abort('You are setting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } });
}
// --pre-jses are emitted after the Module integration code, so that they can
// refer to Module (if they choose; they can also define Module)
Module.noInitialRun = true;
// Sometimes an existing Module object exists with properties
// meant to overwrite the default module functionality. Here
// we collect those properties and reapply _after_ we configure
// the current environment's defaults to avoid having to be so
// defensive during initialization.
var moduleOverrides = {};
var key;
for (key in Module) {
if (Module.hasOwnProperty(key)) {
moduleOverrides[key] = Module[key];
}
}
var arguments_ = [];
var thisProgram = './this.program';
var quit_ = function(status, toThrow) {
throw toThrow;
};
// Determine the runtime environment we are in. You can customize this by
// setting the ENVIRONMENT setting at compile time (see settings.js).
// Attempt to auto-detect the environment
var ENVIRONMENT_IS_WEB = typeof window === 'object';
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
// N.b. Electron.js environment is simultaneously a NODE-environment, but
// also a web environment.
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
if (Module['ENVIRONMENT']) {
throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)');
}
// `/` should be present at the end if `scriptDirectory` is not empty
var scriptDirectory = '';
function locateFile(path) {
if (Module['locateFile']) {
return Module['locateFile'](path, scriptDirectory);
}
return scriptDirectory + path;
}
// Hooks that are implemented differently in different runtime environments.
var read_,
readAsync,
readBinary,
setWindowTitle;
var nodeFS;
var nodePath;
if (ENVIRONMENT_IS_NODE) {
if (!(typeof process === 'object' && typeof require === 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = require('path').dirname(scriptDirectory) + '/';
} else {
scriptDirectory = __dirname + '/';
}
// include: node_shell_read.js
read_ = function shell_read(filename, binary) {
if (!nodeFS) nodeFS = require('fs');
if (!nodePath) nodePath = require('path');
filename = nodePath['normalize'](filename);
return nodeFS['readFileSync'](filename, binary ? null : 'utf8');
};
readBinary = function readBinary(filename) {
var ret = read_(filename, true);
if (!ret.buffer) {
ret = new Uint8Array(ret);
}
assert(ret.buffer);
return ret;
};
readAsync = function readAsync(filename, onload, onerror) {
if (!nodeFS) nodeFS = require('fs');
if (!nodePath) nodePath = require('path');
filename = nodePath['normalize'](filename);
nodeFS['readFile'](filename, function(err, data) {
if (err) onerror(err);
else onload(data.buffer);
});
};
// end include: node_shell_read.js
if (process['argv'].length > 1) {
thisProgram = process['argv'][1].replace(/\\/g, '/');
}
arguments_ = process['argv'].slice(2);
// MODULARIZE will export the module in the proper place outside, we don't need to export here
process['on']('uncaughtException', function(ex) {
// suppress ExitStatus exceptions from showing an error
if (!(ex instanceof ExitStatus)) {
throw ex;
}
});
process['on']('unhandledRejection', abort);
quit_ = function(status, toThrow) {
if (keepRuntimeAlive()) {
process['exitCode'] = status;
throw toThrow;
}
process['exit'](status);
};
Module['inspect'] = function () { return '[Emscripten Module object]'; };
} else
if (ENVIRONMENT_IS_SHELL) {
if ((typeof process === 'object' && typeof require === 'function') || typeof window === 'object' || typeof importScripts === 'function') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
if (typeof read != 'undefined') {
read_ = function shell_read(f) {
return read(f);
};
}
readBinary = function readBinary(f) {
var data;
if (typeof readbuffer === 'function') {
return new Uint8Array(readbuffer(f));
}
data = read(f, 'binary');
assert(typeof data === 'object');
return data;
};
readAsync = function readAsync(f, onload, onerror) {
setTimeout(function() { onload(readBinary(f)); }, 0);
};
if (typeof scriptArgs != 'undefined') {
arguments_ = scriptArgs;
} else if (typeof arguments != 'undefined') {
arguments_ = arguments;
}
if (typeof quit === 'function') {
quit_ = function(status) {
quit(status);
};
}
if (typeof print !== 'undefined') {
// Prefer to use print/printErr where they exist, as they usually work better.
if (typeof console === 'undefined') console = /** @type{!Console} */({});
console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print);
}
} else
// Note that this includes Node.js workers when relevant (pthreads is enabled).
// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
// ENVIRONMENT_IS_NODE.
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
scriptDirectory = self.location.href;
} else if (typeof document !== 'undefined' && document.currentScript) { // web
scriptDirectory = document.currentScript.src;
}
// When MODULARIZE, this JS may be executed later, after document.currentScript
// is gone, so we saved it, and we use it here instead of any other info.
if (_scriptDir) {
scriptDirectory = _scriptDir;
}
// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
// otherwise, slice off the final part of the url to find the script directory.
// if scriptDirectory does not contain a slash, lastIndexOf will return -1,
// and scriptDirectory will correctly be replaced with an empty string.
if (scriptDirectory.indexOf('blob:') !== 0) {
scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1);
} else {
scriptDirectory = '';
}
if (!(typeof window === 'object' || typeof importScripts === 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
// Differentiate the Web Worker from the Node Worker case, as reading must
// be done differently.
{
// include: web_or_worker_shell_read.js
read_ = function(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send(null);
return xhr.responseText;
};
if (ENVIRONMENT_IS_WORKER) {
readBinary = function(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.responseType = 'arraybuffer';
xhr.send(null);
return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
};
}
readAsync = function(url, onload, onerror) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
onload(xhr.response);
return;
}
onerror();
};
xhr.onerror = onerror;
xhr.send(null);
};
// end include: web_or_worker_shell_read.js
}
setWindowTitle = function(title) { document.title = title };
} else
{
throw new Error('environment detection error');
}
// Set up the out() and err() hooks, which are how we can print to stdout or
// stderr, respectively.
var out = Module['print'] || console.log.bind(console);
var err = Module['printErr'] || console.warn.bind(console);
// Merge back in the overrides
for (key in moduleOverrides) {
if (moduleOverrides.hasOwnProperty(key)) {
Module[key] = moduleOverrides[key];
}
}
// Free the object hierarchy contained in the overrides, this lets the GC
// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
moduleOverrides = null;
// Emit code to handle expected values on the Module object. This applies Module.x
// to the proper local x. This has two benefits: first, we only emit it if it is
// expected to arrive, and second, by using a local everywhere else that can be
// minified.
if (Module['arguments']) arguments_ = Module['arguments'];
if (!Object.getOwnPropertyDescriptor(Module, 'arguments')) {
Object.defineProperty(Module, 'arguments', {
configurable: true,
get: function() {
abort('Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
if (Module['thisProgram']) thisProgram = Module['thisProgram'];
if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) {
Object.defineProperty(Module, 'thisProgram', {
configurable: true,
get: function() {
abort('Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
if (Module['quit']) quit_ = Module['quit'];
if (!Object.getOwnPropertyDescriptor(Module, 'quit')) {
Object.defineProperty(Module, 'quit', {
configurable: true,
get: function() {
abort('Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
// Assertions on removed incoming Module JS APIs.
assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)');
assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');
assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
if (!Object.getOwnPropertyDescriptor(Module, 'read')) {
Object.defineProperty(Module, 'read', {
configurable: true,
get: function() {
abort('Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) {
Object.defineProperty(Module, 'readAsync', {
configurable: true,
get: function() {
abort('Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) {
Object.defineProperty(Module, 'readBinary', {
configurable: true,
get: function() {
abort('Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) {
Object.defineProperty(Module, 'setWindowTitle', {
configurable: true,
get: function() {
abort('Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-s ENVIRONMENT` to enable.");
var STACK_ALIGN = 16;
function getNativeTypeSize(type) {
switch (type) {
case 'i1': case 'i8': return 1;
case 'i16': return 2;
case 'i32': return 4;
case 'i64': return 8;
case 'float': return 4;
case 'double': return 8;
default: {
if (type[type.length-1] === '*') {
return 4; // A pointer
} else if (type[0] === 'i') {
var bits = Number(type.substr(1));
assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
return bits / 8;
} else {
return 0;
}
}
}
}
function warnOnce(text) {
if (!warnOnce.shown) warnOnce.shown = {};
if (!warnOnce.shown[text]) {
warnOnce.shown[text] = 1;
err(text);
}
}
// include: runtime_functions.js
// Wraps a JS function as a wasm function with a given signature.
function convertJsFunctionToWasm(func, sig) {
// If the type reflection proposal is available, use the new
// "WebAssembly.Function" constructor.
// Otherwise, construct a minimal wasm module importing the JS function and
// re-exporting it.
if (typeof WebAssembly.Function === "function") {
var typeNames = {
'i': 'i32',
'j': 'i64',
'f': 'f32',
'd': 'f64'
};
var type = {
parameters: [],
results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
};
for (var i = 1; i < sig.length; ++i) {
type.parameters.push(typeNames[sig[i]]);
}
return new WebAssembly.Function(type, func);
}
// The module is static, with the exception of the type section, which is
// generated based on the signature passed in.
var typeSection = [
0x01, // id: section,
0x00, // length: 0 (placeholder)
0x01, // count: 1
0x60, // form: func
];
var sigRet = sig.slice(0, 1);
var sigParam = sig.slice(1);
var typeCodes = {
'i': 0x7f, // i32
'j': 0x7e, // i64
'f': 0x7d, // f32
'd': 0x7c, // f64
};
// Parameters, length + signatures
typeSection.push(sigParam.length);
for (var i = 0; i < sigParam.length; ++i) {
typeSection.push(typeCodes[sigParam[i]]);
}
// Return values, length + signatures
// With no multi-return in MVP, either 0 (void) or 1 (anything else)
if (sigRet == 'v') {
typeSection.push(0x00);
} else {
typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
}
// Write the overall length of the type section back into the section header
// (excepting the 2 bytes for the section id and length)
typeSection[1] = typeSection.length - 2;
// Rest of the module is static
var bytes = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
0x01, 0x00, 0x00, 0x00, // version: 1
].concat(typeSection, [
0x02, 0x07, // import section
// (import "e" "f" (func 0 (type 0)))
0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
0x07, 0x05, // export section
// (export "f" (func 0 (type 0)))
0x01, 0x01, 0x66, 0x00, 0x00,
]));
// We can compile this wasm module synchronously because it is very small.
// This accepts an import (at "e.f"), that it reroutes to an export (at "f")
var module = new WebAssembly.Module(bytes);
var instance = new WebAssembly.Instance(module, {
'e': {
'f': func
}
});
var wrappedFunc = instance.exports['f'];
return wrappedFunc;
}
var freeTableIndexes = [];
// Weak map of functions in the table to their indexes, created on first use.
var functionsInTableMap;
function getEmptyTableSlot() {
// Reuse a free index if there is one, otherwise grow.
if (freeTableIndexes.length) {
return freeTableIndexes.pop();
}
// Grow the table
try {
wasmTable.grow(1);
} catch (err) {
if (!(err instanceof RangeError)) {
throw err;
}
throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
}
return wasmTable.length - 1;
}
// Add a wasm function to the table.
function addFunctionWasm(func, sig) {
// Check if the function is already in the table, to ensure each function
// gets a unique index. First, create the map if this is the first use.
if (!functionsInTableMap) {
functionsInTableMap = new WeakMap();
for (var i = 0; i < wasmTable.length; i++) {
var item = wasmTable.get(i);
// Ignore null values.
if (item) {
functionsInTableMap.set(item, i);
}
}
}
if (functionsInTableMap.has(func)) {
return functionsInTableMap.get(func);
}
// It's not in the table, add it now.
var ret = getEmptyTableSlot();
// Set the new value.
try {
// Attempting to call this with JS function will cause of table.set() to fail
wasmTable.set(ret, func);
} catch (err) {
if (!(err instanceof TypeError)) {
throw err;
}
assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction: ' + func);
var wrapped = convertJsFunctionToWasm(func, sig);
wasmTable.set(ret, wrapped);
}
functionsInTableMap.set(func, ret);
return ret;
}
function removeFunction(index) {
functionsInTableMap.delete(wasmTable.get(index));
freeTableIndexes.push(index);
}
// 'sig' parameter is required for the llvm backend but only when func is not
// already a WebAssembly function.
function addFunction(func, sig) {
assert(typeof func !== 'undefined');
return addFunctionWasm(func, sig);
}
// end include: runtime_functions.js
// include: runtime_debug.js
// end include: runtime_debug.js
var tempRet0 = 0;
var setTempRet0 = function(value) {
tempRet0 = value;
};
var getTempRet0 = function() {
return tempRet0;
};
// === Preamble library stuff ===
// Documentation for the public APIs defined in this file must be updated in:
// site/source/docs/api_reference/preamble.js.rst
// A prebuilt local version of the documentation is available at:
// site/build/text/docs/api_reference/preamble.js.txt
// You can also build docs locally as HTML or other formats in site/
// An online HTML version (which may be of a different version of Emscripten)
// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
var wasmBinary;
if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) {
Object.defineProperty(Module, 'wasmBinary', {
configurable: true,
get: function() {
abort('Module.wasmBinary has been replaced with plain wasmBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
var noExitRuntime = Module['noExitRuntime'] || true;
if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) {
Object.defineProperty(Module, 'noExitRuntime', {
configurable: true,
get: function() {
abort('Module.noExitRuntime has been replaced with plain noExitRuntime (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)')
}
});
}
if (typeof WebAssembly !== 'object') {
abort('no native wasm support detected');
}
// include: runtime_safe_heap.js
// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
/** @param {number} ptr
@param {number} value
@param {string} type
@param {number|boolean=} noSafe */
function setValue(ptr, value, type, noSafe) {
type = type || 'i8';
if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
switch (type) {
case 'i1': HEAP8[((ptr)>>0)] = value; break;
case 'i8': HEAP8[((ptr)>>0)] = value; break;
case 'i16': HEAP16[((ptr)>>1)] = value; break;
case 'i32': HEAP32[((ptr)>>2)] = value; break;
case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;
case 'float': HEAPF32[((ptr)>>2)] = value; break;
case 'double': HEAPF64[((ptr)>>3)] = value; break;
default: abort('invalid type for setValue: ' + type);
}
}
/** @param {number} ptr
@param {string} type
@param {number|boolean=} noSafe */
function getValue(ptr, type, noSafe) {
type = type || 'i8';
if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
switch (type) {
case 'i1': return HEAP8[((ptr)>>0)];
case 'i8': return HEAP8[((ptr)>>0)];
case 'i16': return HEAP16[((ptr)>>1)];
case 'i32': return HEAP32[((ptr)>>2)];
case 'i64': return HEAP32[((ptr)>>2)];
case 'float': return HEAPF32[((ptr)>>2)];
case 'double': return HEAPF64[((ptr)>>3)];
default: abort('invalid type for getValue: ' + type);
}
return null;
}
// end include: runtime_safe_heap.js
// Wasm globals
var wasmMemory;
//========================================
// Runtime essentials
//========================================
// whether we are quitting the application. no code should run after this.
// set in exit() and abort()
var ABORT = false;
// set by exit() and abort(). Passed to 'onExit' handler.
// NOTE: This is also used as the process return code code in shell environments
// but only when noExitRuntime is false.
var EXITSTATUS;
/** @type {function(*, string=)} */
function assert(condition, text) {
if (!condition) {
abort('Assertion failed: ' + text);
}
}
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
function getCFunc(ident) {
var func = Module['_' + ident]; // closure exported function
assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
return func;
}
// C calling interface.
/** @param {string|null=} returnType
@param {Array=} argTypes
@param {Arguments|Array=} args
@param {Object=} opts */
function ccall(ident, returnType, argTypes, args, opts) {
// For fast lookup of conversion functions
var toC = {
'string': function(str) {
var ret = 0;
if (str !== null && str !== undefined && str !== 0) { // null string
// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
var len = (str.length << 2) + 1;
ret = stackAlloc(len);
stringToUTF8(str, ret, len);
}
return ret;
},
'array': function(arr) {
var ret = stackAlloc(arr.length);
writeArrayToMemory(arr, ret);
return ret;
}
};
function convertReturnValue(ret) {
if (returnType === 'string') return UTF8ToString(ret);
if (returnType === 'boolean') return Boolean(ret);
return ret;
}
var func = getCFunc(ident);
var cArgs = [];
var stack = 0;
assert(returnType !== 'array', 'Return type should not be "array".');
if (args) {
for (var i = 0; i < args.length; i++) {
var converter = toC[argTypes[i]];
if (converter) {
if (stack === 0) stack = stackSave();
cArgs[i] = converter(args[i]);
} else {
cArgs[i] = args[i];
}
}
}
var ret = func.apply(null, cArgs);
function onDone(ret) {
if (stack !== 0) stackRestore(stack);
return convertReturnValue(ret);
}
ret = onDone(ret);
return ret;
}
/** @param {string=} returnType
@param {Array=} argTypes
@param {Object=} opts */
function cwrap(ident, returnType, argTypes, opts) {
return function() {
return ccall(ident, returnType, argTypes, arguments, opts);
}
}
// We used to include malloc/free by default in the past. Show a helpful error in
// builds with assertions.
function _free() {
// Show a helpful error since we used to include free by default in the past.
abort("free() called but not included in the build - add '_free' to EXPORTED_FUNCTIONS");
}
var ALLOC_NORMAL = 0; // Tries to use _malloc()
var ALLOC_STACK = 1; // Lives for the duration of the current function call
// allocate(): This is for internal use. You can use it yourself as well, but the interface
// is a little tricky (see docs right below). The reason is that it is optimized
// for multiple syntaxes to save space in generated code. So you should
// normally not use allocate(), and instead allocate memory using _malloc(),
// initialize it with setValue(), and so forth.
// @slab: An array of data.
// @allocator: How to allocate memory, see ALLOC_*
/** @type {function((Uint8Array|Array<number>), number)} */
function allocate(slab, allocator) {
var ret;
assert(typeof allocator === 'number', 'allocate no longer takes a type argument')
assert(typeof slab !== 'number', 'allocate no longer takes a number as arg0')
if (allocator == ALLOC_STACK) {
ret = stackAlloc(slab.length);
} else {
ret = _malloc(slab.length);
}
if (slab.subarray || slab.slice) {
HEAPU8.set(/** @type {!Uint8Array} */(slab), ret);
} else {
HEAPU8.set(new Uint8Array(slab), ret);
}
return ret;
}
// include: runtime_strings.js
// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
// a copy of that string as a Javascript String object.
var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
/**
* @param {number} idx
* @param {number=} maxBytesToRead
* @return {string}
*/
function UTF8ArrayToString(heap, idx, maxBytesToRead) {
var endIdx = idx + maxBytesToRead;
var endPtr = idx;
// TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
// Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
// (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)
while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
return UTF8Decoder.decode(heap.subarray(idx, endPtr));
} else {
var str = '';
// If building with TextDecoder, we have already computed the string length above, so test loop end condition against that
while (idx < endPtr) {
// For UTF8 byte structure, see:
// http://en.wikipedia.org/wiki/UTF-8#Description
// https://www.ietf.org/rfc/rfc2279.txt
// https://tools.ietf.org/html/rfc3629
var u0 = heap[idx++];
if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
var u1 = heap[idx++] & 63;
if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
var u2 = heap[idx++] & 63;
if ((u0 & 0xF0) == 0xE0) {
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
} else {
if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
}
if (u0 < 0x10000) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 0x10000;
str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
}
}
}
return str;
}
// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a
// copy of that string as a Javascript String object.
// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit
// this parameter to scan the string until the first \0 byte. If maxBytesToRead is
// passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the
// middle, then the string will cut short at that byte index (i.e. maxBytesToRead will
// not produce a string of exact length [ptr, ptr+maxBytesToRead[)
/
gitextract_j5v1h9cg/ ├── .coderabbit.yaml ├── .eslintrc.js ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── config.yml │ │ └── submit_translation.yml │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── docker-publish.yml │ ├── release-appx.yml │ ├── release.yml │ └── upload.yml ├── .gitignore ├── .prettierrc ├── .yarnrc ├── Dockerfile ├── LICENSE ├── README.md ├── README_cn.md ├── README_hi.md ├── README_id.md ├── README_pt.md ├── assets/ │ ├── icons/ │ │ ├── azw3.icns │ │ ├── comic.icns │ │ ├── epub.icns │ │ ├── fb2.icns │ │ ├── icon.icns │ │ ├── mobi.icns │ │ └── pdf.icns │ ├── macos/ │ │ └── entitlements.mac.plist │ └── windows/ │ └── installer.nsh ├── docker-compose-secret.yml ├── docker-compose.yml ├── electron-builder.env ├── httpServer.js ├── main.js ├── package.json ├── public/ │ ├── LICENSE │ ├── assets/ │ │ └── styles/ │ │ ├── dark.css │ │ └── default.css │ ├── index.html │ ├── lib/ │ │ ├── 7z-wasm/ │ │ │ ├── 7zz.umd.js │ │ │ ├── 7zz.wasm │ │ │ └── License.txt │ │ ├── esearch-ocr/ │ │ │ └── esearch-ocr.umd.js │ │ ├── libunrar/ │ │ │ ├── libunrar.js │ │ │ ├── libunrar.wasm │ │ │ ├── rpc.js │ │ │ └── worker.js │ │ ├── pdfjs/ │ │ │ ├── annotation_layer_builder.css │ │ │ ├── cmaps/ │ │ │ │ ├── 78-EUC-H.bcmap │ │ │ │ ├── 78-EUC-V.bcmap │ │ │ │ ├── 78-H.bcmap │ │ │ │ ├── 78-RKSJ-H.bcmap │ │ │ │ ├── 78-RKSJ-V.bcmap │ │ │ │ ├── 78-V.bcmap │ │ │ │ ├── 78ms-RKSJ-H.bcmap │ │ │ │ ├── 78ms-RKSJ-V.bcmap │ │ │ │ ├── 83pv-RKSJ-H.bcmap │ │ │ │ ├── 90ms-RKSJ-H.bcmap │ │ │ │ ├── 90ms-RKSJ-V.bcmap │ │ │ │ ├── 90msp-RKSJ-H.bcmap │ │ │ │ ├── 90msp-RKSJ-V.bcmap │ │ │ │ ├── 90pv-RKSJ-H.bcmap │ │ │ │ ├── 90pv-RKSJ-V.bcmap │ │ │ │ ├── Add-H.bcmap │ │ │ │ ├── Add-RKSJ-H.bcmap │ │ │ │ ├── Add-RKSJ-V.bcmap │ │ │ │ ├── Add-V.bcmap │ │ │ │ ├── Adobe-CNS1-0.bcmap │ │ │ │ ├── Adobe-CNS1-1.bcmap │ │ │ │ ├── Adobe-CNS1-2.bcmap │ │ │ │ ├── Adobe-CNS1-3.bcmap │ │ │ │ ├── Adobe-CNS1-4.bcmap │ │ │ │ ├── Adobe-CNS1-5.bcmap │ │ │ │ ├── Adobe-CNS1-6.bcmap │ │ │ │ ├── Adobe-CNS1-UCS2.bcmap │ │ │ │ ├── Adobe-GB1-0.bcmap │ │ │ │ ├── Adobe-GB1-1.bcmap │ │ │ │ ├── Adobe-GB1-2.bcmap │ │ │ │ ├── Adobe-GB1-3.bcmap │ │ │ │ ├── Adobe-GB1-4.bcmap │ │ │ │ ├── Adobe-GB1-5.bcmap │ │ │ │ ├── Adobe-GB1-UCS2.bcmap │ │ │ │ ├── Adobe-Japan1-0.bcmap │ │ │ │ ├── Adobe-Japan1-1.bcmap │ │ │ │ ├── Adobe-Japan1-2.bcmap │ │ │ │ ├── Adobe-Japan1-3.bcmap │ │ │ │ ├── Adobe-Japan1-4.bcmap │ │ │ │ ├── Adobe-Japan1-5.bcmap │ │ │ │ ├── Adobe-Japan1-6.bcmap │ │ │ │ ├── Adobe-Japan1-UCS2.bcmap │ │ │ │ ├── Adobe-Korea1-0.bcmap │ │ │ │ ├── Adobe-Korea1-1.bcmap │ │ │ │ ├── Adobe-Korea1-2.bcmap │ │ │ │ ├── Adobe-Korea1-UCS2.bcmap │ │ │ │ ├── B5-H.bcmap │ │ │ │ ├── B5-V.bcmap │ │ │ │ ├── B5pc-H.bcmap │ │ │ │ ├── B5pc-V.bcmap │ │ │ │ ├── CNS-EUC-H.bcmap │ │ │ │ ├── CNS-EUC-V.bcmap │ │ │ │ ├── CNS1-H.bcmap │ │ │ │ ├── CNS1-V.bcmap │ │ │ │ ├── CNS2-H.bcmap │ │ │ │ ├── CNS2-V.bcmap │ │ │ │ ├── ETHK-B5-H.bcmap │ │ │ │ ├── ETHK-B5-V.bcmap │ │ │ │ ├── ETen-B5-H.bcmap │ │ │ │ ├── ETen-B5-V.bcmap │ │ │ │ ├── ETenms-B5-H.bcmap │ │ │ │ ├── ETenms-B5-V.bcmap │ │ │ │ ├── EUC-H.bcmap │ │ │ │ ├── EUC-V.bcmap │ │ │ │ ├── Ext-H.bcmap │ │ │ │ ├── Ext-RKSJ-H.bcmap │ │ │ │ ├── Ext-RKSJ-V.bcmap │ │ │ │ ├── Ext-V.bcmap │ │ │ │ ├── GB-EUC-H.bcmap │ │ │ │ ├── GB-EUC-V.bcmap │ │ │ │ ├── GB-H.bcmap │ │ │ │ ├── GB-V.bcmap │ │ │ │ ├── GBK-EUC-H.bcmap │ │ │ │ ├── GBK-EUC-V.bcmap │ │ │ │ ├── GBK2K-H.bcmap │ │ │ │ ├── GBK2K-V.bcmap │ │ │ │ ├── GBKp-EUC-H.bcmap │ │ │ │ ├── GBKp-EUC-V.bcmap │ │ │ │ ├── GBT-EUC-H.bcmap │ │ │ │ ├── GBT-EUC-V.bcmap │ │ │ │ ├── GBT-H.bcmap │ │ │ │ ├── GBT-V.bcmap │ │ │ │ ├── GBTpc-EUC-H.bcmap │ │ │ │ ├── GBTpc-EUC-V.bcmap │ │ │ │ ├── GBpc-EUC-H.bcmap │ │ │ │ ├── GBpc-EUC-V.bcmap │ │ │ │ ├── H.bcmap │ │ │ │ ├── HKdla-B5-H.bcmap │ │ │ │ ├── HKdla-B5-V.bcmap │ │ │ │ ├── HKdlb-B5-H.bcmap │ │ │ │ ├── HKdlb-B5-V.bcmap │ │ │ │ ├── HKgccs-B5-H.bcmap │ │ │ │ ├── HKgccs-B5-V.bcmap │ │ │ │ ├── HKm314-B5-H.bcmap │ │ │ │ ├── HKm314-B5-V.bcmap │ │ │ │ ├── HKm471-B5-H.bcmap │ │ │ │ ├── HKm471-B5-V.bcmap │ │ │ │ ├── HKscs-B5-H.bcmap │ │ │ │ ├── HKscs-B5-V.bcmap │ │ │ │ ├── Hankaku.bcmap │ │ │ │ ├── Hiragana.bcmap │ │ │ │ ├── KSC-EUC-H.bcmap │ │ │ │ ├── KSC-EUC-V.bcmap │ │ │ │ ├── KSC-H.bcmap │ │ │ │ ├── KSC-Johab-H.bcmap │ │ │ │ ├── KSC-Johab-V.bcmap │ │ │ │ ├── KSC-V.bcmap │ │ │ │ ├── KSCms-UHC-H.bcmap │ │ │ │ ├── KSCms-UHC-HW-H.bcmap │ │ │ │ ├── KSCms-UHC-HW-V.bcmap │ │ │ │ ├── KSCms-UHC-V.bcmap │ │ │ │ ├── KSCpc-EUC-H.bcmap │ │ │ │ ├── KSCpc-EUC-V.bcmap │ │ │ │ ├── Katakana.bcmap │ │ │ │ ├── LICENSE │ │ │ │ ├── NWP-H.bcmap │ │ │ │ ├── NWP-V.bcmap │ │ │ │ ├── RKSJ-H.bcmap │ │ │ │ ├── RKSJ-V.bcmap │ │ │ │ ├── Roman.bcmap │ │ │ │ ├── UniCNS-UCS2-H.bcmap │ │ │ │ ├── UniCNS-UCS2-V.bcmap │ │ │ │ ├── UniCNS-UTF16-H.bcmap │ │ │ │ ├── UniCNS-UTF16-V.bcmap │ │ │ │ ├── UniCNS-UTF32-H.bcmap │ │ │ │ ├── UniCNS-UTF32-V.bcmap │ │ │ │ ├── UniCNS-UTF8-H.bcmap │ │ │ │ ├── UniCNS-UTF8-V.bcmap │ │ │ │ ├── UniGB-UCS2-H.bcmap │ │ │ │ ├── UniGB-UCS2-V.bcmap │ │ │ │ ├── UniGB-UTF16-H.bcmap │ │ │ │ ├── UniGB-UTF16-V.bcmap │ │ │ │ ├── UniGB-UTF32-H.bcmap │ │ │ │ ├── UniGB-UTF32-V.bcmap │ │ │ │ ├── UniGB-UTF8-H.bcmap │ │ │ │ ├── UniGB-UTF8-V.bcmap │ │ │ │ ├── UniJIS-UCS2-H.bcmap │ │ │ │ ├── UniJIS-UCS2-HW-H.bcmap │ │ │ │ ├── UniJIS-UCS2-HW-V.bcmap │ │ │ │ ├── UniJIS-UCS2-V.bcmap │ │ │ │ ├── UniJIS-UTF16-H.bcmap │ │ │ │ ├── UniJIS-UTF16-V.bcmap │ │ │ │ ├── UniJIS-UTF32-H.bcmap │ │ │ │ ├── UniJIS-UTF32-V.bcmap │ │ │ │ ├── UniJIS-UTF8-H.bcmap │ │ │ │ ├── UniJIS-UTF8-V.bcmap │ │ │ │ ├── UniJIS2004-UTF16-H.bcmap │ │ │ │ ├── UniJIS2004-UTF16-V.bcmap │ │ │ │ ├── UniJIS2004-UTF32-H.bcmap │ │ │ │ ├── UniJIS2004-UTF32-V.bcmap │ │ │ │ ├── UniJIS2004-UTF8-H.bcmap │ │ │ │ ├── UniJIS2004-UTF8-V.bcmap │ │ │ │ ├── UniJISPro-UCS2-HW-V.bcmap │ │ │ │ ├── UniJISPro-UCS2-V.bcmap │ │ │ │ ├── UniJISPro-UTF8-V.bcmap │ │ │ │ ├── UniJISX0213-UTF32-H.bcmap │ │ │ │ ├── UniJISX0213-UTF32-V.bcmap │ │ │ │ ├── UniJISX02132004-UTF32-H.bcmap │ │ │ │ ├── UniJISX02132004-UTF32-V.bcmap │ │ │ │ ├── UniKS-UCS2-H.bcmap │ │ │ │ ├── UniKS-UCS2-V.bcmap │ │ │ │ ├── UniKS-UTF16-H.bcmap │ │ │ │ ├── UniKS-UTF16-V.bcmap │ │ │ │ ├── UniKS-UTF32-H.bcmap │ │ │ │ ├── UniKS-UTF32-V.bcmap │ │ │ │ ├── UniKS-UTF8-H.bcmap │ │ │ │ ├── UniKS-UTF8-V.bcmap │ │ │ │ ├── V.bcmap │ │ │ │ └── WP-Symbol.bcmap │ │ │ ├── pdf.mjs │ │ │ ├── pdf.worker.mjs │ │ │ ├── standard_fonts/ │ │ │ │ ├── FoxitDingbats.pfb │ │ │ │ ├── FoxitFixed.pfb │ │ │ │ ├── FoxitFixedBold.pfb │ │ │ │ ├── FoxitFixedBoldItalic.pfb │ │ │ │ ├── FoxitFixedItalic.pfb │ │ │ │ ├── FoxitSerif.pfb │ │ │ │ ├── FoxitSerifBold.pfb │ │ │ │ ├── FoxitSerifBoldItalic.pfb │ │ │ │ ├── FoxitSerifItalic.pfb │ │ │ │ ├── FoxitSymbol.pfb │ │ │ │ ├── LICENSE_FOXIT │ │ │ │ └── LICENSE_LIBERATION │ │ │ └── text_layer_builder.css │ │ └── sqljs-wasm/ │ │ ├── sql-wasm.js │ │ └── sql-wasm.wasm │ └── robots.txt ├── src/ │ ├── assets/ │ │ ├── lib/ │ │ │ └── kookit-extra.min.mjs │ │ ├── locales/ │ │ │ ├── am/ │ │ │ │ └── translation.json │ │ │ ├── ar/ │ │ │ │ └── translation.json │ │ │ ├── bg/ │ │ │ │ └── translation.json │ │ │ ├── bn/ │ │ │ │ └── translation.json │ │ │ ├── bo/ │ │ │ │ └── translation.json │ │ │ ├── cs/ │ │ │ │ └── translation.json │ │ │ ├── da/ │ │ │ │ └── translation.json │ │ │ ├── de/ │ │ │ │ └── translation.json │ │ │ ├── el/ │ │ │ │ └── translation.json │ │ │ ├── en/ │ │ │ │ └── translation.json │ │ │ ├── es/ │ │ │ │ └── translation.json │ │ │ ├── fa/ │ │ │ │ └── translation.json │ │ │ ├── fi/ │ │ │ │ └── translation.json │ │ │ ├── fr/ │ │ │ │ └── translation.json │ │ │ ├── ga/ │ │ │ │ └── translation.json │ │ │ ├── hi/ │ │ │ │ └── translation.json │ │ │ ├── hu/ │ │ │ │ └── translation.json │ │ │ ├── hy/ │ │ │ │ └── translation.json │ │ │ ├── id/ │ │ │ │ └── translation.json │ │ │ ├── ie/ │ │ │ │ └── translation.json │ │ │ ├── it/ │ │ │ │ └── translation.json │ │ │ ├── ja/ │ │ │ │ └── translation.json │ │ │ ├── ko/ │ │ │ │ └── translation.json │ │ │ ├── nl/ │ │ │ │ └── translation.json │ │ │ ├── pl/ │ │ │ │ └── translation.json │ │ │ ├── pt/ │ │ │ │ └── translation.json │ │ │ ├── pt-BR/ │ │ │ │ └── translation.json │ │ │ ├── ro/ │ │ │ │ └── translation.json │ │ │ ├── ru/ │ │ │ │ └── translation.json │ │ │ ├── sl/ │ │ │ │ └── translation.json │ │ │ ├── sr/ │ │ │ │ └── translation.json │ │ │ ├── sv/ │ │ │ │ └── translation.json │ │ │ ├── ta/ │ │ │ │ └── translation.json │ │ │ ├── th/ │ │ │ │ └── translation.json │ │ │ ├── tl/ │ │ │ │ └── translation.json │ │ │ ├── tr/ │ │ │ │ └── translation.json │ │ │ ├── uk/ │ │ │ │ └── translation.json │ │ │ ├── vi/ │ │ │ │ └── translation.json │ │ │ ├── zh-CN/ │ │ │ │ └── translation.json │ │ │ ├── zh-MO/ │ │ │ │ └── translation.json │ │ │ └── zh-TW/ │ │ │ └── translation.json │ │ ├── lotties/ │ │ │ ├── exit.json │ │ │ ├── message.json │ │ │ ├── new.json │ │ │ ├── safe.json │ │ │ ├── success.json │ │ │ └── support.json │ │ └── styles/ │ │ ├── global.css │ │ ├── reset.css │ │ └── style.css │ ├── components/ │ │ ├── arrow/ │ │ │ ├── arrow.css │ │ │ └── index.tsx │ │ ├── background/ │ │ │ ├── background.css │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── bookCardItem/ │ │ │ ├── bookCardItem.css │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── bookCoverItem/ │ │ │ ├── bookCoverItem.css │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── bookListItem/ │ │ │ ├── bookListItem.css │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── colorOption/ │ │ │ ├── colorOption.css │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── deleteIcon/ │ │ │ ├── component.tsx │ │ │ ├── deleteIcon.css │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── dialogs/ │ │ │ ├── aboutDialog/ │ │ │ │ ├── aboutDialog.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── actionDialog/ │ │ │ │ ├── actionDialog.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── addDialog/ │ │ │ │ ├── addDialog.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── backupDialog/ │ │ │ │ ├── backupDialog.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── convertDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── convertDialog.css │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── deleteDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── deleteDialog.css │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── deletePopup/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── detailDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── updateInfo.css │ │ │ ├── editDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── editDialog.css │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── importDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── importDialog.css │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── loadingDialog/ │ │ │ │ ├── index.tsx │ │ │ │ └── loadingDialog.css │ │ │ ├── localFileDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── localFileDialog.css │ │ │ ├── moreAction/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── moreAction.css │ │ │ ├── settingDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── settingDialog.css │ │ │ ├── sortBookDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── sortDialog.css │ │ │ ├── sortShelfDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── sortShelfDialog.css │ │ │ ├── speechDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── speechDialog.css │ │ │ ├── supportDialog/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── supportDialog.css │ │ │ └── updateDialog/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── updateInfo.css │ │ ├── emptyCover/ │ │ │ ├── emptyCover.css │ │ │ └── index.tsx │ │ ├── imageViewer/ │ │ │ ├── component.tsx │ │ │ ├── imageViewer.css │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── importLocal/ │ │ │ ├── component.tsx │ │ │ ├── importLocal.css │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── noteTag/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── noteTag.css │ │ ├── popups/ │ │ │ ├── popupAssist/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupAssist.css │ │ │ ├── popupBox/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupMenu.css │ │ │ ├── popupDict/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupDict.css │ │ │ ├── popupMenu/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupMenu.css │ │ │ ├── popupNote/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupNote.css │ │ │ ├── popupOption/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupOption.css │ │ │ ├── popupRefer/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── popupRefer.css │ │ │ └── popupTrans/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── popupTrans.css │ │ ├── readerSettings/ │ │ │ ├── dropdownList/ │ │ │ │ ├── component.tsx │ │ │ │ ├── dropdownList.css │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── modeControl/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── modeControl.css │ │ │ ├── settingSwitch/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── sliderList/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── sliderList.css │ │ │ └── themeList/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── themeList.css │ │ ├── searchBox/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── searchBox.css │ │ ├── selectBook/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── selectBook.css │ │ ├── textToSpeech/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── textToSpeech.css │ │ └── viewMode/ │ │ ├── component.tsx │ │ ├── index.tsx │ │ ├── interface.tsx │ │ └── viewMode.css │ ├── constants/ │ │ ├── driveList.tsx │ │ ├── dropdownList.tsx │ │ ├── emptyList.tsx │ │ ├── loginList.tsx │ │ ├── mimetype.tsx │ │ ├── popupList.tsx │ │ ├── settingList.tsx │ │ ├── sideMenu.tsx │ │ ├── themeList.tsx │ │ ├── ttsList.tsx │ │ └── viewMode.tsx │ ├── containers/ │ │ ├── emptyPage/ │ │ │ ├── component.tsx │ │ │ ├── emptyPage.css │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── header/ │ │ │ ├── component.tsx │ │ │ ├── header.css │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── lists/ │ │ │ ├── bookList/ │ │ │ │ ├── booklist.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── cardList/ │ │ │ │ ├── cardList.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── contentList/ │ │ │ │ ├── component.tsx │ │ │ │ ├── contentList.css │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── deletedBookList/ │ │ │ │ ├── booklist.css │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── navList/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── navList.css │ │ │ └── noteList/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── noteList.css │ │ ├── pageWidget/ │ │ │ ├── background.css │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── panels/ │ │ │ ├── navigationPanel/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── navigationPanel.css │ │ │ ├── operationPanel/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── operationPanel.css │ │ │ ├── progressPanel/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── interface.tsx │ │ │ │ └── progressPanel.css │ │ │ └── settingPanel/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── settingPanel.css │ │ ├── settings/ │ │ │ ├── accountSetting/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── generalSetting/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ ├── pluginSetting/ │ │ │ │ ├── component.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── interface.tsx │ │ │ └── syncSetting/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ ├── sidebar/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── sidebar.css │ │ └── viewer/ │ │ ├── component.tsx │ │ ├── index.css │ │ ├── index.tsx │ │ └── interface.tsx │ ├── i18n-script.js │ ├── i18n.tsx │ ├── index.tsx │ ├── models/ │ │ ├── Book.ts │ │ ├── BookLocation.ts │ │ ├── Bookmark.ts │ │ ├── DictHistory.ts │ │ ├── HtmlBook.ts │ │ ├── Note.ts │ │ └── Plugin.ts │ ├── pages/ │ │ ├── login/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── login.css │ │ ├── manager/ │ │ │ ├── component.tsx │ │ │ ├── index.tsx │ │ │ ├── interface.tsx │ │ │ └── manager.css │ │ ├── reader/ │ │ │ ├── component.tsx │ │ │ ├── index.css │ │ │ ├── index.tsx │ │ │ └── interface.tsx │ │ └── redirect/ │ │ ├── component.tsx │ │ ├── index.tsx │ │ ├── interface.tsx │ │ └── manager.css │ ├── react-app-env.d.ts │ ├── router/ │ │ ├── index.tsx │ │ └── routes.tsx │ ├── store/ │ │ ├── actions/ │ │ │ ├── backupPage.tsx │ │ │ ├── book.tsx │ │ │ ├── index.tsx │ │ │ ├── manager.tsx │ │ │ ├── progressPanel.tsx │ │ │ ├── reader.tsx │ │ │ ├── sidebar.tsx │ │ │ └── viewArea.tsx │ │ ├── index.tsx │ │ └── reducers/ │ │ ├── backupPage.tsx │ │ ├── book.tsx │ │ ├── index.tsx │ │ ├── manager.tsx │ │ ├── progressPanel.tsx │ │ ├── reader.tsx │ │ ├── sidebar.tsx │ │ └── viewArea.tsx │ ├── upload.sh │ └── utils/ │ ├── common.ts │ ├── file/ │ │ ├── backup.ts │ │ ├── bookUtil.ts │ │ ├── common.ts │ │ ├── configUtil.ts │ │ ├── coverUtil.ts │ │ ├── export.ts │ │ ├── googlePicker.ts │ │ ├── localFile.ts │ │ ├── restore.ts │ │ └── sqlUtil.ts │ ├── reader/ │ │ ├── docUtil.ts │ │ ├── launchUtil.ts │ │ ├── mouseEvent.ts │ │ ├── styleUtil.ts │ │ ├── themeUtil.ts │ │ └── ttsUtil.ts │ ├── request/ │ │ ├── common.ts │ │ ├── reader.ts │ │ ├── thirdparty.ts │ │ └── user.ts │ └── storage/ │ ├── databaseService.ts │ └── syncService.ts ├── tsconfig.json ├── types/ │ └── index.d.ts └── webpack.config.js
Showing preview only (443K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6072 symbols across 181 files)
FILE: httpServer.js
function getDockerSecret (line 7) | function getDockerSecret(secretName) {
constant UPLOAD_DIR (line 20) | const UPLOAD_DIR = path.resolve("./uploads");
constant PORT (line 21) | const PORT = process.env.PORT || 8080;
constant SERVER_ENABLED (line 22) | const SERVER_ENABLED = process.env.ENABLE_HTTP_SERVER === "true";
constant SERVER_PASSWORD_FILE (line 24) | const SERVER_PASSWORD_FILE = process.env.SERVER_PASSWORD_FILE || "my_sec...
constant SERVER_PASSWORD (line 25) | const SERVER_PASSWORD =
constant VALID_CREDENTIALS (line 29) | const VALID_CREDENTIALS = {
function authenticate (line 103) | function authenticate(req) {
function sanitizeFilename (line 121) | function sanitizeFilename(originalName) {
function resolveSafePath (line 130) | function resolveSafePath(...pathSegments) {
function handleUpload (line 143) | function handleUpload(req, res, dirParam) {
function parseMultipart (line 214) | function parseMultipart(buffer, boundary) {
function handleDownload (line 264) | function handleDownload(req, res, dirParam) {
function handleDelete (line 309) | function handleDelete(req, res, dirParam) {
function handleList (line 370) | function handleList(req, res, dirParam) {
FILE: public/lib/7z-wasm/7zz.umd.js
function locateFile (line 163) | function locateFile(path) {
function getNativeTypeSize (line 474) | function getNativeTypeSize(type) {
function warnOnce (line 496) | function warnOnce(text) {
function convertJsFunctionToWasm (line 508) | function convertJsFunctionToWasm(func, sig) {
function getEmptyTableSlot (line 596) | function getEmptyTableSlot() {
function addFunctionWasm (line 614) | function addFunctionWasm(func, sig) {
function removeFunction (line 653) | function removeFunction(index) {
function addFunction (line 660) | function addFunction(func, sig) {
function setValue (line 727) | function setValue(ptr, value, type, noSafe) {
function getValue (line 745) | function getValue(ptr, type, noSafe) {
function assert (line 780) | function assert(condition, text) {
function getCFunc (line 787) | function getCFunc(ident) {
function ccall (line 798) | function ccall(ident, returnType, argTypes, args, opts) {
function cwrap (line 852) | function cwrap(ident, returnType, argTypes, opts) {
function _free (line 860) | function _free() {
function allocate (line 876) | function allocate(slab, allocator) {
function UTF8ArrayToString (line 910) | function UTF8ArrayToString(heap, idx, maxBytesToRead) {
function UTF8ToString (line 966) | function UTF8ToString(ptr, maxBytesToRead) {
function stringToUTF8Array (line 983) | function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
function stringToUTF8 (line 1029) | function stringToUTF8(str, outPtr, maxBytesToWrite) {
function lengthBytesUTF8 (line 1035) | function lengthBytesUTF8(str) {
function AsciiToString (line 1059) | function AsciiToString(ptr) {
function stringToAscii (line 1071) | function stringToAscii(str, outPtr) {
function UTF16ToString (line 1080) | function UTF16ToString(ptr, maxBytesToRead) {
function stringToUTF16 (line 1121) | function stringToUTF16(str, outPtr, maxBytesToWrite) {
function lengthBytesUTF16 (line 1145) | function lengthBytesUTF16(str) {
function UTF32ToString (line 1149) | function UTF32ToString(ptr, maxBytesToRead) {
function stringToUTF32 (line 1183) | function stringToUTF32(str, outPtr, maxBytesToWrite) {
function lengthBytesUTF32 (line 1212) | function lengthBytesUTF32(str) {
function allocateUTF8 (line 1227) | function allocateUTF8(str) {
function allocateUTF8OnStack (line 1235) | function allocateUTF8OnStack(str) {
function writeStringToMemory (line 1248) | function writeStringToMemory(string, buffer, dontAddNull) {
function writeArrayToMemory (line 1263) | function writeArrayToMemory(array, buffer) {
function writeAsciiToMemory (line 1269) | function writeAsciiToMemory(str, buffer, dontAddNull) {
function alignUp (line 1281) | function alignUp(x, multiple) {
function updateGlobalBufferAndViews (line 1308) | function updateGlobalBufferAndViews(buf) {
function writeStackCookie (line 1354) | function writeStackCookie() {
function checkStackCookie (line 1364) | function checkStackCookie() {
function keepRuntimeAlive (line 1399) | function keepRuntimeAlive() {
function preRun (line 1403) | function preRun() {
function initRuntime (line 1415) | function initRuntime() {
function preMain (line 1429) | function preMain() {
function exitRuntime (line 1435) | function exitRuntime() {
function postRun (line 1440) | function postRun() {
function addOnPreRun (line 1453) | function addOnPreRun(cb) {
function addOnInit (line 1457) | function addOnInit(cb) {
function addOnPreMain (line 1461) | function addOnPreMain(cb) {
function addOnExit (line 1465) | function addOnExit(cb) {
function addOnPostRun (line 1468) | function addOnPostRun(cb) {
function getUniqueRunDependency (line 1501) | function getUniqueRunDependency(id) {
function addRunDependency (line 1509) | function addRunDependency(id) {
function removeRunDependency (line 1545) | function removeRunDependency(id) {
function abort (line 1575) | function abort(what) {
function isDataURI (line 1616) | function isDataURI(filename) {
function isFileURI (line 1622) | function isFileURI(filename) {
function createExportWrapper (line 1627) | function createExportWrapper(name, fixedasm) {
function getBinary (line 1649) | function getBinary(file) {
function getBinaryPromise (line 1665) | function getBinaryPromise() {
function createWasm (line 1700) | function createWasm() {
function callRuntimeCallbacks (line 1822) | function callRuntimeCallbacks(callbacks) {
function demangle (line 1842) | function demangle(func) {
function demangleAll (line 1847) | function demangleAll(text) {
function handleException (line 1857) | function handleException(e) {
function jsStackTrace (line 1875) | function jsStackTrace() {
function stackTrace (line 1892) | function stackTrace() {
function ___cxa_allocate_exception (line 1898) | function ___cxa_allocate_exception(size) {
function _atexit (line 1903) | function _atexit(func, arg) {
function ___cxa_atexit (line 1905) | function ___cxa_atexit(a0,a1
function ExceptionInfo (line 1910) | function ExceptionInfo(excPtr) {
function ___cxa_throw (line 1978) | function ___cxa_throw(ptr, type, destructor) {
function _gmtime_r (line 1987) | function _gmtime_r(time, tmPtr) {
function ___gmtime_r (line 2006) | function ___gmtime_r(a0,a1
function _tzset_impl (line 2011) | function _tzset_impl() {
function _tzset (line 2049) | function _tzset() {
function _localtime_r (line 2055) | function _localtime_r(time, tmPtr) {
function ___localtime_r (line 2082) | function ___localtime_r(a0,a1
function getRandomDevice (line 2156) | function getRandomDevice() {
function trim (line 2199) | function trim(arr) {
function zeroMemory (line 2371) | function zeroMemory(address, size) {
function alignMemory (line 2375) | function alignMemory(size, alignment) {
function mmapAlloc (line 2379) | function mmapAlloc(size) {
function asyncLoad (line 2702) | function asyncLoad(url, onload, onerror, noRunDep) {
function ensureParent (line 2999) | function ensureParent(path) {
function base (line 3019) | function base(path) {
function doCallback (line 3431) | function doCallback(errCode) {
function done (line 3437) | function done(errCode) {
function LazyUint8Array (line 4475) | function LazyUint8Array() {
function processData (line 4633) | function processData(byteArray) {
function finish (line 4686) | function finish() {
function finish (line 4717) | function finish() {
function ___sys_chmod (line 4894) | function ___sys_chmod(path, mode) {try {
function ___sys_chown32 (line 4905) | function ___sys_chown32(path, owner, group) {try {
function ___sys_fstat64 (line 4916) | function ___sys_fstat64(fd, buf) {try {
function ___sys_fstatat64 (line 4926) | function ___sys_fstatat64(dirfd, path, buf, flags) {try {
function ___sys_ftruncate64 (line 4941) | function ___sys_ftruncate64(fd, zero, low, high) {try {
function ___sys_getcwd (line 4952) | function ___sys_getcwd(buf, size) {try {
function ___sys_getdents64 (line 4966) | function ___sys_getdents64(fd, dirp, count) {try {
function ___sys_getpid (line 5010) | function ___sys_getpid() {
function ___sys_getppid (line 5014) | function ___sys_getppid() {
function ___sys_ioctl (line 5018) | function ___sys_ioctl(fd, op, varargs) {SYSCALLS.varargs = varargs;
function ___sys_link (line 5072) | function ___sys_link(oldpath, newpath) {
function ___sys_lstat64 (line 5076) | function ___sys_lstat64(path, buf) {try {
function ___sys_mkdir (line 5086) | function ___sys_mkdir(path, mode) {try {
function ___sys_open (line 5096) | function ___sys_open(path, flags, varargs) {SYSCALLS.varargs = varargs;
function ___sys_readlink (line 5109) | function ___sys_readlink(path, buf, bufsize) {try {
function ___sys_rename (line 5119) | function ___sys_rename(old_path, new_path) {try {
function ___sys_rmdir (line 5131) | function ___sys_rmdir(path) {try {
function ___sys_stat64 (line 5142) | function ___sys_stat64(path, buf) {try {
function ___sys_symlink (line 5152) | function ___sys_symlink(target, linkpath) {try {
function ___sys_umask (line 5164) | function ___sys_umask(mask) {try {
function ___sys_uname (line 5175) | function ___sys_uname(buf) {try {
function ___sys_unlink (line 5195) | function ___sys_unlink(path) {try {
function ___sys_utimensat (line 5206) | function ___sys_utimensat(dirfd, path, times, flags) {try {
function _abort (line 5226) | function _abort() {
function _emscripten_get_heap_max (line 5230) | function _emscripten_get_heap_max() {
function _emscripten_memcpy_big (line 5236) | function _emscripten_memcpy_big(dest, src, num) {
function emscripten_realloc_buffer (line 5240) | function emscripten_realloc_buffer(size) {
function _emscripten_resize_heap (line 5252) | function _emscripten_resize_heap(requestedSize) {
function getExecutableName (line 5300) | function getExecutableName() {
function getEnvStrings (line 5303) | function getEnvStrings() {
function _environ_get (line 5333) | function _environ_get(__environ, environ_buf) {
function _environ_sizes_get (line 5344) | function _environ_sizes_get(penviron_count, penviron_buf_size) {
function _exit (line 5355) | function _exit(status) {
function _fd_close (line 5361) | function _fd_close(fd) {try {
function _fd_fdstat_get (line 5372) | function _fd_fdstat_get(fd, pbuf) {try {
function _fd_read (line 5392) | function _fd_read(fd, iov, iovcnt, pnum) {try {
function _fd_seek (line 5404) | function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {try {
function _fd_write (line 5428) | function _fd_write(fd, iov, iovcnt, pnum) {try {
function _getgrgid (line 5440) | function _getgrgid() { throw 'getgrgid: TODO' }
function _getpwuid (line 5442) | function _getpwuid() { throw 'getpwuid: TODO' }
function _gettimeofday (line 5444) | function _gettimeofday(ptr) {
function _mktime (line 5451) | function _mktime(tmPtr) {
function _setTempRet0 (line 5493) | function _setTempRet0(val) {
function _time (line 5497) | function _time(ptr) {
function _times (line 5505) | function _times(buffer) {
function intArrayFromString (line 5690) | function intArrayFromString(stringy, dontAddNull, length) {
function intArrayToString (line 5698) | function intArrayToString(array) {
function ExitStatus (line 6078) | function ExitStatus(status) {
function callMain (line 6092) | function callMain(args) {
function stackCheckInit (line 6126) | function stackCheckInit() {
function run (line 6136) | function run(args) {
function checkUnflushedContent (line 6189) | function checkUnflushedContent() {
function exit (line 6230) | function exit(status, implicit) {
function procExit (line 6249) | function procExit(code) {
FILE: public/lib/esearch-ocr/esearch-ocr.umd.js
function F (line 1) | function F(t,e){return O(t,e)}
function Qt (line 1) | function Qt(t){O=t}
function Tt (line 1) | function Tt(t){return t>0?Math.floor(t):Math.ceil(t)}
function X (line 1) | function X(t,e,s){return Math.max(e,Math.min(t,s))}
function gt (line 1) | function gt(t,e,s,o,a="high"){return Zt(t,e,s,o,a).getImageData(0,0,e,s)}
function Zt (line 1) | function Zt(t,e,s,o,a="high"){const r=H(t),u=F(e,s).getContext("2d");ret...
function H (line 1) | function H(t,e,s){const o=F(e||t.width,s||t.height);return o.getContext(...
function bt (line 1) | function bt(t,e,s){const o=t.data,a=[],r=[],i=[];let u=0,m=0;for(let h=0...
class Pt (line 1) | class Pt{constructor(e){vt(this,"tl",[]);vt(this,"name");this.name=e}l(e...
method constructor (line 1) | constructor(e){vt(this,"tl",[]);vt(this,"name");this.name=e}
method l (line 1) | l(e){const s=performance.now();this.tl.push({t:e,n:s});const o=[];for(...
function Jt (line 1) | async function Jt(t,e,s,o,a,r){const{transposedData:i,image:u}=tn(t,a,r)...
function tn (line 1) | function tn(t,e,s){const o=gt(t,e,s);return{transposedData:bt(o,[.485,.4...
function nn (line 1) | async function nn(t,e,s,o){const a=t.flat(Number.POSITIVE_INFINITY),r=Fl...
function en (line 1) | function en(t){if(t.length===0)throw new Error("Empty contour");const e=...
function on (line 1) | function on(t){t.sort((o,a)=>o.x-a.x||o.y-a.y);const e=[];for(const o of...
function Et (line 1) | function Et(t,e,s){return(e.x-t.x)*(s.y-t.y)-(e.y-t.y)*(s.x-t.x)}
function sn (line 1) | function sn(t,e,s="CHAIN_APPROX_SIMPLE"){const o=t.length,a=o>0?t[0].len...
function At (line 1) | function At(t,e,s){return t[s][e]!==0&&(s>0&&t[s-1][e]===0||s<t.length-1...
function cn (line 1) | function cn(t,e,s,o,a){const r=[];let i={x:s,y:o},u={x:s-1,y:o};const m=...
function rn (line 1) | function rn(t,e,s){function o(i){return i.x+i.y*t[0].length}const a=e.ge...
function yt (line 1) | function yt(t,e){const s=lt.findIndex(({dx:o,dy:a})=>t===o&&e===a);retur...
function ln (line 1) | function ln(t){if(t.length<3)return[...t];const e=[t[0]];for(let s=1;s<t...
function an (line 1) | function an(t,e,s){return(e.x-t.x)*(s.y-e.y)===(e.y-t.y)*(s.x-e.x)}
function st (line 1) | function st(t,e){var o;const s=document.createElement("canvas");s.width=...
function L (line 1) | function L(...t){pt&&console.log(...t)}
function un (line 1) | function un(...t){pt&&console.log(t.map(e=>`%c${e}`).join(""),...t.map(e...
function hn (line 1) | async function hn(t){_t(t);const e={det:"det"in t?t.det:{input:t.detPath...
function _t (line 1) | function _t(t){j=!!t.dev,pt=j||!!t.log,j||(q.l=()=>{},Y.l=()=>{}),t.canv...
function Ot (line 1) | async function Ot(t){let e;if(typeof window>"u"){const s=t;if(!s.data||!...
function It (line 1) | function It(){try{F(1,1),at(new Uint8ClampedArray(4),1,1)}catch(t){throw...
function fn (line 1) | async function fn(t){if(!W)throw new Error("need init");return W.ocr(t)}
function dn (line 1) | async function dn(t){if(!W)throw new Error("need init");return W.det(t)}
function xn (line 1) | async function xn(t){if(!W)throw new Error("need init");return W.rec(t)}
function mn (line 1) | async function mn(t){It();const e={ort:t.ort,ortOption:t.ortOption},s=t....
function wt (line 1) | function wt(t,e,s){return typeof e=="string"||e instanceof ArrayBuffer||...
function zt (line 1) | async function zt(t){const e=await wt(t.ort,t.input,t.ortOption);return{...
function Rt (line 1) | async function Rt(t){It();let e=1;const s=await wt(t.ort,t.input,t.ortOp...
function gn (line 1) | function gn(t){const e=t;return[{box:[[0,0],[e.width,0],[e.width,e.heigh...
function Lt (line 1) | async function Lt(t){var u;It();let e=48;const s=await wt(t.ort,t.input,...
function bn (line 1) | async function bn(t,e,s,o){const a=Float32Array.from(t.flat(3)),r=new o....
function yn (line 1) | async function yn(t,e,s,o,a){const r=Float32Array.from(t.flat(3)),i=new ...
function pn (line 1) | function pn(t,e){const s=Math.max(Math.round(t.height*e/32)*32,32),o=Mat...
function In (line 1) | function In(t,e,s,o){Y.l("");const a=Math.min(o.width,e),r=Math.min(o.he...
function wn (line 1) | function wn(t){let e=-1;const s=t.length;let o,a=t[s-1],r=0;for(;++e<s;)...
function Mn (line 1) | function Mn(t){let e=-1;const s=t.length;let o=t[s-1],a,r,i=o[0],u=o[1],...
function kn (line 1) | function kn(t){const s=Math.abs(wn(t)),o=Mn(t),a=s*1.5/o,r=[];for(const[...
function Cn (line 1) | function Cn(t,e,s){const o=e.width,a=e.height,r=s*Math.PI/180,i=Math.cos...
function Sn (line 1) | function Sn(t){const s=en(t),o=Array.from(Cn(s.center,s.size,s.angle)).s...
function Vt (line 1) | function Vt(t,e){return Math.sqrt((t[0]-e[0])**2+(t[1]-e[1])**2)}
function Nn (line 1) | function Nn(t){const e=[[0,0],[0,0],[0,0],[0,0]],s=t.map(r=>r[0]+r[1]);e...
function Dn (line 1) | function Dn(t,e){const[s,o,a,r]=e.map(T=>({x:T[0],y:T[1]})),i=Math.sqrt(...
function Bn (line 1) | function Bn(t){var m,h;const e=new Map,s=t.data;for(let l=0;l<s.length;l...
function ut (line 1) | function ut(t,e){const s=t,o=e;return Math.sqrt((s[0]-o[0])**2+(s[1]-o[1...
function vn (line 1) | function vn(t,e=1){let s=[];return t.forEach((o,a)=>{s.length===0?s.push...
function Tn (line 1) | function Tn(t,e,s){let o=0,a=e.height,r=0,i=e.width;function u(x){return...
function ht (line 1) | function ht(t,e,s){const o=(s*t.width+e)*4;return Array.from(t.data.slic...
function Pn (line 1) | function Pn(t,e){const s=[];function o(a){const r=Math.floor(e*(a.width/...
function En (line 1) | function En(t,e,s){const o=t.dims[2],a=[];let r=t.dims[0]-1;const i=s.to...
function Ft (line 1) | function Ft(t,e){var Xt;L(t);const s=(e==null?void 0:e.docDirs)??[{block...
function Mt (line 1) | function Mt(t){return t.reduce((e,s)=>e+s,0)/t.length}
function jt (line 1) | function jt(t){const e=t.map(o=>o[1]).reduce((o,a)=>o+a,0);let s=0;for(c...
function ft (line 1) | function ft(t){return(t%360+360)%360}
function kt (line 1) | function kt(t,e){const s=ft(e);if(s===0)return t;if(![90,180,270].includ...
function An (line 1) | function An(t,e="",s,o,a){if(!j)return;const i=document.querySelector(`#...
FILE: public/lib/libunrar/libunrar.js
function assert (line 10) | function assert(a,b){a||u("Assertion failed: "+b)}
function D (line 11) | function D(a,b,d){var e=b+d;for(d=b;a[d]&&!(d>=e);)++d;if(16<d-b&&a.suba...
function F (line 11) | function F(a,b){return a?D(pa,a,b):""}
function qa (line 12) | function qa(a,b,d,e){if(!(0<e))return 0;var f=d;e=d+e-1;for(var h=0;h<a....
function ra (line 12) | function ra(a,b,d){return qa(a,pa,b,d)}
function sa (line 13) | function sa(a){for(var b=0,d=0;d<a.length;++d){var e=a.charCodeAt(d);552...
function ta (line 13) | function ta(a){var b=sa(a)+1,d=ua(b);d&&qa(a,G,d,b);return d}
function wa (line 14) | function wa(a){va=a;c.HEAP8=G=new Int8Array(a);c.HEAP16=new Int16Array(a...
function ya (line 15) | function ya(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b...
function Ea (line 15) | function Ea(){var a=c.preRun.shift();za.unshift(a)}
function La (line 15) | function La(){K++;c.monitorRunDependencies&&c.monitorRunDependencies(K)}
function Ma (line 16) | function Ma(){K--;c.monitorRunDependencies&&c.monitorRunDependencies(K);...
function u (line 16) | function u(a){if(c.onAbort)c.onAbort(a);ka(a);v(a);na=!0;throw new WebAs...
function Na (line 16) | function Na(a){var b=L;return String.prototype.startsWith?b.startsWith(a...
function Oa (line 16) | function Oa(){return Na("data:application/octet-stream;base64,")}
function Qa (line 17) | function Qa(){try{if(ma)return new Uint8Array(ma);if(ha)return ha(L);thr...
function Ra (line 17) | function Ra(){return ma||!da&&!m||"function"!==typeof fetch||Na("file://...
function Ta (line 18) | function Ta(a){return a.replace(/\b_Z[\w\d_]+/g,function(b){return b===b...
function Ua (line 18) | function Ua(){return 0<Ua.Ea}
function Va (line 18) | function Va(a,b){for(var d=0,e=a.length-1;0<=e;e--){var f=a[e];"."===f?a...
function O (line 19) | function O(a){var b="/"===a.charAt(0),d="/"===a.substr(-1);(a=Va(a.split...
function Wa (line 19) | function Wa(a){var b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|)...
function P (line 19) | function P(a){if("/"===a)return"/";var b=a.lastIndexOf("/");return-1===b...
function Xa (line 20) | function Xa(){var a=Array.prototype.slice.call(arguments,0);return O(a.j...
function Q (line 20) | function Q(a,b){return O(a+"/"+b)}
function Ya (line 20) | function Ya(a){return H[Za()>>2]=a}
function R (line 20) | function R(){for(var a="",b=!1,d=arguments.length-1;-1<=d&&!b;d--){b=0<=...
function $a (line 21) | function $a(a,b){function d(k){for(var l=0;l<k.length&&""===k[l];l++);fo...
function bb (line 21) | function bb(a,b){ab[a]={input:[],output:[],Ta:b};S.Hb(a,cb)}
function b (line 32) | function b(h){h=h.split("/");for(var k=e,l=0;l<h.length-1;l++){var q=h.s...
function d (line 32) | function d(h){h=h.split("/");return h[h.length-1]}
function d (line 43) | function d(k){S.nb--;return b(k)}
function e (line 43) | function e(k){if(k){if(!e.Ea)return e.Ea=!0,d(k)}else++h>=f.length&&d(nu...
function h (line 68) | function h(){this.zb=!1;this.Ea=[]}
function t (line 73) | function t(B){function A(J){n&&n();l||S.hb(a,b,J,e,f,q);h&&h();Ma(C)}var...
function ib (line 77) | function ib(a,b,d){try{var e=a(b)}catch(f){if(f&&f.node&&O(b)!==O(S.Ja(f...
function kb (line 78) | function kb(a){a=S.Ya(a);if(!a)throw new S.ra(8);return a}
function mb (line 79) | function mb(){if(!nb){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/"...
function ob (line 80) | function ob(){function a(h){return(h=h.toTimeString().match(/\(([A-Za-z ...
function tb (line 81) | function tb(a,b,d,e){a||(a=this);this.parent=a;this.Aa=a.Aa;this.bb=null...
function db (line 82) | function db(a,b){var d=Array(sa(a)+1);a=qa(a,d,0,d.length);b&&(d.length=...
function a (line 92) | function a(f){c.asm=f.exports;Ma("wasm-instantiate")}
function b (line 92) | function b(f){a(f.instance)}
function d (line 92) | function d(f){return Ra().then(function(h){return WebAssembly.instantiat...
function Vb (line 109) | function Vb(){function a(){if(!Tb&&(Tb=!0,c.calledRun=!0,!na)){Da=!0;c.n...
function V (line 110) | function V(){}
function Wb (line 110) | function Wb(a){return(a||V).gb}
function Xb (line 110) | function Xb(a,b){var d=Wb(b),e=d[a];if(e)return e;e=Object.create((b||V)...
function cc (line 111) | function cc(){if(ac){for(var a=0;a<$b.length;a++)c._free($b[a]);$b.lengt...
function dc (line 112) | function dc(a){if("string"===typeof a){a=db(a);var b=G;assert(W);b=a.len...
function X (line 112) | function X(){this.va=wb();Wb(X)[this.va]=this}
function Y (line 115) | function Y(){this.va=Cb();Wb(Y)[this.va]=this}
function Z (line 118) | function Z(){throw"cannot construct a VoidPtr, no constructor in IDL";}
function a (line 119) | function a(){}
function cleanup (line 414) | function cleanup (data,handle,cb,type) {
function makeDirTree (line 424) | function makeDirTree(returnVal){
function RARcb (line 463) | function RARcb(pars,callbackFn) {
function ShowArcInfo (line 501) | function ShowArcInfo(Flags) {
FILE: public/lib/pdfjs/pdf.mjs
function F (line 674) | function F() { /* empty */ }
function __webpack_require__ (line 4674) | function __webpack_require__(moduleId) {
constant IDENTITY_MATRIX (line 4795) | const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
constant FONT_IDENTITY_MATRIX (line 4796) | const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
constant MAX_IMAGE_SIZE_TO_CACHE (line 4797) | const MAX_IMAGE_SIZE_TO_CACHE = 10e6;
constant LINE_FACTOR (line 4798) | const LINE_FACTOR = 1.35;
constant LINE_DESCENT_FACTOR (line 4799) | const LINE_DESCENT_FACTOR = 0.35;
constant BASELINE_FACTOR (line 4800) | const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
constant OPS (line 4977) | const OPS = {
function setVerbosityLevel (line 5074) | function setVerbosityLevel(level) {
function getVerbosityLevel (line 5079) | function getVerbosityLevel() {
function info (line 5082) | function info(msg) {
function warn (line 5087) | function warn(msg) {
function unreachable (line 5092) | function unreachable(msg) {
function assert (line 5095) | function assert(cond, msg) {
function _isValidProtocol (line 5100) | function _isValidProtocol(url) {
function createValidAbsoluteUrl (line 5112) | function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
function shadow (line 5137) | function shadow(obj, prop, value, nonSerializable = false) {
function BaseException (line 5147) | function BaseException(message, name) {
class PasswordException (line 5155) | class PasswordException extends BaseException {
method constructor (line 5156) | constructor(msg, code) {
class UnknownErrorException (line 5161) | class UnknownErrorException extends BaseException {
method constructor (line 5162) | constructor(msg, details) {
class InvalidPDFException (line 5167) | class InvalidPDFException extends BaseException {
method constructor (line 5168) | constructor(msg) {
class MissingPDFException (line 5172) | class MissingPDFException extends BaseException {
method constructor (line 5173) | constructor(msg) {
class UnexpectedResponseException (line 5177) | class UnexpectedResponseException extends BaseException {
method constructor (line 5178) | constructor(msg, status) {
class FormatError (line 5183) | class FormatError extends BaseException {
method constructor (line 5184) | constructor(msg) {
class AbortException (line 5188) | class AbortException extends BaseException {
method constructor (line 5189) | constructor(msg) {
function bytesToString (line 5193) | function bytesToString(bytes) {
function stringToBytes (line 5210) | function stringToBytes(str) {
function string32 (line 5221) | function string32(value) {
function objectSize (line 5224) | function objectSize(obj) {
function objectFromMap (line 5227) | function objectFromMap(map) {
function isLittleEndian (line 5234) | function isLittleEndian() {
function isEvalSupported (line 5240) | function isEvalSupported() {
class util_FeatureTest (line 5248) | class util_FeatureTest {
method isLittleEndian (line 5249) | static get isLittleEndian() {
method isEvalSupported (line 5252) | static get isEvalSupported() {
method isOffscreenCanvasSupported (line 5255) | static get isOffscreenCanvasSupported() {
method platform (line 5258) | static get platform() {
method isCSSRoundSupported (line 5272) | static get isCSSRoundSupported() {
class Util (line 5277) | class Util {
method makeHexColor (line 5278) | static makeHexColor(r, g, b) {
method scaleMinMax (line 5281) | static scaleMinMax(transform, minMax) {
method transform (line 5325) | static transform(m1, m2) {
method applyTransform (line 5328) | static applyTransform(p, m) {
method applyInverseTransform (line 5333) | static applyInverseTransform(p, m) {
method getAxialAlignedBoundingBox (line 5339) | static getAxialAlignedBoundingBox(r, m) {
method inverseTransform (line 5346) | static inverseTransform(m) {
method singularValueDecompose2dScale (line 5350) | static singularValueDecompose2dScale(m) {
method normalizeRect (line 5362) | static normalizeRect(rect) {
method intersect (line 5374) | static intersect(rect1, rect2) {
method #getExtremumOnCurve (line 5387) | static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
method #getExtremum (line 5401) | static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) {
method bezierBoundingBox (line 5417) | static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
function stringToPDFString (line 5432) | function stringToPDFString(str) {
function stringToUTF8String (line 5476) | function stringToUTF8String(str) {
function utf8StringToString (line 5479) | function utf8StringToString(str) {
function isArrayEqual (line 5482) | function isArrayEqual(arr1, arr2) {
function getModificationDate (line 5493) | function getModificationDate(date = new Date()) {
function normalizeUnicode (line 5499) | function normalizeUnicode(str) {
function getUuid (line 5506) | function getUuid() {
class BaseFilterFactory (line 5567) | class BaseFilterFactory {
method addFilter (line 5568) | addFilter(maps) {
method addHCMFilter (line 5571) | addHCMFilter(fgColor, bgColor) {
method addAlphaFilter (line 5574) | addAlphaFilter(map) {
method addLuminosityFilter (line 5577) | addLuminosityFilter(map) {
method addHighlightHCMFilter (line 5580) | addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgC...
method destroy (line 5583) | destroy(keepHCM = false) {}
class BaseCanvasFactory (line 5585) | class BaseCanvasFactory {
method constructor (line 5587) | constructor({
method create (line 5592) | create(width, height) {
method reset (line 5604) | reset(canvasAndContext, width, height) {
method destroy (line 5614) | destroy(canvasAndContext) {
method _createCanvas (line 5623) | _createCanvas(width, height) {
class BaseCMapReaderFactory (line 5627) | class BaseCMapReaderFactory {
method constructor (line 5628) | constructor({
method fetch (line 5635) | async fetch({
method _fetchData (line 5650) | _fetchData(url, compressionType) {
class BaseStandardFontDataFactory (line 5654) | class BaseStandardFontDataFactory {
method constructor (line 5655) | constructor({
method fetch (line 5660) | async fetch({
method _fetchData (line 5674) | _fetchData(url) {
class BaseSVGFactory (line 5678) | class BaseSVGFactory {
method create (line 5679) | create(width, height, skipDimensions = false) {
method createElement (line 5693) | createElement(type) {
method _createSVG (line 5699) | _createSVG(type) {
constant SVG_NS (line 5720) | const SVG_NS = "http://www.w3.org/2000/svg";
class PixelsPerInch (line 5721) | class PixelsPerInch {
class DOMFilterFactory (line 5726) | class DOMFilterFactory extends BaseFilterFactory {
method constructor (line 5734) | constructor({
method #cache (line 5742) | get #cache() {
method #hcmCache (line 5745) | get #hcmCache() {
method #defs (line 5748) | get #defs() {
method #createTables (line 5770) | #createTables(maps) {
method #createUrl (line 5791) | #createUrl(id) {
method addFilter (line 5805) | addFilter(maps) {
method addHCMFilter (line 5828) | addHCMFilter(fgColor, bgColor) {
method addAlphaFilter (line 5882) | addAlphaFilter(map) {
method addLuminosityFilter (line 5902) | addLuminosityFilter(map) {
method addHighlightHCMFilter (line 5930) | addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgC...
method destroy (line 5986) | destroy(keepHCM = false) {
method #addLuminosityConversion (line 6000) | #addLuminosityConversion(filter) {
method #addGrayConversion (line 6006) | #addGrayConversion(filter) {
method #createFilter (line 6012) | #createFilter(id) {
method #appendFeFunc (line 6019) | #appendFeFunc(feComponentTransfer, func, table) {
method #addTransferMapConversion (line 6025) | #addTransferMapConversion(rTable, gTable, bTable, filter) {
method #addTransferMapAlphaConversion (line 6032) | #addTransferMapAlphaConversion(aTable, filter) {
method #getRGB (line 6037) | #getRGB(color) {
class DOMCanvasFactory (line 6042) | class DOMCanvasFactory extends BaseCanvasFactory {
method constructor (line 6043) | constructor({
method _createCanvas (line 6052) | _createCanvas(width, height) {
function fetchData (line 6059) | async function fetchData(url, type = "text") {
class DOMCMapReaderFactory (line 6099) | class DOMCMapReaderFactory extends BaseCMapReaderFactory {
method _fetchData (line 6100) | _fetchData(url, compressionType) {
class DOMStandardFontDataFactory (line 6107) | class DOMStandardFontDataFactory extends BaseStandardFontDataFactory {
method _fetchData (line 6108) | _fetchData(url) {
class DOMSVGFactory (line 6112) | class DOMSVGFactory extends BaseSVGFactory {
method _createSVG (line 6113) | _createSVG(type) {
class PageViewport (line 6117) | class PageViewport {
method constructor (line 6118) | constructor({
method rawDims (line 6187) | get rawDims() {
method clone (line 6198) | clone({
method convertToViewportPoint (line 6214) | convertToViewportPoint(x, y) {
method convertToViewportRectangle (line 6217) | convertToViewportRectangle(rect) {
method convertToPdfPoint (line 6222) | convertToPdfPoint(x, y) {
class RenderingCancelledException (line 6226) | class RenderingCancelledException extends BaseException {
method constructor (line 6227) | constructor(msg, extraDelay = 0) {
function isDataScheme (line 6232) | function isDataScheme(url) {
function isPdfFile (line 6240) | function isPdfFile(filename) {
function getFilenameFromUrl (line 6243) | function getFilenameFromUrl(url) {
function getPdfFilenameFromUrl (line 6247) | function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
class StatTimer (line 6269) | class StatTimer {
method time (line 6272) | time(name) {
method timeEnd (line 6278) | timeEnd(name) {
method toString (line 6289) | toString() {
function isValidFetchUrl (line 6307) | function isValidFetchUrl(url, baseUrl) {
function noContextMenu (line 6317) | function noContextMenu(e) {
function deprecated (line 6320) | function deprecated(details) {
class PDFDateString (line 6324) | class PDFDateString {
method toDateObject (line 6325) | static toDateObject(input) {
function getXfaPageViewport (line 6360) | function getXfaPageViewport(xfaPage, {
function getRGB (line 6375) | function getRGB(color) {
function getColorValues (line 6389) | function getColorValues(colors) {
function getCurrentTransform (line 6400) | function getCurrentTransform(ctx) {
function getCurrentTransformInverse (line 6411) | function getCurrentTransformInverse(ctx) {
function setLayerDimensions (line 6422) | function setLayerDimensions(div, viewport, mustFlip = false, mustRotate ...
class OutputScale (line 6448) | class OutputScale {
method constructor (line 6449) | constructor() {
method scaled (line 6454) | get scaled() {
method symmetric (line 6457) | get symmetric() {
class EditorToolbar (line 6464) | class EditorToolbar {
method constructor (line 6471) | constructor(editor) {
method render (line 6480) | render() {
method div (line 6506) | get div() {
method #pointerDown (line 6509) | static #pointerDown(e) {
method #focusIn (line 6512) | #focusIn(e) {
method #focusOut (line 6517) | #focusOut(e) {
method #addListenersToElement (line 6522) | #addListenersToElement(element) {
method hide (line 6536) | hide() {
method show (line 6540) | show() {
method #addDeleteButton (line 6544) | #addDeleteButton() {
method #divider (line 6561) | get #divider() {
method addAltText (line 6566) | async addAltText(altText) {
method addColorPicker (line 6572) | addColorPicker(colorPicker) {
method remove (line 6578) | remove() {
class HighlightToolbar (line 6584) | class HighlightToolbar {
method constructor (line 6588) | constructor(uiManager) {
method #render (line 6591) | #render() {
method #getLastPoint (line 6604) | #getLastPoint(boxes, isLTR) {
method show (line 6628) | show(parent, boxes, isLTR) {
method hide (line 6637) | hide() {
method #addHighlightButton (line 6640) | #addHighlightButton() {
function bindEvents (line 6687) | function bindEvents(obj, element, names) {
function opacityToHex (line 6692) | function opacityToHex(opacity) {
class IdManager (line 6695) | class IdManager {
method id (line 6697) | get id() {
class ImageManager (line 6701) | class ImageManager {
method _isSVGFittingCanvas (line 6705) | static get _isSVGFittingCanvas() {
method #get (line 6719) | async #get(key, rawData) {
method getFromFile (line 6777) | async getFromFile(file) {
method getFromUrl (line 6786) | async getFromUrl(url) {
method getFromBlob (line 6789) | async getFromBlob(id, blobPromise) {
method getFromId (line 6793) | async getFromId(id) {
method getFromCanvas (line 6815) | getFromCanvas(id, canvas) {
method getSvgUrl (line 6835) | getSvgUrl(id) {
method deleteId (line 6842) | deleteId(id) {
method isValidId (line 6864) | isValidId(id) {
class CommandManager (line 6868) | class CommandManager {
method constructor (line 6873) | constructor(maxSize = 128) {
method add (line 6876) | add({
method undo (line 6923) | undo() {
method redo (line 6937) | redo() {
method hasSomethingToUndo (line 6950) | hasSomethingToUndo() {
method hasSomethingToRedo (line 6953) | hasSomethingToRedo() {
method destroy (line 6956) | destroy() {
class KeyboardManager (line 6960) | class KeyboardManager {
method constructor (line 6961) | constructor(callbacks) {
method #serialize (line 6987) | #serialize(event) {
method exec (line 7005) | exec(self, event) {
class ColorManager (line 7031) | class ColorManager {
method _colors (line 7033) | get _colors() {
method convert (line 7038) | convert(color) {
method getHexCode (line 7050) | getHexCode(name) {
class AnnotationEditorUIManager (line 7058) | class AnnotationEditorUIManager {
method _keyboardManager (line 7109) | static get _keyboardManager() {
method constructor (line 7167) | constructor(container, viewer, altTextManager, eventBus, pdfDocument, ...
method destroy (line 7208) | destroy() {
method combinedSignal (line 7235) | combinedSignal(ac) {
method mlManager (line 7238) | get mlManager() {
method useNewAltTextFlow (line 7241) | get useNewAltTextFlow() {
method useNewAltTextWhenAddingImage (line 7244) | get useNewAltTextWhenAddingImage() {
method hcmFilter (line 7247) | get hcmFilter() {
method direction (line 7250) | get direction() {
method highlightColors (line 7253) | get highlightColors() {
method highlightColorNames (line 7256) | get highlightColorNames() {
method setMainHighlightColorPicker (line 7259) | setMainHighlightColorPicker(colorPicker) {
method editAltText (line 7262) | editAltText(editor, firstTime = false) {
method switchToMode (line 7265) | switchToMode(mode, callback) {
method setPreference (line 7275) | setPreference(name, value) {
method onSetPreference (line 7282) | onSetPreference({
method onPageChanging (line 7292) | onPageChanging({
method focusMainContainer (line 7297) | focusMainContainer() {
method findParent (line 7300) | findParent(x, y) {
method disableUserSelect (line 7314) | disableUserSelect(value = false) {
method addShouldRescale (line 7317) | addShouldRescale(editor) {
method removeShouldRescale (line 7320) | removeShouldRescale(editor) {
method onScaleChanging (line 7323) | onScaleChanging({
method onRotationChanging (line 7332) | onRotationChanging({
method #getAnchorElementForSelection (line 7338) | #getAnchorElementForSelection({
method #getLayerForTextLayer (line 7343) | #getLayerForTextLayer(textLayer) {
method highlightSelection (line 7357) | highlightSelection(methodOfCreation = "") {
method #displayHighlightToolbar (line 7401) | #displayHighlightToolbar() {
method addToAnnotationStorage (line 7415) | addToAnnotationStorage(editor) {
method #selectionChange (line 7420) | #selectionChange() {
method #onSelectEnd (line 7485) | #onSelectEnd(methodOfCreation = "") {
method #addSelectionListener (line 7492) | #addSelectionListener() {
method #addFocusManager (line 7497) | #addFocusManager() {
method #removeFocusManager (line 7510) | #removeFocusManager() {
method blur (line 7514) | blur() {
method focus (line 7534) | focus() {
method #addKeyboardManager (line 7548) | #addKeyboardManager() {
method #removeKeyboardManager (line 7561) | #removeKeyboardManager() {
method #addCopyPasteListeners (line 7565) | #addCopyPasteListeners() {
method #removeCopyPasteListeners (line 7581) | #removeCopyPasteListeners() {
method #addDragAndDropListeners (line 7585) | #addDragAndDropListeners() {
method addEditListeners (line 7594) | addEditListeners() {
method removeEditListeners (line 7598) | removeEditListeners() {
method dragOver (line 7602) | dragOver(event) {
method drop (line 7615) | drop(event) {
method copy (line 7626) | copy(event) {
method cut (line 7644) | cut(event) {
method paste (line 7648) | async paste(event) {
method keydown (line 7705) | keydown(event) {
method keyup (line 7713) | keyup(event) {
method onEditingAction (line 7722) | onEditingAction({
method #dispatchUpdateStates (line 7737) | #dispatchUpdateStates(details) {
method #dispatchUpdateUI (line 7749) | #dispatchUpdateUI(details) {
method setEditingState (line 7755) | setEditingState(isEditing) {
method registerEditorTypes (line 7775) | registerEditorTypes(types) {
method getId (line 7784) | getId() {
method currentLayer (line 7787) | get currentLayer() {
method getLayer (line 7790) | getLayer(pageIndex) {
method currentPageIndex (line 7793) | get currentPageIndex() {
method addLayer (line 7796) | addLayer(layer) {
method removeLayer (line 7804) | removeLayer(layer) {
method updateMode (line 7807) | async updateMode(mode, editId = null, isFromKeyboard = false) {
method addNewEditorFromKeyboard (line 7848) | addNewEditorFromKeyboard() {
method updateToolbar (line 7853) | updateToolbar(mode) {
method updateParams (line 7862) | updateParams(type, value) {
method showAllEditors (line 7895) | showAllEditors(type, visible, updateButton = false) {
method enableWaiting (line 7906) | enableWaiting(mustWait = false) {
method #enableAll (line 7920) | async #enableAll() {
method #disableAll (line 7933) | #disableAll() {
method getEditors (line 7945) | getEditors(pageIndex) {
method getEditor (line 7954) | getEditor(id) {
method addEditor (line 7957) | addEditor(editor) {
method removeEditor (line 7960) | removeEditor(editor) {
method addDeletedAnnotationElement (line 7976) | addDeletedAnnotationElement(editor) {
method isDeletedAnnotationElement (line 7981) | isDeletedAnnotationElement(annotationElementId) {
method removeDeletedAnnotationElement (line 7984) | removeDeletedAnnotationElement(editor) {
method #addEditorToLayer (line 7989) | #addEditorToLayer(editor) {
method setActiveEditor (line 7998) | setActiveEditor(editor) {
method #lastSelectedEditor (line 8007) | get #lastSelectedEditor() {
method updateUI (line 8012) | updateUI(editor) {
method toggleSelected (line 8017) | toggleSelected(editor) {
method setSelected (line 8033) | setSelected(editor) {
method isSelected (line 8047) | isSelected(editor) {
method firstSelectedEditor (line 8050) | get firstSelectedEditor() {
method unselect (line 8053) | unselect(editor) {
method hasSelection (line 8060) | get hasSelection() {
method isEnterHandled (line 8063) | get isEnterHandled() {
method undo (line 8066) | undo() {
method redo (line 8074) | redo() {
method addCommands (line 8082) | addCommands(params) {
method #isEmpty (line 8090) | #isEmpty() {
method delete (line 8101) | delete() {
method commitOrRemove (line 8123) | commitOrRemove() {
method hasSomethingToControl (line 8126) | hasSomethingToControl() {
method #selectEditors (line 8129) | #selectEditors(editors) {
method selectAll (line 8145) | selectAll() {
method unselectAll (line 8151) | unselectAll() {
method translateSelectedEditors (line 8169) | translateSelectedEditors(x, y, noCommit = false) {
method setUpDragSession (line 8209) | setUpDragSession() {
method endDragSession (line 8226) | endDragSession() {
method dragSelectedEditors (line 8282) | dragSelectedEditors(tx, ty) {
method rebuild (line 8290) | rebuild(editor) {
method isEditorHandlingKeyboard (line 8305) | get isEditorHandlingKeyboard() {
method isActive (line 8308) | isActive(editor) {
method getActive (line 8311) | getActive() {
method getMode (line 8314) | getMode() {
method imageManager (line 8317) | get imageManager() {
method getSelectionBoxes (line 8320) | getSelectionBoxes(textLayer) {
method addChangedExistingAnnotation (line 8391) | addChangedExistingAnnotation({
method removeChangedExistingAnnotation (line 8397) | removeChangedExistingAnnotation({
method renderAnnotationElement (line 8402) | renderAnnotationElement(annotation) {
class AltText (line 8420) | class AltText {
method constructor (line 8434) | constructor(editor) {
method initialize (line 8443) | static initialize(l10nPromise) {
method render (line 8446) | async render() {
method #label (line 8493) | get #label() {
method finish (line 8496) | finish() {
method isEmpty (line 8505) | isEmpty() {
method hasData (line 8511) | hasData() {
method guessedText (line 8517) | get guessedText() {
method setGuessedText (line 8520) | async setGuessedText(guessedText) {
method toggleAltTextBadge (line 8530) | toggleAltTextBadge(visibility = false) {
method serialize (line 8543) | serialize(isForCopying) {
method data (line 8555) | get data() {
method data (line 8561) | set data({
method toggle (line 8581) | toggle(enabled = false) {
method shown (line 8591) | shown() {
method destroy (line 8599) | destroy() {
method #setState (line 8606) | async #setState() {
class AnnotationEditor (line 8687) | class AnnotationEditor {
method _resizerKeyboardManager (line 8720) | static get _resizerKeyboardManager() {
method constructor (line 8742) | constructor(parameters) {
method editorType (line 8773) | get editorType() {
method _defaultLineColor (line 8776) | static get _defaultLineColor() {
method deleteAnnotationElement (line 8779) | static deleteAnnotationElement(editor) {
method initialize (line 8789) | static initialize(l10n, _uiManager, options) {
method updateDefaultParams (line 8812) | static updateDefaultParams(_type, _value) {}
method defaultPropertiesToUpdate (line 8813) | static get defaultPropertiesToUpdate() {
method isHandlingMimeForPasting (line 8816) | static isHandlingMimeForPasting(mime) {
method paste (line 8819) | static paste(item, parent) {
method propertiesToUpdate (line 8822) | get propertiesToUpdate() {
method _isDraggable (line 8825) | get _isDraggable() {
method _isDraggable (line 8828) | set _isDraggable(value) {
method isEnterHandled (line 8832) | get isEnterHandled() {
method center (line 8835) | center() {
method addCommands (line 8857) | addCommands(params) {
method currentLayer (line 8860) | get currentLayer() {
method setInBackground (line 8863) | setInBackground() {
method setInForeground (line 8866) | setInForeground() {
method setParent (line 8869) | setParent(parent) {
method focusin (line 8878) | focusin(event) {
method focusout (line 8888) | focusout(event) {
method commitOrRemove (line 8904) | commitOrRemove() {
method commit (line 8911) | commit() {
method addToAnnotationStorage (line 8914) | addToAnnotationStorage() {
method setAt (line 8917) | setAt(x, y, tx, ty) {
method #translate (line 8924) | #translate([width, height], x, y) {
method translate (line 8930) | translate(x, y) {
method translateInPage (line 8933) | translateInPage(x, y) {
method drag (line 8940) | drag(tx, ty) {
method _hasBeenMoved (line 8968) | get _hasBeenMoved() {
method getBaseTranslation (line 8971) | getBaseTranslation() {
method _mustFixPosition (line 8989) | get _mustFixPosition() {
method fixAndSetPosition (line 8992) | fixAndSetPosition(rotation = this.rotation) {
method #rotatePoint (line 9036) | static #rotatePoint(x, y, angle) {
method screenToPageTranslation (line 9048) | screenToPageTranslation(x, y) {
method pageTranslationToScreen (line 9051) | pageTranslationToScreen(x, y) {
method #getRotationMatrix (line 9054) | #getRotationMatrix(rotation) {
method parentScale (line 9072) | get parentScale() {
method parentRotation (line 9075) | get parentRotation() {
method parentDimensions (line 9078) | get parentDimensions() {
method setDims (line 9085) | setDims(width, height) {
method fixDims (line 9092) | fixDims() {
method getInitialTranslation (line 9113) | getInitialTranslation() {
method #createResizers (line 9116) | #createResizers() {
method #resizerPointerdown (line 9139) | #resizerPointerdown(name, event) {
method #addResizeToUndoStack (line 9184) | #addResizeToUndoStack(savedX, savedY, savedWidth, savedHeight) {
method #resizerPointermove (line 9214) | #resizerPointermove(name, event) {
method altTextFinish (line 9300) | altTextFinish() {
method addEditToolbar (line 9303) | async addEditToolbar() {
method removeEditToolbar (line 9314) | removeEditToolbar() {
method addContainer (line 9322) | addContainer(container) {
method getClientDimensions (line 9330) | getClientDimensions() {
method addAltTextButton (line 9333) | async addAltTextButton() {
method altTextData (line 9345) | get altTextData() {
method altTextData (line 9348) | set altTextData(data) {
method guessedAltText (line 9354) | get guessedAltText() {
method setGuessedAltText (line 9357) | async setGuessedAltText(text) {
method serializeAltText (line 9360) | serializeAltText(isForCopying) {
method hasAltText (line 9363) | hasAltText() {
method hasAltTextData (line 9366) | hasAltTextData() {
method render (line 9369) | render() {
method pointerdown (line 9390) | pointerdown(event) {
method #selectOnPointerEvent (line 9405) | #selectOnPointerEvent(event) {
method #setUpDragSession (line 9415) | #setUpDragSession(event) {
method moveInDOM (line 9457) | moveInDOM() {
method _setParentAndPosition (line 9466) | _setParentAndPosition(parent, x, y) {
method getRect (line 9472) | getRect(tx, ty, rotation = this.rotation) {
method getRectInCurrentCoords (line 9495) | getRectInCurrentCoords(rect, pageHeight) {
method onceAdded (line 9512) | onceAdded() {}
method isEmpty (line 9513) | isEmpty() {
method enableEditMode (line 9516) | enableEditMode() {
method disableEditMode (line 9519) | disableEditMode() {
method isInEditMode (line 9522) | isInEditMode() {
method shouldGetKeyboardEvents (line 9525) | shouldGetKeyboardEvents() {
method needsToBeRebuilt (line 9528) | needsToBeRebuilt() {
method #addFocusListeners (line 9531) | #addFocusListeners() {
method rebuild (line 9544) | rebuild() {
method rotate (line 9547) | rotate(_angle) {}
method serializeDeleted (line 9548) | serializeDeleted() {
method serialize (line 9556) | serialize(isForCopying = false, context = null) {
method deserialize (line 9559) | static async deserialize(data, parent, uiManager) {
method hasBeenModified (line 9575) | get hasBeenModified() {
method remove (line 9578) | remove() {
method isResizable (line 9603) | get isResizable() {
method makeResizable (line 9606) | makeResizable() {
method toolbarPosition (line 9613) | get toolbarPosition() {
method keydown (line 9616) | keydown(event) {
method #resizerKeydown (line 9682) | #resizerKeydown(event) {
method #resizerBlur (line 9685) | #resizerBlur(event) {
method #resizerFocus (line 9690) | #resizerFocus(name) {
method #setResizerTabIndex (line 9693) | #setResizerTabIndex(value) {
method _resizeWithKeyboard (line 9701) | _resizeWithKeyboard(x, y) {
method #stopResizing (line 9710) | #stopResizing() {
method _stopResizingWithKeyboard (line 9724) | _stopResizingWithKeyboard() {
method select (line 9728) | select() {
method unselect (line 9742) | unselect() {
method updateParams (line 9753) | updateParams(type, value) {}
method disableEditing (line 9754) | disableEditing() {}
method enableEditing (line 9755) | enableEditing() {}
method enterInEditMode (line 9756) | enterInEditMode() {}
method getImageForAltText (line 9757) | getImageForAltText() {
method contentDiv (line 9760) | get contentDiv() {
method isEditing (line 9763) | get isEditing() {
method isEditing (line 9766) | set isEditing(value) {
method setAspectRatio (line 9778) | setAspectRatio(width, height) {
method MIN_SIZE (line 9787) | static get MIN_SIZE() {
method canCreateNewEmptyEditor (line 9790) | static canCreateNewEmptyEditor() {
method telemetryInitialData (line 9793) | get telemetryInitialData() {
method telemetryFinalData (line 9798) | get telemetryFinalData() {
method _reportTelemetry (line 9801) | _reportTelemetry(data, mustWait = false) {
method show (line 9830) | show(visible = this._isVisible) {
method enable (line 9834) | enable() {
method disable (line 9840) | disable() {
method renderAnnotationElement (line 9846) | renderAnnotationElement(annotation) {
method resetAnnotationElement (line 9860) | resetAnnotationElement(annotation) {
class FakeEditor (line 9869) | class FakeEditor extends AnnotationEditor {
method constructor (line 9870) | constructor(params) {
method serialize (line 9875) | serialize() {
constant SEED (line 9887) | const SEED = 0xc3d2e1f0;
constant MASK_HIGH (line 9888) | const MASK_HIGH = 0xffff0000;
constant MASK_LOW (line 9889) | const MASK_LOW = 0xffff;
class MurmurHash3_64 (line 9890) | class MurmurHash3_64 {
method constructor (line 9891) | constructor(seed) {
method update (line 9895) | update(input) {
method hexdigest (line 9965) | hexdigest() {
class AnnotationStorage (line 9998) | class AnnotationStorage {
method constructor (line 10002) | constructor() {
method getValue (line 10007) | getValue(key, defaultValue) {
method getRawValue (line 10014) | getRawValue(key) {
method remove (line 10017) | remove(key) {
method setValue (line 10031) | setValue(key, value) {
method has (line 10052) | has(key) {
method getAll (line 10055) | getAll() {
method setAll (line 10058) | setAll(obj) {
method size (line 10063) | get size() {
method #setModified (line 10066) | #setModified() {
method resetModified (line 10074) | resetModified() {
method print (line 10082) | get print() {
method serializable (line 10085) | get serializable() {
method editorStats (line 10115) | get editorStats() {
method resetModifiedIds (line 10152) | resetModifiedIds() {
method modifiedIds (line 10155) | get modifiedIds() {
class PrintAnnotationStorage (line 10172) | class PrintAnnotationStorage extends AnnotationStorage {
method constructor (line 10174) | constructor(parent) {
method print (line 10190) | get print() {
method serializable (line 10193) | get serializable() {
method modifiedIds (line 10196) | get modifiedIds() {
class FontLoader (line 10215) | class FontLoader {
method constructor (line 10217) | constructor({
method addNativeFontFace (line 10227) | addNativeFontFace(nativeFontFace) {
method removeNativeFontFace (line 10231) | removeNativeFontFace(nativeFontFace) {
method insertRule (line 10235) | insertRule(rule) {
method clear (line 10243) | clear() {
method loadSystemFont (line 10254) | async loadSystemFont({
method bind (line 10282) | async bind(font) {
method isFontLoadingAPISupported (line 10317) | get isFontLoadingAPISupported() {
method isSyncFontLoadingSupported (line 10321) | get isSyncFontLoadingSupported() {
method _queueLoadingCallback (line 10330) | _queueLoadingCallback(callback) {
method _loadTestFont (line 10350) | get _loadTestFont() {
method _prepareFontLoadEvent (line 10354) | _prepareFontLoadEvent(font, request) {
class FontFaceObject (line 10419) | class FontFaceObject {
method constructor (line 10420) | constructor(translatedData, {
method createNativeFontFace (line 10431) | createNativeFontFace() {
method createFontFaceRule (line 10450) | createFontFaceRule() {
method getPathGenerator (line 10469) | getPathGenerator(objs, character) {
class NodePackages (line 10611) | class NodePackages {
method promise (line 10612) | static get promise() {
method get (line 10615) | static get(name) {
class NodeFilterFactory (line 10623) | class NodeFilterFactory extends BaseFilterFactory {}
class NodeCanvasFactory (line 10624) | class NodeCanvasFactory extends BaseCanvasFactory {
method _createCanvas (line 10625) | _createCanvas(width, height) {
class NodeCMapReaderFactory (line 10630) | class NodeCMapReaderFactory extends BaseCMapReaderFactory {
method _fetchData (line 10631) | _fetchData(url, compressionType) {
class NodeStandardFontDataFactory (line 10638) | class NodeStandardFontDataFactory extends BaseStandardFontDataFactory {
method _fetchData (line 10639) | _fetchData(url) {
function applyBoundingBox (line 10652) | function applyBoundingBox(ctx, bbox) {
class BaseShadingPattern (line 10662) | class BaseShadingPattern {
method getPattern (line 10663) | getPattern() {
class RadialAxialShadingPattern (line 10667) | class RadialAxialShadingPattern extends BaseShadingPattern {
method constructor (line 10668) | constructor(IR) {
method _createGradient (line 10679) | _createGradient(ctx) {
method getPattern (line 10691) | getPattern(ctx, owner, inverse, pathType) {
function drawTriangle (line 10721) | function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {
function drawFigure (line 10823) | function drawFigure(data, figure, context) {
class MeshShadingPattern (line 10849) | class MeshShadingPattern extends BaseShadingPattern {
method constructor (line 10850) | constructor(IR) {
method _createMeshCanvas (line 10860) | _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) {
method getPattern (line 10907) | getPattern(ctx, owner, inverse, pathType) {
class DummyShadingPattern (line 10931) | class DummyShadingPattern extends BaseShadingPattern {
method getPattern (line 10932) | getPattern() {
function getShadingPattern (line 10936) | function getShadingPattern(IR) {
class TilingPattern (line 10951) | class TilingPattern {
method constructor (line 10953) | constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) {
method createPatternCanvas (line 10966) | createPatternCanvas(owner) {
method getSizeAndScale (line 11062) | getSizeAndScale(step, realOutputSize, scale) {
method clipBbox (line 11075) | clipBbox(graphics, x0, y0, x1, y1) {
method setFillAndStrokeStyleToContext (line 11083) | setFillAndStrokeStyleToContext(graphics, paintType, color) {
method getPattern (line 11105) | getPattern(ctx, owner, inverse, pathType) {
function convertToRGBA (line 11131) | function convertToRGBA(params) {
function convertBlackAndWhiteToRGBA (line 11140) | function convertBlackAndWhiteToRGBA({
function convertRGBToRGBA (line 11181) | function convertRGBToRGBA({
function grayToRGBA (line 11224) | function grayToRGBA(src, dest) {
constant MIN_FONT_SIZE (line 11252) | const MIN_FONT_SIZE = 16;
constant MAX_FONT_SIZE (line 11253) | const MAX_FONT_SIZE = 100;
constant EXECUTION_TIME (line 11254) | const EXECUTION_TIME = 15;
constant EXECUTION_STEPS (line 11255) | const EXECUTION_STEPS = 10;
constant MAX_SIZE_TO_COMPILE (line 11256) | const MAX_SIZE_TO_COMPILE = 1000;
constant FULL_CHUNK_HEIGHT (line 11257) | const FULL_CHUNK_HEIGHT = 16;
function mirrorContextOperations (line 11258) | function mirrorContextOperations(ctx, destCtx) {
class CachedCanvases (line 11356) | class CachedCanvases {
method constructor (line 11357) | constructor(canvasFactory) {
method getCanvas (line 11361) | getCanvas(id, width, height) {
method delete (line 11372) | delete(id) {
method clear (line 11375) | clear() {
function drawImageAtIntegerCoords (line 11383) | function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, d...
function compileType3Glyph (line 11418) | function compileType3Glyph(imgData) {
class CanvasExtraState (line 11548) | class CanvasExtraState {
method constructor (line 11549) | constructor(width, height) {
method clone (line 11576) | clone() {
method setCurrentPoint (line 11581) | setCurrentPoint(x, y) {
method updatePathMinMax (line 11585) | updatePathMinMax(transform, x, y) {
method updateRectMinMax (line 11592) | updateRectMinMax(transform, rect) {
method updateScalingPathMinMax (line 11602) | updateScalingPathMinMax(transform, minMax) {
method updateCurvePathMinMax (line 11609) | updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMa...
method getPathBoundingBox (line 11616) | getPathBoundingBox(pathType = PathType.FILL, transform = null) {
method updateClipFromPath (line 11632) | updateClipFromPath() {
method isEmptyClip (line 11636) | isEmptyClip() {
method startNewPathAndClipBox (line 11639) | startNewPathAndClipBox(box) {
method getClippedPathBoundingBox (line 11646) | getClippedPathBoundingBox(pathType = PathType.FILL, transform = null) {
function putBinaryImageData (line 11650) | function putBinaryImageData(ctx, imgData) {
function putBinaryImageMask (line 11743) | function putBinaryImageMask(ctx, imgData) {
function copyCtxState (line 11772) | function copyCtxState(sourceCtx, destCtx) {
function resetCtxToDefault (line 11784) | function resetCtxToDefault(ctx) {
function getImageSmoothingEnabled (line 11807) | function getImageSmoothingEnabled(transform, interpolate) {
constant LINE_CAP_STYLES (line 11817) | const LINE_CAP_STYLES = ["butt", "round", "square"];
constant LINE_JOIN_STYLES (line 11818) | const LINE_JOIN_STYLES = ["miter", "round", "bevel"];
constant NORMAL_CLIP (line 11819) | const NORMAL_CLIP = {};
constant EO_CLIP (line 11820) | const EO_CLIP = {};
class CanvasGraphics (line 11821) | class CanvasGraphics {
method constructor (line 11822) | constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, {
method getObject (line 11860) | getObject(data, fallback = null) {
method beginDrawing (line 11866) | beginDrawing({
method executeOperatorList (line 11897) | executeOperatorList(operatorList, executionStartIdx, continueCallback,...
method #restoreInitialState (line 11941) | #restoreInitialState() {
method endDrawing (line 11956) | endDrawing() {
method #drawFilter (line 11971) | #drawFilter() {
method _scaleImage (line 11982) | _scaleImage(img, inverseTransform) {
method _createMaskCanvas (line 12017) | _createMaskCanvas(img) {
method setLineWidth (line 12085) | setLineWidth(width) {
method setLineCap (line 12092) | setLineCap(style) {
method setLineJoin (line 12095) | setLineJoin(style) {
method setMiterLimit (line 12098) | setMiterLimit(limit) {
method setDash (line 12101) | setDash(dashArray, dashPhase) {
method setRenderingIntent (line 12108) | setRenderingIntent(intent) {}
method setFlatness (line 12109) | setFlatness(flatness) {}
method setGState (line 12110) | setGState(states) {
method inSMaskMode (line 12158) | get inSMaskMode() {
method checkSMaskState (line 12161) | checkSMaskState() {
method beginSMaskMode (line 12169) | beginSMaskMode() {
method endSMaskMode (line 12185) | endSMaskMode() {
method compose (line 12194) | compose(dirtyBox) {
method composeSMask (line 12214) | composeSMask(ctx, smask, layerCtx, layerBox) {
method genericComposeSMask (line 12230) | genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdro...
method save (line 12275) | save() {
method restore (line 12286) | restore() {
method transform (line 12304) | transform(a, b, c, d, e, f) {
method constructPath (line 12309) | constructPath(ops, args, minMax) {
method closePath (line 12393) | closePath() {
method stroke (line 12396) | stroke(consumePath = true) {
method closeStroke (line 12415) | closeStroke() {
method fill (line 12419) | fill(consumePath = true) {
method eoFill (line 12445) | eoFill() {
method fillStroke (line 12449) | fillStroke() {
method eoFillStroke (line 12454) | eoFillStroke() {
method closeFillStroke (line 12458) | closeFillStroke() {
method closeEOFillStroke (line 12462) | closeEOFillStroke() {
method endPath (line 12467) | endPath() {
method clip (line 12470) | clip() {
method eoClip (line 12473) | eoClip() {
method beginText (line 12476) | beginText() {
method endText (line 12482) | endText() {
method setCharSpacing (line 12501) | setCharSpacing(spacing) {
method setWordSpacing (line 12504) | setWordSpacing(spacing) {
method setHScale (line 12507) | setHScale(scale) {
method setLeading (line 12510) | setLeading(leading) {
method setFont (line 12513) | setFont(fontRefName, size) {
method setTextRenderingMode (line 12552) | setTextRenderingMode(mode) {
method setTextRise (line 12555) | setTextRise(rise) {
method moveText (line 12558) | moveText(x, y) {
method setLeadingMoveText (line 12562) | setLeadingMoveText(x, y) {
method setTextMatrix (line 12566) | setTextMatrix(a, b, c, d, e, f) {
method nextLine (line 12572) | nextLine() {
method paintChar (line 12575) | paintChar(character, x, y, patternTransform) {
method isFontSubpixelAAEnabled (line 12622) | get isFontSubpixelAAEnabled() {
method showText (line 12638) | showText(glyphs) {
method showType3Text (line 12768) | showType3Text(glyphs) {
method setCharWidth (line 12821) | setCharWidth(xWidth, yWidth) {}
method setCharWidthAndBounds (line 12822) | setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) {
method getColorN_Pattern (line 12827) | getColorN_Pattern(IR) {
method setStrokeColorN (line 12844) | setStrokeColorN() {
method setFillColorN (line 12847) | setFillColorN() {
method setStrokeRGBColor (line 12851) | setStrokeRGBColor(r, g, b) {
method setStrokeTransparent (line 12854) | setStrokeTransparent() {
method setFillRGBColor (line 12857) | setFillRGBColor(r, g, b) {
method setFillTransparent (line 12861) | setFillTransparent() {
method _getPattern (line 12865) | _getPattern(objId, matrix = null) {
method shadingFill (line 12878) | shadingFill(objId) {
method beginInlineImage (line 12900) | beginInlineImage() {
method beginImageData (line 12903) | beginImageData() {
method paintFormXObjectBegin (line 12906) | paintFormXObjectBegin(matrix, bbox) {
method paintFormXObjectEnd (line 12925) | paintFormXObjectEnd() {
method beginGroup (line 12932) | beginGroup(group) {
method endGroup (line 12993) | endGroup(group) {
method beginAnnotation (line 13017) | beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) {
method endAnnotation (line 13065) | endAnnotation() {
method paintImageMaskXObject (line 13074) | paintImageMaskXObject(img) {
method paintImageMaskXObjectRepeat (line 13100) | paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY,...
method paintImageMaskXObjectGroup (line 13119) | paintImageMaskXObjectGroup(images) {
method paintImageXObject (line 13150) | paintImageXObject(objId) {
method paintImageXObjectRepeat (line 13161) | paintImageXObjectRepeat(objId, scaleX, scaleY, positions) {
method applyTransferMapsToCanvas (line 13184) | applyTransferMapsToCanvas(ctx) {
method applyTransferMapsToBitmap (line 13192) | applyTransferMapsToBitmap(imgData) {
method paintInlineImageXObject (line 13208) | paintInlineImageXObject(imgData) {
method paintInlineImageXObjectGroup (line 13242) | paintInlineImageXObjectGroup(imgData, map) {
method paintSolidColorImageMask (line 13267) | paintSolidColorImageMask() {
method markPoint (line 13274) | markPoint(tag) {}
method markPointProps (line 13275) | markPointProps(tag, properties) {}
method beginMarkedContent (line 13276) | beginMarkedContent(tag) {
method beginMarkedContentProps (line 13281) | beginMarkedContentProps(tag, properties) {
method endMarkedContent (line 13293) | endMarkedContent() {
method beginCompat (line 13297) | beginCompat() {}
method endCompat (line 13298) | endCompat() {}
method consumePath (line 13299) | consumePath(clipBox) {
method getSinglePixelWidth (line 13321) | getSinglePixelWidth() {
method getScaleForStroking (line 13335) | getScaleForStroking() {
method rescaleAndStroke (line 13384) | rescaleAndStroke(saveRestore) {
method isContentVisible (line 13412) | isContentVisible() {
class GlobalWorkerOptions (line 13428) | class GlobalWorkerOptions {
method workerPort (line 13431) | static get workerPort() {
method workerPort (line 13434) | static set workerPort(val) {
method workerSrc (line 13440) | static get workerSrc() {
method workerSrc (line 13443) | static set workerSrc(val) {
function wrapReason (line 13470) | function wrapReason(reason) {
class MessageHandler (line 13489) | class MessageHandler {
method constructor (line 13490) | constructor(sourceName, targetName, comObj) {
method on (line 13561) | on(actionName, handler) {
method send (line 13568) | send(actionName, data, transfers) {
method sendWithPromise (line 13576) | sendWithPromise(actionName, data, transfers) {
method sendWithStream (line 13593) | sendWithStream(actionName, data, queueingStrategy, transfers) {
method #createStreamSink (line 13646) | #createStreamSink(data) {
method #processStreamMessage (line 13729) | #processStreamMessage(data) {
method #deleteStreamController (line 13846) | async #deleteStreamController(streamController, streamId) {
method destroy (line 13850) | destroy() {
class Metadata (line 13857) | class Metadata {
method constructor (line 13860) | constructor({
method getRaw (line 13867) | getRaw() {
method get (line 13870) | get(name) {
method getAll (line 13873) | getAll() {
method has (line 13876) | has(name) {
constant INTERNAL (line 13884) | const INTERNAL = Symbol("INTERNAL");
class OptionalContentGroup (line 13885) | class OptionalContentGroup {
method constructor (line 13890) | constructor(renderingIntent, {
method visible (line 13901) | get visible() {
method _setVisible (line 13919) | _setVisible(internal, visible, userSet = false) {
class OptionalContentConfig (line 13927) | class OptionalContentConfig {
method constructor (line 13932) | constructor(data, renderingIntent = RenderingIntentFlag.DISPLAY) {
method #evaluateVisibilityExpression (line 13958) | #evaluateVisibilityExpression(array) {
method isVisible (line 13994) | isVisible(group) {
method setVisibility (line 14063) | setVisibility(id, visible = true) {
method setOCGState (line 14072) | setOCGState({
method hasInitialVisibility (line 14103) | get hasInitialVisibility() {
method getOrder (line 14106) | getOrder() {
method getGroups (line 14115) | getGroups() {
method getGroup (line 14118) | getGroup(id) {
method getHash (line 14121) | getHash() {
class PDFDataTransportStream (line 14146) | class PDFDataTransportStream {
method constructor (line 14147) | constructor(pdfDataRangeTransport, {
method _onReceiveData (line 14193) | _onReceiveData({
method _progressiveDataLength (line 14215) | get _progressiveDataLength() {
method _onProgress (line 14218) | _onProgress(evt) {
method _onProgressiveDone (line 14230) | _onProgressiveDone() {
method _removeRangeReader (line 14234) | _removeRangeReader(reader) {
method getFullReader (line 14240) | getFullReader() {
method getRangeReader (line 14246) | getRangeReader(begin, end) {
method cancelAllRequests (line 14255) | cancelAllRequests(reason) {
class PDFDataTransportStreamReader (line 14263) | class PDFDataTransportStreamReader {
method constructor (line 14264) | constructor(stream, queuedChunks, progressiveDone = false, contentDisp...
method _enqueue (line 14278) | _enqueue(chunk) {
method headersReady (line 14293) | get headersReady() {
method filename (line 14296) | get filename() {
method isRangeSupported (line 14299) | get isRangeSupported() {
method isStreamingSupported (line 14302) | get isStreamingSupported() {
method contentLength (line 14305) | get contentLength() {
method read (line 14308) | async read() {
method cancel (line 14326) | cancel(reason) {
method progressiveDone (line 14336) | progressiveDone() {
class PDFDataTransportStreamRangeReader (line 14343) | class PDFDataTransportStreamRangeReader {
method constructor (line 14344) | constructor(stream, begin, end) {
method _enqueue (line 14353) | _enqueue(chunk) {
method isStreamingSupported (line 14376) | get isStreamingSupported() {
method read (line 14379) | async read() {
method cancel (line 14398) | cancel(reason) {
function getFilenameFromContentDispositionHeader (line 14415) | function getFilenameFromContentDispositionHeader(contentDisposition) {
function createHeaders (line 14548) | function createHeaders(isHttp, httpHeaders) {
function validateRangeRequestCapabilities (line 14561) | function validateRangeRequestCapabilities({
function extractFilenameFromHeader (line 14592) | function extractFilenameFromHeader(responseHeaders) {
function createResponseStatusError (line 14607) | function createResponseStatusError(status, url) {
function validateResponseStatus (line 14613) | function validateResponseStatus(status) {
function createFetchOptions (line 14628) | function createFetchOptions(headers, withCredentials, abortController) {
function getArrayBuffer (line 14638) | function getArrayBuffer(val) {
class PDFFetchStream (line 14648) | class PDFFetchStream {
method constructor (line 14649) | constructor(source) {
method _progressiveDataLength (line 14656) | get _progressiveDataLength() {
method getFullReader (line 14659) | getFullReader() {
method getRangeReader (line 14664) | getRangeReader(begin, end) {
method cancelAllRequests (line 14672) | cancelAllRequests(reason) {
class PDFFetchStreamReader (line 14679) | class PDFFetchStreamReader {
method constructor (line 14680) | constructor(stream) {
method headersReady (line 14724) | get headersReady() {
method filename (line 14727) | get filename() {
method contentLength (line 14730) | get contentLength() {
method isRangeSupported (line 14733) | get isRangeSupported() {
method isStreamingSupported (line 14736) | get isStreamingSupported() {
method read (line 14739) | async read() {
method cancel (line 14761) | cancel(reason) {
class PDFFetchStreamRangeReader (line 14766) | class PDFFetchStreamRangeReader {
method constructor (line 14767) | constructor(stream, begin, end) {
method isStreamingSupported (line 14788) | get isStreamingSupported() {
method read (line 14791) | async read() {
method cancel (line 14812) | cancel(reason) {
constant OK_RESPONSE (line 14824) | const OK_RESPONSE = 200;
constant PARTIAL_CONTENT_RESPONSE (line 14825) | const PARTIAL_CONTENT_RESPONSE = 206;
function network_getArrayBuffer (line 14826) | function network_getArrayBuffer(xhr) {
class NetworkManager (line 14833) | class NetworkManager {
method constructor (line 14834) | constructor({
method requestRange (line 14846) | requestRange(begin, end, listeners) {
method requestFull (line 14856) | requestFull(listeners) {
method request (line 14859) | request(args) {
method onProgress (line 14891) | onProgress(xhrId, evt) {
method onStateChange (line 14898) | onStateChange(xhrId, evt) {
method getRequestXhr (line 14942) | getRequestXhr(xhrId) {
method isPendingRequest (line 14945) | isPendingRequest(xhrId) {
method abortRequest (line 14948) | abortRequest(xhrId) {
class PDFNetworkStream (line 14954) | class PDFNetworkStream {
method constructor (line 14955) | constructor(source) {
method _onRangeRequestReaderClosed (line 14962) | _onRangeRequestReaderClosed(reader) {
method getFullReader (line 14968) | getFullReader() {
method getRangeReader (line 14973) | getRangeReader(begin, end) {
method cancelAllRequests (line 14979) | cancelAllRequests(reason) {
class PDFNetworkStreamFullRequestReader (line 14986) | class PDFNetworkStreamFullRequestReader {
method constructor (line 14987) | constructor(manager, source) {
method _onHeadersReceived (line 15013) | _onHeadersReceived() {
method _onDone (line 15039) | _onDone(data) {
method _onError (line 15063) | _onError(status) {
method _onProgress (line 15072) | _onProgress(evt) {
method filename (line 15078) | get filename() {
method isRangeSupported (line 15081) | get isRangeSupported() {
method isStreamingSupported (line 15084) | get isStreamingSupported() {
method contentLength (line 15087) | get contentLength() {
method headersReady (line 15090) | get headersReady() {
method read (line 15093) | async read() {
method cancel (line 15114) | cancel(reason) {
class PDFNetworkStreamRangeRequestReader (line 15130) | class PDFNetworkStreamRangeRequestReader {
method constructor (line 15131) | constructor(manager, begin, end) {
method _close (line 15147) | _close() {
method _onDone (line 15150) | _onDone(data) {
method _onError (line 15171) | _onError(status) {
method _onProgress (line 15179) | _onProgress(evt) {
method isStreamingSupported (line 15186) | get isStreamingSupported() {
method read (line 15189) | async read() {
method cancel (line 15211) | cancel(reason) {
function parseUrlOrPath (line 15243) | function parseUrlOrPath(sourceUrl) {
function createRequest (line 15250) | function createRequest(url, headers, callback) {
class PDFNodeStream (line 15262) | class PDFNodeStream {
method constructor (line 15263) | constructor(source) {
method _progressiveDataLength (line 15272) | get _progressiveDataLength() {
method getFullReader (line 15275) | getFullReader() {
method getRangeReader (line 15280) | getRangeReader(start, end) {
method cancelAllRequests (line 15288) | cancelAllRequests(reason) {
class BaseFullReader (line 15295) | class BaseFullReader {
method constructor (line 15296) | constructor(stream) {
method headersReady (line 15316) | get headersReady() {
method filename (line 15319) | get filename() {
method contentLength (line 15322) | get contentLength() {
method isRangeSupported (line 15325) | get isRangeSupported() {
method isStreamingSupported (line 15328) | get isStreamingSupported() {
method read (line 15331) | async read() {
method cancel (line 15358) | cancel(reason) {
method _error (line 15365) | _error(reason) {
method _setReadableStream (line 15369) | _setReadableStream(readableStream) {
class BaseRangeReader (line 15390) | class BaseRangeReader {
method constructor (line 15391) | constructor(stream) {
method isStreamingSupported (line 15402) | get isStreamingSupported() {
method read (line 15405) | async read() {
method cancel (line 15431) | cancel(reason) {
method _error (line 15438) | _error(reason) {
method _setReadableStream (line 15442) | _setReadableStream(readableStream) {
class PDFNodeStreamFullReader (line 15460) | class PDFNodeStreamFullReader extends BaseFullReader {
method constructor (line 15461) | constructor(stream) {
class PDFNodeStreamRangeReader (line 15495) | class PDFNodeStreamRangeReader extends BaseRangeReader {
method constructor (line 15496) | constructor(stream, start, end) {
class PDFNodeStreamFsFullReader (line 15515) | class PDFNodeStreamFsFullReader extends BaseFullReader {
method constructor (line 15516) | constructor(stream) {
class PDFNodeStreamFsRangeReader (line 15532) | class PDFNodeStreamFsRangeReader extends BaseRangeReader {
method constructor (line 15533) | constructor(stream, start, end) {
constant MAX_TEXT_DIVS_TO_RENDER (line 15555) | const MAX_TEXT_DIVS_TO_RENDER = 100000;
constant DEFAULT_FONT_SIZE (line 15556) | const DEFAULT_FONT_SIZE = 30;
constant DEFAULT_FONT_ASCENT (line 15557) | const DEFAULT_FONT_ASCENT = 0.8;
class TextLayer (line 15558) | class TextLayer {
method constructor (line 15582) | constructor({
method fontFamilyMap (line 15624) | static get fontFamilyMap() {
method render (line 15631) | render() {
method update (line 15652) | update({
method cancel (line 15680) | cancel() {
method textDivs (line 15686) | get textDivs() {
method textContentItemsStr (line 15689) | get textContentItemsStr() {
method #processItems (line 15692) | #processItems(items) {
method #appendText (line 15723) | #appendText(geom) {
method #layout (line 15798) | #layout(params) {
method cleanup (line 15834) | static cleanup() {
method #getCtx (line 15846) | static #getCtx(lang = null) {
method #ensureCtxFont (line 15865) | static #ensureCtxFont(ctx, size, family) {
method #ensureMinFontSizeComputed (line 15874) | static #ensureMinFontSizeComputed() {
method #getAscent (line 15888) | static #getAscent(fontFamily, lang) {
class XfaText (line 15935) | class XfaText {
method textContent (line 15936) | static textContent(xfa) {
method shouldBuildText (line 15972) | static shouldBuildText(name) {
constant DEFAULT_RANGE_CHUNK_SIZE (line 16014) | const DEFAULT_RANGE_CHUNK_SIZE = 65536;
constant RENDERING_CANCELLED_TIMEOUT (line 16015) | const RENDERING_CANCELLED_TIMEOUT = 100;
constant DELAYED_CLEANUP_TIMEOUT (line 16016) | const DELAYED_CLEANUP_TIMEOUT = 5000;
function getDocument (line 16021) | function getDocument(src = {}) {
function getUrlProp (line 16186) | function getUrlProp(val) {
function getDataProp (line 16199) | function getDataProp(val) {
function isRefProxy (line 16214) | function isRefProxy(ref) {
class PDFDocumentLoadingTask (line 16217) | class PDFDocumentLoadingTask {
method constructor (line 16219) | constructor() {
method promise (line 16228) | get promise() {
method destroy (line 16231) | async destroy() {
class PDFDataRangeTransport (line 16251) | class PDFDataRangeTransport {
method constructor (line 16252) | constructor(length, initialData, progressiveDone = false, contentDispo...
method addRangeListener (line 16263) | addRangeListener(listener) {
method addProgressListener (line 16266) | addProgressListener(listener) {
method addProgressiveReadListener (line 16269) | addProgressiveReadListener(listener) {
method addProgressiveDoneListener (line 16272) | addProgressiveDoneListener(listener) {
method onDataRange (line 16275) | onDataRange(begin, chunk) {
method onDataProgress (line 16280) | onDataProgress(loaded, total) {
method onDataProgressiveRead (line 16287) | onDataProgressiveRead(chunk) {
method onDataProgressiveDone (line 16294) | onDataProgressiveDone() {
method transportReady (line 16301) | transportReady() {
method requestDataRange (line 16304) | requestDataRange(begin, end) {
method abort (line 16307) | abort() {}
class PDFDocumentProxy (line 16309) | class PDFDocumentProxy {
method constructor (line 16310) | constructor(pdfInfo, transport) {
method annotationStorage (line 16314) | get annotationStorage() {
method canvasFactory (line 16317) | get canvasFactory() {
method filterFactory (line 16320) | get filterFactory() {
method numPages (line 16323) | get numPages() {
method fingerprints (line 16326) | get fingerprints() {
method isPureXfa (line 16329) | get isPureXfa() {
method allXfaHtml (line 16332) | get allXfaHtml() {
method getPage (line 16335) | getPage(pageNumber) {
method getPageIndex (line 16338) | getPageIndex(ref) {
method getDestinations (line 16341) | getDestinations() {
method getDestination (line 16344) | getDestination(id) {
method getPageLabels (line 16347) | getPageLabels() {
method getPageLayout (line 16350) | getPageLayout() {
method getPageMode (line 16353) | getPageMode() {
method getViewerPreferences (line 16356) | getViewerPreferences() {
method getOpenAction (line 16359) | getOpenAction() {
method getAttachments (line 16362) | getAttachments() {
method getJSActions (line 16365) | getJSActions() {
method getOutline (line 16368) | getOutline() {
method getOptionalContentConfig (line 16371) | getOptionalContentConfig({
method getPermissions (line 16379) | getPermissions() {
method getMetadata (line 16382) | getMetadata() {
method getMarkInfo (line 16385) | getMarkInfo() {
method getData (line 16388) | getData() {
method saveDocument (line 16391) | saveDocument() {
method getDownloadInfo (line 16394) | getDownloadInfo() {
method cleanup (line 16397) | cleanup(keepLoadedFonts = false) {
method destroy (line 16400) | destroy() {
method cachedPageNumber (line 16403) | cachedPageNumber(ref) {
method loadingParams (line 16406) | get loadingParams() {
method loadingTask (line 16409) | get loadingTask() {
method getFieldObjects (line 16412) | getFieldObjects() {
method hasJSActions (line 16415) | hasJSActions() {
method getCalculationOrderIds (line 16418) | getCalculationOrderIds() {
class PDFPageProxy (line 16422) | class PDFPageProxy {
method constructor (line 16425) | constructor(pageIndex, pageInfo, transport, pdfBug = false) {
method pageNumber (line 16437) | get pageNumber() {
method rotate (line 16440) | get rotate() {
method ref (line 16443) | get ref() {
method userUnit (line 16446) | get userUnit() {
method view (line 16449) | get view() {
method getViewport (line 16452) | getViewport({
method getAnnotations (line 16468) | getAnnotations({
method getJSActions (line 16476) | getJSActions() {
method filterFactory (line 16479) | get filterFactory() {
method isPureXfa (line 16482) | get isPureXfa() {
method getXfa (line 16485) | async getXfa() {
method render (line 16488) | render({
method getOperatorList (line 16592) | getOperatorList({
method streamTextContent (line 16627) | streamTextContent({
method getTextContent (line 16643) | getTextContent(params = {}) {
method getStructTree (line 16673) | getStructTree() {
method _destroy (line 16676) | _destroy() {
method cleanup (line 16698) | cleanup(resetStats = false) {
method #tryCleanup (line 16706) | #tryCleanup(delayed = false) {
method #abortDelayedCleanup (line 16731) | #abortDelayedCleanup() {
method _startRenderPage (line 16737) | _startRenderPage(transparency, cacheKey) {
method _renderPageChunk (line 16745) | _renderPageChunk(operatorListChunk, intentState) {
method _pumpOperatorList (line 16759) | _pumpOperatorList({
method _abortOperatorList (line 16816) | _abortOperatorList({
method stats (line 16861) | get stats() {
class LoopbackPort (line 16865) | class LoopbackPort {
method postMessage (line 16868) | postMessage(obj, transfer) {
method addEventListener (line 16880) | addEventListener(name, listener) {
method removeEventListener (line 16883) | removeEventListener(name, listener) {
method terminate (line 16886) | terminate() {
class PDFWorker (line 16890) | class PDFWorker {
method constructor (line 16919) | constructor({
method promise (line 16941) | get promise() {
method #resolve (line 16947) | #resolve() {
method port (line 16953) | get port() {
method messageHandler (line 16956) | get messageHandler() {
method _initializeFromPort (line 16959) | _initializeFromPort(port) {
method _initialize (line 16965) | _initialize() {
method _setupFakeWorker (line 17033) | _setupFakeWorker() {
method destroy (line 17054) | destroy() {
method fromPort (line 17067) | static fromPort(params) {
method workerSrc (line 17080) | static get workerSrc() {
method #mainThreadWorkerMessageHandler (line 17086) | static get #mainThreadWorkerMessageHandler() {
method _setupFakeWorkerGlobal (line 17093) | static get _setupFakeWorkerGlobal() {
class WorkerTransport (line 17104) | class WorkerTransport {
method constructor (line 17110) | constructor(messageHandler, loadingTask, networkStream, params, factor...
method #cacheSimpleMethod (line 17132) | #cacheSimpleMethod(name, data = null) {
method annotationStorage (line 17141) | get annotationStorage() {
method getRenderingIntent (line 17144) | getRenderingIntent(intent, annotationMode = AnnotationMode.ENABLE, pri...
method destroy (line 17194) | destroy() {
method setupMessageHandler (line 17228) | setupMessageHandler() {
method getData (line 17505) | getData() {
method saveDocument (line 17508) | saveDocument() {
method getPage (line 17525) | getPage(pageNumber) {
method getPageIndex (line 17550) | getPageIndex(ref) {
method getAnnotations (line 17559) | getAnnotations(pageIndex, intent) {
method getFieldObjects (line 17565) | getFieldObjects() {
method hasJSActions (line 17568) | hasJSActions() {
method getCalculationOrderIds (line 17571) | getCalculationOrderIds() {
method getDestinations (line 17574) | getDestinations() {
method getDestination (line 17577) | getDestination(id) {
method getPageLabels (line 17585) | getPageLabels() {
method getPageLayout (line 17588) | getPageLayout() {
method getPageMode (line 17591) | getPageMode() {
method getViewerPreferences (line 17594) | getViewerPreferences() {
method getOpenAction (line 17597) | getOpenAction() {
method getAttachments (line 17600) | getAttachments() {
method getDocJSActions (line 17603) | getDocJSActions() {
method getPageJSActions (line 17606) | getPageJSActions(pageIndex) {
method getStructTree (line 17611) | getStructTree(pageIndex) {
method getOutline (line 17616) | getOutline() {
method getOptionalContentConfig (line 17619) | getOptionalContentConfig(renderingIntent) {
method getPermissions (line 17622) | getPermissions() {
method getMetadata (line 17625) | getMetadata() {
method getMarkInfo (line 17640) | getMarkInfo() {
method startCleanup (line 17643) | async startCleanup(keepLoadedFonts = false) {
method cachedPageNumber (line 17662) | cachedPageNumber(ref) {
constant INITIAL_DATA (line 17670) | const INITIAL_DATA = Symbol("INITIAL_DATA");
class PDFObjects (line 17671) | class PDFObjects {
method #ensureObj (line 17673) | #ensureObj(objId) {
method get (line 17679) | get(objId, callback = null) {
method has (line 17691) | has(objId) {
method resolve (line 17695) | resolve(objId, data = null) {
method clear (line 17700) | clear() {
method [Symbol.iterator] (line 17709) | *[Symbol.iterator]() {
class RenderTask (line 17721) | class RenderTask {
method constructor (line 17723) | constructor(internalRenderTask) {
method promise (line 17727) | get promise() {
method cancel (line 17730) | cancel(extraDelay = 0) {
method separateAnnots (line 17733) | get separateAnnots() {
class InternalRenderTask (line 17746) | class InternalRenderTask {
method constructor (line 17749) | constructor({
method completed (line 17788) | get completed() {
method initializeGraphics (line 17791) | initializeGraphics({
method cancel (line 17828) | cancel(error = null, extraDelay = 0) {
method operatorListChanged (line 17839) | operatorListChanged() {
method _continue (line 17850) | _continue() {
method _scheduleNext (line 17861) | _scheduleNext() {
method _next (line 17871) | async _next() {
function makeColorComp (line 17893) | function makeColorComp(n) {
function scaleAndClamp (line 17896) | function scaleAndClamp(x) {
class ColorConverters (line 17899) | class ColorConverters {
method CMYK_G (line 17900) | static CMYK_G([c, y, m, k]) {
method G_CMYK (line 17903) | static G_CMYK([g]) {
method G_RGB (line 17906) | static G_RGB([g]) {
method G_rgb (line 17909) | static G_rgb([g]) {
method G_HTML (line 17913) | static G_HTML([g]) {
method RGB_G (line 17917) | static RGB_G([r, g, b]) {
method RGB_rgb (line 17920) | static RGB_rgb(color) {
method RGB_HTML (line 17923) | static RGB_HTML(color) {
method T_HTML (line 17926) | static T_HTML() {
method T_rgb (line 17929) | static T_rgb() {
method CMYK_RGB (line 17932) | static CMYK_RGB([c, y, m, k]) {
method CMYK_rgb (line 17935) | static CMYK_rgb([c, y, m, k]) {
method CMYK_HTML (line 17938) | static CMYK_HTML(components) {
method RGB_CMYK (line 17942) | static RGB_CMYK([r, g, b]) {
class XfaLayer (line 17954) | class XfaLayer {
method setupStorage (line 17955) | static setupStorage(html, id, element, storage, intent) {
method setAttributes (line 18023) | static setAttributes({
method render (line 18071) | static render(parameters) {
method update (line 18156) | static update(parameters) {
constant DEFAULT_TAB_INDEX (line 18180) | const DEFAULT_TAB_INDEX = 1000;
function getRectDims (line 18183) | function getRectDims(rect) {
class AnnotationElementFactory (line 18189) | class AnnotationElementFactory {
method create (line 18190) | static create(parameters) {
class AnnotationElement (line 18250) | class AnnotationElement {
method constructor (line 18254) | constructor(parameters, {
method _hasPopupData (line 18279) | static _hasPopupData({
method _isEditable (line 18286) | get _isEditable() {
method hasPopupData (line 18289) | get hasPopupData() {
method updateEdited (line 18292) | updateEdited(params) {
method resetEdited (line 18307) | resetEdited() {
method #setRectEdited (line 18315) | #setRectEdited(rect) {
method _createContainer (line 18349) | _createContainer(ignoreBorder) {
method setRotation (line 18446) | setRotation(angle, container = this.container) {
method _commonActions (line 18470) | get _commonActions() {
method _dispatchEventFromSandbox (line 18548) | _dispatchEventFromSandbox(actions, jsEvent) {
method _setDefaultPropertiesFromJS (line 18555) | _setDefaultPropertiesFromJS(element) {
method _createQuadrilaterals (line 18578) | _createQuadrilaterals() {
method _createPopup (line 18648) | _createPopup() {
method render (line 18671) | render() {
method _getElementsByName (line 18674) | _getElementsByName(name, skipId = null) {
method show (line 18724) | show() {
method hide (line 18730) | hide() {
method getElementsToTriggerPopup (line 18736) | getElementsToTriggerPopup() {
method addHighlightArea (line 18739) | addHighlightArea() {
method _editOnDoubleClick (line 18749) | _editOnDoubleClick() {
class LinkAnnotationElement (line 18768) | class LinkAnnotationElement extends AnnotationElement {
method constructor (line 18769) | constructor(parameters, options = null) {
method render (line 18777) | render() {
method #setInternalLink (line 18819) | #setInternalLink() {
method _bindLink (line 18822) | _bindLink(link, destination) {
method _bindNamedAction (line 18834) | _bindNamedAction(link, action) {
method #bindAttachment (line 18842) | #bindAttachment(link, attachment, dest = null) {
method #bindSetOCGState (line 18853) | #bindSetOCGState(link, action) {
method _bindJSAction (line 18861) | _bindJSAction(link, data) {
method _bindResetFormAction (line 18885) | _bindResetFormAction(link, resetForm) {
class TextAnnotationElement (line 18988) | class TextAnnotationElement extends AnnotationElement {
method constructor (line 18989) | constructor(parameters) {
method render (line 18994) | render() {
class WidgetAnnotationElement (line 19009) | class WidgetAnnotationElement extends AnnotationElement {
method render (line 19010) | render() {
method showElementAndHideCanvas (line 19013) | showElementAndHideCanvas(element) {
method _getKeyModifier (line 19021) | _getKeyModifier(event) {
method _setEventListener (line 19024) | _setEventListener(element, elementData, baseName, eventName, valueGett...
method _setEventListeners (line 19065) | _setEventListeners(element, elementData, names, getter) {
method _setBackgroundColor (line 19082) | _setBackgroundColor(element) {
method _setTextStyle (line 19086) | _setTextStyle(element) {
method _setRequired (line 19111) | _setRequired(element, isRequired) {
class TextWidgetAnnotationElement (line 19120) | class TextWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 19121) | constructor(parameters) {
method setPropertyOnSiblings (line 19127) | setPropertyOnSiblings(base, key, value, keyInStorage) {
method render (line 19138) | render() {
class SignatureWidgetAnnotationElement (line 19438) | class SignatureWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 19439) | constructor(parameters) {
class CheckboxWidgetAnnotationElement (line 19445) | class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 19446) | constructor(parameters) {
method render (line 19451) | render() {
class RadioButtonWidgetAnnotationElement (line 19519) | class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 19520) | constructor(parameters) {
method render (line 19525) | render() {
class PushButtonWidgetAnnotationElement (line 19602) | class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
method constructor (line 19603) | constructor(parameters) {
method render (line 19608) | render() {
class ChoiceWidgetAnnotationElement (line 19621) | class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
method constructor (line 19622) | constructor(parameters) {
method render (line 19627) | render() {
class PopupAnnotationElement (line 19843) | class PopupAnnotationElement extends AnnotationElement {
method constructor (line 19844) | constructor(parameters) {
method render (line 19855) | render() {
class PopupElement (line 19880) | class PopupElement {
method constructor (line 19900) | constructor({
method render (line 19938) | render() {
method #html (line 19985) | get #html() {
method #fontSize (line 19993) | get #fontSize() {
method #fontColor (line 19996) | get #fontColor() {
method #makePopupContent (line 19999) | #makePopupContent(text) {
method _formatContents (line 20029) | _formatContents({
method #keyDown (line 20046) | #keyDown(event) {
method updateEdited (line 20054) | updateEdited({
method resetEdited (line 20072) | resetEdited() {
method #setPosition (line 20085) | #setPosition() {
method #toggle (line 20123) | #toggle() {
method #show (line 20135) | #show() {
method #hide (line 20147) | #hide() {
method forceHide (line 20155) | forceHide() {
method maybeShow (line 20162) | maybeShow() {
method isVisible (line 20172) | get isVisible() {
class FreeTextAnnotationElement (line 20176) | class FreeTextAnnotationElement extends AnnotationElement {
method constructor (line 20177) | constructor(parameters) {
method render (line 20186) | render() {
class LineAnnotationElement (line 20206) | class LineAnnotationElement extends AnnotationElement {
method constructor (line 20208) | constructor(parameters) {
method render (line 20214) | render() {
method getElementsToTriggerPopup (line 20237) | getElementsToTriggerPopup() {
method addHighlightArea (line 20240) | addHighlightArea() {
class SquareAnnotationElement (line 20244) | class SquareAnnotationElement extends AnnotationElement {
method constructor (line 20246) | constructor(parameters) {
method render (line 20252) | render() {
method getElementsToTriggerPopup (line 20276) | getElementsToTriggerPopup() {
method addHighlightArea (line 20279) | addHighlightArea() {
class CircleAnnotationElement (line 20283) | class CircleAnnotationElement extends AnnotationElement {
method constructor (line 20285) | constructor(parameters) {
method render (line 20291) | render() {
method getElementsToTriggerPopup (line 20315) | getElementsToTriggerPopup() {
method addHighlightArea (line 20318) | addHighlightArea() {
class PolylineAnnotationElement (line 20322) | class PolylineAnnotationElement extends AnnotationElement {
method constructor (line 20324) | constructor(parameters) {
method render (line 20332) | render() {
method getElementsToTriggerPopup (line 20369) | getElementsToTriggerPopup() {
method addHighlightArea (line 20372) | addHighlightArea() {
class PolygonAnnotationElement (line 20376) | class PolygonAnnotationElement extends PolylineAnnotationElement {
method constructor (line 20377) | constructor(parameters) {
class CaretAnnotationElement (line 20383) | class CaretAnnotationElement extends AnnotationElement {
method constructor (line 20384) | constructor(parameters) {
method render (line 20390) | render() {
class InkAnnotationElement (line 20398) | class InkAnnotationElement extends AnnotationElement {
method constructor (line 20400) | constructor(parameters) {
method render (line 20409) | render() {
method getElementsToTriggerPopup (line 20447) | getElementsToTriggerPopup() {
method addHighlightArea (line 20450) | addHighlightArea() {
class HighlightAnnotationElement (line 20454) | class HighlightAnnotationElement extends AnnotationElement {
method constructor (line 20455) | constructor(parameters) {
method render (line 20463) | render() {
class UnderlineAnnotationElement (line 20472) | class UnderlineAnnotationElement extends AnnotationElement {
method constructor (line 20473) | constructor(parameters) {
method render (line 20480) | render() {
class SquigglyAnnotationElement (line 20488) | class SquigglyAnnotationElement extends AnnotationElement {
method constructor (line 20489) | constructor(parameters) {
method render (line 20496) | render() {
class StrikeOutAnnotationElement (line 20504) | class StrikeOutAnnotationElement extends AnnotationElement {
method constructor (line 20505) | constructor(parameters) {
method render (line 20512) | render() {
class StampAnnotationElement (line 20520) | class StampAnnotationElement extends AnnotationElement {
method constructor (line 20521) | constructor(parameters) {
method render (line 20528) | render() {
class FileAttachmentAnnotationElement (line 20538) | class FileAttachmentAnnotationElement extends AnnotationElement {
method constructor (line 20540) | constructor(parameters) {
method render (line 20554) | render() {
method getElementsToTriggerPopup (line 20588) | getElementsToTriggerPopup() {
method addHighlightArea (line 20591) | addHighlightArea() {
method #download (line 20594) | #download() {
class AnnotationLayer (line 20598) | class AnnotationLayer {
method constructor (line 20603) | constructor({
method hasEditableAnnotations (line 20621) | hasEditableAnnotations() {
method #appendElement (line 20624) | async #appendElement(element, id) {
method render (line 20636) | async render(params) {
method update (line 20703) | update({
method #setAnnotationCanvasMap (line 20714) | #setAnnotationCanvasMap() {
method getEditableAnnotations (line 20740) | getEditableAnnotations() {
method getEditableAnnotation (line 20743) | getEditableAnnotation(id) {
constant EOL_PATTERN (line 20756) | const EOL_PATTERN = /\r\n?|\n/g;
class FreeTextEditor (line 20757) | class FreeTextEditor extends AnnotationEditor {
method _keyboardManager (line 20767) | static get _keyboardManager() {
method constructor (line 20802) | constructor(params) {
method initialize (line 20810) | static initialize(l10n, uiManager) {
method updateDefaultParams (line 20817) | static updateDefaultParams(type, value) {
method updateParams (line 20827) | updateParams(type, value) {
method defaultPropertiesToUpdate (line 20837) | static get defaultPropertiesToUpdate() {
method propertiesToUpdate (line 20840) | get propertiesToUpdate() {
method #updateFontSize (line 20843) | #updateFontSize(fontSize) {
method #updateColor (line 20861) | #updateColor(color) {
method _translateEmpty (line 20876) | _translateEmpty(x, y) {
method getInitialTranslation (line 20879) | getInitialTranslation() {
method rebuild (line 20883) | rebuild() {
method enableEditMode (line 20895) | enableEditMode() {
method disableEditMode (line 20924) | disableEditMode() {
method focusin (line 20942) | focusin(event) {
method onceAdded (line 20951) | onceAdded() {
method isEmpty (line 20962) | isEmpty() {
method remove (line 20965) | remove() {
method #extractText (line 20973) | #extractText() {
method #setEditorDimensions (line 20986) | #setEditorDimensions() {
method commit (line 21015) | commit() {
method shouldGetKeyboardEvents (line 21047) | shouldGetKeyboardEvents() {
method enterInEditMode (line 21050) | enterInEditMode() {
method dblclick (line 21054) | dblclick(event) {
method keydown (line 21057) | keydown(event) {
method editorDivKeydown (line 21063) | editorDivKeydown(event) {
method editorDivFocus (line 21066) | editorDivFocus(event) {
method editorDivBlur (line 21069) | editorDivBlur(event) {
method editorDivInput (line 21072) | editorDivInput(event) {
method disableEditing (line 21075) | disableEditing() {
method enableEditing (line 21079) | enableEditing() {
method render (line 21083) | render() {
method #getNodeContent (line 21155) | static #getNodeContent(node) {
method editorDivPaste (line 21158) | editorDivPaste(event) {
method #setContent (line 21234) | #setContent() {
method #serializeContent (line 21245) | #serializeContent() {
method #deserializeContent (line 21248) | static #deserializeContent(content) {
method contentDiv (line 21251) | get contentDiv() {
method deserialize (line 21254) | static async deserialize(data, parent, uiManager) {
method serialize (line 21301) | serialize(isForCopying = false) {
method #hasElementChanged (line 21330) | #hasElementChanged(serialized) {
method renderAnnotationElement (line 21339) | renderAnnotationElement(annotation) {
method resetAnnotationElement (line 21362) | resetAnnotationElement(annotation) {
class Outliner (line 21384) | class Outliner {
method constructor (line 21388) | constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {
method getOutlines (line 21433) | getOutlines() {
method #getOutlines (line 21447) | #getOutlines(outlineVerticalEdges) {
method #binarySearch (line 21494) | #binarySearch(y) {
method #insert (line 21512) | #insert([, y1, y2]) {
method #remove (line 21516) | #remove([, y1, y2]) {
method #breakEdge (line 21539) | #breakEdge(edge) {
class Outline (line 21572) | class Outline {
method toSVGPath (line 21573) | toSVGPath() {
method box (line 21576) | get box() {
method serialize (line 21579) | serialize(_bbox, _rotation) {
method free (line 21582) | get free() {
class HighlightOutline (line 21586) | class HighlightOutline extends Outline {
method constructor (line 21589) | constructor(outlines, box) {
method toSVGPath (line 21594) | toSVGPath() {
method serialize (line 21614) | serialize([blX, blY, trX, trY], _rotation) {
method box (line 21628) | get box() {
class FreeOutliner (line 21632) | class FreeOutliner {
method constructor (line 21649) | constructor({
method free (line 21663) | get free() {
method isEmpty (line 21666) | isEmpty() {
method #getLastCoords (line 21669) | #getLastCoords() {
method add (line 21675) | add({
method toSVGPath (line 21733) | toSVGPath() {
method getOutlines (line 21766) | getOutlines() {
class FreeHighlightOutline (line 21814) | class FreeHighlightOutline extends Outline {
method constructor (line 21822) | constructor(outline, points, box, scaleFactor, innerMargin, isLTR) {
method toSVGPath (line 21846) | toSVGPath() {
method serialize (line 21858) | serialize([blX, blY, trX, trY], rotation) {
method #rescale (line 21886) | #rescale(src, tx, ty, sx, sy) {
method #rescaleAndSwap (line 21894) | #rescaleAndSwap(src, tx, ty, sx, sy) {
method #computeMinMax (line 21902) | #computeMinMax(isLTR) {
method box (line 21953) | get box() {
method getNewOutline (line 21956) | getNewOutline(thickness, innerMargin) {
class ColorPicker (line 21986) | class ColorPicker {
method _keyboardManager (line 22000) | static get _keyboardManager() {
method constructor (line 22003) | constructor({
method renderButton (line 22026) | renderButton() {
method renderMainDropdown (line 22046) | renderMainDropdown() {
method #getDropdownRoot (line 22052) | #getDropdownRoot() {
method #colorSelect (line 22085) | #colorSelect(color, event) {
method _colorSelectFromKeyboard (line 22093) | _colorSelectFromKeyboard(event) {
method _moveToNext (line 22104) | _moveToNext(event) {
method _moveToPrevious (line 22115) | _moveToPrevious(event) {
method _moveToBeginning (line 22127) | _moveToBeginning(event) {
method _moveToEnd (line 22134) | _moveToEnd(event) {
method #keyDown (line 22141) | #keyDown(event) {
method #openDropdown (line 22144) | #openDropdown(event) {
method #pointerDown (line 22160) | #pointerDown(event) {
method hideDropdown (line 22166) | hideDropdown() {
method #isDropdownVisible (line 22170) | get #isDropdownVisible() {
method _hideDropdownFromKeyboard (line 22173) | _hideDropdownFromKeyboard() {
method updateColor (line 22187) | updateColor(color) {
method destroy (line 22199) | destroy() {
class HighlightEditor (line 22225) | class HighlightEditor extends AnnotationEditor {
method _keyboardManager (line 22252) | static get _keyboardManager() {
method constructor (line 22264) | constructor(params) {
method telemetryInitialData (line 22290) | get telemetryInitialData() {
method telemetryFinalData (line 22299) | get telemetryFinalData() {
method computeTelemetryFinalData (line 22305) | static computeTelemetryFinalData(data) {
method #createOutlines (line 22310) | #createOutlines() {
method #createFreeOutlines (line 22326) | #createFreeOutlines({
method initialize (line 22389) | static initialize(l10n, uiManager) {
method updateDefaultParams (line 22393) | static updateDefaultParams(type, value) {
method translateInPage (line 22403) | translateInPage(x, y) {}
method toolbarPosition (line 22404) | get toolbarPosition() {
method updateParams (line 22407) | updateParams(type, value) {
method defaultPropertiesToUpdate (line 22417) | static get defaultPropertiesToUpdate() {
method propertiesToUpdate (line 22420) | get propertiesToUpdate() {
method #updateColor (line 22423) | #updateColor(color) {
method #updateThickness (line 22447) | #updateThickness(thickness) {
method addEditToolbar (line 22467) | async addEditToolbar() {
method disableEditing (line 22480) | disableEditing() {
method enableEditing (line 22484) | enableEditing() {
method fixAndSetPosition (line 22488) | fixAndSetPosition() {
method getBaseTranslation (line 22491) | getBaseTranslation() {
method getRect (line 22494) | getRect(tx, ty) {
method onceAdded (line 22497) | onceAdded() {
method remove (line 22503) | remove() {
method rebuild (line 22510) | rebuild() {
method setParent (line 22523) | setParent(parent) {
method #changeThickness (line 22537) | #changeThickness(thickness) {
method #cleanDrawLayer (line 22548) | #cleanDrawLayer() {
method #addToDrawLayer (line 22557) | #addToDrawLayer(parent = this.parent) {
method #rotateBbox (line 22570) | static #rotateBbox({
method rotate (line 22606) | rotate(angle) {
method render (line 22622) | render() {
method pointerover (line 22649) | pointerover() {
method pointerleave (line 22652) | pointerleave() {
method #keydown (line 22655) | #keydown(event) {
method _moveCaret (line 22658) | _moveCaret(direction) {
method #setCaret (line 22671) | #setCaret(start) {
method select (line 22682) | select() {
method unselect (line 22690) | unselect() {
method _mustFixPosition (line 22700) | get _mustFixPosition() {
method show (line 22703) | show(visible = this._isVisible) {
method #getRotation (line 22710) | #getRotation() {
method #serializeBoxes (line 22713) | #serializeBoxes() {
method #serializeOutlines (line 22738) | #serializeOutlines(rect) {
method startHighlighting (line 22741) | static startHighlighting(parent, isLTR, {
method #highlightMove (line 22788) | static #highlightMove(parent, event) {
method #endHighlight (line 22793) | static #endHighlight(parent, event) {
method deserialize (line 22808) | static async deserialize(data, parent, uiManager) {
method serialize (line 22928) | serialize(isForCopying = false) {
method #hasElementChanged (line 22955) | #hasElementChanged(serialized) {
method renderAnnotationElement (line 22961) | renderAnnotationElement(annotation) {
method canCreateNewEmptyEditor (line 22967) | static canCreateNewEmptyEditor() {
class InkEditor (line 22980) | class InkEditor extends AnnotationEditor {
method constructor (line 22999) | constructor(params) {
method initialize (line 23017) | static initialize(l10n, uiManager) {
method updateDefaultParams (line 23020) | static updateDefaultParams(type, value) {
method updateParams (line 23033) | updateParams(type, value) {
method defaultPropertiesToUpdate (line 23046) | static get defaultPropertiesToUpdate() {
method propertiesToUpdate (line 23049) | get propertiesToUpdate() {
method #updateThickness (line 23052) | #updateThickness(thickness) {
method #updateColor (line 23068) | #updateColor(color) {
method #updateOpacity (line 23084) | #updateOpacity(opacity) {
method rebuild (line 23101) | rebuild() {
method remove (line 23119) | remove() {
method setParent (line 23137) | setParent(parent) {
method onScaleChanging (line 23145) | onScaleChanging() {
method enableEditMode (line 23151) | enableEditMode() {
method disableEditMode (line 23159) | disableEditMode() {
method onceAdded (line 23168) | onceAdded() {
method isEmpty (line 23171) | isEmpty() {
method #getInitialBBox (line 23174) | #getInitialBBox() {
method #setStroke (line 23190) | #setStroke() {
method #startDrawing (line 23205) | #startDrawing(x, y) {
method #draw (line 23240) | #draw(x, y) {
method #endPath (line 23260) | #endPath() {
method #stopDrawing (line 23267) | #stopDrawing(x, y) {
method #drawPoints (line 23310) | #drawPoints() {
method #makeBezierCurve (line 23334) | #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) {
method #generateBezierPoints (line 23341) | #generateBezierPoints() {
method #redraw (line 23366) | #redraw() {
method commit (line 23383) | commit() {
method focusin (line 23401) | focusin(event) {
method #addPointerdownListener (line 23408) | #addPointerdownListener() {
method #removePointerdownListener (line 23418) | #removePointerdownListener() {
method canvasPointerdown (line 23422) | canvasPointerdown(event) {
method canvasPointermove (line 23435) | canvasPointermove(event) {
method canvasPointerup (line 23439) | canvasPointerup(event) {
method canvasPointerleave (line 23443) | canvasPointerleave(event) {
method #endDrawing (line 23446) | #endDrawing(event) {
method #createCanvas (line 23461) | #createCanvas() {
method #createObserver (line 23469) | #createObserver() {
method isResizable (line 23484) | get isResizable() {
method render (line 23487) | render() {
method #setCanvasDims (line 23518) | #setCanvasDims() {
method setDimensions (line 23527) | setDimensions(width, height) {
method #setScaleFactor (line 23548) | #setScaleFactor(width, height) {
method #updateTransform (line 23554) | #updateTransform() {
method #buildPath2D (line 23558) | static #buildPath2D(bezier) {
method #toPDFCoordinates (line 23569) | static #toPDFCoordinates(points, rect, rotation) {
method #fromPDFCoordinates (line 23603) | static #fromPDFCoordinates(points, rect, rotation) {
method #serializePaths (line 23637) | #serializePaths(s, tx, ty, rect) {
method #getBbox (line 23679) | #getBbox() {
method #getPadding (line 23695) | #getPadding() {
method #fitToContent (line 23698) | #fitToContent(firstTime = false) {
method deserialize (line 23728) | static async deserialize(data, parent, uiManager) {
method serialize (line 23777) | serialize() {
class StampEditor (line 23806) | class StampEditor extends AnnotationEditor {
method constructor (line 23820) | constructor(params) {
method initialize (line 23828) | static initialize(l10n, uiManager) {
method supportedTypes (line 23831) | static get supportedTypes() {
method supportedTypesStr (line 23835) | static get supportedTypesStr() {
method isHandlingMimeForPasting (line 23838) | static isHandlingMimeForPasting(mime) {
method paste (line 23841) | static paste(item, parent) {
method altTextFinish (line 23846) | altTextFinish() {
method telemetryFinalData (line 23852) | get telemetryFinalData() {
method computeTelemetryFinalData (line 23858) | static computeTelemetryFinalData(data) {
method #getBitmapFetched (line 23865) | #getBitmapFetched(data, fromId = false) {
method #getBitmapDone (line 23880) | #getBitmapDone() {
method mlGuessAltText (line 23905) | async mlGuessAltText(imageData = null, updateAltTextData = true) {
method #getBitmap (line 23954) | #getBitmap() {
method remove (line 24006) | remove() {
method rebuild (line 24021) | rebuild() {
method onceAdded (line 24039) | onceAdded() {
method isEmpty (line 24043) | isEmpty() {
method isResizable (line 24046) | get isResizable() {
method render (line 24049) | render() {
method #createCanvas (line 24073) | #createCanvas() {
method copyCanvas (line 24113) | copyCanvas(maxDataDimension, maxPreviewDimension, createImageData = fa...
method #setDimensions (line 24197) | #setDimensions(width, height) {
method #scaleBitmap (line 24216) | #scaleBitmap(width, height) {
method #drawBitmap (line 24240) | #drawBitmap(width, height) {
method getImageForAltText (line 24255) | getImageForAltText() {
method #serializeBitmap (line 24258) | #serializeBitmap(toUrl) {
method #createObserver (line 24286) | #createObserver() {
method deserialize (line 24304) | static async deserialize(data, parent, uiManager) {
method serialize (line 24373) | serialize(isForCopying = false, context = null) {
method #hasElementChanged (line 24437) | #hasElementChanged(serialized) {
method renderAnnotationElement (line 24453) | renderAnnotationElement(annotation) {
class AnnotationEditorLayer (line 24477) | class AnnotationEditorLayer {
method constructor (line 24492) | constructor({
method isEmpty (line 24523) | get isEmpty() {
method isInvisible (line 24526) | get isInvisible() {
method updateToolbar (line 24529) | updateToolbar(mode) {
method updateMode (line 24532) | updateMode(mode = this.#uiManager.getMode()) {
method hasTextLayer (line 24566) | hasTextLayer(textLayer) {
method addInkEditorIfNeeded (line 24569) | addInkEditorIfNeeded(isCommitting) {
method setEditingState (line 24587) | setEditingState(isEditing) {
method addCommands (line 24590) | addCommands(params) {
method toggleDrawing (line 24593) | toggleDrawing(enabled = false) {
method togglePointerEvents (line 24596) | togglePointerEvents(enabled = false) {
method toggleAnnotationLayerPointerEvents (line 24599) | toggleAnnotationLayerPointerEvents(enabled = false) {
method enable (line 24602) | async enable() {
method disable (line 24634) | disable() {
method getEditableAnnotation (line 24694) | getEditableAnnotation(id) {
method setActiveEditor (line 24697) | setActiveEditor(editor) {
method enableTextSelection (line 24704) | enableTextSelection() {
method disableTextSelection (line 24715) | disableTextSelection() {
method #textLayerPointerDown (line 24723) | #textLayerPointerDown(event) {
method enableClick (line 24753) | enableClick() {
method disableClick (line 24766) | disableClick() {
method attach (line 24770) | attach(editor) {
method detach (line 24779) | detach(editor) {
method remove (line 24786) | remove(editor) {
method changeParent (line 24795) | changeParent(editor) {
method add (line 24812) | add(editor) {
method moveEditorInDOM (line 24829) | moveEditorInDOM(editor) {
method addOrRebuild (line 24855) | addOrRebuild(editor) {
method addUndoableEditor (line 24864) | addUndoableEditor(editor) {
method getNextId (line 24875) | getNextId() {
method #currentEditorType (line 24878) | get #currentEditorType() {
method combinedSignal (line 24881) | combinedSignal(ac) {
method #createNewEditor (line 24884) | #createNewEditor(params) {
method canCreateNewEmptyEditor (line 24888) | canCreateNewEmptyEditor() {
method pasteEditor (line 24891) | pasteEditor(mode, params) {
method deserialize (line 24912) | async deserialize(data) {
method createAndAddNewEditor (line 24915) | createAndAddNewEditor(event, isCentered, data = {}) {
method #getCenterPoint (line 24931) | #getCenterPoint() {
method addNewEditor (line 24950) | addNewEditor() {
method setSelected (line 24953) | setSelected(editor) {
method toggleSelected (line 24956) | toggleSelected(editor) {
method isSelected (line 24959) | isSelected(editor) {
method unselect (line 24962) | unselect(editor) {
method pointerup (line 24965) | pointerup(event) {
method pointerdown (line 24989) | pointerdown(event) {
method findNewParent (line 25010) | findNewParent(editor, x, y) {
method destroy (line 25018) | destroy() {
method #cleanup (line 25037) | #cleanup() {
method render (line 25046) | render({
method update (line 25057) | update({
method pageDimensions (line 25075) | get pageDimensions() {
method scale (line 25082) | get scale() {
class DrawLayer (line 25090) | class DrawLayer {
method constructor (line 25095) | constructor({
method setParent (line 25100) | setParent(parent) {
method _svgFactory (line 25115) | static get _svgFactory() {
method #setBox (line 25118) | static #setBox(element, {
method #createSVG (line 25132) | #createSVG(box) {
method #createClipPath (line 25139) | #createClipPath(defs, pathId) {
method highlight (line 25151) | highlight(outlines, color, opacity, isPathUpdatable = false) {
method highlightOutline (line 25180) | highlightOutline(outlines) {
method finalizeLine (line 25226) | finalizeLine(id, line) {
method updateLine (line 25232) | updateLine(id, line) {
method removeFreeHighlight (line 25238) | removeFreeHighlight(id) {
method updatePath (line 25242) | updatePath(id, line) {
method updateBox (line 25245) | updateBox(id, box) {
method show (line 25248) | show(id, visible) {
method rotate (line 25251) | rotate(id, angle) {
method changeColor (line 25254) | changeColor(id, color) {
method changeOpacity (line 25257) | changeOpacity(id, opacity) {
method addClass (line 25260) | addClass(id, className) {
method removeClass (line 25263) | removeClass(id, className) {
method getSVGRoot (line 25266) | getSVGRoot(id) {
method remove (line 25269) | remove(id) {
method destroy (line 25276) | destroy() {
FILE: public/lib/pdfjs/pdf.worker.mjs
function F (line 674) | function F() { /* empty */ }
function __webpack_require__ (line 4461) | function __webpack_require__(moduleId) {
constant IDENTITY_MATRIX (line 4565) | const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
constant FONT_IDENTITY_MATRIX (line 4566) | const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
constant MAX_IMAGE_SIZE_TO_CACHE (line 4567) | const MAX_IMAGE_SIZE_TO_CACHE = 10e6;
constant LINE_FACTOR (line 4568) | const LINE_FACTOR = 1.35;
constant LINE_DESCENT_FACTOR (line 4569) | const LINE_DESCENT_FACTOR = 0.35;
constant BASELINE_FACTOR (line 4570) | const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
constant OPS (line 4747) | const OPS = {
function setVerbosityLevel (line 4844) | function setVerbosityLevel(level) {
function getVerbosityLevel (line 4849) | function getVerbosityLevel() {
function info (line 4852) | function info(msg) {
function warn (line 4857) | function warn(msg) {
function unreachable (line 4862) | function unreachable(msg) {
function assert (line 4865) | function assert(cond, msg) {
function _isValidProtocol (line 4870) | function _isValidProtocol(url) {
function createValidAbsoluteUrl (line 4882) | function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
function shadow (line 4907) | function shadow(obj, prop, value, nonSerializable = false) {
function BaseException (line 4917) | function BaseException(message, name) {
class PasswordException (line 4925) | class PasswordException extends BaseException {
method constructor (line 4926) | constructor(msg, code) {
class UnknownErrorException (line 4931) | class UnknownErrorException extends BaseException {
method constructor (line 4932) | constructor(msg, details) {
class InvalidPDFException (line 4937) | class InvalidPDFException extends BaseException {
method constructor (line 4938) | constructor(msg) {
class MissingPDFException (line 4942) | class MissingPDFException extends BaseException {
method constructor (line 4943) | constructor(msg) {
class UnexpectedResponseException (line 4947) | class UnexpectedResponseException extends BaseException {
method constructor (line 4948) | constructor(msg, status) {
class FormatError (line 4953) | class FormatError extends BaseException {
method constructor (line 4954) | constructor(msg) {
class AbortException (line 4958) | class AbortException extends BaseException {
method constructor (line 4959) | constructor(msg) {
function bytesToString (line 4963) | function bytesToString(bytes) {
function stringToBytes (line 4980) | function stringToBytes(str) {
function string32 (line 4991) | function string32(value) {
function objectSize (line 4994) | function objectSize(obj) {
function objectFromMap (line 4997) | function objectFromMap(map) {
function isLittleEndian (line 5004) | function isLittleEndian() {
function isEvalSupported (line 5010) | function isEvalSupported() {
class FeatureTest (line 5018) | class FeatureTest {
method isLittleEndian (line 5019) | static get isLittleEndian() {
method isEvalSupported (line 5022) | static get isEvalSupported() {
method isOffscreenCanvasSupported (line 5025) | static get isOffscreenCanvasSupported() {
method platform (line 5028) | static get platform() {
method isCSSRoundSupported (line 5042) | static get isCSSRoundSupported() {
class Util (line 5047) | class Util {
method makeHexColor (line 5048) | static makeHexColor(r, g, b) {
method scaleMinMax (line 5051) | static scaleMinMax(transform, minMax) {
method transform (line 5095) | static transform(m1, m2) {
method applyTransform (line 5098) | static applyTransform(p, m) {
method applyInverseTransform (line 5103) | static applyInverseTransform(p, m) {
method getAxialAlignedBoundingBox (line 5109) | static getAxialAlignedBoundingBox(r, m) {
method inverseTransform (line 5116) | static inverseTransform(m) {
method singularValueDecompose2dScale (line 5120) | static singularValueDecompose2dScale(m) {
method normalizeRect (line 5132) | static normalizeRect(rect) {
method intersect (line 5144) | static intersect(rect1, rect2) {
method #getExtremumOnCurve (line 5157) | static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
method #getExtremum (line 5171) | static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) {
method bezierBoundingBox (line 5187) | static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
function stringToPDFString (line 5202) | function stringToPDFString(str) {
function stringToUTF8String (line 5246) | function stringToUTF8String(str) {
function utf8StringToString (line 5249) | function utf8StringToString(str) {
function isArrayEqual (line 5252) | function isArrayEqual(arr1, arr2) {
function getModificationDate (line 5263) | function getModificationDate(date = new Date()) {
function normalizeUnicode (line 5269) | function normalizeUnicode(str) {
function getUuid (line 5276) | function getUuid() {
constant CIRCULAR_REF (line 5315) | const CIRCULAR_REF = Symbol("CIRCULAR_REF");
constant EOF (line 5316) | const EOF = Symbol("EOF");
function clearPrimitiveCaches (line 5320) | function clearPrimitiveCaches() {
class Name (line 5325) | class Name {
method constructor (line 5326) | constructor(name) {
method get (line 5329) | static get(name) {
class Cmd (line 5333) | class Cmd {
method constructor (line 5334) | constructor(cmd) {
method get (line 5337) | static get(cmd) {
class Dict (line 5344) | class Dict {
method constructor (line 5345) | constructor(xref = null) {
method assignXref (line 5352) | assignXref(newXref) {
method size (line 5355) | get size() {
method get (line 5358) | get(key1, key2, key3) {
method getAsync (line 5371) | async getAsync(key1, key2, key3) {
method getArray (line 5384) | getArray(key1, key2, key3) {
method getRaw (line 5405) | getRaw(key) {
method getKeys (line 5408) | getKeys() {
method getRawValues (line 5411) | getRawValues() {
method set (line 5414) | set(key, value) {
method has (line 5417) | has(key) {
method forEach (line 5420) | forEach(callback) {
method empty (line 5425) | static get empty() {
method merge (line 5432) | static merge({
method clone (line 5474) | clone() {
method delete (line 5481) | delete(key) {
class Ref (line 5485) | class Ref {
method constructor (line 5486) | constructor(num, gen) {
method toString (line 5490) | toString() {
method fromString (line 5496) | static fromString(str) {
method get (line 5507) | static get(num, gen) {
class RefSet (line 5512) | class RefSet {
method constructor (line 5513) | constructor(parent = null) {
method has (line 5516) | has(ref) {
method put (line 5519) | put(ref) {
method remove (line 5522) | remove(ref) {
method clear (line 5528) | clear() {
method [Symbol.iterator] (line 5525) | [Symbol.iterator]() {
class RefSetCache (line 5532) | class RefSetCache {
method constructor (line 5533) | constructor() {
method size (line 5536) | get size() {
method get (line 5539) | get(ref) {
method has (line 5542) | has(ref) {
method put (line 5545) | put(ref, obj) {
method putAlias (line 5548) | putAlias(ref, aliasRef) {
method clear (line 5554) | clear() {
method items (line 5557) | *items() {
method [Symbol.iterator] (line 5551) | [Symbol.iterator]() {
function isName (line 5563) | function isName(v, name) {
function isCmd (line 5566) | function isCmd(v, cmd) {
function isDict (line 5569) | function isDict(v, type) {
function isRefsEqual (line 5572) | function isRefsEqual(v1, v2) {
class BaseStream (line 5578) | class BaseStream {
method length (line 5579) | get length() {
method isEmpty (line 5582) | get isEmpty() {
method isDataLoaded (line 5585) | get isDataLoaded() {
method getByte (line 5588) | getByte() {
method getBytes (line 5591) | getBytes(length) {
method getImageData (line 5594) | async getImageData(length, decoderOptions) {
method asyncGetBytes (line 5597) | async asyncGetBytes() {
method isAsync (line 5600) | get isAsync() {
method canAsyncDecodeImageFromBuffer (line 5603) | get canAsyncDecodeImageFromBuffer() {
method peekByte (line 5606) | peekByte() {
method peekBytes (line 5613) | peekBytes(length) {
method getUint16 (line 5618) | getUint16() {
method getInt32 (line 5626) | getInt32() {
method getByteRange (line 5633) | getByteRange(begin, end) {
method getString (line 5636) | getString(length) {
method skip (line 5639) | skip(n) {
method reset (line 5642) | reset() {
method moveStart (line 5645) | moveStart() {
method makeSubStream (line 5648) | makeSubStream(start, length, dict = null) {
method getBaseStreams (line 5651) | getBaseStreams() {
constant PDF_VERSION_REGEXP (line 5677) | const PDF_VERSION_REGEXP = /^[1-9]\.\d$/;
function getLookupTableFactory (line 5678) | function getLookupTableFactory(initializer) {
class MissingDataException (line 5689) | class MissingDataException extends BaseException {
method constructor (line 5690) | constructor(begin, end) {
class ParserEOFException (line 5696) | class ParserEOFException extends BaseException {
method constructor (line 5697) | constructor(msg) {
class XRefEntryException (line 5701) | class XRefEntryException extends BaseException {
method constructor (line 5702) | constructor(msg) {
class XRefParseException (line 5706) | class XRefParseException extends BaseException {
method constructor (line 5707) | constructor(msg) {
function arrayBuffersToBytes (line 5711) | function arrayBuffersToBytes(arr) {
function getInheritableProperty (line 5732) | function getInheritableProperty({
constant ROMAN_NUMBER_MAP (line 5755) | const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", ...
function toRomanNumerals (line 5756) | function toRomanNumerals(number, lowerCase = false) {
function log2 (line 5774) | function log2(x) {
function readInt8 (line 5780) | function readInt8(data, offset) {
function readUint16 (line 5783) | function readUint16(data, offset) {
function readUint32 (line 5786) | function readUint32(data, offset) {
function isWhiteSpace (line 5789) | function isWhiteSpace(ch) {
function isBooleanArray (line 5792) | function isBooleanArray(arr, len) {
function isNumberArray (line 5795) | function isNumberArray(arr, len) {
function lookupMatrix (line 5801) | function lookupMatrix(arr, fallback) {
function lookupRect (line 5804) | function lookupRect(arr, fallback) {
function lookupNormalRect (line 5807) | function lookupNormalRect(arr, fallback) {
function parseXFAPath (line 5810) | function parseXFAPath(path) {
function escapePDFName (line 5826) | function escapePDFName(str) {
function escapeString (line 5847) | function escapeString(str) {
function _collectJS (line 5857) | function _collectJS(entry, xref, list, parents) {
function collectActions (line 5894) | function collectActions(xref, dict, eventType) {
function encodeToXmlString (line 5949) | function encodeToXmlString(str) {
function validateFontName (line 5982) | function validateFontName(fontFamily, mustWarn = false) {
function validateCSSFont (line 6004) | function validateCSSFont(cssFontInfo) {
function recoverJsURL (line 6022) | function recoverJsURL(str) {
function numberToString (line 6039) | function numberToString(value) {
function getNewAnnotationsMap (line 6052) | function getNewAnnotationsMap(annotationStorage) {
function stringToAsciiOrUTF16BE (line 6070) | function stringToAsciiOrUTF16BE(str) {
function isAscii (line 6073) | function isAscii(str) {
function stringToUTF16HexString (line 6076) | function stringToUTF16HexString(str) {
function stringToUTF16String (line 6084) | function stringToUTF16String(str, bigEndian = false) {
function getRotationMatrix (line 6095) | function getRotationMatrix(rotation, width, height) {
function getSizeInBytes (line 6107) | function getSizeInBytes(x) {
class Stream (line 6120) | class Stream extends BaseStream {
method constructor (line 6121) | constructor(arrayBuffer, start, length, dict) {
method length (line 6129) | get length() {
method isEmpty (line 6132) | get isEmpty() {
method getByte (line 6135) | getByte() {
method getBytes (line 6141) | getBytes(length) {
method getByteRange (line 6155) | getByteRange(begin, end) {
method reset (line 6164) | reset() {
method moveStart (line 6167) | moveStart() {
method makeSubStream (line 6170) | makeSubStream(start, length, dict = null) {
class StringStream (line 6174) | class StringStream extends Stream {
method constructor (line 6175) | constructor(str) {
class NullStream (line 6179) | class NullStream extends Stream {
method constructor (line 6180) | constructor() {
class ChunkedStream (line 6204) | class ChunkedStream extends Stream {
method constructor (line 6205) | constructor(length, chunkSize, manager) {
method getMissingChunks (line 6214) | getMissingChunks() {
method numChunksLoaded (line 6223) | get numChunksLoaded() {
method isDataLoaded (line 6226) | get isDataLoaded() {
method onReceiveData (line 6229) | onReceiveData(begin, chunk) {
method onReceiveProgressiveData (line 6245) | onReceiveProgressiveData(data) {
method ensureByte (line 6256) | ensureByte(pos) {
method ensureRange (line 6272) | ensureRange(begin, end) {
method nextEmptyChunk (line 6290) | nextEmptyChunk(beginChunk) {
method hasChunk (line 6300) | hasChunk(chunk) {
method getByte (line 6303) | getByte() {
method getBytes (line 6313) | getBytes(length) {
method getByteRange (line 6333) | getByteRange(begin, end) {
method makeSubStream (line 6345) | makeSubStream(start, length, dict = null) {
method getBaseStreams (line 6382) | getBaseStreams() {
class ChunkedStreamManager (line 6386) | class ChunkedStreamManager {
method constructor (line 6387) | constructor(pdfNetworkStream, args) {
method sendRequest (line 6402) | sendRequest(begin, end) {
method requestAllChunks (line 6444) | requestAllChunks(noFetch = false) {
method _requestChunks (line 6451) | _requestChunks(chunks) {
method getStream (line 6490) | getStream() {
method requestRange (line 6493) | requestRange(begin, end) {
method requestRanges (line 6503) | requestRanges(ranges = []) {
method groupChunks (line 6519) | groupChunks(chunks) {
method onProgress (line 6545) | onProgress(args) {
method onReceiveData (line 6551) | onReceiveData(args) {
method onError (line 6609) | onError(err) {
method getBeginChunk (line 6612) | getBeginChunk(begin) {
method getEndChunk (line 6615) | getEndChunk(end) {
method abort (line 6618) | abort(reason) {
function resizeRgbImage (line 6646) | function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) {
class ColorSpace (line 6669) | class ColorSpace {
method constructor (line 6670) | constructor(name, numComps) {
method getRgb (line 6674) | getRgb(src, srcOffset) {
method getRgbItem (line 6679) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 6682) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 6685) | getOutputLength(inputLength, alpha01) {
method isPassthrough (line 6688) | isPassthrough(bits) {
method isDefaultDecode (line 6691) | isDefaultDecode(decodeMap, bpc) {
method fillRgb (line 6694) | fillRgb(dest, originalWidth, originalHeight, width, height, actualHeig...
method usesZeroToOneRange (line 6748) | get usesZeroToOneRange() {
method _cache (line 6751) | static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) {
method getCached (line 6770) | static getCached(cacheKey, xref, localColorSpaceCache) {
method parseAsync (line 6795) | static async parseAsync({
method parse (line 6806) | static parse({
method _parse (line 6821) | static _parse(cs, xref, resources = null, pdfFunctionFactory) {
method isDefaultDecode (line 6935) | static isDefaultDecode(decode, numComps) {
method singletons (line 6950) | static get singletons() {
class AlternateCS (line 6967) | class AlternateCS extends ColorSpace {
method constructor (line 6968) | constructor(numComps, base, tintFn) {
method getRgbItem (line 6974) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 6979) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7010) | getOutputLength(inputLength, alpha01) {
class PatternCS (line 7014) | class PatternCS extends ColorSpace {
method constructor (line 7015) | constructor(baseCS) {
method isDefaultDecode (line 7019) | isDefaultDecode(decodeMap, bpc) {
class IndexedCS (line 7023) | class IndexedCS extends ColorSpace {
method constructor (line 7024) | constructor(base, highVal, lookup) {
method getRgbItem (line 7041) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7046) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7057) | getOutputLength(inputLength, alpha01) {
method isDefaultDecode (line 7060) | isDefaultDecode(decodeMap, bpc) {
class DeviceGrayCS (line 7075) | class DeviceGrayCS extends ColorSpace {
method constructor (line 7076) | constructor() {
method getRgbItem (line 7079) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7083) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7095) | getOutputLength(inputLength, alpha01) {
class DeviceRgbCS (line 7099) | class DeviceRgbCS extends ColorSpace {
method constructor (line 7100) | constructor() {
method getRgbItem (line 7103) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7108) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7123) | getOutputLength(inputLength, alpha01) {
method isPassthrough (line 7126) | isPassthrough(bits) {
class DeviceRgbaCS (line 7130) | class DeviceRgbaCS extends ColorSpace {
method constructor (line 7131) | constructor() {
method getOutputLength (line 7134) | getOutputLength(inputLength, _alpha01) {
method isPassthrough (line 7137) | isPassthrough(bits) {
class DeviceCmykCS (line 7141) | class DeviceCmykCS extends ColorSpace {
method constructor (line 7142) | constructor() {
method #toRgb (line 7145) | #toRgb(src, srcOffset, srcScale, dest, destOffset) {
method getRgbItem (line 7154) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7157) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7165) | getOutputLength(inputLength, alpha01) {
class CalGrayCS (line 7169) | class CalGrayCS extends ColorSpace {
method constructor (line 7170) | constructor(whitePoint, blackPoint, gamma) {
method #toRgb (line 7193) | #toRgb(src, srcOffset, dest, destOffset, scale) {
method getRgbItem (line 7202) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7205) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7213) | getOutputLength(inputLength, alpha01) {
class CalRGBCS (line 7217) | class CalRGBCS extends ColorSpace {
method constructor (line 7226) | constructor(whitePoint, blackPoint, gamma, matrix) {
method #matrixProduct (line 7247) | #matrixProduct(a, b, result) {
method #toFlat (line 7252) | #toFlat(sourceWhitePoint, LMS, result) {
method #toD65 (line 7257) | #toD65(sourceWhitePoint, LMS, result) {
method #sRGBTransferFunction (line 7265) | #sRGBTransferFunction(color) {
method #adjustToRange (line 7274) | #adjustToRange(min, max, value) {
method #decodeL (line 7277) | #decodeL(L) {
method #compensateBlackPoint (line 7286) | #compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) {
method #normalizeWhitePointToFlat (line 7310) | #normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) {
method #normalizeWhitePointToD65 (line 7323) | #normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) {
method #toRgb (line 7330) | #toRgb(src, srcOffset, dest, destOffset, scale) {
method getRgbItem (line 7356) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7359) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7367) | getOutputLength(inputLength, alpha01) {
class LabCS (line 7371) | class LabCS extends ColorSpace {
method constructor (line 7372) | constructor(whitePoint, blackPoint, range) {
method #fn_g (line 7395) | #fn_g(x) {
method #decode (line 7398) | #decode(value, high1, low2, high2) {
method #toRgb (line 7401) | #toRgb(src, srcOffset, maxVal, dest, destOffset) {
method getRgbItem (line 7440) | getRgbItem(src, srcOffset, dest, destOffset) {
method getRgbBuffer (line 7443) | getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) {
method getOutputLength (line 7451) | getOutputLength(inputLength, alpha01) {
method isDefaultDecode (line 7454) | isDefaultDecode(decodeMap, bpc) {
method usesZeroToOneRange (line 7457) | get usesZeroToOneRange() {
function hexToInt (line 7470) | function hexToInt(a, size) {
function hexToStr (line 7477) | function hexToStr(a, size) {
function addHex (line 7486) | function addHex(a, b, size) {
function incHex (line 7494) | function incHex(a, size) {
constant MAX_NUM_SIZE (line 7502) | const MAX_NUM_SIZE = 16;
constant MAX_ENCODED_NUM_SIZE (line 7503) | const MAX_ENCODED_NUM_SIZE = 19;
class BinaryCMapStream (line 7504) | class BinaryCMapStream {
method constructor (line 7505) | constructor(data) {
method readByte (line 7511) | readByte() {
method readNumber (line 7517) | readNumber() {
method readSigned (line 7530) | readSigned() {
method readHex (line 7534) | readHex(num, size) {
method readHexNumber (line 7538) | readHexNumber(num, size) {
method readHexSigned (line 7564) | readHexSigned(num, size) {
method readString (line 7573) | readString() {
class BinaryCMapReader (line 7582) | class BinaryCMapReader {
method process (line 7583) | async process(data, cMap, extend) {
class DecodeStream (line 7736) | class DecodeStream extends BaseStream {
method constructor (line 7737) | constructor(maybeMinBufferLength) {
method isEmpty (line 7751) | get isEmpty() {
method ensureBuffer (line 7757) | ensureBuffer(requested) {
method getByte (line 7770) | getByte() {
method getBytes (line 7780) | getBytes(length, decoderOptions = null) {
method getImageData (line 7802) | async getImageData(length, decoderOptions = null) {
method reset (line 7809) | reset() {
method makeSubStream (line 7812) | makeSubStream(start, length, dict = null) {
method getBaseStreams (line 7825) | getBaseStreams() {
class StreamsSequenceStream (line 7829) | class StreamsSequenceStream extends DecodeStream {
method constructor (line 7830) | constructor(streams, onError = null) {
method readBlock (line 7839) | readBlock() {
method getBaseStreams (line 7862) | getBaseStreams() {
class Ascii85Stream (line 7883) | class Ascii85Stream extends DecodeStream {
method constructor (line 7884) | constructor(str, maybeLength) {
method readBlock (line 7893) | readBlock() {
class AsciiHexStream (line 7949) | class AsciiHexStream extends DecodeStream {
method constructor (line 7950) | constructor(str, maybeLength) {
method readBlock (line 7959) | readBlock() {
class CCITTFaxDecoder (line 8023) | class CCITTFaxDecoder {
method constructor (line 8024) | constructor(source, options = {}) {
method readNextChar (line 8059) | readNextChar() {
method _addPixels (line 8349) | _addPixels(a1, blackPixels) {
method _addPixelsNeg (line 8365) | _addPixelsNeg(a1, blackPixels) {
method _findTableCode (line 8391) | _findTableCode(start, end, table, limit) {
method _getTwoDimCode (line 8411) | _getTwoDimCode() {
method _getWhiteCode (line 8430) | _getWhiteCode() {
method _getBlackCode (line 8457) | _getBlackCode() {
method _lookBits (line 8493) | _lookBits(n) {
method _eatBits (line 8507) | _eatBits(n) {
class CCITTFaxStream (line 8518) | class CCITTFaxStream extends DecodeStream {
method constructor (line 8519) | constructor(str, maybeLength, params) {
method readBlock (line 8541) | readBlock() {
class FlateStream (line 8570) | class FlateStream extends DecodeStream {
method constructor (line 8571) | constructor(str, maybeLength) {
method getImageData (line 8592) | async getImageData(length, _decoderOptions) {
method asyncGetBytes (line 8596) | async asyncGetBytes() {
method isAsync (line 8626) | get isAsync() {
method getBits (line 8629) | getBits(bits) {
method getCode (line 8646) | getCode(table) {
method generateHuffmanTable (line 8670) | generateHuffmanTable(lengths) {
method #endsStreamOnError (line 8699) | #endsStreamOnError(err) {
method readBlock (line 8703) | readBlock() {
class ArithmeticDecoder (line 9087) | class ArithmeticDecoder {
method constructor (line 9088) | constructor(data, start, end) {
method byteIn (line 9100) | byteIn() {
method readBit (line 9124) | readBit(contexts, pos) {
class Jbig2Error (line 9188) | class Jbig2Error extends BaseException {
method constructor (line 9189) | constructor(msg) {
class ContextCache (line 9193) | class ContextCache {
method getContexts (line 9194) | getContexts(id) {
class DecodingContext (line 9201) | class DecodingContext {
method constructor (line 9202) | constructor(data, start, end) {
method decoder (line 9207) | get decoder() {
method contextCache (line 9211) | get contextCache() {
constant MAX_INT_32 (line 9216) | const MAX_INT_32 = 2 ** 31 - 1;
constant MIN_INT_32 (line 9217) | const MIN_INT_32 = -(2 ** 31);
function decodeInteger (line 9218) | function decodeInteger(contextCache, procedure, decoder) {
function decodeIAID (line 9243) | function decodeIAID(contextCache, decoder, codeLength) {
function decodeBitmapTemplate0 (line 9455) | function decodeBitmapTemplate0(width, height, decodingContext) {
function decodeBitmap (line 9473) | function decodeBitmap(mmr, width, height, templateIndex, prediction, ski...
function decodeRefinement (line 9581) | function decodeRefinement(width, height, templateIndex, referenceBitmap,...
function decodeSymbolDictionary (line 9649) | function decodeSymbolDictionary(huffman, refinement, symbols, numberOfNe...
function decodeTextRegion (line 9759) | function decodeTextRegion(huffman, refinement, width, height, defaultPix...
function decodePatternDictionary (line 9876) | function decodePatternDictionary(mmr, patternWidth, patternHeight, maxPa...
function decodeHalftoneRegion (line 9910) | function decodeHalftoneRegion(mmr, patterns, template, regionWidth, regi...
function readSegmentHeader (line 10007) | function readSegmentHeader(data, start) {
function readSegments (line 10099) | function readSegments(header, data, start, end) {
function readRegionSegmentInformation (line 10128) | function readRegionSegmentInformation(data, start) {
function processSegment (line 10138) | function processSegment(segment, visitor) {
function processSegments (line 10330) | function processSegments(segments, visitor) {
function parseJbig2Chunks (line 10335) | function parseJbig2Chunks(chunks) {
function parseJbig2 (line 10344) | function parseJbig2(data) {
class SimpleSegmentVisitor (line 10347) | class SimpleSegmentVisitor {
method onPageInformation (line 10348) | onPageInformation(info) {
method drawBitmap (line 10357) | drawBitmap(regionInfo, bitmap) {
method onImmediateGenericRegion (line 10406) | onImmediateGenericRegion(region, data, start, end) {
method onImmediateLosslessGenericRegion (line 10412) | onImmediateLosslessGenericRegion() {
method onSymbolDictionary (line 10415) | onSymbolDictionary(dictionary, currentSegment, referredSegments, data,...
method onImmediateTextRegion (line 10435) | onImmediateTextRegion(region, referredSegments, data, start, end) {
method onImmediateLosslessTextRegion (line 10455) | onImmediateLosslessTextRegion() {
method onPatternDictionary (line 10458) | onPatternDictionary(dictionary, currentSegment, data, start, end) {
method onImmediateHalftoneRegion (line 10466) | onImmediateHalftoneRegion(region, referredSegments, data, start, end) {
method onImmediateLosslessHalftoneRegion (line 10473) | onImmediateLosslessHalftoneRegion() {
method onTables (line 10476) | onTables(currentSegment, data, start, end) {
class HuffmanLine (line 10484) | class HuffmanLine {
method constructor (line 10485) | constructor(lineData) {
class HuffmanTreeNode (line 10503) | class HuffmanTreeNode {
method constructor (line 10504) | constructor(line) {
method buildTree (line 10516) | buildTree(line, shift) {
method decodeNode (line 10528) | decodeNode(reader) {
class HuffmanTable (line 10543) | class HuffmanTable {
method constructor (line 10544) | constructor(lines, prefixCodesDone) {
method decode (line 10556) | decode(reader) {
method assignPrefixCodes (line 10559) | assignPrefixCodes(lines) {
function decodeTablesSegment (line 10591) | function decodeTablesSegment(data, start, end) {
function getStandardTable (line 10619) | function getStandardTable(number) {
class Reader (line 10681) | class Reader {
method constructor (line 10682) | constructor(data, start, end) {
method readBit (line 10690) | readBit() {
method readBits (line 10702) | readBits(numBits) {
method byteAlign (line 10710) | byteAlign() {
method next (line 10713) | next() {
function getCustomHuffmanTable (line 10720) | function getCustomHuffmanTable(index, referredTo, customTables) {
function getTextRegionHuffmanTables (line 10733) | function getTextRegionHuffmanTables(textRegion, referredTo, customTables...
function getSymbolDictionaryHuffmanTables (line 10827) | function getSymbolDictionaryHuffmanTables(dictionary, referredTo, custom...
function readUncompressedBitmap (line 10874) | function readUncompressedBitmap(reader, width, height) {
function decodeMMRBitmap (line 10886) | function decodeMMRBitmap(input, width, height, endOfBlock) {
class Jbig2Image (line 10925) | class Jbig2Image {
method parseChunks (line 10926) | parseChunks(chunks) {
method parse (line 10929) | parse(data) {
class Jbig2Stream (line 10941) | class Jbig2Stream extends DecodeStream {
method constructor (line 10942) | constructor(stream, maybeLength, params) {
method bytes (line 10949) | get bytes() {
method ensureBuffer (line 10952) | ensureBuffer(requested) {}
method readBlock (line 10953) | readBlock() {
method decodeImage (line 10956) | decodeImage(bytes) {
method canAsyncDecodeImageFromBuffer (line 10989) | get canAsyncDecodeImageFromBuffer() {
function convertToRGBA (line 11002) | function convertToRGBA(params) {
function convertBlackAndWhiteToRGBA (line 11011) | function convertBlackAndWhiteToRGBA({
function convertRGBToRGBA (line 11052) | function convertRGBToRGBA({
function grayToRGBA (line 11095) | function grayToRGBA(src, dest) {
class JpegError (line 11118) | class JpegError extends BaseException {
method constructor (line 11119) | constructor(msg) {
class DNLMarkerError (line 11123) | class DNLMarkerError extends BaseException {
method constructor (line 11124) | constructor(message, scanLines) {
class EOIMarkerError (line 11129) | class EOIMarkerError extends BaseException {
method constructor (line 11130) | constructor(msg) {
function buildHuffmanTable (line 11143) | function buildHuffmanTable(codeLengths, values) {
function getBlockBufferOffset (line 11187) | function getBlockBufferOffset(component, row, col) {
function decodeScan (line 11190) | function decodeScan(data, offset, frame, components, resetInterval, spec...
function quantizeAndInverse (line 11458) | function quantizeAndInverse(component, blockBufferOffset, p) {
function buildComponentData (line 11661) | function buildComponentData(frame, component) {
function findNextFileMarker (line 11673) | function findNextFileMarker(data, currentPos, startPos = currentPos) {
class JpegImage (line 11700) | class JpegImage {
method constructor (line 11701) | constructor({
method parse (line 11708) | parse(data, {
method _getLinearizedBlockData (line 11979) | _getLinearizedBlockData(width, height, isSourcePDF = false) {
method _isColorConversionNeeded (line 12029) | get _isColorConversionNeeded() {
method _convertYccToRgb (line 12046) | _convertYccToRgb(data) {
method _convertYccToRgba (line 12058) | _convertYccToRgba(data, out) {
method _convertYcckToRgb (line 12070) | _convertYcckToRgb(data) {
method _convertYcckToRgba (line 12084) | _convertYcckToRgba(data) {
method _convertYcckToCmyk (line 12097) | _convertYcckToCmyk(data) {
method _convertCmykToRgb (line 12109) | _convertCmykToRgb(data) {
method _convertCmykToRgba (line 12123) | _convertCmykToRgba(data) {
method getData (line 12136) | getData({
class JpegStream (line 12197) | class JpegStream extends DecodeStream {
method constructor (line 12198) | constructor(stream, maybeLength, params) {
method bytes (line 12205) | get bytes() {
method ensureBuffer (line 12208) | ensureBuffer(requested) {}
method readBlock (line 12209) | readBlock() {
method decodeImage (line 12212) | decodeImage(bytes) {
method canAsyncDecodeImageFromBuffer (line 12267) | get canAsyncDecodeImageFromBuffer() {
function intArrayFromBase64 (line 12381) | function intArrayFromBase64(s) {
function tryParseAsDataURI (line 12389) | function tryParseAsDataURI(filename) {
function updateMemoryViews (line 12398) | function updateMemoryViews() {
function preRun (line 12413) | function preRun() {
function initRuntime (line 12422) | function initRuntime() {
function postRun (line 12426) | function postRun() {
function addOnPreRun (line 12435) | function addOnPreRun(cb) {
function addOnInit (line 12438) | function addOnInit(cb) {
function addOnPostRun (line 12441) | function addOnPostRun(cb) {
function addRunDependency (line 12447) | function addRunDependency(id) {
function removeRunDependency (line 12451) | function removeRunDependency(id) {
function findWasmBinary (line 12468) | function findWasmBinary() {
function getBinarySync (line 12473) | function getBinarySync(file) {
function instantiateSync (line 12486) | function instantiateSync(file, info) {
function getWasmImports (line 12493) | function getWasmImports() {
function createWasm (line 12498) | function createWasm() {
function _copy_pixels_1 (line 12528) | function _copy_pixels_1(compG_ptr, nb_pixels) {
function _copy_pixels_3 (line 12534) | function _copy_pixels_3(compR_ptr, compG_ptr, compB_ptr, nb_pixels) {
function _copy_pixels_4 (line 12548) | function _copy_pixels_4(compR_ptr, compG_ptr, compB_ptr, compA_ptr, nb_p...
function _fd_seek (line 12645) | function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
function _gray_to_rgba (line 12709) | function _gray_to_rgba(compG_ptr, nb_pixels) {
function _graya_to_rgba (line 12718) | function _graya_to_rgba(compG_ptr, compA_ptr, nb_pixels) {
function _jsPrintWarning (line 12729) | function _jsPrintWarning(message_ptr) {
function _rgb_to_rgba (line 12733) | function _rgb_to_rgba(compR_ptr, compG_ptr, compB_ptr, nb_pixels) {
function _storeErrorMessage (line 12748) | function _storeErrorMessage(message_ptr) {
function run (line 12783) | function run() {
class JpxError (line 12832) | class JpxError extends BaseException {
method constructor (line 12833) | constructor(msg) {
class JpxImage (line 12837) | class JpxImage {
method decode (line 12839) | static decode(data, decoderOptions) {
method cleanup (line 12850) | static cleanup() {
method parseImageProperties (line 12853) | static parseImageProperties(stream) {
class JpxStream (line 12883) | class JpxStream extends DecodeStream {
method constructor (line 12884) | constructor(stream, maybeLength, params) {
method bytes (line 12891) | get bytes() {
method ensureBuffer (line 12894) | ensureBuffer(requested) {}
method readBlock (line 12895) | readBlock(decoderOptions) {
method decodeImage (line 12898) | decodeImage(bytes, decoderOptions) {
method canAsyncDecodeImageFromBuffer (line 12908) | get canAsyncDecodeImageFromBuffer() {
class LZWStream (line 12921) | class LZWStream extends DecodeStream {
method constructor (line 12922) | constructor(str, maybeLength, earlyChange) {
method readBits (line 12945) | readBits(n) {
method readBlock (line 12962) | readBlock() {
class PredictorStream (line 13046) | class PredictorStream extends DecodeStream {
method constructor (line 13047) | constructor(str, maybeLength, params) {
method readBlockTiff (line 13069) | readBlockTiff() {
method readBlockPng (line 13141) | readBlockPng() {
class RunLengthStream (line 13231) | class RunLengthStream extends DecodeStream {
method constructor (line 13232) | constructor(str, maybeLength) {
method readBlock (line 13237) | readBlock() {
constant MAX_LENGTH_TO_CACHE (line 13290) | const MAX_LENGTH_TO_CACHE = 1000;
function getInlineImageCacheKey (line 13291) | function getInlineImageCacheKey(bytes) {
class Parser (line 13303) | class Parser {
method constructor (line 13304) | constructor({
method refill (line 13318) | refill() {
method shift (line 13322) | shift() {
method tryShift (line 13331) | tryShift() {
method getObj (line 13342) | getObj(cipherTransform = null) {
method findDefaultInlineStreamEnd (line 13409) | findDefaultInlineStreamEnd(stream) {
method findDCTDecodeInlineStreamEnd (line 13500) | findDCTDecodeInlineStreamEnd(stream) {
method findASCII85DecodeInlineStreamEnd (line 13577) | findASCII85DecodeInlineStreamEnd(stream) {
method findASCIIHexDecodeInlineStreamEnd (line 13611) | findASCIIHexDecodeInlineStreamEnd(stream) {
method inlineStreamSkipEI (line 13629) | inlineStreamSkipEI(stream) {
method makeInlineImage (line 13644) | makeInlineImage(cipherTransform) {
method #findStreamLength (line 13723) | #findStreamLength(startPos) {
method makeStream (line 13778) | makeStream(dict, cipherTransform) {
method filter (line 13810) | filter(stream, dict, length) {
method makeFilter (line 13838) | makeFilter(stream, name, maybeLength, params) {
function toHexDigit (line 13894) | function toHexDigit(ch) {
class Lexer (line 13903) | class Lexer {
method constructor (line 13904) | constructor(stream, knownCommands = null) {
method nextChar (line 13912) | nextChar() {
method peekChar (line 13915) | peekChar() {
method getNumber (line 13918) | getNumber() {
method getString (line 13992) | getString() {
method getName (line 14090) | getName() {
method _hexStringWarn (line 14129) | _hexStringWarn(ch) {
method getHexString (line 14140) | getHexString() {
method getObj (line 14175) | getObj() {
method skipToNextLine (line 14277) | skipToNextLine() {
class Linearization (line 14294) | class Linearization {
method create (line 14295) | static create(stream) {
constant BUILT_IN_CMAPS (line 14354) | const BUILT_IN_CMAPS = ["Adobe-GB1-UCS2", "Adobe-CNS1-UCS2", "Adobe-Japa...
constant MAX_MAP_RANGE (line 14355) | const MAX_MAP_RANGE = 2 ** 24 - 1;
class CMap (line 14356) | class CMap {
method constructor (line 14357) | constructor(builtInCMap = false) {
method addCodespaceRange (line 14366) | addCodespaceRange(n, low, high) {
method mapCidRange (line 14370) | mapCidRange(low, high, dstLow) {
method mapBfRange (line 14378) | mapBfRange(low, high, dstLow) {
method mapBfRangeToArray (line 14393) | mapBfRangeToArray(low, high, array) {
method mapOne (line 14404) | mapOne(src, dst) {
method lookup (line 14407) | lookup(code) {
method contains (line 14410) | contains(code) {
method forEach (line 14413) | forEach(callback) {
method charCodeOf (line 14428) | charCodeOf(value) {
method getMap (line 14440) | getMap() {
method readCharCode (line 14443) | readCharCode(str, offset, out) {
method getCharCodeLength (line 14462) | getCharCodeLength(charCode) {
method length (line 14476) | get length() {
method isIdentityCMap (line 14479) | get isIdentityCMap() {
class IdentityCMap (line 14494) | class IdentityCMap extends CMap {
method constructor (line 14495) | constructor(vertical, n) {
method mapCidRange (line 14500) | mapCidRange(low, high, dstLow) {
method mapBfRange (line 14503) | mapBfRange(low, high, dstLow) {
method mapBfRangeToArray (line 14506) | mapBfRangeToArray(low, high, array) {
method mapOne (line 14509) | mapOne(src, dst) {
method lookup (line 14512) | lookup(code) {
method contains (line 14515) | contains(code) {
method forEach (line 14518) | forEach(callback) {
method charCodeOf (line 14523) | charCodeOf(value) {
method getMap (line 14526) | getMap() {
method length (line 14533) | get length() {
method isIdentityCMap (line 14536) | get isIdentityCMap() {
function strToInt (line 14540) | function strToInt(str) {
function expectString (line 14547) | function expectString(obj) {
function expectInt (line 14552) | function expectInt(obj) {
function parseBfChar (line 14557) | function parseBfChar(cMap, lexer) {
function parseBfRange (line 14574) | function parseBfRange(cMap, lexer) {
function parseCidChar (line 14606) | function parseCidChar(cMap, lexer) {
function parseCidRange (line 14623) | function parseCidRange(cMap, lexer) {
function parseCodespaceRange (line 14643) | function parseCodespaceRange(cMap, lexer) {
function parseWMode (line 14665) | function parseWMode(cMap, lexer) {
function parseCMapName (line 14671) | function parseCMapName(cMap, lexer) {
function parseCMap (line 14677) | async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
function extendCMap (line 14733) | async function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
function createBuiltInCMap (line 14749) | async function createBuiltInCMap(name, fetchBuiltInCMap) {
class CMapFactory (line 14775) | class CMapFactory {
method create (line 14776) | static async create({
function getEncoding (line 14809) | function getEncoding(encodingName) {
constant MAX_SUBR_NESTING (line 14841) | const MAX_SUBR_NESTING = 10;
constant NUM_STANDARD_CFF_STRINGS (line 14843) | const NUM_STANDARD_CFF_STRINGS = 391;
method stackFn (line 14961) | stackFn(stack, index) {
method stackFn (line 14968) | stackFn(stack, index) {
method stackFn (line 14975) | stackFn(stack, index) {
method stackFn (line 14982) | stackFn(stack, index) {
method stackFn (line 15013) | stackFn(stack, index) {
class CFFParser (line 15053) | class CFFParser {
method constructor (line 15054) | constructor(file, properties, seacAnalysisEnabled) {
method parse (line 15059) | parse() {
method parseHeader (line 15120) | parseHeader() {
method parseDict (line 15145) | parseDict(dict) {
method parseIndex (line 15210) | parseIndex(pos) {
method parseNameIndex (line 15240) | parseNameIndex(index) {
method parseStringIndex (line 15248) | parseStringIndex(index) {
method createDict (line 15256) | createDict(Type, dict, strings) {
method parseCharString (line 15263) | parseCharString(state, data, localSubrIndex, globalSubrIndex) {
method parseCharStrings (line 15414) | parseCharStrings({
method emptyPrivateDictionary (line 15481) | emptyPrivateDictionary(parentDict) {
method parsePrivateDict (line 15486) | parsePrivateDict(parentDict) {
method parseCharsets (line 15522) | parseCharsets(pos, length, strings, cid) {
method parseEncoding (line 15568) | parseEncoding(pos, properties, strings, charset) {
method parseFDSelect (line 15626) | parseFDSelect(pos, length) {
class CFF (line 15663) | class CFF {
method constructor (line 15664) | constructor() {
method duplicateFirstGlyph (line 15677) | duplicateFirstGlyph() {
method hasGlyphId (line 15688) | hasGlyphId(id) {
class CFFHeader (line 15696) | class CFFHeader {
method constructor (line 15697) | constructor(major, minor, hdrSize, offSize) {
class CFFStrings (line 15704) | class CFFStrings {
method constructor (line 15705) | constructor() {
method get (line 15708) | get(index) {
method getSID (line 15717) | getSID(str) {
method add (line 15728) | add(value) {
method count (line 15731) | get count() {
class CFFIndex (line 15735) | class CFFIndex {
method constructor (line 15736) | constructor() {
method add (line 15740) | add(data) {
method set (line 15744) | set(index, data) {
method get (line 15748) | get(index) {
method count (line 15751) | get count() {
class CFFDict (line 15755) | class CFFDict {
method constructor (line 15756) | constructor(tables, strings) {
method setByKey (line 15766) | setByKey(key, value) {
method setByName (line 15786) | setByName(name, value) {
method hasName (line 15792) | hasName(name) {
method getByName (line 15795) | getByName(name) {
method removeByName (line 15805) | removeByName(name) {
method createTables (line 15808) | static createTables(layout) {
class CFFTopDict (line 15830) | class CFFTopDict extends CFFDict {
method tables (line 15831) | static get tables() {
method constructor (line 15834) | constructor(strings) {
class CFFPrivateDict (line 15840) | class CFFPrivateDict extends CFFDict {
method tables (line 15841) | static get tables() {
method constructor (line 15844) | constructor(strings) {
class CFFCharset (line 15854) | class CFFCharset {
method constructor (line 15855) | constructor(predefined, format, charset, raw) {
class CFFEncoding (line 15862) | class CFFEncoding {
method constructor (line 15863) | constructor(predefined, format, encoding, raw) {
class CFFFDSelect (line 15870) | class CFFFDSelect {
method constructor (line 15871) | constructor(format, fdSelect) {
method getFDIndex (line 15875) | getFDIndex(glyphIndex) {
class CFFOffsetTracker (line 15882) | class CFFOffsetTracker {
method constructor (line 15883) | constructor() {
method isTracking (line 15886) | isTracking(key) {
method track (line 15889) | track(key, location) {
method offset (line 15895) | offset(value) {
method setEntryLocation (line 15900) | setEntryLocation(key, values, output) {
class CFFCompiler (line 15925) | class CFFCompiler {
method constructor (line 15926) | constructor(cff) {
method compile (line 15929) | compile() {
method encodeNumber (line 16001) | encodeNumber(value) {
method EncodeFloatRegExp (line 16007) | static get EncodeFloatRegExp() {
method encodeFloat (line 16010) | encodeFloat(num) {
method encodeInteger (line 16038) | encodeInteger(value) {
method compileHeader (line 16055) | compileHeader(header) {
method compileNameIndex (line 16058) | compileNameIndex(names) {
method compileTopDicts (line 16078) | compileTopDicts(dicts, length, removeCidKeys) {
method compilePrivateDicts (line 16101) | compilePrivateDicts(dicts, trackers, output) {
method compileDict (line 16124) | compileDict(dict, offsetTracker) {
method compileStringIndex (line 16171) | compileStringIndex(strings) {
method compileCharStrings (line 16178) | compileCharStrings(charStrings) {
method compileCharset (line 16190) | compileCharset(charset, numGlyphs, strings, isCIDFont) {
method compileEncoding (line 16221) | compileEncoding(encoding) {
method compileFDSelect (line 16224) | compileFDSelect(fdSelect) {
method compileTypedArray (line 16255) | compileTypedArray(data) {
method compileIndex (line 16258) | compileIndex(index, trackers = []) {
function mapSpecialUnicodeValues (line 20872) | function mapSpecialUnicodeValues(code) {
function getUnicodeForGlyph (line 20882) | function getUnicodeForGlyph(name, glyphsUnicodeMap) {
function getUnicodeRangeFor (line 20910) | function getUnicodeRangeFor(value, lastPosition = -1) {
function getCharUnicodeCategory (line 20931) | function getCharUnicodeCategory(char) {
function clearUnicodeCaches (line 20945) | function clearUnicodeCaches() {
constant SEAC_ANALYSIS_ENABLED (line 20956) | const SEAC_ANALYSIS_ENABLED = true;
function recoverGlyphName (line 20969) | function recoverGlyphName(name, glyphsUnicodeMap) {
function type1FontGlyphMapping (line 20984) | function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) {
function normalizeFontName (line 21031) | function normalizeFontName(name) {
function getStandardFontName (line 21915) | function getStandardFontName(name) {
function isKnownFontName (line 21920) | function isKnownFontName(name) {
class ToUnicodeMap (line 21927) | class ToUnicodeMap {
method constructor (line 21928) | constructor(cmap = []) {
method length (line 21931) | get length() {
method forEach (line 21934) | forEach(callback) {
method has (line 21939) | has(i) {
method get (line 21942) | get(i) {
method charCodeOf (line 21945) | charCodeOf(value) {
method amend (line 21957) | amend(map) {
class IdentityToUnicodeMap (line 21963) | class IdentityToUnicodeMap {
method constructor (line 21964) | constructor(firstChar, lastChar) {
method length (line 21968) | get length() {
method forEach (line 21971) | forEach(callback) {
method has (line 21976) | has(i) {
method get (line 21979) | get(i) {
method charCodeOf (line 21985) | charCodeOf(v) {
method amend (line 21988) | amend(map) {
class CFFFont (line 21997) | class CFFFont {
method constructor (line 21998) | constructor(file, properties) {
method numGlyphs (line 22013) | get numGlyphs() {
method getCharset (line 22016) | getCharset() {
method getGlyphMapping (line 22019) | getGlyphMapping() {
method hasGlyphId (line 22066) | hasGlyphId(id) {
method _createBuiltInEncoding (line 22069) | _createBuiltInEncoding() {
function getUint32 (line 22111) | function getUint32(data, offset) {
function getUint16 (line 22114) | function getUint16(data, offset) {
function getInt16 (line 22117) | function getInt16(data, offset) {
function getInt8 (line 22120) | function getInt8(data, offset) {
function getFloat214 (line 22123) | function getFloat214(data, offset) {
function getSubroutineBias (line 22126) | function getSubroutineBias(subrs) {
function parseCmap (line 22136) | function parseCmap(data, start, end) {
function parseCff (line 22186) | function parseCff(data, start, end, seacAnalysisEnabled) {
function parseGlyfTable (line 22199) | function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {
function lookupCmap (line 22217) | function lookupCmap(ranges, unicode) {
function compileGlyf (line 22238) | function compileGlyf(code, cmds, font) {
function compileCharString (line 22395) | function compileCharString(charStringCode, cmds, font, glyphId) {
constant NOOP (line 22743) | const NOOP = [];
class Commands (line 22744) | class Commands {
method add (line 22746) | add(cmd, args) {
class CompiledFont (line 22760) | class CompiledFont {
method constructor (line 22761) | constructor(fontMatrix) {
method getPathJs (line 22766) | getPathJs(unicode) {
method compileGlyph (line 22788) | compileGlyph(code, glyphId) {
method compileGlyphImpl (line 22810) | compileGlyphImpl() {
method hasBuiltPath (line 22813) | hasBuiltPath(unicode) {
class TrueTypeCompiled (line 22821) | class TrueTypeCompiled extends CompiledFont {
method constructor (line 22822) | constructor(glyphs, cmap, fontMatrix) {
method compileGlyphImpl (line 22827) | compileGlyphImpl(code, cmds) {
class Type2Compiled (line 22831) | class Type2Compiled extends CompiledFont {
method constructor (line 22832) | constructor(cffInfo, cmap, fontMatrix, glyphNameMap) {
method compileGlyphImpl (line 22845) | compileGlyphImpl(code, cmds, glyphId) {
class FontRendererFactory (line 22849) | class FontRendererFactory {
method create (line 22850) | static create(font, seacAnalysisEnabled) {
constant ON_CURVE_POINT (line 25923) | const ON_CURVE_POINT = 1 << 0;
constant X_SHORT_VECTOR (line 25924) | const X_SHORT_VECTOR = 1 << 1;
constant Y_SHORT_VECTOR (line 25925) | const Y_SHORT_VECTOR = 1 << 2;
constant REPEAT_FLAG (line 25926) | const REPEAT_FLAG = 1 << 3;
constant X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR (line 25927) | const X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR = 1 << 4;
constant Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR (line 25928) | const Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR = 1 << 5;
constant OVERLAP_SIMPLE (line 25929) | const OVERLAP_SIMPLE = 1 << 6;
constant ARG_1_AND_2_ARE_WORDS (line 25930) | const ARG_1_AND_2_ARE_WORDS = 1 << 0;
constant ARGS_ARE_XY_VALUES (line 25931) | const ARGS_ARE_XY_VALUES = 1 << 1;
constant WE_HAVE_A_SCALE (line 25932) | const WE_HAVE_A_SCALE = 1 << 3;
constant MORE_COMPONENTS (line 25933) | const MORE_COMPONENTS = 1 << 5;
constant WE_HAVE_AN_X_AND_Y_SCALE (line 25934) | const WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
constant WE_HAVE_A_TWO_BY_TWO (line 25935) | const WE_HAVE_A_TWO_BY_TWO = 1 << 7;
constant WE_HAVE_INSTRUCTIONS (line 25936) | const WE_HAVE_INSTRUCTIONS = 1 << 8;
class GlyfTable (line 25937) | class GlyfTable {
method constructor (line 25938) | constructor({
method getSize (line 25962) | getSize() {
method write (line 25968) | write() {
method scale (line 25997) | scale(factors) {
class Glyph (line 26003) | class Glyph {
method constructor (line 26004) | constructor({
method parse (line 26013) | static parse(pos, glyf) {
method getSize (line 26037) | getSize() {
method write (line 26044) | write(pos, buf) {
method scale (line 26059) | scale(factor) {
class GlyphHeader (line 26074) | class GlyphHeader {
method constructor (line 26075) | constructor({
method parse (line 26088) | static parse(pos, glyf) {
method getSize (line 26097) | getSize() {
method write (line 26100) | write(pos, buf) {
method scale (line 26108) | scale(x, factor) {
class Contour (line 26113) | class Contour {
method constructor (line 26114) | constructor({
class SimpleGlyph (line 26124) | class SimpleGlyph {
method constructor (line 26125) | constructor({
method parse (line 26132) | static parse(pos, glyf, numberOfContours) {
method getSize (line 26216) | getSize() {
method write (line 26243) | write(pos, buf) {
method scale (line 26319) | scale(x, factor) {
class CompositeGlyph (line 26330) | class CompositeGlyph {
method constructor (line 26331) | constructor({
method parse (line 26346) | static parse(pos, glyf) {
method getSize (line 26399) | getSize() {
method write (line 26414) | write(pos, buf) {
method scale (line 26450) | scale(x, factor) {}
function writeInt16 (line 26463) | function writeInt16(dest, offset, num) {
function writeInt32 (line 26467) | function writeInt32(dest, offset, num) {
function writeData (line 26473) | function writeData(dest, offset, data) {
constant OTF_HEADER_SIZE (line 26486) | const OTF_HEADER_SIZE = 12;
constant OTF_TABLE_ENTRY_SIZE (line 26487) | const OTF_TABLE_ENTRY_SIZE = 16;
class OpenTypeFileBuilder (line 26488) | class OpenTypeFileBuilder {
method constructor (line 26489) | constructor(sfnt) {
method getSearchParams (line 26493) | static getSearchParams(entriesCount, entrySize) {
method toArray (line 26507) | toArray() {
method addTable (line 26558) | addTable(tag, data) {
constant HINTING_ENABLED (line 26578) | const HINTING_ENABLED = false;
constant COMMAND_MAP (line 26579) | const COMMAND_MAP = {
class Type1CharString (line 26596) | class Type1CharString {
method constructor (line 26597) | constructor() {
method convert (line 26604) | convert(encoded, subrs, seacAnalysisEnabled) {
method executeCommand (line 26797) | executeCommand(howManyArgs, command, keepStack) {
constant EEXEC_ENCRYPT_KEY (line 26821) | const EEXEC_ENCRYPT_KEY = 55665;
constant CHAR_STRS_ENCRYPT_KEY (line 26822) | const CHAR_STRS_ENCRYPT_KEY = 4330;
function isHexDigit (line 26823) | function isHexDigit(code) {
function decrypt (line 26826) | function decrypt(data, key, discardNumber) {
function decryptAscii (line 26847) | function decryptAscii(data, key, discardNumber) {
function isSpecial (line 26873) | function isSpecial(c) {
class Type1Parser (line 26876) | class Type1Parser {
method constructor (line 26877) | constructor(stream, encrypted, seacAnalysisEnabled) {
method readNumberArray (line 26887) | readNumberArray() {
method readNumber (line 26899) | readNumber() {
method readInt (line 26903) | readInt() {
method readBoolean (line 26907) | readBoolean() {
method nextChar (line 26911) | nextChar() {
method prevChar (line 26914) | prevChar() {
method getToken (line 26918) | getToken() {
method readCharStrings (line 26947) | readCharStrings(bytes, lenIV) {
method extractFontProgram (line 26953) | extractFontProgram(properties) {
method extractFontHeader (line 27086) | extractFontHeader(properties) {
function findBlock (line 27146) | function findBlock(streamBytes, signature, startIndex) {
function getHeaderBlock (line 27172) | function getHeaderBlock(stream, suggestedLength) {
function getEexecBlock (line 27218) | function getEexecBlock(stream, suggestedLength) {
class Type1Font (line 27228) | class Type1Font {
method constructor (line 27229) | constructor(name, file, properties) {
method numGlyphs (line 27259) | get numGlyphs() {
method getCharset (line 27262) | getCharset() {
method getGlyphMapping (line 27271) | getGlyphMapping(properties) {
method hasGlyphId (line 27298) | hasGlyphId(id) {
method getSeacs (line 27308) | getSeacs(charstrings) {
method getType2Charstrings (line 27318) | getType2Charstrings(type1Charstrings) {
method getType2Subrs (line 27325) | getType2Subrs(type1Subrs) {
method wrap (line 27345) | wrap(name, glyphs, charstrings, subrs, properties) {
constant PRIVATE_USE_AREAS (line 27452) | const PRIVATE_USE_AREAS = [[0xe000, 0xf8ff], [0x100000, 0x10fffd]];
constant PDF_GLYPH_SPACE_UNITS (line 27453) | const PDF_GLYPH_SPACE_UNITS = 1000;
constant EXPORT_DATA_PROPERTIES (line 27454) | const EXPORT_DATA_PROPERTIES = ["ascent", "bbox", "black", "bold", "char...
constant EXPORT_DATA_EXTRA_PROPERTIES (line 27455) | const EXPORT_DATA_EXTRA_PROPERTIES = ["cMap", "defaultEncoding", "differ...
function adjustWidths (line 27456) | function adjustWidths(properties) {
function adjustTrueTypeToUnicode (line 27470) | function adjustTrueTypeToUnicode(properties, isSymbolicFont, nameRecords) {
function adjustType1ToUnicode (line 27515) | function adjustType1ToUnicode(properties, builtInEncoding) {
function amendFallbackToUnicode (line 27546) | function amendFallbackToUnicode(properties) {
class fonts_Glyph (line 27564) | class fonts_Glyph {
method constructor (line 27565) | constructor(originalCharCode, fontChar, unicode, accent, width, vmetri...
method category (line 27576) | get category() {
function int16 (line 27580) | function int16(b0, b1) {
function writeSignedInt16 (line 27583) | function writeSignedInt16(bytes, index, value) {
function signedInt16 (line 27587) | function signedInt16(b0, b1) {
function writeUint32 (line 27591) | function writeUint32(bytes, index, value) {
function int32 (line 27597) | function int32(b0, b1, b2, b3) {
function string16 (line 27600) | function string16(value) {
function safeString16 (line 27603) | function safeString16(value) {
function isTrueTypeFile (line 27611) | function isTrueTypeFile(file) {
function isTrueTypeCollectionFile (line 27615) | function isTrueTypeCollectionFile(file) {
function isOpenTypeFile (line 27619) | function isOpenTypeFile(file) {
function isType1File (line 27623) | function isType1File(file) {
function isCFFFile (line 27633) | function isCFFFile(file) {
function getFontFileType (line 27640) | function getFontFileType(file, {
function applyStandardFontGlyphMap (line 27671) | function applyStandardFontGlyphMap(map, glyphMap) {
function buildToFontChar (line 27676) | function buildToFontChar(encoding, glyphsUnicodeMap, differences) {
function isMacNameRecord (line 27693) | function isMacNameRecord(r) {
function isWinNameRecord (line 27696) | function isWinNameRecord(r) {
function convertCidString (line 27699) | function convertCidString(charCode, cid, shouldThrow = false) {
function adjustMapping (line 27713) | function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId, toUn...
function getRanges (line 27759) | function getRanges(glyphs, toUnicodeExtraMap, numGlyphs) {
function createCmapTable (line 27809) | function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
function validateOS2Table (line 27892) | function validateOS2Table(os2, file) {
function createOS2Table (line 27913) | function createOS2Table(properties, charstrings, override) {
function createPostTable (line 27969) | function createPostTable(properties) {
function createPostscriptName (line 27973) | function createPostscriptName(name) {
function createNameTable (line 27976) | function createNameTable(name, proto) {
class Font (line 28010) | class Font {
method constructor (line 28011) | constructor(name, file, properties) {
method renderer (line 28135) | get renderer() {
method exportData (line 28139) | exportData(extraProperties = false) {
method fallbackToSystemFont (line 28151) | fallbackToSystemFont(properties) {
method checkAndRepair (line 28248) | checkAndRepair(name, font, properties) {
method convert (line 29578) | convert(fontName, font, properties) {
method _spaceWidth (line 29680) | get _spaceWidth() {
method _charToGlyph (line 29710) | _charToGlyph(charcode, isSpace = false) {
method charsToGlyphs (line 29775) | charsToGlyphs(chars) {
method getCharPositions (line 29804) | getCharPositions(chars) {
method glyphCacheValues (line 29822) | get glyphCacheValues() {
method encodeString (line 29825) | encodeString(str) {
class ErrorFont (line 29859) | class ErrorFont {
method constructor (line 29860) | constructor(error) {
method charsToGlyphs (line 29865) | charsToGlyphs() {
method encodeString (line 29868) | encodeString(chars) {
method exportData (line 29871) | exportData(extraProperties = false) {
class Pattern (line 29899) | class Pattern {
method constructor (line 29900) | constructor() {
method parseShading (line 29903) | static parseShading(shading, xref, res, pdfFunctionFactory, localColor...
class BaseShading (line 29928) | class BaseShading {
method getIR (line 29930) | getIR() {
class RadialAxialShading (line 29934) | class RadialAxialShading extends BaseShading {
method constructor (line 29935) | constructor(dict, xref, resources, pdfFunctionFactory, localColorSpace...
method getIR (line 30049) | getIR() {
class MeshStreamReader (line 30073) | class MeshStreamReader {
method constructor (line 30074) | constructor(stream, context) {
method hasData (line 30084) | get hasData() {
method readBits (line 30099) | readBits(n) {
method align (line 30123) | align() {
method readFlag (line 30127) | readFlag() {
method readCoordinate (line 30130) | readCoordinate() {
method readComponents (line 30138) | readComponents() {
function buildB (line 30156) | function buildB(count) {
function getB (line 30165) | function getB(count) {
function clearPatternCaches (line 30168) | function clearPatternCaches() {
class MeshShading (line 30171) | class MeshShading extends BaseShading {
method constructor (line 30175) | constructor(stream, xref, resources, pdfFunctionFactory, localColorSpa...
method _decodeType4Shading (line 30239) | _decodeType4Shading(reader) {
method _decodeType5Shading (line 30280) | _decodeType5Shading(reader, verticesPerRow) {
method _decodeType6Shading (line 30298) | _decodeType6Shading(reader) {
method _decodeType7Shading (line 30415) | _decodeType7Shading(reader) {
method _buildFigureFromPatch (line 30540) | _buildFigureFromPatch(index) {
method _updateBounds (line 30613) | _updateBounds() {
method _packData (line 30628) | _packData() {
method getIR (line 30658) | getIR() {
class DummyShading (line 30668) | class DummyShading extends BaseShading {
method getIR (line 30669) | getIR() {
function getTilingPatternIR (line 30673) | function getTilingPatternIR(operatorList, dict, color) {
function getXfaFontName (line 30941) | function getXfaFontName(name) {
function getXfaFontWidths (line 30946) | function getXfaFontWidths(name) {
function getXfaFontDict (line 30975) | function getXfaFontDict(name) {
class PostScriptParser (line 31001) | class PostScriptParser {
method constructor (line 31002) | constructor(lexer) {
method nextToken (line 31008) | nextToken() {
method accept (line 31012) | accept(type) {
method expect (line 31019) | expect(type) {
method parse (line 31025) | parse() {
method parseBlock (line 31032) | parseBlock() {
method parseCondition (line 31045) | parseCondition() {
class PostScriptToken (line 31077) | class PostScriptToken {
method opCache (line 31078) | static get opCache() {
method constructor (line 31081) | constructor(type, value) {
method getOperator (line 31085) | static getOperator(op) {
method LBRACE (line 31088) | static get LBRACE() {
method RBRACE (line 31091) | static get RBRACE() {
method IF (line 31094) | static get IF() {
method IFELSE (line 31097) | static get IFELSE() {
class PostScriptLexer (line 31101) | class PostScriptLexer {
method constructor (line 31102) | constructor(stream) {
method nextChar (line 31107) | nextChar() {
method getToken (line 31110) | getToken() {
method getNumber (line 31166) | getNumber() {
class BaseLocalCache (line 31196) | class BaseLocalCache {
method constructor (line 31197) | constructor(options) {
method getByName (line 31205) | getByName(name) {
method getByRef (line 31215) | getByRef(ref) {
method set (line 31218) | set(name, ref, data) {
class LocalImageCache (line 31222) | class LocalImageCache extends BaseLocalCache {
method set (line 31223) | set(name, ref = null, data) {
class LocalColorSpaceCache (line 31241) | class LocalColorSpaceCache extends BaseLocalCache {
method set (line 31242) | set(name = null, ref = null, data) {
class LocalFunctionCache (line 31262) | class LocalFunctionCache extends BaseLocalCache {
method constructor (line 31263) | constructor(options) {
method set (line 31268) | set(name = null, ref, data) {
class LocalGStateCache (line 31278) | class LocalGStateCache extends BaseLocalCache {
method set (line 31279) | set(name, ref = null, data) {
class LocalTilingPatternCache (line 31297) | class LocalTilingPatternCache extends BaseLocalCache {
method constructor (line 31298) | constructor(options) {
method set (line 31303) | set(name = null, ref, data) {
class RegionalImageCache (line 31313) | class RegionalImageCache extends BaseLocalCache {
method constructor (line 31314) | constructor(options) {
method set (line 31319) | set(name = null, ref, data) {
class GlobalImageCache (line 31329) | class GlobalImageCache {
method constructor (line 31334) | constructor() {
method #byteSize (line 31338) | get #byteSize() {
method #cacheLimitReached (line 31345) | get #cacheLimitReached() {
method shouldCache (line 31354) | shouldCache(ref, pageIndex) {
method addDecodeFailed (line 31369) | addDecodeFailed(ref) {
method hasDecodeFailed (line 31372) | hasDecodeFailed(ref) {
method addByteSize (line 31375) | addByteSize(ref, byteSize) {
method getData (line 31385) | getData(ref, pageIndex) {
method setData (line 31400) | setData(ref, data) {
method clear (line 31413) | clear(onlyData = false) {
class PDFFunctionFactory (line 31437) | class PDFFunctionFactory {
method constructor (line 31438) | constructor({
method create (line 31445) | create(fn) {
method createFromArray (line 31458) | createFromArray(fnObj) {
method getCached (line 31471) | getCached(cacheKey) {
method _cache (line 31488) | _cache(cacheKey, parsedFunction) {
method _localFunctionCache (line 31504) | get _localFunctionCache() {
function toNumberArray (line 31508) | function toNumberArray(arr) {
class PDFFunction (line 31517) | class PDFFunction {
method getSampleArray (line 31518) | static getSampleArray(size, outputSize, bps, stream) {
method parse (line 31543) | static parse({
method parseArray (line 31582) | static parseArray({
method constructSampled (line 31608) | static constructSampled({
method constructInterpolated (line 31697) | static constructInterpolated({
method constructStiched (line 31717) | static constructStiched({
method constructPostScript (line 31772) | static constructPostScript({
function isPDFFunction (line 31841) | function isPDFFunction(v) {
class PostScriptStack (line 31852) | class PostScriptStack {
method constructor (line 31854) | constructor(initialStack) {
method push (line 31857) | push(value) {
method pop (line 31863) | pop() {
method copy (line 31869) | copy(n) {
method index (line 31878) | index(n) {
method roll (line 31881) | roll(n, p) {
class PostScriptEvaluator (line 31903) | class PostScriptEvaluator {
method constructor (line 31904) | constructor(operators) {
method execute (line 31907) | execute(initialStack) {
class AstNode (line 32135) | class AstNode {
method constructor (line 32136) | constructor(type) {
method visit (line 32139) | visit(visitor) {
class AstArgument (line 32143) | class AstArgument extends AstNode {
method constructor (line 32144) | constructor(index, min, max) {
method visit (line 32150) | visit(visitor) {
class AstLiteral (line 32154) | class AstLiteral extends AstNode {
method constructor (line 32155) | constructor(number) {
method visit (line 32161) | visit(visitor) {
class AstBinaryOperation (line 32165) | class AstBinaryOperation extends AstNode {
method constructor (line 32166) | constructor(op, arg1, arg2, min, max) {
method visit (line 32174) | visit(visitor) {
class AstMin (line 32178) | class AstMin extends AstNode {
method constructor (line 32179) | constructor(arg, max) {
method visit (line 32185) | visit(visitor) {
class AstVariable (line 32189) | class AstVariable extends AstNode {
method constructor (line 32190) | constructor(index, min, max) {
method visit (line 32196) | visit(visitor) {
class AstVariableDefinition (line 32200) | class AstVariableDefinition extends AstNode {
method constructor (line 32201) | constructor(variable, arg) {
method visit (line 32206) | visit(visitor) {
class ExpressionBuilderVisitor (line 32210) | class ExpressionBuilderVisitor {
method constructor (line 32211) | constructor() {
method visitArgument (line 32214) | visitArgument(arg) {
method visitVariable (line 32217) | visitVariable(variable) {
method visitLiteral (line 32220) | visitLiteral(literal) {
method visitBinaryOperation (line 32223) | visitBinaryOperation(operation) {
method visitVariableDefinition (line 32230) | visitVariableDefinition(definition) {
method visitMin (line 32237) | visitMin(max) {
method toString (line 32242) | toString() {
function buildAddOperation (line 32246) | function buildAddOperation(num1, num2) {
function buildMulOperation (line 32258) | function buildMulOperation(num1, num2) {
function buildSubOperation (line 32279) | function buildSubOperation(num1, num2) {
function buildMinOperation (line 32292) | function buildMinOperation(num1, max) {
class PostScriptCompiler (line 32300) | class PostScriptCompiler {
method compile (line 32301) | compile(code, domain, range) {
function isOdd (line 32464) | function isOdd(i) {
function isEven (line 32467) | function isEven(i) {
function findUnequal (line 32470) | function findUnequal(arr, start, value) {
function setValues (line 32479) | function setValues(arr, start, end, value) {
function reverseValues (line 32484) | function reverseValues(arr, start, end) {
function createBidiText (line 32491) | function createBidiText(str, isLTR, vertical = false) {
function bidi (line 32505) | function bidi(str, startLevel = -1, vertical = false) {
constant NORMAL (line 32710) | const NORMAL = {
constant BOLD (line 32714) | const BOLD = {
constant ITALIC (line 32718) | const ITALIC = {
constant BOLDITALIC (line 32722) | const BOLDITALIC = {
function getStyleToAppend (line 32837) | function getStyleToAppend(style) {
function getFamilyName (line 32855) | function getFamilyName(str) {
function generateFont (line 32859) | function generateFont({
function getFontSubstitution (line 32900) | function getFontSubstitution(systemFontCache, idFactory, localFontPath, ...
constant MIN_IMAGE_DIM (line 32979) | const MIN_IMAGE_DIM = 2048;
constant MAX_IMAGE_DIM (line 32980) | const MAX_IMAGE_DIM = 65537;
constant MAX_ERROR (line 32981) | const MAX_ERROR = 128;
class ImageResizer (line 32982) | class ImageResizer {
method constructor (line 32983) | constructor(imgData, isMask) {
method needsToBeResized (line 32987) | static needsToBeResized(width, height) {
method MAX_DIM (line 33012) | static get MAX_DIM() {
method MAX_AREA (line 33015) | static get MAX_AREA() {
method MAX_AREA (line 33019) | static set MAX_AREA(area) {
method setMaxArea (line 33025) | static setMaxArea(area) {
method _areGoodDims (line 33030) | static _areGoodDims(width, height) {
method _guessMax (line 33042) | static _guessMax(start, end, tolerance, defaultHeight) {
method createImage (line 33054) | static async createImage(imgData, isMask = false) {
method _createImage (line 33057) | async _createImage() {
method _encodeBMP (line 33100) | _encodeBMP() {
constant SEED (line 33228) | const SEED = 0xc3d2e1f0;
constant MASK_HIGH (line 33229) | const MASK_HIGH = 0xffff0000;
constant MASK_LOW (line 33230) | const MASK_LOW = 0xffff;
class MurmurHash3_64 (line 33231
Condensed preview — 621 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,864K chars).
[
{
"path": ".coderabbit.yaml",
"chars": 117,
"preview": "reviews:\n auto_review:\n path_filters:\n - \"!src/assets/**\" # Exclude all files in the 'test_files' directory\n"
},
{
"path": ".eslintrc.js",
"chars": 127,
"preview": "module.exports = {\n // 其他配置\n rules: {\n \"no-unused-expressions\": \"off\",\n \"@typescript-eslint/ban-types\": \"off\",\n "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 660,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: General Inquiry\n url: https://koodoreader.com/en/support\n abo"
},
{
"path": ".github/ISSUE_TEMPLATE/submit_translation.yml",
"chars": 1085,
"preview": "name: Submit Translation\ndescription: Edit current translation or add new languages\nlabels: \"submit translation\"\nbody:\n "
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 124,
"preview": "## Description\n\n<!-- Note that we only accept pull request related to translations -->\n<!-- 请注意,我们只接受翻译相关的 Pull Request "
},
{
"path": ".github/workflows/docker-publish.yml",
"chars": 3500,
"preview": "name: Docker\n\n# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and ar"
},
{
"path": ".github/workflows/release-appx.yml",
"chars": 1314,
"preview": "name: Build/release-appx\n\non: workflow_dispatch\n\njobs:\n release:\n runs-on: ${{ matrix.os }}\n\n # Platforms to buil"
},
{
"path": ".github/workflows/release.yml",
"chars": 3536,
"preview": "name: Build/release\n\non: workflow_dispatch\n\njobs:\n release:\n runs-on: ${{ matrix.os }}\n\n # Platforms to build on/"
},
{
"path": ".github/workflows/upload.yml",
"chars": 477,
"preview": "name: Download/upload\n\non: workflow_dispatch\n\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - name: Checkou"
},
{
"path": ".gitignore",
"chars": 476,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
},
{
"path": ".prettierrc",
"chars": 282,
"preview": "{\n \"semi\": true,\n \"singleQuote\": false,\n \"tabWidth\": 2,\n \"useTabs\": false,\n \"printWidth\": 80,\n \"trailingComma\": \"e"
},
{
"path": ".yarnrc",
"chars": 22,
"preview": "network-timeout 600000"
},
{
"path": "Dockerfile",
"chars": 1868,
"preview": "FROM node:20-slim as builder\nRUN apt-get update && apt-get install -y jq curl wget python3 git\nWORKDIR /app\n\n### Get the"
},
{
"path": "LICENSE",
"chars": 34499,
"preview": "GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software "
},
{
"path": "README.md",
"chars": 8444,
"preview": "<div align=\"left\">\n\n[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [हिंदी](https://gith"
},
{
"path": "README_cn.md",
"chars": 3400,
"preview": "<div align=\"left\">\n\n简体中文 | [हिंदी](https://github.com/koodo-reader/koodo-reader/blob/master/README_hi.md) |[Português](h"
},
{
"path": "README_hi.md",
"chars": 3838,
"preview": "<div align=\"left\">\n\n[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [English](https://gi"
},
{
"path": "README_id.md",
"chars": 3904,
"preview": "<div align=\"left\">\n\n[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [हिंदी](https://gith"
},
{
"path": "README_pt.md",
"chars": 4072,
"preview": "<div align=\"left\">\n\n[简体中文](https://github.com/koodo-reader/koodo-reader/blob/master/README_cn.md) | [हिंदी](https://gith"
},
{
"path": "assets/macos/entitlements.mac.plist",
"chars": 490,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "assets/windows/installer.nsh",
"chars": 264,
"preview": "!macro customUnInstall\n MessageBox MB_YESNO \"Do you want to delete all your data including books, notes, highlights, bo"
},
{
"path": "docker-compose-secret.yml",
"chars": 583,
"preview": "# This docker-compose file uses secrets to manage sensitive information like passwords.\nservices:\n koodo-reader:\n im"
},
{
"path": "docker-compose.yml",
"chars": 507,
"preview": "version: \"3.8\"\n\nservices:\n koodo-reader:\n build: .\n container_name: koodo-reader\n restart: unless-stopped\n "
},
{
"path": "electron-builder.env",
"chars": 20,
"preview": "USE_HARD_LINKS=false"
},
{
"path": "httpServer.js",
"chars": 12586,
"preview": "const http = require(\"http\");\nconst fs = require(\"fs\");\nconst path = require(\"path\");\nconst url = require(\"url\");\n\n// 从 "
},
{
"path": "main.js",
"chars": 34389,
"preview": "const {\n app,\n BrowserWindow,\n WebContentsView,\n Menu,\n ipcMain,\n dialog,\n powerSaveBlocker,\n nativeTheme,\n pro"
},
{
"path": "package.json",
"chars": 9118,
"preview": "{\n \"name\": \"koodo-reader\",\n \"main\": \"main.js\",\n \"version\": \"2.3.0\",\n \"description\": \"Koodo Reader is a cross-platfor"
},
{
"path": "public/LICENSE",
"chars": 10174,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "public/assets/styles/dark.css",
"chars": 6790,
"preview": "body {\n -webkit-tap-highlight-color: transparent;\n background: rgba(47, 52, 55, 1);\n color: rgba(235, 235, 235, 1);\n}"
},
{
"path": "public/assets/styles/default.css",
"chars": 6032,
"preview": "body {\n -webkit-tap-highlight-color: transparent;\n background: rgba(255, 255, 255, 1);\n color: rgba(75, 75, 75, 1);\n}"
},
{
"path": "public/index.html",
"chars": 2020,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.p"
},
{
"path": "public/lib/7z-wasm/7zz.umd.js",
"chars": 282041,
"preview": "\nvar SevenZip = (function() {\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.cu"
},
{
"path": "public/lib/7z-wasm/License.txt",
"chars": 1876,
"preview": " 7-Zip\n ~~~~~\n License for use and distribution\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n 7-Zip Copyright (C) 1999-2015 I"
},
{
"path": "public/lib/esearch-ocr/esearch-ocr.umd.js",
"chars": 27897,
"preview": "(function(B,O){typeof exports==\"object\"&&typeof module<\"u\"?O(exports):typeof define==\"function\"&&define.amd?define([\"exp"
},
{
"path": "public/lib/libunrar/libunrar.js",
"chars": 66836,
"preview": "var Module = {\n 'print': function(text) { console.log('stdout: ' + text) },\n 'printErr': function(text) { console"
},
{
"path": "public/lib/libunrar/rpc.js",
"chars": 4263,
"preview": "// Worker side\nif (typeof document === typeof void 0) {\n importScripts(\"Promise.min.js\");\n\n var RPC = {};\n RPC.init ="
},
{
"path": "public/lib/libunrar/worker.js",
"chars": 1023,
"preview": "var st = Date.now()\nconsole.log(\"loading libunrar.js\")\nimportScripts(\"./libunrar.js\")\nvar elapt = Date.now() - st\nconsol"
},
{
"path": "public/lib/pdfjs/annotation_layer_builder.css",
"chars": 10208,
"preview": "/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "public/lib/pdfjs/cmaps/CNS2-V.bcmap",
"chars": 91,
"preview": "\u0003RCopyright 1990-2009 Adobe Systems Incorporated.\nAll rights reserved.\nSee ./LICENSE\u0006CNS2-H"
},
{
"path": "public/lib/pdfjs/cmaps/ETenms-B5-H.bcmap",
"chars": 99,
"preview": "\u0002RCopyright 1990-2009 Adobe Systems Incorporated.\nAll rights reserved.\nSee ./LICENSE\tETen-B5-H`\u0001 ^\u0001"
},
{
"path": "public/lib/pdfjs/cmaps/GB-H.bcmap",
"chars": 356,
"preview": "\u0002RCopyright 1990-2009 Adobe Systems Incorporated.\nAll rights reserved.\nSee ./LICENSE\u0001\u0001!!]aX!!]`21>\u0002\tp\u0002\u000bz$]\u0006\"Rd-U7*\u0017\r\b4%+"
},
{
"path": "public/lib/pdfjs/cmaps/LICENSE",
"chars": 2080,
"preview": "%%Copyright: -----------------------------------------------------------\n%%Copyright: Copyright 1990-2009 Adobe Systems "
},
{
"path": "public/lib/pdfjs/pdf.mjs",
"chars": 765568,
"preview": "/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2024"
},
{
"path": "public/lib/pdfjs/pdf.worker.mjs",
"chars": 2328156,
"preview": "/**\n * @licstart The following is the entire license notice for the\n * JavaScript code in this page\n *\n * Copyright 2024"
},
{
"path": "public/lib/pdfjs/standard_fonts/LICENSE_FOXIT",
"chars": 1553,
"preview": "// Copyright 2014 PDFium Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or "
},
{
"path": "public/lib/pdfjs/standard_fonts/LICENSE_LIBERATION",
"chars": 4414,
"preview": "Digitized data copyright (c) 2010 Google Corporation\n\twith Reserved Font Arimo, Tinos and Cousine.\nCopyright (c) 2012 Re"
},
{
"path": "public/lib/pdfjs/text_layer_builder.css",
"chars": 3186,
"preview": "/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
},
{
"path": "public/lib/sqljs-wasm/sql-wasm.js",
"chars": 48863,
"preview": "\n// We are modularizing this manually because the current modularize setting in Emscripten has some issues:\n// https://g"
},
{
"path": "public/robots.txt",
"chars": 67,
"preview": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
},
{
"path": "src/assets/lib/kookit-extra.min.mjs",
"chars": 110174,
"preview": "import e from\"axios\";import t from\"fs\";import i from\"path\";import{promisify as r}from\"util\";import o from\"stream\";import"
},
{
"path": "src/assets/locales/am/translation.json",
"chars": 52723,
"preview": "{\n \"Books\": \"መጻሕፍት\",\n \"Recent\": \"የቅርብ ጊዜ\",\n \"Bookmarks\": \"ዕልባቶች\",\n \"Favorites\": \"ተወዳጆች\",\n \"Notes\": \"ማስታወሻዎች\",\n \"Hi"
},
{
"path": "src/assets/locales/ar/translation.json",
"chars": 57254,
"preview": "{\n \"Books\": \"الكتب\",\n \"Recent\": \"الأخيرة\",\n \"Bookmarks\": \"العلامات المرجعية\",\n \"Favorites\": \"المفضلة\",\n \"Notes\": \"ا"
},
{
"path": "src/assets/locales/bg/translation.json",
"chars": 62963,
"preview": "{\n \"Books\": \"Книги\",\n \"Recent\": \"Последни\",\n \"Bookmarks\": \"Отметки\",\n \"Favorites\": \"Любими\",\n \"Notes\": \"Бележки\",\n "
},
{
"path": "src/assets/locales/bn/translation.json",
"chars": 59503,
"preview": "{\n \"Books\": \"বই\",\n \"Recent\": \"সর্বশেষ\",\n \"Bookmarks\": \"বুকমার্ক\",\n \"Favorites\": \"পছন্দের বই\",\n \"Notes\": \"নোট\",\n \"H"
},
{
"path": "src/assets/locales/bo/translation.json",
"chars": 60776,
"preview": "{\n \"Books\": \"དཔེ་ཆ།\",\n \"Recent\": \"གསར་སྣོན།\",\n \"Bookmarks\": \"དཔེ་བྱང་།\",\n \"Favorites\": \"དགའ་མོས་དཔེ་ཆ།\",\n \"Notes\": "
},
{
"path": "src/assets/locales/cs/translation.json",
"chars": 59563,
"preview": "{\n \"Books\": \"Všechny knihy\",\n \"Recent\": \"Nedávné\",\n \"Bookmarks\": \"Záložky\",\n \"Favorites\": \"Oblíbené\",\n \"Notes\": \"Po"
},
{
"path": "src/assets/locales/da/translation.json",
"chars": 58651,
"preview": "{\n \"Books\": \"Bøger\",\n \"Recent\": \"Seneste\",\n \"Bookmarks\": \"Bogmærker\",\n \"Favorites\": \"Favoritter\",\n \"Notes\": \"Noter\""
},
{
"path": "src/assets/locales/de/translation.json",
"chars": 63824,
"preview": "{\n \"Books\": \"Bücher\",\n \"Recent\": \"Kürzlich\",\n \"Bookmarks\": \"Lesezeichen\",\n \"Favorites\": \"Favoriten\",\n \"Notes\": \"Not"
},
{
"path": "src/assets/locales/el/translation.json",
"chars": 64062,
"preview": "{\n \"Books\": \"Βιβλία\",\n \"Recent\": \"Πρόσφατα\",\n \"Bookmarks\": \"Σελιδοδείκτες\",\n \"Favorites\": \"Αγαπημένα\",\n \"Notes\": \"Σ"
},
{
"path": "src/assets/locales/en/translation.json",
"chars": 59247,
"preview": "{\n \"Books\": \"Books\",\n \"Recent\": \"Recents\",\n \"Bookmarks\": \"Bookmarks\",\n \"Favorites\": \"Favorites\",\n \"Notes\": \"Notes\","
},
{
"path": "src/assets/locales/es/translation.json",
"chars": 63863,
"preview": "{\n \"Books\": \"Libros\",\n \"Recent\": \"Recientes\",\n \"Bookmarks\": \"Marcadores\",\n \"Favorites\": \"Favoritos\",\n \"Notes\": \"Not"
},
{
"path": "src/assets/locales/fa/translation.json",
"chars": 59177,
"preview": "{\n \"Books\": \"کتاب ها\",\n \"Recent\": \"اخیر\",\n \"Bookmarks\": \"نشان شده ها\",\n \"Favorites\": \"علاقه مندی ها\",\n \"Notes\": \"یا"
},
{
"path": "src/assets/locales/fi/translation.json",
"chars": 58929,
"preview": "{\n \"Books\": \"Kirjat\",\n \"Recent\": \"Viimeisimmät\",\n \"Bookmarks\": \"Kirjanmerkit\",\n \"Favorites\": \"Suosikit\",\n \"Notes\": "
},
{
"path": "src/assets/locales/fr/translation.json",
"chars": 65262,
"preview": "{\n \"Books\": \"Livres\",\n \"Recent\": \"Récents\",\n \"Bookmarks\": \"Signets\",\n \"Favorites\": \"Favoris\",\n \"Notes\": \"Notes\",\n "
},
{
"path": "src/assets/locales/ga/translation.json",
"chars": 62762,
"preview": "{\n \"Books\": \"Leabhair\",\n \"Recent\": \"Le déanaí\",\n \"Bookmarks\": \"Leabharmharcanna\",\n \"Favorites\": \"Ceanáin\",\n \"Notes\""
},
{
"path": "src/assets/locales/hi/translation.json",
"chars": 58412,
"preview": "{\n \"Books\": \"किताबें\",\n \"Recent\": \"हाल के\",\n \"Bookmarks\": \"बुकमार्कस\",\n \"Favorites\": \"पसंदीदा\",\n \"Notes\": \"नोट्स\",\n"
},
{
"path": "src/assets/locales/hu/translation.json",
"chars": 62024,
"preview": "{\n \"Books\": \"Könyvek\",\n \"Recent\": \"Legutóbbiak\",\n \"Bookmarks\": \"Könyvjelzők\",\n \"Favorites\": \"Kedvencek\",\n \"Notes\": "
},
{
"path": "src/assets/locales/hy/translation.json",
"chars": 61973,
"preview": "{\n \"Books\": \"Գրքեր\",\n \"Recent\": \"Նոր\",\n \"Bookmarks\": \"Էջանիշներ\",\n \"Favorites\": \"Ընտրյալներ\",\n \"Notes\": \"Նշումներ\","
},
{
"path": "src/assets/locales/id/translation.json",
"chars": 64820,
"preview": "{\n \"Books\": \"Buku\",\n \"Recent\": \"Baru dibuka\",\n \"Bookmarks\": \"Penanda\",\n \"Favorites\": \"Favorit\",\n \"Notes\": \"Catatan\""
},
{
"path": "src/assets/locales/ie/translation.json",
"chars": 60087,
"preview": "{\n \"Books\": \"Libres\",\n \"Recent\": \"Recenti\",\n \"Bookmarks\": \"Marca-págines\",\n \"Favorites\": \"Preferet\",\n \"Notes\": \"Not"
},
{
"path": "src/assets/locales/it/translation.json",
"chars": 62274,
"preview": "{\n \"Books\": \"Libri\",\n \"Recent\": \"Recenti\",\n \"Bookmarks\": \"Segnalibri\",\n \"Favorites\": \"Preferiti\",\n \"Notes\": \"Note\","
},
{
"path": "src/assets/locales/ja/translation.json",
"chars": 49264,
"preview": "{\n \"Books\": \"全ての本\",\n \"Recent\": \"最近\",\n \"Bookmarks\": \"ブックマーク\",\n \"Favorites\": \"お気に入り\",\n \"Notes\": \"メモ\",\n \"Highlights\":"
},
{
"path": "src/assets/locales/ko/translation.json",
"chars": 48117,
"preview": "{\n \"Books\": \"책\",\n \"Recent\": \"최근에 읽은 책\",\n \"Bookmarks\": \"책갈피\",\n \"Favorites\": \"좋아하는 책\",\n \"Notes\": \"노트\",\n \"Highlights\""
},
{
"path": "src/assets/locales/nl/translation.json",
"chars": 61539,
"preview": "{\n \"Books\": \"Boeken\",\n \"Recent\": \"Onlangs geopend\",\n \"Bookmarks\": \"Bladwijzers\",\n \"Favorites\": \"Toevoegen aan favori"
},
{
"path": "src/assets/locales/pl/translation.json",
"chars": 62559,
"preview": "{\n \"Books\": \"Książki\",\n \"Recent\": \"Ostatnie\",\n \"Bookmarks\": \"Zakładki\",\n \"Favorites\": \"Ulubione\",\n \"Notes\": \"Notatk"
},
{
"path": "src/assets/locales/pt/translation.json",
"chars": 63513,
"preview": "{\n \"Books\": \"Livros\",\n \"Recent\": \"Recente\",\n \"Bookmarks\": \"Marcadores\",\n \"Favorites\": \"Favorito\",\n \"Notes\": \"Notas\""
},
{
"path": "src/assets/locales/pt-BR/translation.json",
"chars": 62635,
"preview": "{\n \"Books\": \"Livros\",\n \"Recent\": \"Recentes\",\n \"Bookmarks\": \"Marcadores\",\n \"Favorites\": \"Favoritos\",\n \"Notes\": \"Nota"
},
{
"path": "src/assets/locales/ro/translation.json",
"chars": 61372,
"preview": "{\n \"Books\": \"Cărți\",\n \"Recent\": \"Recente\",\n \"Bookmarks\": \"Marcaje\",\n \"Favorites\": \"Favorite\",\n \"Notes\": \"Notițe\",\n "
},
{
"path": "src/assets/locales/ru/translation.json",
"chars": 62009,
"preview": "{\n \"Books\": \"Книги\",\n \"Recent\": \"Недавние\",\n \"Bookmarks\": \"Закладки\",\n \"Favorites\": \"Избранное\",\n \"Notes\": \"Заметки"
},
{
"path": "src/assets/locales/sl/translation.json",
"chars": 60619,
"preview": "{\n \"About Project\": \"O projektu\",\n \"Access token expired, refetching token\": \"Žeton za dostop je potekel, ponovno prid"
},
{
"path": "src/assets/locales/sr/translation.json",
"chars": 60952,
"preview": "{\n \"Books\": \"Knjige\",\n \"Recent\": \"Nedavno\",\n \"Bookmarks\": \"Obeleživači\",\n \"Favorites\": \"Omiljeno\",\n \"Notes\": \"Beleš"
},
{
"path": "src/assets/locales/sv/translation.json",
"chars": 61603,
"preview": "{\n \"Books\": \"Böcker\",\n \"Recent\": \"Nyligen\",\n \"Bookmarks\": \"Bokmärken\",\n \"Favorites\": \"Favoriter\",\n \"Notes\": \"Anteck"
},
{
"path": "src/assets/locales/ta/translation.json",
"chars": 64892,
"preview": "{\n \"Books\": \"புத்தகங்கள்\",\n \"Recent\": \"சமீபத்தில்\",\n \"Bookmarks\": \"புத்தககுறி\",\n \"Favorites\": \"விருப்பம்\",\n \"Notes\""
},
{
"path": "src/assets/locales/th/translation.json",
"chars": 56593,
"preview": "{\n \"Books\": \"หนังสือ\",\n \"Recent\": \"ล่าสุด\",\n \"Bookmarks\": \"ที่คั่น\",\n \"Favorites\": \"รายการโปรด\",\n \"Notes\": \"บันทึกย"
},
{
"path": "src/assets/locales/tl/translation.json",
"chars": 63722,
"preview": "{\n \"Books\": \"Mga Libro\",\n \"Recent\": \"Mga Kamakailan\",\n \"Bookmarks\": \"Mga Bookmark\",\n \"Favorites\": \"Mga Paborito\",\n "
},
{
"path": "src/assets/locales/tr/translation.json",
"chars": 61240,
"preview": "{\n \"Books\": \"Kitaplar\",\n \"Recent\": \"Son Bakılanlar\",\n \"Bookmarks\": \"Yer İmleri\",\n \"Favorites\": \"Favoriler\",\n \"Notes"
},
{
"path": "src/assets/locales/uk/translation.json",
"chars": 63407,
"preview": "{\n \"Books\": \"Книги\",\n \"Recent\": \"Нещодавні\",\n \"Bookmarks\": \"Закладки\",\n \"Favorites\": \"Обране\",\n \"Notes\": \"Примітки\""
},
{
"path": "src/assets/locales/vi/translation.json",
"chars": 60678,
"preview": "{\n \"Books\": \"Sách\",\n \"Recent\": \"Gần đây\",\n \"Bookmarks\": \"Dấu trang\",\n \"Favorites\": \"Yêu thích\",\n \"Notes\": \"Ghi chú\""
},
{
"path": "src/assets/locales/zh-CN/translation.json",
"chars": 43650,
"preview": "{\n \"Books\": \"全部图书\",\n \"Recent\": \"最近阅读\",\n \"Bookmarks\": \"我的书签\",\n \"Favorites\": \"我的喜爱\",\n \"Notes\": \"我的笔记\",\n \"Highlights\""
},
{
"path": "src/assets/locales/zh-MO/translation.json",
"chars": 44195,
"preview": "{\n \"Books\": \"書籍\",\n \"Recent\": \"最近\",\n \"Bookmarks\": \"書籤\",\n \"Favorites\": \"最愛\",\n \"Notes\": \"筆記\",\n \"Highlights\": \"高亮\",\n "
},
{
"path": "src/assets/locales/zh-TW/translation.json",
"chars": 44229,
"preview": "{\n \"Books\": \"全部書籍\",\n \"Recent\": \"最近閱讀\",\n \"Bookmarks\": \"我的書籤\",\n \"Favorites\": \"我的最愛\",\n \"Notes\": \"我的筆記\",\n \"Highlights\""
},
{
"path": "src/assets/lotties/exit.json",
"chars": 270631,
"preview": "{\n \"nm\": \"cat\",\n \"ddd\": 0,\n \"h\": 660,\n \"w\": 660,\n \"meta\": { \"g\": \"@lottiefiles/toolkit-js 0.33.2\" },\n \"layers\": [\n"
},
{
"path": "src/assets/lotties/message.json",
"chars": 18957,
"preview": "{\"v\":\"4.8.0\",\"meta\":{\"g\":\"LottieFiles AE 3.1.1\",\"a\":\"\",\"k\":\"\",\"d\":\"\",\"tc\":\"\"},\"fr\":60,\"ip\":0,\"op\":90,\"w\":500,\"h\":500,\"nm"
},
{
"path": "src/assets/lotties/new.json",
"chars": 36527,
"preview": "{\"v\":\"4.9.0\",\"fr\":30,\"ip\":0,\"op\":38,\"w\":315,\"h\":280,\"nm\":\"new\",\"ddd\":0,\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm"
},
{
"path": "src/assets/lotties/safe.json",
"chars": 16463,
"preview": "{\"v\":\"5.5.10\",\"fr\":60,\"ip\":0,\"op\":90,\"w\":450,\"h\":450,\"nm\":\"Tips\",\"ddd\":0,\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\""
},
{
"path": "src/assets/lotties/success.json",
"chars": 12345,
"preview": "{\"v\":\"5.0.1\",\"fr\":29.9700012207031,\"ip\":0,\"op\":45.0000018328876,\"w\":512,\"h\":512,\"nm\":\"Comp 1\",\"ddd\":0,\"assets\":[{\"id\":\"c"
},
{
"path": "src/assets/lotties/support.json",
"chars": 366354,
"preview": "{\"v\":\"5.7.3\",\"fr\":50,\"ip\":98,\"op\":248,\"w\":1500,\"h\":1000,\"nm\":\"Cats\",\"ddd\":0,\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":"
},
{
"path": "src/assets/styles/global.css",
"chars": 701,
"preview": ".icon-return {\n cursor: pointer;\n}\n.center {\n height: 100%;\n display: flex;\n justify-content: center;\n align-items:"
},
{
"path": "src/assets/styles/reset.css",
"chars": 1621,
"preview": "/* http://meyerweb.com/eric/tools/css/reset/\n v2.0 | 20110126\n License: none (public domain)\n*/\nhtml,\nbody,\ndiv,\nspa"
},
{
"path": "src/assets/styles/style.css",
"chars": 5479,
"preview": "@font-face {\n font-family: 'icomoon';\n src: url('fonts/icomoon.eot?qn1hwh');\n src: url('fonts/icomoon.eot?qn1hwh#ie"
},
{
"path": "src/components/arrow/arrow.css",
"chars": 654,
"preview": ".arrow-container {\n width: 80px;\n height: 80px;\n margin-left: 50px;\n display: flex;\n justify-content: center;\n}\n.ci"
},
{
"path": "src/components/arrow/index.tsx",
"chars": 1213,
"preview": "import React from \"react\";\nimport \"./arrow.css\";\nconst Arrow = () => {\n return (\n <div className=\"arrow-container\">\n"
},
{
"path": "src/components/background/background.css",
"chars": 1228,
"preview": ".background-box1 {\n position: absolute;\n left: 5px;\n right: 5px;\n top: 5px;\n bottom: 5px;\n z-index: 0;\n}\n.backgrou"
},
{
"path": "src/components/background/component.tsx",
"chars": 4487,
"preview": "import React from \"react\";\nimport \"./background.css\";\nimport { BackgroundProps, BackgroundState } from \"./interface\";\nim"
},
{
"path": "src/components/background/index.tsx",
"chars": 537,
"preview": "import { connect } from \"react-redux\";\nimport { stateType } from \"../../store\";\nimport Background from \"./component\";\n\nc"
},
{
"path": "src/components/background/interface.tsx",
"chars": 274,
"preview": "export interface BackgroundProps {\n readerMode: string;\n scale: string;\n margin: string;\n isNavLocked: boolean;\n is"
},
{
"path": "src/components/bookCardItem/bookCardItem.css",
"chars": 2828,
"preview": ".book-list-item {\n width: 133px;\n /* height: 192px; */\n float: left;\n overflow: hidden;\n position: relative;\n}\n.boo"
},
{
"path": "src/components/bookCardItem/component.tsx",
"chars": 8567,
"preview": "import React from \"react\";\nimport \"./bookCardItem.css\";\nimport { BookCardProps, BookCardState } from \"./interface\";\nimpo"
},
{
"path": "src/components/bookCardItem/index.tsx",
"chars": 1005,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleActionDialog,\n handleReadingBook,\n handleDragItem,\n handleDel"
},
{
"path": "src/components/bookCardItem/interface.tsx",
"chars": 901,
"preview": "import BookModel from \"../../models/Book\";\nimport { RouteComponentProps } from \"react-router\";\n\nexport interface BookCar"
},
{
"path": "src/components/bookCoverItem/bookCoverItem.css",
"chars": 2436,
"preview": ".book-list-cover-item {\n width: 400px;\n /* height: 200px; */\n float: left;\n overflow: hidden;\n position: relative;\n"
},
{
"path": "src/components/bookCoverItem/component.tsx",
"chars": 10146,
"preview": "import React from \"react\";\nimport \"./bookCoverItem.css\";\nimport { BookCoverProps, BookCoverState } from \"./interface\";\ni"
},
{
"path": "src/components/bookCoverItem/index.tsx",
"chars": 1051,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleActionDialog,\n handleReadingBook,\n handleDragItem,\n handleDel"
},
{
"path": "src/components/bookCoverItem/interface.tsx",
"chars": 945,
"preview": "import BookModel from \"../../models/Book\";\nimport { RouteComponentProps } from \"react-router\";\n\nexport interface BookCov"
},
{
"path": "src/components/bookListItem/bookListItem.css",
"chars": 1198,
"preview": ".book-list-item-container {\n margin: 12px;\n margin-right: 25px;\n position: relative;\n}\n.book-item-list-cover {\n widt"
},
{
"path": "src/components/bookListItem/component.tsx",
"chars": 8994,
"preview": "import React from \"react\";\nimport \"./bookListItem.css\";\nimport { BookItemProps, BookItemState } from \"./interface\";\nimpo"
},
{
"path": "src/components/bookListItem/index.tsx",
"chars": 1171,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleEditDialog,\n handleDeleteDialog,\n handleAddDialog,\n handleRea"
},
{
"path": "src/components/bookListItem/interface.tsx",
"chars": 1077,
"preview": "import BookModel from \"../../models/Book\";\nimport { RouteComponentProps } from \"react-router\";\n\nexport interface BookIte"
},
{
"path": "src/components/colorOption/colorOption.css",
"chars": 1151,
"preview": ".color-option-container {\n width: 90%;\n height: 25px;\n margin-left: 5%;\n padding-bottom: 5px;\n flex-shrink: 0;\n di"
},
{
"path": "src/components/colorOption/component.tsx",
"chars": 2931,
"preview": "import React from \"react\";\nimport \"./colorOption.css\";\nimport { ColorProps, ColorStates } from \"./interface\";\nimport { C"
},
{
"path": "src/components/colorOption/index.tsx",
"chars": 422,
"preview": "import { connect } from \"react-redux\";\nimport { handleColor, handleSelection } from \"../../store/actions\";\nimport { stat"
},
{
"path": "src/components/colorOption/interface.tsx",
"chars": 211,
"preview": "export interface ColorProps {\n color: number;\n targetColor: number;\n isEdit: boolean;\n handleColor: (color: number) "
},
{
"path": "src/components/deleteIcon/component.tsx",
"chars": 2762,
"preview": "import React from \"react\";\nimport \"./deleteIcon.css\";\nimport { DeleteIconProps, DeleteIconStates } from \"./interface\";\ni"
},
{
"path": "src/components/deleteIcon/deleteIcon.css",
"chars": 446,
"preview": ".delete-digest-button {\n width: 18px !important;\n height: 18px !important;\n border-radius: 50%;\n cursor: pointer;\n "
},
{
"path": "src/components/deleteIcon/index.tsx",
"chars": 576,
"preview": "import { connect } from \"react-redux\";\nimport { stateType } from \"../../store\";\nimport {\n handleFetchBookmarks,\n handl"
},
{
"path": "src/components/deleteIcon/interface.tsx",
"chars": 495,
"preview": "export interface DeleteIconProps {\n mode: string;\n index: number;\n tagName: string;\n itemKey: string;\n handleFetchN"
},
{
"path": "src/components/dialogs/aboutDialog/aboutDialog.css",
"chars": 165,
"preview": ".icon-export-all {\n line-height: 18px;\n display: inline-block;\n transform: rotate(-90deg) scale(0.7);\n}\n\n.export-form"
},
{
"path": "src/components/dialogs/aboutDialog/component.tsx",
"chars": 10752,
"preview": "import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { AboutDialogProps, AboutDialogState } from \"./"
},
{
"path": "src/components/dialogs/aboutDialog/index.tsx",
"chars": 660,
"preview": "import { connect } from \"react-redux\";\nimport { handleSetting, handleAbout } from \"../../../store/actions\";\nimport { sta"
},
{
"path": "src/components/dialogs/aboutDialog/interface.tsx",
"chars": 438,
"preview": "import type BookModel from \"../../../models/Book\";\n\nexport interface AboutDialogProps {\n isSettingOpen: boolean;\n isAb"
},
{
"path": "src/components/dialogs/actionDialog/actionDialog.css",
"chars": 788,
"preview": ".action-dialog-container {\n width: 200px;\n /* height: 340px; */\n opacity: 1;\n position: fixed;\n z-index: 9;\n anima"
},
{
"path": "src/components/dialogs/actionDialog/component.tsx",
"chars": 8222,
"preview": "import React from \"react\";\nimport \"./actionDialog.css\";\nimport { Trans } from \"react-i18next\";\nimport { ActionDialogProp"
},
{
"path": "src/components/dialogs/actionDialog/index.tsx",
"chars": 1028,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleEditDialog,\n handleDeleteDialog,\n handleSelectBook,\n handleAd"
},
{
"path": "src/components/dialogs/actionDialog/interface.tsx",
"chars": 961,
"preview": "import { RouteComponentProps } from \"react-router\";\nimport BookModel from \"../../../models/Book\";\n\nexport interface Acti"
},
{
"path": "src/components/dialogs/addDialog/addDialog.css",
"chars": 2022,
"preview": ".add-dialog-container {\n width: 309px;\n height: 189px;\n opacity: 1;\n position: absolute;\n left: calc(50vw - 155px);"
},
{
"path": "src/components/dialogs/addDialog/component.tsx",
"chars": 5431,
"preview": "import React, { Component } from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { AddDialogProps, AddDialogState"
},
{
"path": "src/components/dialogs/addDialog/index.tsx",
"chars": 901,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleAddDialog,\n handleActionDialog,\n handleMode,\n handleShelf,\n "
},
{
"path": "src/components/dialogs/addDialog/interface.tsx",
"chars": 618,
"preview": "import BookModel from \"../../../models/Book\";\n\nexport interface AddDialogProps {\n handleAddDialog: (isShow: boolean) =>"
},
{
"path": "src/components/dialogs/backupDialog/backupDialog.css",
"chars": 3911,
"preview": ".backup-page-container {\n width: 454px;\n height: 278px;\n position: absolute;\n left: calc(50% - 227px);\n top: calc(5"
},
{
"path": "src/components/dialogs/backupDialog/component.tsx",
"chars": 8256,
"preview": "import React from \"react\";\nimport \"./backupDialog.css\";\nimport { driveList } from \"../../../constants/driveList\";\nimport"
},
{
"path": "src/components/dialogs/backupDialog/index.tsx",
"chars": 746,
"preview": "import {\n handleBackupDialog,\n handleTokenDialog,\n handleLoadingDialog,\n handleFetchBooks,\n} from \"../../../store/ac"
},
{
"path": "src/components/dialogs/backupDialog/interface.tsx",
"chars": 514,
"preview": "import { RouteComponentProps } from \"react-router-dom\";\n\nexport interface BackupDialogProps extends RouteComponentProps<"
},
{
"path": "src/components/dialogs/convertDialog/component.tsx",
"chars": 14266,
"preview": "import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { ConvertDialogProps, ConvertDialogState } from"
},
{
"path": "src/components/dialogs/convertDialog/convertDialog.css",
"chars": 107,
"preview": ".icon-export-all {\n line-height: 18px;\n display: inline-block;\n transform: rotate(-90deg) scale(0.7);\n}\n"
},
{
"path": "src/components/dialogs/convertDialog/index.tsx",
"chars": 621,
"preview": "import { connect } from \"react-redux\";\nimport { handleSetting, handleConvertDialog } from \"../../../store/actions\";\nimpo"
},
{
"path": "src/components/dialogs/convertDialog/interface.tsx",
"chars": 415,
"preview": "import BookModel from \"../../../models/Book\";\n\nexport interface ConvertDialogProps {\n isSettingOpen: boolean;\n isAbout"
},
{
"path": "src/components/dialogs/deleteDialog/component.tsx",
"chars": 8315,
"preview": "import React from \"react\";\nimport \"./deleteDialog.css\";\nimport { Trans } from \"react-i18next\";\nimport { DeleteDialogProp"
},
{
"path": "src/components/dialogs/deleteDialog/deleteDialog.css",
"chars": 1234,
"preview": ".delete-dialog-container {\n width: 319px;\n height: 199px;\n opacity: 1;\n position: fixed;\n left: calc(50% - 160px);\n"
},
{
"path": "src/components/dialogs/deleteDialog/index.tsx",
"chars": 1245,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleFetchBooks,\n handleDeleteDialog,\n handleActionDialog,\n handle"
},
{
"path": "src/components/dialogs/deleteDialog/interface.tsx",
"chars": 876,
"preview": "import BookModel from \"../../../models/Book\";\nimport { RouteComponentProps } from \"react-router\";\n\nexport interface Dele"
},
{
"path": "src/components/dialogs/deletePopup/component.tsx",
"chars": 1410,
"preview": "import React from \"react\";\nimport { Trans } from \"react-i18next\";\nimport { DeletePopupProps } from \"./interface\";\nimport"
},
{
"path": "src/components/dialogs/deletePopup/index.tsx",
"chars": 451,
"preview": "import { connect } from \"react-redux\";\nimport { handleFetchBooks } from \"../../../store/actions\";\nimport { stateType } f"
},
{
"path": "src/components/dialogs/deletePopup/interface.tsx",
"chars": 216,
"preview": "export interface DeletePopupProps {\n t: (title: string) => string;\n name: string;\n title: string;\n description: stri"
},
{
"path": "src/components/dialogs/detailDialog/component.tsx",
"chars": 6660,
"preview": "import React from \"react\";\nimport \"./updateInfo.css\";\nimport { DetailDialogProps, DetailDialogState } from \"./interface\""
},
{
"path": "src/components/dialogs/detailDialog/index.tsx",
"chars": 412,
"preview": "import { connect } from \"react-redux\";\nimport { handleDetailDialog } from \"../../../store/actions\";\nimport DetailDialog "
},
{
"path": "src/components/dialogs/detailDialog/interface.tsx",
"chars": 324,
"preview": "import BookModel from \"../../../models/Book\";\nexport interface DetailDialogProps {\n handleDetailDialog: (isDetailDialog"
},
{
"path": "src/components/dialogs/detailDialog/updateInfo.css",
"chars": 4249,
"preview": ".download-desk-title {\n font-size: 18px;\n font-weight: 500;\n opacity: 1;\n text-align: center;\n width: 100%;\n margi"
},
{
"path": "src/components/dialogs/editDialog/component.tsx",
"chars": 5770,
"preview": "import React from \"react\";\nimport \"./editDialog.css\";\n\nimport { Trans } from \"react-i18next\";\nimport { EditDialogProps, "
},
{
"path": "src/components/dialogs/editDialog/editDialog.css",
"chars": 2008,
"preview": ".edit-dialog-container {\n width: 380px;\n height: 440px;\n opacity: 1;\n position: absolute;\n left: calc(50% - 190px);"
},
{
"path": "src/components/dialogs/editDialog/index.tsx",
"chars": 815,
"preview": "import { connect } from \"react-redux\";\nimport \"./editDialog.css\";\nimport {\n handleFetchBooks,\n handleRefreshBookCover,"
},
{
"path": "src/components/dialogs/editDialog/interface.tsx",
"chars": 521,
"preview": "import BookModel from \"../../../models/Book\";\nimport { RouteComponentProps } from \"react-router-dom\";\nexport interface E"
},
{
"path": "src/components/dialogs/importDialog/component.tsx",
"chars": 20129,
"preview": "import React from \"react\";\nimport \"./importDialog.css\";\nimport { driveList } from \"../../../constants/driveList\";\nimport"
},
{
"path": "src/components/dialogs/importDialog/importDialog.css",
"chars": 1167,
"preview": ".cloud-drive-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n width: 100%;\n padding: 10px 0;\n}\n.import-"
},
{
"path": "src/components/dialogs/importDialog/index.tsx",
"chars": 1022,
"preview": "import {\n handleImportDialog,\n handleTokenDialog,\n handleLoadingDialog,\n handleFetchBooks,\n handleImportBookFunc,\n "
},
{
"path": "src/components/dialogs/importDialog/interface.tsx",
"chars": 1102,
"preview": "import { RouteComponentProps } from \"react-router-dom\";\n\nexport interface ImportDialogProps extends RouteComponentProps<"
},
{
"path": "src/components/dialogs/loadingDialog/index.tsx",
"chars": 416,
"preview": "import React from \"react\";\nimport \"./loadingDialog.css\";\nimport { Trans } from \"react-i18next\";\nconst LoadingDialog = (_"
},
{
"path": "src/components/dialogs/loadingDialog/loadingDialog.css",
"chars": 1998,
"preview": ".loading-dialog {\n width: 454px;\n height: 278px;\n position: absolute;\n left: calc(50% - 227px);\n top: calc(50% - 13"
},
{
"path": "src/components/dialogs/localFileDialog/component.tsx",
"chars": 6566,
"preview": "import React from \"react\";\nimport \"./localFileDialog.css\";\nimport { Trans } from \"react-i18next\";\nimport { LocalFileDial"
},
{
"path": "src/components/dialogs/localFileDialog/index.tsx",
"chars": 705,
"preview": "import {\n handleLocalFileDialog,\n handleTokenDialog,\n handleLoadingDialog,\n handleFetchBooks,\n} from \"../../../store"
},
{
"path": "src/components/dialogs/localFileDialog/interface.tsx",
"chars": 492,
"preview": "import { RouteComponentProps } from \"react-router-dom\";\n\nexport interface LocalFileDialogProps extends RouteComponentPro"
},
{
"path": "src/components/dialogs/localFileDialog/localFileDialog.css",
"chars": 157,
"preview": ".backup-page-warning-text {\n font-size: 15px;\n line-height: 1.25;\n margin-top: 12px;\n padding-left: 20px;\n padding-"
},
{
"path": "src/components/dialogs/moreAction/component.tsx",
"chars": 14071,
"preview": "import React from \"react\";\nimport \"./moreAction.css\";\nimport { Trans } from \"react-i18next\";\nimport { MoreActionProps, M"
},
{
"path": "src/components/dialogs/moreAction/index.tsx",
"chars": 930,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleEditDialog,\n handleDeleteDialog,\n handleSelectBook,\n handleAd"
},
{
"path": "src/components/dialogs/moreAction/interface.tsx",
"chars": 710,
"preview": "import { RouteComponentProps } from \"react-router\";\nimport BookModel from \"../../../models/Book\";\n\nexport interface More"
},
{
"path": "src/components/dialogs/moreAction/moreAction.css",
"chars": 968,
"preview": ".action-dialog-container {\n width: 200px;\n /* height: 340px; */\n opacity: 1;\n position: fixed;\n z-index: 9;\n anima"
},
{
"path": "src/components/dialogs/settingDialog/component.tsx",
"chars": 20614,
"preview": "import React from \"react\";\nimport \"./settingDialog.css\";\nimport { SettingInfoProps, SettingInfoState } from \"./interface"
},
{
"path": "src/components/dialogs/settingDialog/index.tsx",
"chars": 1376,
"preview": "import { connect } from \"react-redux\";\nimport SettingDialog from \"./component\";\nimport { withTranslation } from \"react-i"
},
{
"path": "src/components/dialogs/settingDialog/interface.tsx",
"chars": 1873,
"preview": "import PluginModel from \"../../../models/Plugin\";\nimport { RouteComponentProps } from \"react-router-dom\";\nexport interfa"
},
{
"path": "src/components/dialogs/settingDialog/settingDialog.css",
"chars": 5868,
"preview": ".setting-dialog-container {\n width: 510px;\n height: 490px;\n position: absolute;\n left: calc(50% - 255px);\n top: cal"
},
{
"path": "src/components/dialogs/sortBookDialog/component.tsx",
"chars": 5194,
"preview": "import React from \"react\";\nimport \"./sortDialog.css\";\nimport { Trans } from \"react-i18next\";\nimport { SortDialogProps, S"
},
{
"path": "src/components/dialogs/sortBookDialog/index.tsx",
"chars": 713,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleBookSortCode,\n handleNoteSortCode,\n handleSortDisplay,\n handl"
},
{
"path": "src/components/dialogs/sortBookDialog/interface.tsx",
"chars": 510,
"preview": "export interface SortDialogProps {\n bookSortCode: { sort: number; order: number };\n noteSortCode: { sort: number; orde"
},
{
"path": "src/components/dialogs/sortBookDialog/sortDialog.css",
"chars": 656,
"preview": ".sort-dialog-container {\n width: 180px;\n opacity: 1;\n position: absolute;\n left: 425px;\n padding: 5px;\n top: 65px;"
},
{
"path": "src/components/dialogs/sortShelfDialog/component.tsx",
"chars": 8345,
"preview": "import React from \"react\";\nimport \"./sortShelfDialog.css\";\nimport { Trans } from \"react-i18next\";\nimport { SortShelfDial"
},
{
"path": "src/components/dialogs/sortShelfDialog/index.tsx",
"chars": 664,
"preview": "import {\n handleSortShelfDialog,\n handleMode,\n handleShelf,\n} from \"../../../store/actions\";\nimport { connect } from "
},
{
"path": "src/components/dialogs/sortShelfDialog/interface.tsx",
"chars": 489,
"preview": "import { RouteComponentProps } from \"react-router-dom\";\n\nexport interface SortShelfDialogProps extends RouteComponentPro"
},
{
"path": "src/components/dialogs/sortShelfDialog/sortShelfDialog.css",
"chars": 156,
"preview": ".sort-shelf-label {\n font-size: 15px;\n line-height: 1.5;\n font-weight: 500;\n width: calc(100% - 50px);\n text-overfl"
},
{
"path": "src/components/dialogs/speechDialog/component.tsx",
"chars": 1117,
"preview": "import React from \"react\";\nimport { SpeechDialogProps, SpeechDialogState } from \"./interface\";\nimport \"./speechDialog.cs"
},
{
"path": "src/components/dialogs/speechDialog/index.tsx",
"chars": 700,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleSetting,\n handleSpeechDialog,\n handleFetchPlugins,\n} from \"../"
},
{
"path": "src/components/dialogs/speechDialog/interface.tsx",
"chars": 512,
"preview": "import BookModel from \"../../../models/Book\";\nimport Plugin from \"../../../models/Plugin\";\n\nexport interface SpeechDialo"
},
{
"path": "src/components/dialogs/speechDialog/speechDialog.css",
"chars": 107,
"preview": ".icon-export-all {\n line-height: 18px;\n display: inline-block;\n transform: rotate(-90deg) scale(0.7);\n}\n"
},
{
"path": "src/components/dialogs/supportDialog/component.tsx",
"chars": 16711,
"preview": "import React from \"react\";\nimport \"./supportDialog.css\";\nimport { SupportDialogProps, SupportDialogState } from \"./inter"
},
{
"path": "src/components/dialogs/supportDialog/index.tsx",
"chars": 848,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleNewWarning,\n handleFetchAuthed,\n handleFetchUserInfo,\n handle"
},
{
"path": "src/components/dialogs/supportDialog/interface.tsx",
"chars": 588,
"preview": "export interface SupportDialogProps {\n isShowSupport: boolean;\n isAuthed: boolean;\n t: (title: string) => string;\n h"
},
{
"path": "src/components/dialogs/supportDialog/supportDialog.css",
"chars": 494,
"preview": ".support-us-out-button {\n display: flex;\n justify-content: center;\n align-items: center;\n bottom: 20px;\n cursor: po"
},
{
"path": "src/components/dialogs/updateDialog/component.tsx",
"chars": 10337,
"preview": "import React from \"react\";\nimport \"./updateInfo.css\";\nimport { UpdateInfoProps, UpdateInfoState } from \"./interface\";\nim"
},
{
"path": "src/components/dialogs/updateDialog/index.tsx",
"chars": 826,
"preview": "import { connect } from \"react-redux\";\nimport {\n handleNewDialog,\n handleNewWarning,\n handleFetchAuthed,\n handleLogi"
},
{
"path": "src/components/dialogs/updateDialog/interface.tsx",
"chars": 648,
"preview": "import BookModel from \"../../../models/Book\";\nexport interface UpdateInfoProps {\n currentBook: BookModel;\n\n isShowNew:"
},
{
"path": "src/components/dialogs/updateDialog/updateInfo.css",
"chars": 2584,
"preview": ".new-version {\n width: 346px;\n height: 480px;\n position: absolute;\n left: calc(50% - 173px);\n top: calc(50% - 240px"
},
{
"path": "src/components/emptyCover/emptyCover.css",
"chars": 735,
"preview": ".empty-cover {\n width: 105px;\n height: 137px;\n transform-origin: 0% 0%;\n}\n.cover-banner {\n float: left;\n width: 90p"
}
]
// ... and 421 more files (download for full content)
About this extraction
This page contains the full source code of the koodo-reader/koodo-reader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 621 files (8.0 MB), approximately 2.1M tokens, and a symbol index with 6072 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.