├── .gitattributes ├── .github └── workflows │ ├── codeql-analysis.yml │ ├── docker-image.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── common ├── config.go ├── drive_util │ ├── cache.go │ ├── cache_file_pool.go │ ├── drive_factory.go │ ├── fs.go │ ├── inline_file_exts.json │ ├── mem_cache.go │ ├── oauth.go │ ├── registry.go │ └── utils.go ├── errors │ └── errors.go ├── event │ ├── index.go │ └── types.go ├── i18n │ ├── i18n.go │ ├── i18n_file.go │ └── i18n_test.go ├── registry │ └── components.go ├── req │ ├── index.go │ └── types.go ├── task │ ├── context.go │ ├── option.go │ ├── task.go │ └── tunny_runner.go ├── types │ ├── common.go │ ├── db.go │ ├── drive.go │ ├── events.go │ ├── misc.go │ ├── search.go │ └── server.go └── utils │ ├── id_pool.go │ ├── id_pool_test.go │ ├── key_lock.go │ ├── kv_cache.go │ ├── lazy_reader.go │ ├── path_tree.go │ ├── permission_resolver.go │ ├── reflect.go │ ├── signer.go │ ├── signer_test.go │ ├── temp_file.go │ ├── utils.go │ └── utils_test.go ├── docker ├── Dockerfile └── release.Dockerfile ├── docs ├── config.yml ├── drive-uploaders │ ├── README.md │ └── types.d.ts ├── lang │ ├── en-US.yml │ └── zh-CN.yml ├── oauth_callback.html ├── script-drive-template.js ├── scripts │ ├── README.md │ ├── env │ │ ├── drive.d.ts │ │ └── jobs.d.ts │ ├── global.d.ts │ └── libs │ │ └── dayjs.d.ts └── thumbnail-shell-example.sh ├── drive ├── access.go ├── chroot.go ├── dispatcher.go ├── fs │ └── index.go ├── ftp │ └── index.go ├── gdrive │ ├── index.go │ └── util.go ├── imports.go ├── listener_wrapper.go ├── onedrive │ ├── api.go │ ├── index.go │ └── util.go ├── path_meta_wrapper.go ├── permission_wrapper.go ├── root.go ├── s3 │ └── index.go ├── script │ ├── cache.go │ ├── helper.js │ ├── index.go │ ├── script_utils.go │ └── utils.go ├── sftp │ └── index.go └── webdav │ └── index.go ├── go.mod ├── go.sum ├── main.go ├── script-drives ├── dropbox.js ├── qiniu-uploader.js └── qiniu.js ├── script ├── call.go ├── call_common.go ├── call_enc.go ├── call_http.go ├── call_utils.go ├── js │ ├── 49.dayjs.js │ └── 50.common.js ├── object_context.go ├── object_drive.go ├── object_io.go ├── pool.go ├── runtime.go └── utils.go ├── server ├── api_admin.go ├── api_admin_config.go ├── api_admin_drives.go ├── api_admin_jobs.go ├── api_admin_misc.go ├── api_admin_users.go ├── api_auth.go ├── api_common.go ├── api_drive.go ├── api_file_bucket.go ├── api_webdav.go ├── chunk_uploader.go ├── fail_ban.go ├── file_token.go ├── scheduled │ ├── executor.go │ ├── jobs.go │ ├── jobs_drive.go │ ├── jobs_script-helper.js │ ├── jobs_script.go │ ├── types.go │ └── z_init.go ├── search │ ├── index.go │ ├── searcher.go │ ├── searcher_bleve.go │ └── searcher_sqlite.go ├── server.go ├── thumbnail │ ├── image.go │ ├── index.go │ ├── shell.go │ ├── text.go │ └── thumbnail.go ├── user_auth.go ├── utils.go ├── web_files.go └── webdav │ ├── file.go │ ├── file_test.go │ ├── if.go │ ├── if_test.go │ ├── internal │ └── xml │ │ ├── README │ │ ├── atom_test.go │ │ ├── example_test.go │ │ ├── marshal.go │ │ ├── marshal_test.go │ │ ├── read.go │ │ ├── read_test.go │ │ ├── typeinfo.go │ │ ├── xml.go │ │ └── xml_test.go │ ├── litmus_test_server.go │ ├── lock.go │ ├── lock_test.go │ ├── prop.go │ ├── webdav.go │ ├── webdav_test.go │ ├── xml.go │ └── xml_test.go ├── storage ├── db.go ├── drive_cache.go ├── drive_data.go ├── drives.go ├── file_bucket.go ├── groups.go ├── options.go ├── path_meta.go ├── path_mount.go ├── path_permissions.go ├── scheduled.go └── users.go ├── web ├── .eslintrc ├── .gitignore ├── index.html ├── monaco-editor │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── env.d.ts │ │ ├── main.scss │ │ ├── main.ts │ │ ├── types.ts │ │ ├── utils.ts │ │ └── workers.ts │ ├── tsconfig.json │ └── vite.config.ts ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── favicon.png │ ├── pdf.js │ │ ├── LICENSE │ │ ├── build │ │ │ ├── pdf.js │ │ │ ├── pdf.sandbox.js │ │ │ └── pdf.worker.js │ │ └── web │ │ │ ├── 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 │ │ │ ├── compressed.tracemonkey-pldi-09.pdf │ │ │ ├── debugger.css │ │ │ ├── debugger.js │ │ │ ├── images │ │ │ ├── annotation-check.svg │ │ │ ├── annotation-comment.svg │ │ │ ├── annotation-help.svg │ │ │ ├── annotation-insert.svg │ │ │ ├── annotation-key.svg │ │ │ ├── annotation-newparagraph.svg │ │ │ ├── annotation-noicon.svg │ │ │ ├── annotation-note.svg │ │ │ ├── annotation-paragraph.svg │ │ │ ├── cursor-editorInk.svg │ │ │ ├── findbarButton-next.svg │ │ │ ├── findbarButton-previous.svg │ │ │ ├── loading-dark.svg │ │ │ ├── loading-icon.gif │ │ │ ├── loading.svg │ │ │ ├── secondaryToolbarButton-documentProperties.svg │ │ │ ├── secondaryToolbarButton-firstPage.svg │ │ │ ├── secondaryToolbarButton-handTool.svg │ │ │ ├── secondaryToolbarButton-lastPage.svg │ │ │ ├── secondaryToolbarButton-rotateCcw.svg │ │ │ ├── secondaryToolbarButton-rotateCw.svg │ │ │ ├── secondaryToolbarButton-scrollHorizontal.svg │ │ │ ├── secondaryToolbarButton-scrollPage.svg │ │ │ ├── secondaryToolbarButton-scrollVertical.svg │ │ │ ├── secondaryToolbarButton-scrollWrapped.svg │ │ │ ├── secondaryToolbarButton-selectTool.svg │ │ │ ├── secondaryToolbarButton-spreadEven.svg │ │ │ ├── secondaryToolbarButton-spreadNone.svg │ │ │ ├── secondaryToolbarButton-spreadOdd.svg │ │ │ ├── shadow.png │ │ │ ├── toolbarButton-bookmark.svg │ │ │ ├── toolbarButton-currentOutlineItem.svg │ │ │ ├── toolbarButton-download.svg │ │ │ ├── toolbarButton-editorFreeText.svg │ │ │ ├── toolbarButton-editorInk.svg │ │ │ ├── toolbarButton-menuArrow.svg │ │ │ ├── toolbarButton-openFile.svg │ │ │ ├── toolbarButton-pageDown.svg │ │ │ ├── toolbarButton-pageUp.svg │ │ │ ├── toolbarButton-presentationMode.svg │ │ │ ├── toolbarButton-print.svg │ │ │ ├── toolbarButton-search.svg │ │ │ ├── toolbarButton-secondaryToolbarToggle.svg │ │ │ ├── toolbarButton-sidebarToggle.svg │ │ │ ├── toolbarButton-viewAttachments.svg │ │ │ ├── toolbarButton-viewLayers.svg │ │ │ ├── toolbarButton-viewOutline.svg │ │ │ ├── toolbarButton-viewThumbnail.svg │ │ │ ├── toolbarButton-zoomIn.svg │ │ │ ├── toolbarButton-zoomOut.svg │ │ │ ├── treeitem-collapsed.svg │ │ │ └── treeitem-expanded.svg │ │ │ ├── locale │ │ │ ├── ach │ │ │ │ └── viewer.properties │ │ │ ├── af │ │ │ │ └── viewer.properties │ │ │ ├── an │ │ │ │ └── viewer.properties │ │ │ ├── ar │ │ │ │ └── viewer.properties │ │ │ ├── ast │ │ │ │ └── viewer.properties │ │ │ ├── az │ │ │ │ └── viewer.properties │ │ │ ├── be │ │ │ │ └── viewer.properties │ │ │ ├── bg │ │ │ │ └── viewer.properties │ │ │ ├── bn │ │ │ │ └── viewer.properties │ │ │ ├── bo │ │ │ │ └── viewer.properties │ │ │ ├── br │ │ │ │ └── viewer.properties │ │ │ ├── brx │ │ │ │ └── viewer.properties │ │ │ ├── bs │ │ │ │ └── viewer.properties │ │ │ ├── ca │ │ │ │ └── viewer.properties │ │ │ ├── cak │ │ │ │ └── viewer.properties │ │ │ ├── ckb │ │ │ │ └── viewer.properties │ │ │ ├── cs │ │ │ │ └── viewer.properties │ │ │ ├── cy │ │ │ │ └── viewer.properties │ │ │ ├── da │ │ │ │ └── viewer.properties │ │ │ ├── de │ │ │ │ └── viewer.properties │ │ │ ├── dsb │ │ │ │ └── viewer.properties │ │ │ ├── el │ │ │ │ └── viewer.properties │ │ │ ├── en-CA │ │ │ │ └── viewer.properties │ │ │ ├── en-GB │ │ │ │ └── viewer.properties │ │ │ ├── en-US │ │ │ │ └── viewer.properties │ │ │ ├── eo │ │ │ │ └── viewer.properties │ │ │ ├── es-AR │ │ │ │ └── viewer.properties │ │ │ ├── es-CL │ │ │ │ └── viewer.properties │ │ │ ├── es-ES │ │ │ │ └── viewer.properties │ │ │ ├── es-MX │ │ │ │ └── viewer.properties │ │ │ ├── et │ │ │ │ └── viewer.properties │ │ │ ├── eu │ │ │ │ └── viewer.properties │ │ │ ├── fa │ │ │ │ └── viewer.properties │ │ │ ├── ff │ │ │ │ └── viewer.properties │ │ │ ├── fi │ │ │ │ └── viewer.properties │ │ │ ├── fr │ │ │ │ └── viewer.properties │ │ │ ├── fy-NL │ │ │ │ └── viewer.properties │ │ │ ├── ga-IE │ │ │ │ └── viewer.properties │ │ │ ├── gd │ │ │ │ └── viewer.properties │ │ │ ├── gl │ │ │ │ └── viewer.properties │ │ │ ├── gn │ │ │ │ └── viewer.properties │ │ │ ├── gu-IN │ │ │ │ └── viewer.properties │ │ │ ├── he │ │ │ │ └── viewer.properties │ │ │ ├── hi-IN │ │ │ │ └── viewer.properties │ │ │ ├── hr │ │ │ │ └── viewer.properties │ │ │ ├── hsb │ │ │ │ └── viewer.properties │ │ │ ├── hu │ │ │ │ └── viewer.properties │ │ │ ├── hy-AM │ │ │ │ └── viewer.properties │ │ │ ├── hye │ │ │ │ └── viewer.properties │ │ │ ├── ia │ │ │ │ └── viewer.properties │ │ │ ├── id │ │ │ │ └── viewer.properties │ │ │ ├── is │ │ │ │ └── viewer.properties │ │ │ ├── it │ │ │ │ └── viewer.properties │ │ │ ├── ja │ │ │ │ └── viewer.properties │ │ │ ├── ka │ │ │ │ └── viewer.properties │ │ │ ├── kab │ │ │ │ └── viewer.properties │ │ │ ├── kk │ │ │ │ └── viewer.properties │ │ │ ├── km │ │ │ │ └── viewer.properties │ │ │ ├── kn │ │ │ │ └── viewer.properties │ │ │ ├── ko │ │ │ │ └── viewer.properties │ │ │ ├── lij │ │ │ │ └── viewer.properties │ │ │ ├── lo │ │ │ │ └── viewer.properties │ │ │ ├── locale.properties │ │ │ ├── lt │ │ │ │ └── viewer.properties │ │ │ ├── ltg │ │ │ │ └── viewer.properties │ │ │ ├── lv │ │ │ │ └── viewer.properties │ │ │ ├── meh │ │ │ │ └── viewer.properties │ │ │ ├── mk │ │ │ │ └── viewer.properties │ │ │ ├── mr │ │ │ │ └── viewer.properties │ │ │ ├── ms │ │ │ │ └── viewer.properties │ │ │ ├── my │ │ │ │ └── viewer.properties │ │ │ ├── nb-NO │ │ │ │ └── viewer.properties │ │ │ ├── ne-NP │ │ │ │ └── viewer.properties │ │ │ ├── nl │ │ │ │ └── viewer.properties │ │ │ ├── nn-NO │ │ │ │ └── viewer.properties │ │ │ ├── oc │ │ │ │ └── viewer.properties │ │ │ ├── pa-IN │ │ │ │ └── viewer.properties │ │ │ ├── pl │ │ │ │ └── viewer.properties │ │ │ ├── pt-BR │ │ │ │ └── viewer.properties │ │ │ ├── pt-PT │ │ │ │ └── viewer.properties │ │ │ ├── rm │ │ │ │ └── viewer.properties │ │ │ ├── ro │ │ │ │ └── viewer.properties │ │ │ ├── ru │ │ │ │ └── viewer.properties │ │ │ ├── sat │ │ │ │ └── viewer.properties │ │ │ ├── sc │ │ │ │ └── viewer.properties │ │ │ ├── scn │ │ │ │ └── viewer.properties │ │ │ ├── sco │ │ │ │ └── viewer.properties │ │ │ ├── si │ │ │ │ └── viewer.properties │ │ │ ├── sk │ │ │ │ └── viewer.properties │ │ │ ├── sl │ │ │ │ └── viewer.properties │ │ │ ├── son │ │ │ │ └── viewer.properties │ │ │ ├── sq │ │ │ │ └── viewer.properties │ │ │ ├── sr │ │ │ │ └── viewer.properties │ │ │ ├── sv-SE │ │ │ │ └── viewer.properties │ │ │ ├── szl │ │ │ │ └── viewer.properties │ │ │ ├── ta │ │ │ │ └── viewer.properties │ │ │ ├── te │ │ │ │ └── viewer.properties │ │ │ ├── tg │ │ │ │ └── viewer.properties │ │ │ ├── th │ │ │ │ └── viewer.properties │ │ │ ├── tl │ │ │ │ └── viewer.properties │ │ │ ├── tr │ │ │ │ └── viewer.properties │ │ │ ├── trs │ │ │ │ └── viewer.properties │ │ │ ├── uk │ │ │ │ └── viewer.properties │ │ │ ├── ur │ │ │ │ └── viewer.properties │ │ │ ├── uz │ │ │ │ └── viewer.properties │ │ │ ├── vi │ │ │ │ └── viewer.properties │ │ │ ├── wo │ │ │ │ └── viewer.properties │ │ │ ├── xh │ │ │ │ └── viewer.properties │ │ │ ├── zh-CN │ │ │ │ └── viewer.properties │ │ │ └── zh-TW │ │ │ │ └── viewer.properties │ │ │ ├── standard_fonts │ │ │ ├── FoxitDingbats.pfb │ │ │ ├── FoxitFixed.pfb │ │ │ ├── FoxitFixedBold.pfb │ │ │ ├── FoxitFixedBoldItalic.pfb │ │ │ ├── FoxitFixedItalic.pfb │ │ │ ├── FoxitSans.pfb │ │ │ ├── FoxitSansBold.pfb │ │ │ ├── FoxitSansBoldItalic.pfb │ │ │ ├── FoxitSansItalic.pfb │ │ │ ├── FoxitSerif.pfb │ │ │ ├── FoxitSerifBold.pfb │ │ │ ├── FoxitSerifBoldItalic.pfb │ │ │ ├── FoxitSerifItalic.pfb │ │ │ ├── FoxitSymbol.pfb │ │ │ ├── LICENSE_FOXIT │ │ │ ├── LICENSE_LIBERATION │ │ │ ├── LiberationSans-Bold.ttf │ │ │ ├── LiberationSans-BoldItalic.ttf │ │ │ ├── LiberationSans-Italic.ttf │ │ │ └── LiberationSans-Regular.ttf │ │ │ ├── viewer.css │ │ │ ├── viewer.html │ │ │ └── viewer.js │ └── static │ │ └── iconfont │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 ├── src │ ├── App.vue │ ├── api │ │ ├── admin.ts │ │ ├── http.ts │ │ ├── index.ts │ │ └── upload-manager │ │ │ ├── chunk-task.ts │ │ │ ├── index.ts │ │ │ ├── task.ts │ │ │ └── upload-providers │ │ │ ├── custom.ts │ │ │ ├── dispatcher.ts │ │ │ ├── local-chunk.ts │ │ │ ├── local.ts │ │ │ ├── onedrive.ts │ │ │ └── s3.ts │ ├── components │ │ ├── CodeEditor │ │ │ ├── d-ts-imports.ts │ │ │ ├── index.vue │ │ │ ├── js-script-env.ts │ │ │ ├── mapping.ts │ │ │ └── utils.ts │ │ ├── DialogView │ │ │ ├── index.ts │ │ │ ├── index.vue │ │ │ └── state.ts │ │ ├── ErrorView.vue │ │ ├── FloatButton │ │ │ ├── FloatButton.vue │ │ │ └── index.ts │ │ ├── Form │ │ │ ├── FormItem.vue │ │ │ ├── FormItemForm.vue │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── HandlerTitleBar.vue │ │ ├── Icon.vue │ │ ├── ProgressBar.vue │ │ ├── SimpleButton │ │ │ ├── SimpleButton.vue │ │ │ └── index.ts │ │ ├── SimpleDropdown.vue │ │ ├── TextEditor │ │ │ ├── index.vue │ │ │ ├── languages.ts │ │ │ ├── theme-dark.ts │ │ │ └── theme-light.ts │ │ ├── async │ │ │ ├── LoadingComponent.vue │ │ │ └── index.ts │ │ ├── entry │ │ │ ├── EntryIcon.vue │ │ │ ├── EntryItem.vue │ │ │ ├── EntryLink.vue │ │ │ ├── EntryList.vue │ │ │ ├── PathBar.vue │ │ │ ├── file-icon.ts │ │ │ ├── index.ts │ │ │ ├── sort.ts │ │ │ └── useDrag.ts │ │ └── index.ts │ ├── config.ts │ ├── defines.d.ts │ ├── env.d.ts │ ├── handlers │ │ ├── HandlerView.vue │ │ ├── HandlerViewDialog.vue │ │ ├── audio │ │ │ ├── AudioView.vue │ │ │ ├── aplayer.d.ts │ │ │ └── index.ts │ │ ├── copy-move │ │ │ └── index.ts │ │ ├── delete │ │ │ └── index.ts │ │ ├── download │ │ │ ├── DownloadView.vue │ │ │ └── index.ts │ │ ├── handler-ctx.ts │ │ ├── handlers.ts │ │ ├── iframe │ │ │ ├── IframePreviewView.vue │ │ │ └── index.ts │ │ ├── image │ │ │ ├── ImageView.vue │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── mount │ │ │ └── index.ts │ │ ├── permission │ │ │ ├── PermissionsView.vue │ │ │ └── index.ts │ │ ├── rename │ │ │ └── index.ts │ │ ├── text-edit │ │ │ ├── TextEditView.vue │ │ │ └── index.ts │ │ ├── types.ts │ │ ├── video │ │ │ ├── VideoView.vue │ │ │ └── index.ts │ │ └── zip │ │ │ └── index.ts │ ├── i18n │ │ ├── index.ts │ │ └── lang │ │ │ ├── en-US.json │ │ │ └── zh-CN.json │ ├── main.ts │ ├── router │ │ └── index.ts │ ├── store │ │ ├── index.ts │ │ └── options.ts │ ├── styles │ │ ├── index.scss │ │ ├── markdown-dark.scss │ │ └── themes │ │ │ ├── dark.scss │ │ │ └── default.scss │ ├── types │ │ ├── index.ts │ │ └── model │ │ │ ├── admin.ts │ │ │ ├── config.ts │ │ │ └── index.ts │ ├── utils │ │ ├── directives │ │ │ ├── focus.ts │ │ │ ├── lazy-src.ts │ │ │ ├── long-press.ts │ │ │ └── markdown.ts │ │ ├── dom.ts │ │ ├── entry.ts │ │ ├── file.ts │ │ ├── highlight.ts │ │ ├── hooks │ │ │ ├── hotkey.ts │ │ │ └── timer.ts │ │ ├── http │ │ │ ├── http.ts │ │ │ ├── index.ts │ │ │ ├── transformers.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── index.ts │ │ ├── marked.ts │ │ ├── theme.ts │ │ └── ui-utils │ │ │ ├── base-dialog │ │ │ ├── BaseDialog.vue │ │ │ └── index.ts │ │ │ ├── dialog-use.ts │ │ │ ├── index.ts │ │ │ ├── input-dialog │ │ │ ├── InputDialog.vue │ │ │ └── index.ts │ │ │ ├── loading-dialog │ │ │ ├── LoadingDialog.vue │ │ │ └── index.ts │ │ │ ├── open-dialog │ │ │ ├── OpenDialog.vue │ │ │ └── index.ts │ │ │ └── text-dialog │ │ │ ├── TextDialog.vue │ │ │ └── index.ts │ └── views │ │ ├── Admin │ │ ├── Drives.vue │ │ ├── ExtraDrives │ │ │ ├── DriveCodeEditor.vue │ │ │ └── index.vue │ │ ├── FileBuckets.vue │ │ ├── Groups.vue │ │ ├── Jobs │ │ │ ├── ExecutionLogDialogInner.vue │ │ │ ├── execution-log-dialog.ts │ │ │ └── index.vue │ │ ├── Misc │ │ │ ├── CleanCache.vue │ │ │ ├── CleanInvalid.vue │ │ │ ├── RootPermissions.vue │ │ │ ├── SearchIndex.vue │ │ │ └── index.vue │ │ ├── OptionsConfigure.vue │ │ ├── PathMeta.vue │ │ ├── PermissionsEditor.vue │ │ ├── Site.vue │ │ ├── SysStats.vue │ │ ├── Users.vue │ │ ├── drive-configure │ │ │ └── OAuth.vue │ │ └── index.vue │ │ ├── AppWrapper │ │ └── index.vue │ │ ├── EntryExplorer │ │ ├── EntryMenu.vue │ │ ├── NewEntryArea.vue │ │ ├── ReadmeContent.vue │ │ ├── SearchPanel │ │ │ ├── SearchItem.vue │ │ │ └── index.vue │ │ ├── TaskManager │ │ │ ├── TaskItem.vue │ │ │ └── index.vue │ │ ├── explorer.ts │ │ ├── index.vue │ │ └── types.ts │ │ ├── EntryListView │ │ ├── index.vue │ │ └── types.ts │ │ ├── Home.vue │ │ └── Login │ │ └── LoginView.vue ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── wire.go └── wire_gen.go /.gitattributes: -------------------------------------------------------------------------------- 1 | web/public/** linguist-vendored 2 | server/webdav/** linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | tag: 7 | description: "Already created tag" 8 | required: true 9 | 10 | jobs: 11 | buildx: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Set build version 15 | run: | 16 | set -e 17 | [[ "${{ github.event.inputs.tag }}" =~ ^v[0-9.]+$ ]] || exit 1 18 | INPUT_TAG=${{ github.event.inputs.tag }} 19 | tag=${INPUT_TAG##*/} 20 | tag_version=${INPUT_TAG##*/v} 21 | echo "BUILD_TAG=${tag}" >> $GITHUB_ENV 22 | echo "DOCKER_TAG_VERSION=${tag_version}" >> $GITHUB_ENV 23 | 24 | - name: Set up QEMU 25 | uses: docker/setup-qemu-action@v3 26 | 27 | - name: Set up Docker Buildx 28 | uses: docker/setup-buildx-action@v3 29 | 30 | - name: Login to DockerHub 31 | uses: docker/login-action@v3 32 | with: 33 | username: ${{ secrets.DOCKERHUB_USERNAME }} 34 | password: ${{ secrets.DOCKERHUB_TOKEN }} 35 | 36 | - name: Build and push 37 | uses: docker/build-push-action@v5 38 | with: 39 | context: "{{defaultContext}}:docker" 40 | file: release.Dockerfile 41 | build-args: | 42 | TAG=${{ env.BUILD_TAG }} 43 | platforms: linux/amd64,linux/arm/v7,linux/arm64 44 | push: true 45 | tags: devld/go-drive:latest,devld/go-drive:${{ env.DOCKER_TAG_VERSION }} 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .idea/ 3 | *.iml 4 | 5 | /build/ 6 | /run/ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 devld 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | work_dir = build 3 | target_name ?= go-drive_build 4 | build_dir = $(work_dir)/$(target_name) 5 | 6 | all: $(build_dir)/$(target_name).tar.gz 7 | zip: $(build_dir)/$(target_name).zip 8 | 9 | # tar.gz 10 | $(build_dir)/$(target_name).tar.gz: $(build_dir)/$(target_name) 11 | cd $(work_dir); tar acf $(target_name).tar.gz --owner=0 --group=0 $(target_name) 12 | 13 | # zip for windows 14 | $(build_dir)/$(target_name).zip: $(build_dir)/$(target_name) 15 | cd $(work_dir); zip -q -r $(target_name).zip $(target_name) 16 | 17 | $(build_dir)/$(target_name): $(build_dir)/go-drive $(build_dir)/web $(build_dir)/lang $(build_dir)/config.yml 18 | 19 | $(build_dir)/go-drive: $(build_dir) 20 | CGO_CFLAGS="-Wno-return-local-addr" \ 21 | go build -o $(build_dir) -ldflags \ 22 | "-w -s \ 23 | -X 'go-drive/common.Version=${BUILD_VERSION}' \ 24 | -X 'go-drive/common.RevHash=$(shell git rev-parse HEAD)' \ 25 | -X 'go-drive/common.BuildAt=$(shell date -R)'" 26 | 27 | $(build_dir)/web: $(build_dir) web/dist 28 | cp -R web/dist $(build_dir)/web 29 | 30 | $(build_dir)/lang: $(build_dir) 31 | cp -R docs/lang $(build_dir)/ 32 | 33 | $(build_dir)/config.yml: $(build_dir) 34 | cp docs/config.yml $(build_dir)/ 35 | 36 | web/dist: 37 | cd web; npm install && npm run build 38 | 39 | $(build_dir): 40 | mkdir -p $(build_dir) 41 | 42 | .PHONY: clean 43 | 44 | clean: 45 | -rm -r $(work_dir) 46 | -rm -r web/dist 47 | -------------------------------------------------------------------------------- /common/drive_util/inline_file_exts.json: -------------------------------------------------------------------------------- 1 | { 2 | "jpg": "image/jpeg", 3 | "jpeg": "image/jpeg", 4 | "png": "image/png", 5 | "gif": "image/gif", 6 | "webp": "image/webp", 7 | "mp4": "video/mp4", 8 | "avi": "video/x-msvideo", 9 | "mov": "video/quicktime", 10 | "mkv": "video/x-matroska", 11 | "3gp": "video/3gpp", 12 | "wmv": "video/x-ms-wmv", 13 | "txt": "text/plain", 14 | "xml": "application/xml", 15 | "mp3": "audio/mpeg", 16 | "wav": "audio/wav", 17 | "ogg": "audio/ogg", 18 | "aac": "audio/aac", 19 | "flac": "audio/x-flac", 20 | "m4a": "audio/mp4", 21 | "webm": "audio/webm", 22 | "wma": "audio/x-ms-wma" 23 | } 24 | -------------------------------------------------------------------------------- /common/drive_util/registry.go: -------------------------------------------------------------------------------- 1 | package drive_util 2 | 3 | import "go-drive/common" 4 | 5 | type DriveDynamicRegistration func(common.Config) *DriveFactoryConfig 6 | 7 | var registry = make(map[string]interface{}) 8 | 9 | func RegisterDrive(factory DriveFactoryConfig) { 10 | if _, exists := registry[factory.Type]; exists { 11 | panic(factory.Type + " already registered") 12 | } 13 | registry[factory.Type] = factory 14 | } 15 | 16 | func RegisterDynamicDrive(typeName string, factory DriveDynamicRegistration) { 17 | if _, exists := registry[typeName]; exists { 18 | panic(typeName + " already registered") 19 | } 20 | registry[typeName] = factory 21 | } 22 | 23 | func toDriveFactory(typeName string, v interface{}, config common.Config) *DriveFactoryConfig { 24 | if f, ok := v.(DriveFactoryConfig); ok { 25 | return &f 26 | } 27 | fn := v.(DriveDynamicRegistration) 28 | f := fn(config) 29 | if f == nil { 30 | return nil 31 | } 32 | factory := *f 33 | factory.Type = typeName 34 | return &factory 35 | } 36 | 37 | func GetDrive(typeName string, config common.Config) *DriveFactoryConfig { 38 | d, ok := registry[typeName] 39 | if !ok { 40 | return nil 41 | } 42 | return toDriveFactory(typeName, d, config) 43 | } 44 | 45 | func GetRegisteredDrives(config common.Config) []DriveFactoryConfig { 46 | fc := make([]DriveFactoryConfig, 0, len(registry)) 47 | for n, v := range registry { 48 | f := toDriveFactory(n, v, config) 49 | if f != nil { 50 | fc = append(fc, *f) 51 | } 52 | } 53 | return fc 54 | } 55 | -------------------------------------------------------------------------------- /common/event/index.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | eb "github.com/asaskevich/EventBus" 5 | "go-drive/common/registry" 6 | ) 7 | 8 | // Bus is the event bus, all events are published on this bus 9 | // all event handlers must return as soon as possible 10 | // long-running event handlers should be run in task.Runner 11 | type Bus interface { 12 | Publish(topic string, args ...interface{}) 13 | Subscribe(topic string, handler interface{}) 14 | SubscribeOnce(topic string, handler interface{}) 15 | Unsubscribe(topic string, handler interface{}) bool 16 | } 17 | 18 | func NewBus(ch *registry.ComponentsHolder) Bus { 19 | b := &bus{eb.New()} 20 | ch.Add("eventBus", b) 21 | return b 22 | } 23 | 24 | type bus struct { 25 | b eb.Bus 26 | } 27 | 28 | func (b *bus) Publish(topic string, args ...interface{}) { 29 | b.b.Publish(topic, args...) 30 | } 31 | 32 | func (b *bus) Subscribe(topic string, handler interface{}) { 33 | if e := b.b.Subscribe(topic, handler); e != nil { 34 | panic(e) 35 | } 36 | } 37 | 38 | func (b *bus) SubscribeOnce(topic string, handler interface{}) { 39 | if e := b.b.SubscribeOnce(topic, handler); e != nil { 40 | panic(e) 41 | } 42 | } 43 | 44 | func (b *bus) Unsubscribe(topic string, handler interface{}) bool { 45 | return b.b.Unsubscribe(topic, handler) == nil 46 | } 47 | -------------------------------------------------------------------------------- /common/event/types.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | const ( 4 | // EntryAccessed fires when an entry is accessed. 5 | // The args is (types.DriveListenerContext, path). 6 | EntryAccessed = "drive:entry_accessed" 7 | // EntryUpdated fires when an entry is added or updated. 8 | // The args is (types.DriveListenerContext, path, includeDescendants bool). 9 | EntryUpdated = "drive:entry_updated" 10 | // EntryDeleted fires when an entry is deleted. 11 | // The args is (types.DriveListenerContext, path). 12 | EntryDeleted = "drive:entry_deleted" 13 | ) 14 | -------------------------------------------------------------------------------- /common/i18n/i18n_test.go: -------------------------------------------------------------------------------- 1 | package i18n 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestTranslate(t *testing.T) { 9 | tr := Translate("Hello{{2}}{{4}}}{{}}}{3}}{1}{{{ 1 }}}, {1c1}. How are you{2}{{2}}.", "JJ", "?") 10 | if tr != "Hello?{{4}}}{{}}}{3}}{1}{JJ}, {1c1}. How are you{2}?." { 11 | t.Error(tr) 12 | } 13 | } 14 | 15 | func TestT(t *testing.T) { 16 | fmt.Println(T("Hello, {{1}}. \"How are you{{2}}\"", "\"J\"J", "?")) 17 | } 18 | 19 | func TestUnmarshalT(t *testing.T) { 20 | // "Hello, {1}. ""How are you{2}""","""J""J","?" 21 | s := "\"Hello, {{1}}. \"\"How are you{{2}}\"\"\",\"\"\"J\"\"J\",\"?\"" 22 | r, e := UnmarshalT(s) 23 | if e != nil { 24 | t.Error(e) 25 | } 26 | if len(r) != 3 { 27 | t.Errorf("unexpected result: length: %d, %v", len(r), r) 28 | } 29 | for _, ss := range r { 30 | fmt.Print("==> ") 31 | fmt.Println(ss) 32 | } 33 | 34 | s += "," 35 | r, e = UnmarshalT(s) 36 | if e != nil { 37 | t.Error(e) 38 | } 39 | if len(r) != 3 { 40 | t.Errorf("unexpected result: length: %d, %v", len(r), r) 41 | } 42 | for _, ss := range r { 43 | fmt.Print("==> ") 44 | fmt.Println(ss) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/registry/components.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "fmt" 5 | "go-drive/common/types" 6 | ) 7 | 8 | type ComponentsHolder struct { 9 | c map[string]interface{} 10 | } 11 | 12 | func NewComponentHolder() *ComponentsHolder { 13 | return &ComponentsHolder{c: make(map[string]interface{})} 14 | } 15 | 16 | func (c *ComponentsHolder) Add(name string, component interface{}) { 17 | if _, ok := c.c[name]; ok { 18 | panic(fmt.Sprintf("component with name '%s' already added", name)) 19 | } 20 | c.c[name] = component 21 | } 22 | 23 | func (c *ComponentsHolder) Get(name string) interface{} { 24 | if v, ok := c.c[name]; ok { 25 | return v 26 | } 27 | panic(fmt.Sprintf("cannot find component '%s'", name)) 28 | } 29 | 30 | func (c *ComponentsHolder) Gets(matches func(c interface{}) bool) []interface{} { 31 | cs := make([]interface{}, 0) 32 | for _, v := range c.c { 33 | if matches == nil || matches(v) { 34 | cs = append(cs, v) 35 | } 36 | } 37 | return cs 38 | } 39 | 40 | func (c *ComponentsHolder) Dispose() error { 41 | disposables := c.Gets(func(c interface{}) bool { 42 | _, ok := c.(types.IDisposable) 43 | return ok 44 | }) 45 | for _, a := range disposables { 46 | _ = a.(types.IDisposable).Dispose() 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /common/req/types.go: -------------------------------------------------------------------------------- 1 | package req 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | ) 7 | 8 | type Response interface { 9 | Response() *http.Response 10 | Status() int 11 | Json(v interface{}) error 12 | XML(v interface{}) error 13 | Dispose() error 14 | } 15 | 16 | type RequestBody interface { 17 | ContentLength() int64 18 | ContentType() string 19 | Reader() io.Reader 20 | } 21 | -------------------------------------------------------------------------------- /common/task/option.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import "regexp" 4 | 5 | type Option = func(*Task) 6 | 7 | var groupRegexp = regexp.MustCompile("^([A-z0-9-_]+)(/([A-z0-9-_]+))*$") 8 | 9 | func IsValidGroup(group string) bool { 10 | return groupRegexp.MatchString(group) 11 | } 12 | 13 | // WithName sets the description of the task. 14 | func WithName(name string) Option { 15 | return func(t *Task) { 16 | t.Name = name 17 | } 18 | } 19 | 20 | // WithGroup sets the group of the task. 21 | // group is a string in the format "group/subgroup/subsubgroup" 22 | func WithGroup(group string) Option { 23 | if !IsValidGroup(group) { 24 | panic("invalid group name") 25 | } 26 | return func(t *Task) { 27 | t.Group = group 28 | } 29 | } 30 | 31 | // WithNameGroup sets the name and group of the task. 32 | // see WithName and WithGroup 33 | func WithNameGroup(name, group string) Option { 34 | if !IsValidGroup(group) { 35 | panic("invalid group name") 36 | } 37 | return func(t *Task) { 38 | t.Name = name 39 | t.Group = group 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /common/task/task.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | "errors" 5 | "go-drive/common/types" 6 | "time" 7 | ) 8 | 9 | const ( 10 | Pending = "pending" 11 | Running = "running" 12 | Done = "done" 13 | Error = "error" 14 | Canceled = "canceled" 15 | ) 16 | 17 | var ( 18 | ErrorNotFound = errors.New("task not found") 19 | ) 20 | 21 | type Status = string 22 | 23 | type Progress struct { 24 | Loaded int64 `json:"loaded"` 25 | Total int64 `json:"total"` 26 | } 27 | 28 | type Task struct { 29 | Id string `json:"id"` 30 | Status Status `json:"status"` 31 | Progress Progress `json:"progress"` 32 | Result interface{} `json:"result"` 33 | Error interface{} `json:"error"` 34 | CreatedAt time.Time `json:"createdAt"` 35 | UpdatedAt time.Time `json:"updatedAt"` 36 | 37 | // meta data 38 | Name string `json:"name"` 39 | Group string `json:"group"` 40 | } 41 | 42 | func (t Task) Finished() bool { 43 | return t.Status == Done || t.Status == Error || t.Status == Canceled 44 | } 45 | 46 | type Runnable = func(ctx types.TaskCtx) (interface{}, error) 47 | 48 | type Runner interface { 49 | Execute(runnable Runnable, options ...Option) (Task, error) 50 | ExecuteAndWait(runnable Runnable, timeout time.Duration, options ...Option) (Task, error) 51 | GetTask(id string) (Task, error) 52 | GetTasks(group string) ([]Task, error) 53 | StopTask(id string) (Task, error) 54 | RemoveTask(id string) error 55 | Dispose() error 56 | } 57 | -------------------------------------------------------------------------------- /common/types/events.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type DriveListenerContext struct { 4 | Session *Session 5 | Drive IDrive 6 | } 7 | -------------------------------------------------------------------------------- /common/types/misc.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "encoding/json" 4 | 5 | type MergedPathMetaProp[T any] struct { 6 | V T 7 | Path string 8 | } 9 | 10 | func (p MergedPathMetaProp[T]) MarshalJSON() ([]byte, error) { 11 | return json.Marshal(p.V) 12 | } 13 | 14 | type MergedPathMeta struct { 15 | Password MergedPathMetaProp[string] `json:"-"` 16 | DefaultSort MergedPathMetaProp[string] `json:"defaultSort"` 17 | DefaultMode MergedPathMetaProp[string] `json:"defaultMode"` 18 | HiddenPattern MergedPathMetaProp[string] `json:"hiddenPattern"` 19 | } 20 | 21 | var _ json.Marshaler = MergedPathMetaProp[string]{} 22 | -------------------------------------------------------------------------------- /common/types/search.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "time" 4 | 5 | type EntrySearchItem struct { 6 | Path string `json:"path"` 7 | Name string `json:"name"` 8 | Ext string `json:"ext"` 9 | Type EntryType `json:"type"` 10 | Size int64 `json:"size"` 11 | ModTime time.Time `json:"modTime"` 12 | } 13 | 14 | type EntrySearchResultItem struct { 15 | Entry EntrySearchItem `json:"entry"` 16 | Highlights map[string][]string `json:"highlights"` 17 | } 18 | 19 | type EntrySearchResult struct { 20 | Items []EntrySearchResultItem `json:"items"` 21 | Next int `json:"next"` 22 | } 23 | -------------------------------------------------------------------------------- /common/types/server.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | const ( 4 | AdminUserGroup = "admin" 5 | ) 6 | 7 | type Session struct { 8 | User User 9 | Props SM 10 | } 11 | 12 | func NewSession() Session { 13 | return Session{User: User{}, Props: SM{}} 14 | } 15 | 16 | func (s *Session) IsAnonymous() bool { 17 | return s.User.Username == "" 18 | } 19 | 20 | func (s *Session) HasUserGroup(group string) bool { 21 | for _, r := range s.User.Groups { 22 | if r.Name == group { 23 | return true 24 | } 25 | } 26 | return false 27 | } 28 | 29 | type Token struct { 30 | Token string `json:"token"` 31 | Value Session `json:"-"` 32 | // ExpiredAt is unix timestamp 33 | ExpiredAt int64 `json:"expiresAt"` 34 | } 35 | 36 | type TokenStore interface { 37 | // Create a token that store value 38 | Create(value Session) (Token, error) 39 | // Update an existing token value 40 | Update(token string, value Session) (Token, error) 41 | // Validate a token and return the value 42 | Validate(token string) (Token, error) 43 | // Revoke a token, return value is not nil only when an error occurred 44 | Revoke(token string) error 45 | } 46 | -------------------------------------------------------------------------------- /common/utils/id_pool_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestIdPool(t *testing.T) { 8 | p := NewIdPool[uint]() 9 | 10 | for i := 0; i < 100; i++ { 11 | p.Next() 12 | } 13 | if p.max != 100 { 14 | t.Errorf("expect p.max = %d", 100) 15 | return 16 | } 17 | 18 | for i := uint(0); i < 10; i++ { 19 | p.Release(i) 20 | } 21 | for i := uint(20); i < 30; i++ { 22 | p.Release(i) 23 | } 24 | for i := uint(50); i < 60; i++ { 25 | p.Release(i) 26 | } 27 | 28 | t.Log(p.max, p.pool) 29 | 30 | a := p.Next() 31 | if a != 1 { 32 | t.Errorf("expected next is 1, but %d returned", a) 33 | return 34 | } 35 | 36 | t.Log(p.max, p.pool) 37 | 38 | for i := uint(2); i <= 9; i++ { 39 | a := p.Next() 40 | if a != i { 41 | t.Errorf("expected next is %d, but %d returned", i, a) 42 | } 43 | } 44 | t.Log(p.max, p.pool) 45 | 46 | } 47 | -------------------------------------------------------------------------------- /common/utils/key_lock.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "sync" 4 | 5 | type KeyLock struct { 6 | m map[string]*sync.Mutex 7 | mux sync.Mutex 8 | } 9 | 10 | func NewKeyLock(size int) *KeyLock { 11 | return &KeyLock{m: make(map[string]*sync.Mutex, size)} 12 | } 13 | 14 | func (kl *KeyLock) getLock(key string) *sync.Mutex { 15 | kl.mux.Lock() 16 | defer kl.mux.Unlock() 17 | l, exists := kl.m[key] 18 | if !exists { 19 | l = &sync.Mutex{} 20 | kl.m[key] = l 21 | } 22 | return l 23 | } 24 | 25 | func (kl *KeyLock) Lock(key string) { 26 | kl.getLock(key).Lock() 27 | } 28 | 29 | func (kl *KeyLock) TryLock(key string) { 30 | kl.getLock(key).TryLock() 31 | } 32 | 33 | func (kl *KeyLock) UnLock(key string) { 34 | kl.getLock(key).Unlock() 35 | } 36 | -------------------------------------------------------------------------------- /common/utils/lazy_reader.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "io" 4 | 5 | func NewLazyReader(get func() (io.ReadCloser, error)) io.ReadCloser { 6 | return &lazyReader{get: get} 7 | } 8 | 9 | type lazyReader struct { 10 | r io.ReadCloser 11 | get func() (io.ReadCloser, error) 12 | } 13 | 14 | func (l *lazyReader) Read(p []byte) (n int, err error) { 15 | if l.r == nil { 16 | reader, e := l.get() 17 | l.get = nil 18 | if e != nil { 19 | return 0, e 20 | } 21 | l.r = reader 22 | } 23 | return l.r.Read(p) 24 | } 25 | 26 | func (l *lazyReader) Close() error { 27 | if l.r != nil { 28 | return l.r.Close() 29 | } 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /common/utils/signer.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/sha256" 6 | "encoding/binary" 7 | "math/rand" 8 | "time" 9 | ) 10 | 11 | type Signer struct { 12 | secret []byte 13 | } 14 | 15 | func sha256mac(key, data []byte) []byte { 16 | h := hmac.New(sha256.New, key) 17 | h.Write([]byte(data)) 18 | return h.Sum(nil) 19 | } 20 | 21 | func NewSigner() *Signer { 22 | return &Signer{RandSecret(64)} 23 | } 24 | 25 | func (s *Signer) sign(v string, notAfter int64, r uint32) string { 26 | vByte := []byte(v) 27 | buf := make([]byte, 4+8+len(vByte)) 28 | binary.LittleEndian.PutUint32(buf, r) 29 | binary.LittleEndian.PutUint64(buf[4:], uint64(notAfter)) 30 | copy(buf[4+8:], vByte) 31 | signature := sha256mac(s.secret, buf) 32 | 33 | result := make([]byte, 4+8+32) 34 | copy(result[:], buf[:12]) 35 | copy(result[12:], signature) 36 | 37 | return Base64URLEncode(result) 38 | } 39 | 40 | func (s *Signer) Sign(v string, notAfter time.Time) string { 41 | r := rand.Uint32() 42 | return s.sign(v, notAfter.Unix(), r) 43 | } 44 | 45 | func (s *Signer) Validate(v string, signature string) bool { 46 | buf, e := Base64URLDecode(signature) 47 | if e != nil || len(buf) != (4+8+32) { 48 | return false 49 | } 50 | r := binary.LittleEndian.Uint32(buf) 51 | notAfter := int64(binary.LittleEndian.Uint64(buf[4:])) 52 | 53 | actualSignature := s.sign(v, notAfter, r) 54 | if actualSignature != signature { 55 | return false 56 | } 57 | 58 | return notAfter > time.Now().Unix() 59 | } 60 | -------------------------------------------------------------------------------- /common/utils/signer_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestSigner(t *testing.T) { 9 | s := NewSigner() 10 | 11 | signature := s.Sign("hello world", time.Now().Add(3*time.Second)) 12 | 13 | t.Logf("signature: %s\n", signature) 14 | 15 | ok := s.Validate("hello world", signature) 16 | if !ok { 17 | t.Errorf("test failed") 18 | } 19 | 20 | ok = s.Validate("HELLO WORLD", signature) 21 | if ok { 22 | t.Errorf("test failed") 23 | } 24 | 25 | time.Sleep(3 * time.Second) 26 | ok = s.Validate("hello world", signature) 27 | if ok { 28 | t.Errorf("test failed") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /common/utils/temp_file.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func NewTempFile(file *os.File) *TempFile { 8 | return &TempFile{file} 9 | } 10 | 11 | // TempFile is a marker struct that indicates this file can be moved to another location instead of copying it 12 | type TempFile struct { 13 | *os.File 14 | } 15 | 16 | // TransferTo transfers the file to name by moving. 17 | // If the file is opened, is will be closed before moving 18 | func (t *TempFile) TransferTo(name string) (bool, error) { 19 | _ = t.File.Close() 20 | e := os.Rename(t.File.Name(), name) 21 | if e == nil { 22 | return true, nil 23 | } 24 | open, e := os.Open(t.File.Name()) 25 | if e != nil { 26 | return false, e 27 | } 28 | t.File = open 29 | return false, nil 30 | } 31 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.1-alpine AS golang 2 | 3 | FROM alpine AS builder 4 | 5 | ARG REF=heads/master 6 | ARG BUILD_VERSION 7 | 8 | WORKDIR /work 9 | 10 | RUN apk update && \ 11 | apk add git curl tar nodejs npm build-base 12 | # Setup golang 13 | COPY --from=golang /usr/local/go /usr/local/go 14 | ENV PATH="/usr/local/go/bin:${PATH}" 15 | 16 | ADD https://api.github.com/repos/devld/go-drive/git/refs/${REF} /tmp/ref-info 17 | 18 | RUN git clone https://github.com/devld/go-drive.git && \ 19 | cd go-drive && \ 20 | git reset --hard ${REF} && \ 21 | make target_name=go-drive_docker BUILD_VERSION=${BUILD_VERSION} all 22 | 23 | FROM alpine 24 | 25 | WORKDIR /app 26 | 27 | COPY --from=builder /work/go-drive/build/go-drive_docker.tar.gz . 28 | 29 | RUN tar xf go-drive_docker.tar.gz && \ 30 | rm go-drive_docker.tar.gz && \ 31 | mv go-drive_docker/* . && \ 32 | rmdir go-drive_docker && \ 33 | mkdir data && \ 34 | sed 's/data-dir: .\//data-dir: \/app\/data/; s/web-dir: .\/web/web-dir: \/app\/web/; s/lang-dir: .\/lang/lang-dir: \/app\/lang/' -i config.yml 35 | 36 | ENTRYPOINT ["/app/go-drive", "-c", "/app/config.yml"] 37 | 38 | EXPOSE 8089 39 | -------------------------------------------------------------------------------- /docker/release.Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | # Used for docker buildx 3 | 4 | FROM alpine:3.16 5 | 6 | ARG TAG 7 | ARG TARGETPLATFORM 8 | 9 | WORKDIR /app 10 | 11 | RUN set -e; \ 12 | case "${TARGETPLATFORM}" in \ 13 | linux/arm64*) \ 14 | arch=arm64; \ 15 | ;; \ 16 | linux/arm*) \ 17 | arch=arm; \ 18 | ;; \ 19 | linux/amd64) \ 20 | arch=amd64; \ 21 | ;; \ 22 | *) \ 23 | echo 'unsupported TARGETPLATFORM: ' ${TARGETPLATFORM}; \ 24 | return 4 \ 25 | ;;\ 26 | esac; \ 27 | name=go-drive_linux_musl_${arch}; \ 28 | file=/tmp/${name}.tar.gz; \ 29 | url=https://github.com/devld/go-drive/releases/download/${TAG}/${name}.tar.gz; \ 30 | echo downloading ${url} ; \ 31 | wget -q -O ${file} ${url} && \ 32 | tar xf ${file} && \ 33 | rm ${file} && \ 34 | mv ${name}/* . && \ 35 | rmdir ${name} && \ 36 | mkdir data && \ 37 | sed 's/data-dir: .\//data-dir: \/app\/data/; s/web-dir: .\/web/web-dir: \/app\/web/; s/lang-dir: .\/lang/lang-dir: \/app\/lang/' -i config.yml 38 | 39 | ENTRYPOINT ["/app/go-drive", "-c", "/app/config.yml"] 40 | 41 | EXPOSE 8089 42 | -------------------------------------------------------------------------------- /docs/drive-uploaders/README.md: -------------------------------------------------------------------------------- 1 | ## Implementing Drive's uploader 2 | 3 | In general, drives implemented in JavaScript can be uploaded via `go-drive`'s local uploader, in which case the upload will be relayed through `go-drive`. 4 | 5 | If you want to upload directly through the front-end. Then you need to implement a custom uploader. 6 | 7 | This script, unlike the Drive script, will be executed in the browser environment and you can use any API supported by the browser. 8 | 9 | In this script, you need to define a method, the name of the method doesn't matter. 10 | All variables, code need to be declared in this method (closure). 11 | 12 | This method will eventually need to return a [`CustomUploader`](https://github.com/devld/go-drive/blob/d5c3246b68355a76c358c8ea25139b0612f7b7fb/docs/drive-uploaders/types.d.ts#L51-L62). 13 | 14 | Once you finish all, then you can copy this js file to `/script-drives`,and name it `-uploader.js`. 15 | 16 | You can see examples of existing implementations in [`script-drives`](https://github.com/devld/go-drive/tree/master/script-drives). 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/oauth_callback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | Oauth callback 9 | 10 | 11 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/scripts/README.md: -------------------------------------------------------------------------------- 1 | ## Adapting Drive with JavaScript 2 | 3 | First create a new js file where all the code for Drive is located. 4 | 5 | This script will run in the otto environment, which is only **ES5** compatible, it **does not** support the DOM API, and only support limited APIs, which you can find in [`global.d.ts`](https://github.com/devld/go-drive/blob/master/docs/scripts/global.d.ts) and [`drive.d.ts`](https://github.com/devld/go-drive/blob/master/docs/scripts/env/drive.d.ts). 6 | 7 | In this file, the first line is the display name of the Drive, and from the second line to the next empty line is the description(markdown supported) of the Drive. 8 | 9 | Next, you can write the Drive's code. 10 | 11 | There are three main methods `defineCreate`, `defineInitConfig` and `defineInit`. 12 | 13 | - `defineCreate`: Creates an instance of the Drive 14 | - `defineInitConfig`: Get the configuration form for each step of the Drive 15 | - `defineInit`: the user fills the form returned by `defineInitConfig`, and the data will be passed to this method, you need to do some initialization in this method 16 | 17 | This whole script is evaluated when getting the initialization configuration (`initConfig`), initializing (`init`) or creating (`create`), and will not be executed again when the Drive is created. 18 | 19 | You can see examples of existing implementations in [`script-drives`](https://github.com/devld/go-drive/tree/master/script-drives). 20 | 21 | 22 | Once you finish all, then you can copy this js file to `/script-drives`. 23 | -------------------------------------------------------------------------------- /docs/scripts/env/jobs.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare const drive: DriveInstance; 4 | 5 | declare function log(s: string): void; 6 | 7 | /** copy files */ 8 | declare function cp(from: string, to: string, override: boolean): DriveEntry; 9 | /** move files */ 10 | declare function mv(from: string, to: string, override: boolean): DriveEntry; 11 | /** delete files */ 12 | declare function rm(path: string): void; 13 | /** list directory */ 14 | declare function ls(path: string): DriveEntry[]; 15 | /** create directory */ 16 | declare function mkdir(path: string): DriveEntry; 17 | -------------------------------------------------------------------------------- /docs/thumbnail-shell-example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | LOG_DIR=/tmp/go-drive-thumbnail.log 5 | 6 | echo "Type: $GO_DRIVE_ENTRY_TYPE" >> $LOG_DIR 7 | echo "RealPath: $GO_DRIVE_ENTRY_REAL_PATH" >> $LOG_DIR 8 | echo "Path: $GO_DRIVE_ENTRY_PATH" >> $LOG_DIR 9 | echo "Type: $GO_DRIVE_ENTRY_TYPE" >> $LOG_DIR 10 | echo "Name $GO_DRIVE_ENTRY_NAME" >> $LOG_DIR 11 | echo "Size: $GO_DRIVE_ENTRY_SIZE" >> $LOG_DIR 12 | echo "ModTime: $GO_DRIVE_ENTRY_MOD_TIME" >> $LOG_DIR 13 | echo "URL: $GO_DRIVE_ENTRY_URL" >> $LOG_DIR 14 | echo >> $LOG_DIR 15 | 16 | # ffmpeg read from stdin and write to stdout 17 | ffmpeg -hide_banner -loglevel error -i - -frames:v 1 -vf scale=220:-1 -f mjpeg - 18 | 19 | # or 20 | 21 | # ffmpeg read from url and write to stdout 22 | #ffmpeg -hide_banner -loglevel error -i http://localhost:8089$GO_DRIVE_ENTRY_URL -frames:v 1 -vf scale=220:-1 -f mjpeg - 23 | -------------------------------------------------------------------------------- /drive/imports.go: -------------------------------------------------------------------------------- 1 | package drive 2 | 3 | import ( 4 | _ "go-drive/drive/fs" 5 | _ "go-drive/drive/ftp" 6 | _ "go-drive/drive/gdrive" 7 | _ "go-drive/drive/onedrive" 8 | _ "go-drive/drive/s3" 9 | _ "go-drive/drive/script" 10 | _ "go-drive/drive/sftp" 11 | _ "go-drive/drive/webdav" 12 | ) 13 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "go-drive/common" 6 | "go-drive/common/registry" 7 | "log" 8 | "net/http" 9 | "os" 10 | "os/signal" 11 | "syscall" 12 | "time" 13 | ) 14 | 15 | func main() { 16 | ch := registry.NewComponentHolder() 17 | 18 | engine, e := Initialize(context.Background(), ch) 19 | if e != nil { 20 | log.Fatalln(e) 21 | } 22 | 23 | dispose := func() { _ = ch.Dispose() } 24 | 25 | conf := ch.Get("config").(common.Config) 26 | server := &http.Server{Addr: conf.Listen, Handler: engine} 27 | 28 | go func() { 29 | if e := server.ListenAndServe(); e != nil && e != http.ErrServerClosed { 30 | dispose() 31 | log.Fatalln(e) 32 | } 33 | }() 34 | 35 | quit := make(chan os.Signal, 1) 36 | signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) 37 | <-quit 38 | log.Println("Signal received. Shutting down...") 39 | 40 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 41 | defer cancel() 42 | 43 | if e := server.Shutdown(ctx); e != nil { 44 | dispose() 45 | log.Fatalln(e) 46 | } 47 | 48 | dispose() 49 | } 50 | -------------------------------------------------------------------------------- /script/object_context.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "context" 5 | "go-drive/common/types" 6 | ) 7 | 8 | func NewContext(vm *VM, c context.Context) Context { 9 | return Context{vm, c} 10 | } 11 | 12 | func NewTaskCtx(vm *VM, c types.TaskCtx) TaskCtx { 13 | return TaskCtx{NewContext(vm, c), c} 14 | } 15 | 16 | func GetContext(v interface{}) context.Context { 17 | switch v := v.(type) { 18 | case Context: 19 | return v.v 20 | case TaskCtx: 21 | return v.v 22 | } 23 | return nil 24 | } 25 | 26 | func GetTaskCtx(v interface{}) types.TaskCtx { 27 | switch v := v.(type) { 28 | case TaskCtx: 29 | return v.v 30 | } 31 | return nil 32 | } 33 | 34 | type Context struct { 35 | vm *VM 36 | v context.Context 37 | } 38 | 39 | func (c Context) Err() { 40 | e := c.v.Err() 41 | if e != nil { 42 | c.vm.ThrowError(e) 43 | } 44 | } 45 | 46 | type TaskCtx struct { 47 | Context 48 | v types.TaskCtx 49 | } 50 | 51 | func (t TaskCtx) Progress(loaded int64, abs bool) { 52 | t.v.Progress(loaded, abs) 53 | } 54 | 55 | func (t TaskCtx) Total(total int64, abs bool) { 56 | t.v.Total(total, abs) 57 | } 58 | -------------------------------------------------------------------------------- /server/scheduled/jobs.go: -------------------------------------------------------------------------------- 1 | package scheduled 2 | 3 | import "fmt" 4 | 5 | var registeredJobs = make(map[string]*JobDefinition) 6 | 7 | func RegisterJob(job JobDefinition) { 8 | if _, exists := registeredJobs[job.Name]; exists { 9 | panic(fmt.Sprintf("job '%s' already registered", job.Name)) 10 | } 11 | registeredJobs[job.Name] = &job 12 | } 13 | 14 | func GetJob(name string) *JobDefinition { 15 | jd, exists := registeredJobs[name] 16 | if !exists { 17 | return nil 18 | } 19 | job := *jd 20 | return &job 21 | } 22 | 23 | func GetJobs() []JobDefinition { 24 | jobs := make([]JobDefinition, 0, len(registeredJobs)) 25 | for _, j := range registeredJobs { 26 | jobs = append(jobs, *j) 27 | } 28 | return jobs 29 | } 30 | -------------------------------------------------------------------------------- /server/scheduled/jobs_script-helper.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | function __copyOrMove__(isMove, from, to, override) { 4 | var ctx = newTaskCtx(newContext()); 5 | 6 | var fromEntries = findEntries(ctx, drive, from); 7 | 8 | for (var i = 0; i < fromEntries.length; i++) { 9 | var fromEntry = fromEntries[i]; 10 | var toPath = pathUtils.join(to, fromEntry.Name()); 11 | if (isMove) { 12 | drive.Move(ctx, fromEntry, toPath, !!override); 13 | } else { 14 | drive.Copy(ctx, fromEntry, toPath, !!override); 15 | } 16 | } 17 | } 18 | 19 | function cp(from, to, override) { 20 | return __copyOrMove__(false, from, to, override); 21 | } 22 | 23 | function mv(from, to, override) { 24 | return __copyOrMove__(true, from, to, override); 25 | } 26 | 27 | function rm(path) { 28 | var ctx = newTaskCtx(newContext()); 29 | var entries = findEntries(ctx, drive, path); 30 | for (var i = entries.length - 1; i >= 0; i--) { 31 | try { 32 | drive.Delete(ctx, entries[i].Path()); 33 | } catch (e) { 34 | if (!isNotFoundErr(e)) throw e; 35 | } 36 | } 37 | } 38 | 39 | function ls(path) { 40 | return drive.List(newContext(), path); 41 | } 42 | 43 | function mkdir(path) { 44 | return drive.MakeDir(newContext(), path); 45 | } 46 | -------------------------------------------------------------------------------- /server/scheduled/types.go: -------------------------------------------------------------------------------- 1 | package scheduled 2 | 3 | import ( 4 | "context" 5 | "go-drive/common/registry" 6 | "go-drive/common/types" 7 | ) 8 | 9 | type JobWork func(context.Context, types.SM, *registry.ComponentsHolder, func(string)) error 10 | 11 | type JobDefinition struct { 12 | Name string `json:"name"` 13 | DisplayName string `json:"displayName" i18n:""` 14 | Description string `json:"description" i18n:""` 15 | ParamsForm []types.FormItem `json:"paramsForm"` 16 | Do JobWork `json:"-"` 17 | } 18 | -------------------------------------------------------------------------------- /server/search/searcher.go: -------------------------------------------------------------------------------- 1 | package search 2 | 3 | import ( 4 | "errors" 5 | "go-drive/common" 6 | "go-drive/common/types" 7 | "strings" 8 | ) 9 | 10 | var EmptySearchResult = types.EntrySearchResult{Next: -1} 11 | 12 | var searcherRegistry = make(map[string]SearcherFactory) 13 | 14 | func RegisterSearcher(name string, factory SearcherFactory) { 15 | if _, ok := searcherRegistry[name]; ok { 16 | panic("Searcher already registered: " + name) 17 | } 18 | searcherRegistry[name] = factory 19 | } 20 | 21 | func GetSearcher(name string) (SearcherFactory, error) { 22 | factory, ok := searcherRegistry[name] 23 | if !ok { 24 | ss := make([]string, 0, len(searcherRegistry)) 25 | for k := range searcherRegistry { 26 | ss = append(ss, k) 27 | } 28 | return nil, errors.New("Searcher not found: " + name + ", available searchers: " + strings.Join(ss, ", ")) 29 | } 30 | return factory, nil 31 | } 32 | 33 | type SearcherFactory func(config common.Config, searcherConfig types.SM) (Searcher, error) 34 | 35 | type Searcher interface { 36 | Search(path string, query string, from, size int) ([]types.EntrySearchResultItem, error) 37 | // Index add or update an entry to the index 38 | Index(ctx types.TaskCtx, entries []types.EntrySearchItem) error 39 | // Delete remove all entries in the dir(or single file) from the index 40 | Delete(ctx types.TaskCtx, dirPath string) error 41 | 42 | // Examples returns a list of example search queries 43 | Examples() []string 44 | Stats() (types.SM, error) 45 | Dispose() error 46 | } 47 | -------------------------------------------------------------------------------- /server/user_auth.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | err "go-drive/common/errors" 5 | "go-drive/common/i18n" 6 | "go-drive/common/types" 7 | "go-drive/storage" 8 | 9 | "golang.org/x/crypto/bcrypt" 10 | ) 11 | 12 | type UserAuth struct { 13 | userDAO *storage.UserDAO 14 | } 15 | 16 | func NewUserAuth(userDao *storage.UserDAO) *UserAuth { 17 | return &UserAuth{userDAO: userDao} 18 | } 19 | 20 | func (ua *UserAuth) AuthByUsernamePassword(username, password string) (types.User, error) { 21 | getUser, e := ua.userDAO.GetUser(username) 22 | if e != nil { 23 | if err.IsNotFoundError(e) { 24 | return types.User{}, 25 | err.NewNotAllowedMessageError(i18n.T("api.auth.invalid_username_or_password")) 26 | } else { 27 | return types.User{}, e 28 | } 29 | } 30 | if e := bcrypt.CompareHashAndPassword([]byte(getUser.Password), []byte(password)); e != nil { 31 | return types.User{}, 32 | err.NewNotAllowedMessageError(i18n.T("api.auth.invalid_username_or_password")) 33 | } 34 | return getUser, nil 35 | } 36 | -------------------------------------------------------------------------------- /server/webdav/internal/xml/README: -------------------------------------------------------------------------------- 1 | This is a fork of the encoding/xml package at ca1d6c4, the last commit before 2 | https://go.googlesource.com/go/+/c0d6d33 "encoding/xml: restore Go 1.4 name 3 | space behavior" made late in the lead-up to the Go 1.5 release. 4 | 5 | The list of encoding/xml changes is at 6 | https://go.googlesource.com/go/+log/master/src/encoding/xml 7 | 8 | This fork is temporary, and I (nigeltao) expect to revert it after Go 1.6 is 9 | released. 10 | 11 | See http://golang.org/issue/11841 12 | -------------------------------------------------------------------------------- /storage/drives.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "errors" 5 | err "go-drive/common/errors" 6 | "go-drive/common/i18n" 7 | "go-drive/common/registry" 8 | "go-drive/common/types" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | type DriveDAO struct { 14 | db *DB 15 | } 16 | 17 | func NewDriveDAO(db *DB, ch *registry.ComponentsHolder) *DriveDAO { 18 | dao := &DriveDAO{db: db} 19 | ch.Add("drivesDAO", dao) 20 | return dao 21 | } 22 | 23 | func (d *DriveDAO) GetDrives() ([]types.Drive, error) { 24 | var drivesConfig []types.Drive 25 | e := d.db.C().Find(&drivesConfig).Error 26 | return drivesConfig, e 27 | } 28 | 29 | func (d *DriveDAO) GetDrive(name string) (types.Drive, error) { 30 | var config types.Drive 31 | e := d.db.C().Where("`name` = ?", name).Take(&config).Error 32 | if errors.Is(e, gorm.ErrRecordNotFound) { 33 | return config, err.NewNotFoundError() 34 | } 35 | return config, e 36 | } 37 | 38 | func (d *DriveDAO) AddDrive(drive types.Drive) (types.Drive, error) { 39 | e := d.db.C().Where("`name` = ?", drive.Name).Take(&types.Drive{}).Error 40 | if e == nil { 41 | return types.Drive{}, 42 | err.NewNotAllowedMessageError(i18n.T("storage.drives.drive_exists", drive.Name)) 43 | } 44 | if !errors.Is(e, gorm.ErrRecordNotFound) { 45 | return types.Drive{}, e 46 | } 47 | e = d.db.C().Create(&drive).Error 48 | return drive, e 49 | } 50 | 51 | func (d *DriveDAO) UpdateDrive(name string, drive types.Drive) error { 52 | drive.Name = name 53 | return d.db.C().Save(drive).Error 54 | } 55 | 56 | func (d *DriveDAO) DeleteDrive(name string) error { 57 | return d.db.C().Delete(&types.Drive{}, "`name` = ?", name).Error 58 | } 59 | -------------------------------------------------------------------------------- /storage/path_permissions.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "go-drive/common/registry" 5 | "go-drive/common/types" 6 | 7 | "gorm.io/gorm" 8 | ) 9 | 10 | type PathPermissionDAO struct { 11 | db *DB 12 | } 13 | 14 | func NewPathPermissionDAO(db *DB, ch *registry.ComponentsHolder) *PathPermissionDAO { 15 | dao := &PathPermissionDAO{db} 16 | ch.Add("pathPermissionDAO", dao) 17 | return dao 18 | } 19 | 20 | func (p *PathPermissionDAO) GetAll() ([]types.PathPermission, error) { 21 | pps := make([]types.PathPermission, 0) 22 | if e := p.db.C().Find(&pps).Error; e != nil { 23 | return nil, e 24 | } 25 | return pps, nil 26 | } 27 | 28 | func (p *PathPermissionDAO) GetByPath(path string) ([]types.PathPermission, error) { 29 | r := make([]types.PathPermission, 0) 30 | if e := p.db.C().Find(&r, "`path` = ?", path).Error; e != nil { 31 | return nil, e 32 | } 33 | return r, nil 34 | } 35 | 36 | func (p *PathPermissionDAO) SavePathPermissions(path string, permissions []types.PathPermission) error { 37 | return p.db.C().Transaction(func(tx *gorm.DB) error { 38 | if e := tx.Delete(&types.PathPermission{}, "`path` = ?", path).Error; e != nil { 39 | return e 40 | } 41 | for _, p := range permissions { 42 | p.Path = &path 43 | if e := tx.Create(&p).Error; e != nil { 44 | return e 45 | } 46 | } 47 | return nil 48 | }) 49 | } 50 | 51 | func (p *PathPermissionDAO) DeleteByPath(path string) error { 52 | return p.db.C().Delete(&types.PathPermission{}, "`path` = ?", path).Error 53 | } 54 | -------------------------------------------------------------------------------- /web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "browser": true, 5 | "es2021": true, 6 | "node": true 7 | }, 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:vue/vue3-recommended", 11 | "@vue/typescript/recommended", 12 | "prettier" 13 | ], 14 | "parserOptions": { 15 | "ecmaVersion": 2021 16 | }, 17 | "plugins": [], 18 | "rules": { 19 | "vue/require-default-prop": "off", 20 | "vue/multi-word-component-names": "off", 21 | "@typescript-eslint/no-non-null-assertion": "off", 22 | "@typescript-eslint/no-explicit-any": "off" 23 | }, 24 | "overrides": [ 25 | { 26 | "files": "*.vue", 27 | "rules": { 28 | "no-undef": "off" 29 | } 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | /stats.html 27 | 28 | /public/code-editor -------------------------------------------------------------------------------- /web/monaco-editor/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /web/monaco-editor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "go-drive-web-monaco-editor", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "description": "Monaco editor of go-drive web", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vue-tsc --noEmit && vite build", 9 | "preview": "vite preview", 10 | "lint": "vue-tsc --noEmit && eslint" 11 | }, 12 | "dependencies": { 13 | "monaco-editor": "^0.52.0" 14 | }, 15 | "devDependencies": { 16 | "eslint": "^8.56.0", 17 | "eslint-config-prettier": "^9.1.0", 18 | "sass": "^1.79.4", 19 | "typescript": "^5.6.2", 20 | "vite": "^6.2.6", 21 | "vue-tsc": "^2.1.6" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/devld/go-drive.git" 26 | }, 27 | "license": "MIT", 28 | "prettier": { 29 | "semi": false, 30 | "singleQuote": true, 31 | "trailingComma": "es5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web/monaco-editor/src/env.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/monaco-editor/src/env.d.ts -------------------------------------------------------------------------------- /web/monaco-editor/src/main.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | width: 100%; 4 | height: 100%; 5 | margin: 0; 6 | overflow: hidden; 7 | } 8 | 9 | .editor-container { 10 | width: 100%; 11 | height: 100%; 12 | overflow: hidden; 13 | } -------------------------------------------------------------------------------- /web/monaco-editor/src/main.ts: -------------------------------------------------------------------------------- 1 | import './main.scss' 2 | import { EditorInMessageHandlers } from './types' 3 | import { 4 | createEditor, 5 | emit, 6 | queries, 7 | setupDataExchanging, 8 | setupJavaScript, 9 | } from './utils' 10 | import './workers' 11 | import { KeyCode, KeyMod } from 'monaco-editor' 12 | 13 | const language = queries['lang'] 14 | 15 | const editor = createEditor(language) 16 | emit('ready', undefined) 17 | 18 | editor.getModel()!.onDidChangeContent(() => { 19 | emit('change', editor.getValue()) 20 | }) 21 | editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyS, () => { 22 | emit('save', undefined) 23 | }) 24 | 25 | const messageHandlers: EditorInMessageHandlers = { 26 | setValue: (data) => { 27 | editor.setValue(data) 28 | }, 29 | setupJs: (data) => { 30 | setupJavaScript(data) 31 | }, 32 | setDisabled: (disabled) => { 33 | editor.updateOptions({ readOnly: disabled }) 34 | }, 35 | setTheme: (theme) => { 36 | editor.updateOptions({ theme }) 37 | }, 38 | } 39 | 40 | setupDataExchanging(messageHandlers) 41 | -------------------------------------------------------------------------------- /web/monaco-editor/src/types.ts: -------------------------------------------------------------------------------- 1 | export const MESSAGE_KEY_PREFIX = 'monaco-editor-data-' 2 | 3 | export type MessageHandler = (data: T) => void 4 | 5 | export interface JavaScriptLibItem { 6 | name: string 7 | content: string 8 | } 9 | export interface JavaScriptSetupOptions { 10 | target?: string 11 | lib?: string[] 12 | extraLibs?: JavaScriptLibItem[] 13 | } 14 | 15 | export interface EditorInMessageTypes { 16 | setValue: string 17 | setupJs: JavaScriptSetupOptions 18 | setDisabled: boolean 19 | setTheme: string 20 | } 21 | 22 | export interface EditorOutMessageTypes { 23 | ready: undefined 24 | change: string 25 | save: undefined 26 | } 27 | 28 | export type EditorInMessageHandlers = { 29 | [K in keyof EditorInMessageTypes]: MessageHandler 30 | } 31 | 32 | export type EditorOutMessageHandlers = { 33 | [K in keyof EditorOutMessageTypes]: MessageHandler 34 | } 35 | -------------------------------------------------------------------------------- /web/monaco-editor/src/workers.ts: -------------------------------------------------------------------------------- 1 | import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' 2 | 3 | self.MonacoEnvironment = { 4 | getWorker: (_id: string, label: string) => { 5 | switch (label) { 6 | case 'css': 7 | case 'scss': 8 | case 'less': 9 | return import( 10 | 'monaco-editor/esm/vs/language/css/css.worker?worker' 11 | ).then((g) => new g.default()) 12 | case 'html': 13 | return import( 14 | 'monaco-editor/esm/vs/language/html/html.worker?worker' 15 | ).then((g) => new g.default()) 16 | case 'json': 17 | return import( 18 | 'monaco-editor/esm/vs/language/json/json.worker?worker' 19 | ).then((g) => new g.default()) 20 | case 'typescript': 21 | case 'javascript': 22 | return import( 23 | 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' 24 | ).then((g) => new g.default()) 25 | case 'editorWorkerService': 26 | return new editorWorker() 27 | } 28 | throw new Error('unsupported: ' + label) 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /web/monaco-editor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": true, 12 | "esModuleInterop": true, 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | "skipLibCheck": true, 18 | "paths": { 19 | "@/*": [ 20 | "./src/*" 21 | ] 22 | }, 23 | "types": [ 24 | "vite/client" 25 | ] 26 | }, 27 | "include": [ 28 | "src/**/*.ts", 29 | "src/**/*.d.ts", 30 | ], 31 | } -------------------------------------------------------------------------------- /web/monaco-editor/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | 3 | // https://vitejs.dev/config/ 4 | export default defineConfig({ 5 | base: './', 6 | server: { 7 | port: 9804, 8 | }, 9 | css: { preprocessorOptions: { scss: { api: 'modern-compiler' } } }, 10 | build: { 11 | outDir: '../public/code-editor', 12 | emptyOutDir: true, 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/favicon.ico -------------------------------------------------------------------------------- /web/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/favicon.png -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78ms-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78ms-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/78ms-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/78ms-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/83pv-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/83pv-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/90ms-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/90ms-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/90ms-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/90ms-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/90msp-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/90msp-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/90msp-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/90msp-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/90pv-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/90pv-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/90pv-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/90pv-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Add-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Add-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Add-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Add-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Add-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Add-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Add-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Add-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-0.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-0.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-1.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-1.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-3.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-3.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-4.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-4.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-5.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-5.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-6.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-6.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-CNS1-UCS2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-CNS1-UCS2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-0.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-0.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-1.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-1.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-3.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-3.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-4.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-4.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-5.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-5.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-GB1-UCS2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-GB1-UCS2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-0.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-0.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-1.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-1.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-3.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-3.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-4.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-4.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-5.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-5.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-6.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-6.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Japan1-UCS2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Japan1-UCS2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Korea1-0.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Korea1-0.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Korea1-1.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Korea1-1.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Korea1-2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Korea1-2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Adobe-Korea1-UCS2.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Adobe-Korea1-UCS2.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/B5pc-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/B5pc-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/B5pc-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/B5pc-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/CNS-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/CNS-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/CNS-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/CNS-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/CNS1-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/CNS1-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/CNS1-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/CNS1-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/CNS2-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/CNS2-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/CNS2-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/CNS2-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/ETHK-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/ETHK-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/ETHK-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/ETHK-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/ETen-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/ETen-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/ETen-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/ETen-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/ETenms-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/ETenms-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/ETenms-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/ETenms-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Ext-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Ext-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Ext-RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Ext-RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Ext-RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Ext-RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Ext-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Ext-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GB-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GB-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GB-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GB-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GB-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GB-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GB-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GB-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBK-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBK-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBK-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBK-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBK2K-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBK2K-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBK2K-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBK2K-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBKp-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBKp-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBKp-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBKp-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBT-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBT-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBT-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBT-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBT-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBT-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBT-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBT-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBTpc-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBTpc-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBTpc-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBTpc-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBpc-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBpc-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/GBpc-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/GBpc-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKdla-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKdla-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKdla-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKdla-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKdlb-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKdlb-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKdlb-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKdlb-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKgccs-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKgccs-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKgccs-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKgccs-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKm314-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKm314-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKm314-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKm314-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKm471-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKm471-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKm471-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKm471-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKscs-B5-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKscs-B5-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/HKscs-B5-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/HKscs-B5-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Hankaku.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Hankaku.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Hiragana.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Hiragana.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSC-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSC-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSC-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSC-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSC-Johab-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSC-Johab-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSC-Johab-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSC-Johab-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSCms-UHC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSCms-UHC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSCms-UHC-HW-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSCms-UHC-HW-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSCms-UHC-HW-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSCms-UHC-HW-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSCms-UHC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSCms-UHC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSCpc-EUC-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSCpc-EUC-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/KSCpc-EUC-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/KSCpc-EUC-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Katakana.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Katakana.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/NWP-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/NWP-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/NWP-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/NWP-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/RKSJ-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/RKSJ-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/RKSJ-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/RKSJ-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/Roman.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/Roman.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UCS2-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UCS2-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UCS2-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UCS2-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UTF16-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UTF16-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UTF16-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UTF16-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UTF8-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UTF8-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniCNS-UTF8-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniCNS-UTF8-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UCS2-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UCS2-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UCS2-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UCS2-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UTF16-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UTF16-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UTF16-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UTF16-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UTF8-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UTF8-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniGB-UTF8-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniGB-UTF8-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UCS2-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UCS2-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UCS2-HW-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UCS2-HW-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UCS2-HW-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UCS2-HW-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UCS2-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UCS2-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UTF16-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UTF16-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UTF16-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UTF16-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UTF8-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UTF8-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS-UTF8-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS-UTF8-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS2004-UTF16-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS2004-UTF16-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS2004-UTF16-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS2004-UTF16-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS2004-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS2004-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS2004-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS2004-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS2004-UTF8-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS2004-UTF8-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJIS2004-UTF8-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJIS2004-UTF8-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISPro-UCS2-HW-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISPro-UCS2-HW-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISPro-UCS2-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISPro-UCS2-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISPro-UTF8-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISPro-UTF8-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISX0213-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISX0213-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISX0213-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISX0213-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISX02132004-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISX02132004-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniJISX02132004-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniJISX02132004-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UCS2-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UCS2-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UCS2-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UCS2-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UTF16-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UTF16-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UTF16-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UTF16-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UTF32-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UTF32-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UTF32-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UTF32-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UTF8-H.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UTF8-H.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/UniKS-UTF8-V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/UniKS-UTF8-V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/V.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/V.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/cmaps/WP-Symbol.bcmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/cmaps/WP-Symbol.bcmap -------------------------------------------------------------------------------- /web/public/pdf.js/web/compressed.tracemonkey-pldi-09.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/compressed.tracemonkey-pldi-09.pdf -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-comment.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-insert.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-key.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-newparagraph.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-noicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-note.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 14 | 21 | 28 | 35 | 42 | 43 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/annotation-paragraph.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/cursor-editorInk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/findbarButton-next.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/findbarButton-previous.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/loading-icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/images/loading-icon.gif -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/loading.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-documentProperties.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-firstPage.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-handTool.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-lastPage.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-rotateCcw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-rotateCw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-scrollHorizontal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-scrollPage.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-scrollVertical.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-scrollWrapped.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-selectTool.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-spreadEven.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-spreadNone.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/secondaryToolbarButton-spreadOdd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/images/shadow.png -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-bookmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-currentOutlineItem.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-editorFreeText.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-editorInk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-menuArrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-openFile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-pageDown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-pageUp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-presentationMode.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-print.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-secondaryToolbarToggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-sidebarToggle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-viewAttachments.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-viewLayers.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-viewOutline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-viewThumbnail.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-zoomIn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/toolbarButton-zoomOut.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/treeitem-collapsed.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/images/treeitem-expanded.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitDingbats.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitDingbats.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitFixed.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitFixed.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitFixedBold.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitFixedBold.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitFixedBoldItalic.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitFixedBoldItalic.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitFixedItalic.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitFixedItalic.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSans.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSans.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSansBold.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSansBold.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSansBoldItalic.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSansBoldItalic.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSansItalic.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSansItalic.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSerif.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSerif.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSerifBold.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSerifBold.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSerifBoldItalic.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSerifBoldItalic.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSerifItalic.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSerifItalic.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/FoxitSymbol.pfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/FoxitSymbol.pfb -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/LiberationSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/LiberationSans-Bold.ttf -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/LiberationSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/LiberationSans-BoldItalic.ttf -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/LiberationSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/LiberationSans-Italic.ttf -------------------------------------------------------------------------------- /web/public/pdf.js/web/standard_fonts/LiberationSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/pdf.js/web/standard_fonts/LiberationSans-Regular.ttf -------------------------------------------------------------------------------- /web/public/static/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/static/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /web/public/static/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/static/iconfont/iconfont.woff -------------------------------------------------------------------------------- /web/public/static/iconfont/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devld/go-drive/2e8a123f6f23ea62ce6c0f20bc7cacc411134909/web/public/static/iconfont/iconfont.woff2 -------------------------------------------------------------------------------- /web/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | 17 | 31 | -------------------------------------------------------------------------------- /web/src/components/CodeEditor/d-ts-imports.ts: -------------------------------------------------------------------------------- 1 | import type { JavaScriptLibItem } from '../../../monaco-editor/src/types' 2 | 3 | import { filename, mapOf } from '@/utils' 4 | import serverGlobal from '../../../../docs/scripts/global.d.ts?raw' 5 | const serverLibs = import.meta.glob('../../../../docs/scripts/libs/*.d.ts', { 6 | query: '?raw', 7 | import: 'default', 8 | eager: true, 9 | }) 10 | const serverEnvs = import.meta.glob('../../../../docs/scripts/env/*.d.ts', { 11 | query: '?raw', 12 | import: 'default', 13 | eager: true, 14 | }) 15 | 16 | const getName = (path: string) => filename(path).replace(/\.d\.ts$/, '') 17 | 18 | export const D_SERVER_GLOBAL: JavaScriptLibItem = { 19 | name: 'global', 20 | content: serverGlobal, 21 | } 22 | 23 | export const D_SERVER_LIBS: JavaScriptLibItem[] = Object.entries( 24 | serverLibs as unknown as Record 25 | ).map((e) => ({ 26 | name: getName(e[0]), 27 | content: e[1], 28 | })) 29 | 30 | export const D_SERVER_ENVS_MAP: Record = mapOf( 31 | Object.entries(serverEnvs as unknown as Record).map((e) => ({ 32 | name: getName(e[0]), 33 | content: e[1], 34 | })), 35 | (e) => e.name 36 | ) 37 | 38 | import driveUploaderEnv from '../../../../docs/drive-uploaders/types.d.ts?raw' 39 | 40 | export const D_BROWSER_ENVS_MAP: Record = { 41 | uploader: { name: 'uploader', content: driveUploaderEnv }, 42 | } 43 | -------------------------------------------------------------------------------- /web/src/components/CodeEditor/js-script-env.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | JavaScriptLibItem, 3 | JavaScriptSetupOptions, 4 | } from '../../../monaco-editor/src/types' 5 | import { 6 | D_SERVER_ENVS_MAP, 7 | D_SERVER_GLOBAL, 8 | D_SERVER_LIBS, 9 | D_BROWSER_ENVS_MAP, 10 | } from './d-ts-imports' 11 | 12 | export const serverConsoleLib: JavaScriptLibItem = { 13 | name: 'console', 14 | content: `interface Console { 15 | debug(...message?: any[]): void; 16 | error(...message?: any[]): void; 17 | info(...message?: any[]): void; 18 | log(...message?: any[]): void; 19 | warn(...message?: any[]): void; 20 | } 21 | declare const console: Console;`, 22 | } 23 | 24 | export const serverBaseOptions = ( 25 | libs: JavaScriptLibItem[] 26 | ): JavaScriptSetupOptions => ({ 27 | target: 'es5', 28 | lib: ['es5'], 29 | extraLibs: [serverConsoleLib, ...D_SERVER_LIBS, D_SERVER_GLOBAL, ...libs], 30 | }) 31 | 32 | export const browserBaseOptions = ( 33 | libs?: JavaScriptLibItem[] 34 | ): JavaScriptSetupOptions => ({ extraLibs: libs }) 35 | 36 | export const getEnv = (name: string) => { 37 | if (name.startsWith('server-')) { 38 | name = name.substring(7) 39 | const env = D_SERVER_ENVS_MAP[name] 40 | if (!env) { 41 | console.warn('[CodeEditor] unknown env: ' + name) 42 | return 43 | } 44 | return serverBaseOptions([env]) 45 | } 46 | const env = D_BROWSER_ENVS_MAP[name] 47 | if (!env) { 48 | console.warn('[CodeEditor] unknown env: ' + name) 49 | return 50 | } 51 | return browserBaseOptions([env]) 52 | } 53 | -------------------------------------------------------------------------------- /web/src/components/DialogView/index.ts: -------------------------------------------------------------------------------- 1 | import DialogView from './DialogView.vue' 2 | 3 | export default DialogView 4 | -------------------------------------------------------------------------------- /web/src/components/DialogView/state.ts: -------------------------------------------------------------------------------- 1 | let scrollLockedCount = 0 2 | 3 | export function addScrollLockedCount(delta: number) { 4 | return (scrollLockedCount += delta) 5 | } 6 | 7 | export function getScrollLockedCount() { 8 | return scrollLockedCount 9 | } 10 | -------------------------------------------------------------------------------- /web/src/components/ErrorView.vue: -------------------------------------------------------------------------------- 1 | 12 | 22 | 42 | -------------------------------------------------------------------------------- /web/src/components/FloatButton/index.ts: -------------------------------------------------------------------------------- 1 | import FloatButton from './FloatButton.vue' 2 | 3 | export interface FloatButtonItem extends O { 4 | title?: I18nText 5 | slot: string 6 | icon?: string 7 | } 8 | 9 | export interface FloatButtonClickEventData { 10 | button: FloatButtonItem 11 | index: number 12 | } 13 | 14 | export default FloatButton 15 | -------------------------------------------------------------------------------- /web/src/components/Form/index.ts: -------------------------------------------------------------------------------- 1 | import FormItem from './FormItem.vue' 2 | import SimpleForm from './index.vue' 3 | 4 | export const SimpleFormItem = FormItem 5 | export default SimpleForm 6 | -------------------------------------------------------------------------------- /web/src/components/HandlerTitleBar.vue: -------------------------------------------------------------------------------- 1 | 19 | 32 | 66 | -------------------------------------------------------------------------------- /web/src/components/Icon.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /web/src/components/SimpleButton/index.ts: -------------------------------------------------------------------------------- 1 | import SimpleButton from './SimpleButton.vue' 2 | 3 | export type SimpleButtonType = 'info' | 'success' | 'warning' | 'danger' 4 | 5 | export type SimpleButtonNativeType = 'submit' | 'reset' | 'button' 6 | 7 | export default SimpleButton 8 | -------------------------------------------------------------------------------- /web/src/components/SimpleDropdown.vue: -------------------------------------------------------------------------------- 1 | 17 | 51 | 70 | -------------------------------------------------------------------------------- /web/src/components/async/LoadingComponent.vue: -------------------------------------------------------------------------------- 1 | 4 | 12 | -------------------------------------------------------------------------------- /web/src/components/async/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AsyncComponentLoader, 3 | Component, 4 | ComponentPublicInstance, 5 | defineAsyncComponent, 6 | } from 'vue' 7 | import LoadingComponent from './LoadingComponent.vue' 8 | 9 | export function wrapAsyncComponent< 10 | T extends Component = { 11 | new (): ComponentPublicInstance 12 | } 13 | >(loader: AsyncComponentLoader) { 14 | return defineAsyncComponent({ 15 | loader, 16 | loadingComponent: LoadingComponent, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /web/src/components/entry/index.ts: -------------------------------------------------------------------------------- 1 | import EntryIcon_ from './EntryIcon.vue' 2 | import EntryLink_ from './EntryLink.vue' 3 | import EntryItem_ from './EntryItem.vue' 4 | import EntryList_ from './EntryList.vue' 5 | import PathBar_ from './PathBar.vue' 6 | import { Entry } from '@/types' 7 | 8 | export type ListViewMode = 'list' | 'thumbnail' 9 | 10 | export interface EntryEventData { 11 | entry?: Entry 12 | path?: string 13 | event?: Event 14 | } 15 | 16 | export type GetLinkFn = (e: Entry | string) => string | undefined 17 | 18 | export const EntryIcon = EntryIcon_ 19 | export const EntryLink = EntryLink_ 20 | export const EntryItem = EntryItem_ 21 | export const EntryList = EntryList_ 22 | export const PathBar = PathBar_ 23 | -------------------------------------------------------------------------------- /web/src/components/entry/sort.ts: -------------------------------------------------------------------------------- 1 | import { Entry } from '@/types' 2 | 3 | export const SORTS_METHOD: O<(a: Entry, b: Entry) => number> = { 4 | name_asc: (a, b) => 5 | a.type.localeCompare(b.type) || a.name.localeCompare(b.name), 6 | name_desc: (a, b) => 7 | -a.type.localeCompare(b.type) || -a.name.localeCompare(b.name), 8 | mod_time_asc: (a, b) => 9 | a.type.localeCompare(b.type) || 10 | a.modTime - b.modTime || 11 | a.name.localeCompare(b.name), 12 | mod_time_desc: (a, b) => 13 | -a.type.localeCompare(b.type) || 14 | b.modTime - a.modTime || 15 | a.name.localeCompare(b.name), 16 | size_asc: (a, b) => 17 | a.type.localeCompare(b.type) || 18 | a.size - b.size || 19 | a.name.localeCompare(b.name), 20 | size_desc: (a, b) => 21 | -a.type.localeCompare(b.type) || 22 | b.size - a.size || 23 | a.name.localeCompare(b.name), 24 | } 25 | 26 | export const sortModes = Object.keys(SORTS_METHOD).map((key) => ({ 27 | key, 28 | name: `app.sort.${key}`, 29 | })) 30 | -------------------------------------------------------------------------------- /web/src/components/index.ts: -------------------------------------------------------------------------------- 1 | import { Component, Plugin } from 'vue' 2 | 3 | import Icon from './Icon.vue' 4 | import { EntryIcon, EntryLink, EntryItem, EntryList, PathBar } from './entry' 5 | import ErrorView from './ErrorView.vue' 6 | import DialogView from './DialogView/index.vue' 7 | import FloatButton from './FloatButton' 8 | import SimpleButton from './SimpleButton' 9 | import SimpleFormItem from './Form/FormItem.vue' 10 | import SimpleForm from './Form/index.vue' 11 | import SimpleDropdown from './SimpleDropdown.vue' 12 | import ProgressBar from './ProgressBar.vue' 13 | 14 | const components: O = { 15 | Icon, 16 | SimpleButton, 17 | SimpleForm, 18 | SimpleFormItem, 19 | SimpleDropdown, 20 | EntryIcon, 21 | EntryLink, 22 | EntryList, 23 | EntryItem, 24 | PathBar, 25 | ErrorView, 26 | DialogView, 27 | FloatButton, 28 | ProgressBar, 29 | } 30 | 31 | export default { 32 | install(app) { 33 | Object.keys(components).forEach((key) => { 34 | app.component(key, components[key]) 35 | }) 36 | }, 37 | } as Plugin 38 | -------------------------------------------------------------------------------- /web/src/config.ts: -------------------------------------------------------------------------------- 1 | export const EXPLORER_PATH_BASE = '/_' 2 | 3 | export const TEXT_EDITOR_MAX_FILE_SIZE = 128 * 1024 // 128kb 4 | 5 | export const DEFAULT_TEXT_FILE_EXTS = 6 | 'txt,md,xml,html,css,scss,js,json,jsx,ts,properties,yml,yaml,ini,c,h,cpp,go,java,kt,gradle,ps1' 7 | 8 | export const DEFAULT_IMAGE_FILE_EXTS = 'jpg,jpeg,png,gif' 9 | 10 | export const DEFAULT_AUDIO_FILE_EXTS = 'mp3,m4a,flac' 11 | 12 | export const DEFAULT_VIDEO_FILE_EXTS = 'mp4,ogg' 13 | 14 | export const DEFAULT_EXTERNAL_FILE_PREVIEWERS = ` 15 | # lines starting with # are comments and will be ignored 16 | # 17 | pdf pdf.js/web/viewer.html?file={URL} PDF Viewer 18 | 19 | # uncomment the next two lines to enable the Office files preview 20 | #docx,doc,xlsx,xls,pptx,ppt https://view.officeapps.live.com/op/embed.aspx?src={URL} Microsoft 21 | #docx,doc,xlsx,xls,pptx,ppt https://docs.google.com/gview?embedded=true&url={URL} Google 22 | `.trim() 23 | 24 | export const FILE_BUCKET_SECRET_KEY = 't' 25 | -------------------------------------------------------------------------------- /web/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /web/src/handlers/audio/aplayer.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'aplayer' { 2 | export default any 3 | } 4 | -------------------------------------------------------------------------------- /web/src/handlers/audio/index.ts: -------------------------------------------------------------------------------- 1 | import { wrapAsyncComponent } from '@/components/async' 2 | import { T } from '@/i18n' 3 | import { filenameExt } from '@/utils' 4 | import { EntryHandler } from '../types' 5 | 6 | export default { 7 | name: 'audio', 8 | display: { 9 | name: T('handler.audio.name'), 10 | description: T('handler.audio.desc'), 11 | icon: '#icon-play-circle', 12 | }, 13 | view: { 14 | name: 'AudioView', 15 | component: wrapAsyncComponent(() => import('./AudioView.vue')), 16 | }, 17 | supports: ({ entry }, { options }) => 18 | entry.type === 'file' && 19 | options['web.audioFileExts'].includes(filenameExt(entry.name)), 20 | order: 1000, 21 | } as EntryHandler 22 | -------------------------------------------------------------------------------- /web/src/handlers/copy-move/index.ts: -------------------------------------------------------------------------------- 1 | import { T } from '@/i18n' 2 | import { copyOrMove } from '@/utils/entry' 3 | import { EntryHandler } from '../types' 4 | 5 | const createHandler = (isMove: boolean): EntryHandler => { 6 | return { 7 | name: isMove ? 'move' : 'copy', 8 | display: { 9 | name: T( 10 | isMove ? 'handler.copy_move.move_to' : 'handler.copy_move.copy_to' 11 | ), 12 | description: T( 13 | isMove ? 'handler.copy_move.move_desc' : 'handler.copy_move.copy_desc' 14 | ), 15 | icon: isMove ? '#icon-move' : '#icon-copy', 16 | }, 17 | multiple: true, 18 | supports: isMove 19 | ? ({ entry, parent }) => 20 | !!(entry.every((e) => e.meta.writable) && parent?.meta.writable) 21 | : () => true, 22 | handler: ({ entry: entries }, { open }) => { 23 | return new Promise((resolve) => { 24 | open({ 25 | title: T( 26 | isMove 27 | ? 'handler.copy_move.move_open_title' 28 | : 'handler.copy_move.copy_open_title' 29 | ), 30 | type: 'dir', 31 | filter: 'write', 32 | async onOk(destEntry) { 33 | const executed = await copyOrMove(isMove, entries, destEntry.path) 34 | resolve({ update: executed.length > 0 }) 35 | }, 36 | }) 37 | }) 38 | }, 39 | order: isMove ? 2004 : 2003, 40 | } 41 | } 42 | 43 | export const copy = createHandler(false) 44 | export const move = createHandler(true) 45 | -------------------------------------------------------------------------------- /web/src/handlers/download/index.ts: -------------------------------------------------------------------------------- 1 | import { T } from '@/i18n' 2 | import { EntryHandler } from '../types' 3 | import DownloadView from './DownloadView.vue' 4 | 5 | export default { 6 | name: 'download', 7 | display: { 8 | name: T('handler.download.name'), 9 | description: T('handler.download.desc'), 10 | icon: '#icon-download', 11 | }, 12 | view: { 13 | name: 'DownloadView', 14 | component: DownloadView, 15 | }, 16 | multiple: true, 17 | supports: ({ entry }) => entry.every((e) => e.type === 'file'), 18 | order: 2000, 19 | } as EntryHandler 20 | -------------------------------------------------------------------------------- /web/src/handlers/handler-ctx.ts: -------------------------------------------------------------------------------- 1 | import { useAppStore } from '@/store' 2 | import { computed } from 'vue' 3 | 4 | export const useHandlerCtx = () => { 5 | const store = useAppStore() 6 | 7 | return computed(() => ({ 8 | user: store.user, 9 | config: store.config!, 10 | options: store.config!.options, 11 | })) 12 | } 13 | -------------------------------------------------------------------------------- /web/src/handlers/iframe/index.ts: -------------------------------------------------------------------------------- 1 | import { T } from '@/i18n' 2 | import { entryMatches } from '@/utils' 3 | import { EntryHandler } from '../types' 4 | import IframePreviewView from './IframePreviewView.vue' 5 | 6 | export default { 7 | name: 'iframe', 8 | display: { 9 | name: T('handler.iframe.name'), 10 | description: T('handler.iframe.desc'), 11 | icon: '#icon-wendang', 12 | }, 13 | style: { fullscreen: true }, 14 | view: { 15 | name: 'IframePreviewView', 16 | component: IframePreviewView, 17 | }, 18 | supports: ({ entry }, { options }) => 19 | entry.type === 'file' && 20 | options['web.externalFileViewers'].some((e) => entryMatches(entry, e.exts)), 21 | } as EntryHandler 22 | -------------------------------------------------------------------------------- /web/src/handlers/image/index.ts: -------------------------------------------------------------------------------- 1 | import { wrapAsyncComponent } from '@/components/async' 2 | import { T } from '@/i18n' 3 | import { filenameExt } from '@/utils' 4 | import { EntryHandler } from '../types' 5 | 6 | export default { 7 | name: 'image', 8 | display: { 9 | name: T('handler.image.name'), 10 | description: T('handler.image.desc'), 11 | icon: '#icon-image', 12 | }, 13 | style: { fullscreen: true }, 14 | view: { 15 | name: 'ImageView', 16 | component: wrapAsyncComponent(() => import('./ImageView.vue')), 17 | }, 18 | supports: ({ entry }, { options }) => 19 | entry.type === 'file' && 20 | options['web.imageFileExts'].includes(filenameExt(entry.name)), 21 | } as EntryHandler 22 | -------------------------------------------------------------------------------- /web/src/handlers/mount/index.ts: -------------------------------------------------------------------------------- 1 | import { mountPaths } from '@/api/admin' 2 | import { T } from '@/i18n' 3 | import { isAdmin } from '@/utils' 4 | import { EntryHandler } from '../types' 5 | 6 | export default { 7 | name: 'mount', 8 | display: { 9 | name: T('handler.mount.name'), 10 | description: T('handler.mount.desc'), 11 | icon: '#icon-path', 12 | }, 13 | supports: ({ entry }, { user }) => 14 | isAdmin(user) && !entry.some((e) => e.meta.mountAt), 15 | multiple: true, 16 | async handler({ entry: entries }, { open, loading, alert }) { 17 | open({ 18 | title: T('handler.mount.open_title'), 19 | type: 'dir', 20 | async onOk(destEntry) { 21 | loading(true) 22 | try { 23 | await mountPaths( 24 | destEntry.path, 25 | entries.map((e) => ({ path: e.path, name: e.name })) 26 | ) 27 | } catch (e: any) { 28 | alert(e.message) 29 | throw e 30 | } finally { 31 | loading() 32 | } 33 | }, 34 | }) 35 | }, 36 | order: 2002, 37 | } as EntryHandler 38 | -------------------------------------------------------------------------------- /web/src/handlers/permission/index.ts: -------------------------------------------------------------------------------- 1 | import { wrapAsyncComponent } from '@/components/async' 2 | import { T } from '@/i18n' 3 | import { isAdmin } from '@/utils' 4 | import { EntryHandler } from '../types' 5 | 6 | export default { 7 | name: 'permission', 8 | display: { 9 | name: T('handler.permission.name'), 10 | description: T('handler.permission.desc'), 11 | icon: '#icon-permission', 12 | }, 13 | view: { 14 | name: 'PermissionsView', 15 | component: wrapAsyncComponent(() => import('./PermissionsView.vue')), 16 | }, 17 | supports: (_, { user }) => isAdmin(user), 18 | order: 2001, 19 | } as EntryHandler 20 | -------------------------------------------------------------------------------- /web/src/handlers/rename/index.ts: -------------------------------------------------------------------------------- 1 | import { moveEntry } from '@/api' 2 | import { T } from '@/i18n' 3 | import { dir, pathClean, pathJoin, taskDone, TASK_CANCELLED } from '@/utils' 4 | import { EntryHandler } from '../types' 5 | 6 | export default { 7 | name: 'rename', 8 | display: { 9 | name: T('handler.rename.name'), 10 | description: T('handler.rename.desc'), 11 | icon: '#icon-rename', 12 | }, 13 | supports: ({ entry, parent }) => entry.meta.writable && parent?.meta.writable, 14 | handler: ({ entry }, { input, alert }) => { 15 | return new Promise((resolve) => { 16 | input({ 17 | title: T('handler.rename.input_title'), 18 | text: entry.name, 19 | validator: { 20 | pattern: /^[^/\0:*"<>|]+$/, 21 | message: T('handler.rename.invalid_filename'), 22 | }, 23 | onOk: async (text) => { 24 | if (text === entry.name) return 25 | try { 26 | await taskDone( 27 | moveEntry(entry.path, pathClean(pathJoin(dir(entry.path), text))) 28 | ) 29 | resolve({ update: true }) 30 | } catch (e: any) { 31 | if (e === TASK_CANCELLED) return 32 | alert(e.message) 33 | throw e 34 | } 35 | }, 36 | }) 37 | }) 38 | }, 39 | order: 2005, 40 | } as EntryHandler 41 | -------------------------------------------------------------------------------- /web/src/handlers/text-edit/index.ts: -------------------------------------------------------------------------------- 1 | import { wrapAsyncComponent } from '@/components/async' 2 | import { TEXT_EDITOR_MAX_FILE_SIZE } from '@/config' 3 | import { T } from '@/i18n' 4 | import { entryMatches } from '@/utils' 5 | import { EntryHandler } from '../types' 6 | 7 | export default { 8 | name: 'editor', 9 | display: (entry) => ({ 10 | name: T( 11 | entry.meta.writable 12 | ? 'handler.text_edit.edit_name' 13 | : 'handler.text_edit.view_name' 14 | ), 15 | description: T( 16 | entry.meta.writable 17 | ? 'handler.text_edit.edit_desc' 18 | : 'handler.text_edit.view_desc' 19 | ), 20 | icon: '#icon-cursor-text', 21 | }), 22 | style: { fullscreen: true }, 23 | view: { 24 | name: 'TextEditView', 25 | component: wrapAsyncComponent(() => import('./TextEditView.vue')), 26 | }, 27 | supports: ({ entry }, { options }) => 28 | entry.type === 'file' && 29 | entryMatches(entry, options['web.textFileExts']) && 30 | entry.size <= TEXT_EDITOR_MAX_FILE_SIZE, 31 | } as EntryHandler 32 | -------------------------------------------------------------------------------- /web/src/handlers/video/VideoView.vue: -------------------------------------------------------------------------------- 1 | 10 | 25 | 48 | -------------------------------------------------------------------------------- /web/src/handlers/video/index.ts: -------------------------------------------------------------------------------- 1 | import { T } from '@/i18n' 2 | import { filenameExt } from '@/utils' 3 | import { EntryHandler } from '../types' 4 | import VideoView from './VideoView.vue' 5 | 6 | export default { 7 | name: 'video', 8 | display: { 9 | name: T('handler.video.name'), 10 | description: T('handler.video.desc'), 11 | icon: '#icon-play-circle', 12 | }, 13 | view: { 14 | name: 'VideoView', 15 | component: VideoView, 16 | }, 17 | supports: ({ entry }, { options }) => 18 | entry.type === 'file' && 19 | options['web.videoFileExts'].includes(filenameExt(entry.name)), 20 | order: 1001, 21 | } as EntryHandler 22 | -------------------------------------------------------------------------------- /web/src/handlers/zip/index.ts: -------------------------------------------------------------------------------- 1 | import { zipUrl } from '@/api' 2 | import { AUTH_PARAM, getToken } from '@/api/http' 3 | import { T } from '@/i18n' 4 | import { EntryHandler } from '../types' 5 | 6 | export default { 7 | name: 'zip', 8 | display: { 9 | name: T('handler.zip.name'), 10 | description: T('handler.zip.desc'), 11 | icon: '#icon-zip-grey', 12 | }, 13 | supports: () => true, 14 | multiple: true, 15 | handler: async ({ entry: entries, parent }) => { 16 | const form = document.createElement('form') 17 | form.style.display = 'none' 18 | form.method = 'post' 19 | form.action = zipUrl() 20 | form.target = '_blank' 21 | 22 | if (parent) { 23 | const prefix = document.createElement('input') 24 | prefix.name = 'prefix' 25 | prefix.value = parent.path 26 | form.appendChild(prefix) 27 | } 28 | 29 | const token = document.createElement('input') 30 | token.name = AUTH_PARAM 31 | token.value = getToken()! 32 | form.appendChild(token) 33 | 34 | const files = document.createElement('textarea') 35 | files.name = 'files' 36 | files.value = entries.map((e) => e.path).join('\n') 37 | form.appendChild(files) 38 | 39 | document.body.appendChild(form) 40 | form.submit() 41 | document.body.removeChild(form) 42 | }, 43 | order: 2000, 44 | } as EntryHandler 45 | -------------------------------------------------------------------------------- /web/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | import router from './router' 5 | import store from './store' 6 | import i18n, { setLang } from './i18n' 7 | 8 | import Components from '@/components' 9 | import Utils from '@/utils' 10 | 11 | import '@/styles/index.scss' 12 | ;(async () => { 13 | await setLang(navigator.language) 14 | 15 | createApp(App) 16 | .use(Utils) 17 | .use(Components) 18 | .use(router) 19 | .use(store) 20 | .use(i18n) 21 | .mount('#app') 22 | })() 23 | -------------------------------------------------------------------------------- /web/src/styles/markdown-dark.scss: -------------------------------------------------------------------------------- 1 | .markdown-body { 2 | color: var(--primary-text-color); 3 | 4 | h1, 5 | h2 { 6 | border-bottom-color: var(--border-color); 7 | } 8 | 9 | h1, 10 | h2, 11 | h3, 12 | h4, 13 | h5, 14 | h6 { 15 | &:hover .anchor { 16 | .octicon-link::before { 17 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' fill='%23fff' width='16' height='16' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z'%3E%3C/path%3E%3C/svg%3E"); 18 | } 19 | } 20 | } 21 | 22 | .highlight pre, 23 | pre { 24 | background-color: var(--secondary-bg-color); 25 | } 26 | 27 | kbd { 28 | background-color: var(--secondary-bg-color); 29 | color: var(--primary-text-color); 30 | border-color: var(--border-color); 31 | } 32 | 33 | table td, 34 | table th { 35 | background-color: var(--secondary-bg-color); 36 | border-color: var(--border-color); 37 | } 38 | 39 | blockquote { 40 | border-left-color: var(--border-color); 41 | } 42 | 43 | hr { 44 | background-color: var(--secondary-bg-color); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /web/src/styles/themes/dark.scss: -------------------------------------------------------------------------------- 1 | $theme-dark: ( 2 | body-bg-color: #303030, 3 | primary-bg-color: #121212, 4 | secondary-bg-color: #2b2b2b, 5 | border-color: #383838, 6 | primary-text-color: #e1e1e1, 7 | secondary-text-color: gray, 8 | link-color: #5d9cff, 9 | dialog-overlay-bg-color: rgba(53, 53, 53, 0.3), 10 | dialog-content-shadow: 0 6px 10px rgba(0, 0, 0, 0.8), 11 | form-value-bg-color: #121212, 12 | form-value-bg-color-disabled: #555555, 13 | form-value-border: solid 1px rgba(255, 255, 255, 0.1), 14 | hover-bg-color: #333333, 15 | focus-bg-color: #333333, 16 | select-bg-color: #555555, 17 | thead-bg-color: #353535, 18 | btn-bg-color-default: #409eff, 19 | btn-bg-color-disabled-default: #a0cfff, 20 | btn-color-default: #fff, 21 | btn-color-disabled-default: #fff, 22 | btn-bg-color-info: #909399, 23 | btn-bg-color-disabled-info: #c8c9cc, 24 | btn-color-info: #fff, 25 | btn-color-disabled-info: #fff, 26 | btn-bg-color-success: #67c23a, 27 | btn-bg-color-disabled-success: #b3e19d, 28 | btn-color-success: #fff, 29 | btn-color-disabled-success: #fff, 30 | btn-bg-color-warning: #e6a23c, 31 | btn-bg-color-disabled-warning: #f3d19e, 32 | btn-color-warning: #fff, 33 | btn-color-disabled-warning: #fff, 34 | btn-bg-color-danger: #f56c6c, 35 | btn-bg-color-disabled-danger: #fab6b6, 36 | btn-color-danger: #fff, 37 | btn-color-disabled-danger: #fff, 38 | progress-bar-color: #666, 39 | loading-overlay-bg-color: rgba(0, 0, 0, 0.6), 40 | ); 41 | -------------------------------------------------------------------------------- /web/src/styles/themes/default.scss: -------------------------------------------------------------------------------- 1 | $theme-default: ( 2 | body-bg-color: #f2f5fa, 3 | primary-bg-color: #fff, 4 | secondary-bg-color: #fff, 5 | border-color: rgba(0, 0, 0, 0.1), 6 | primary-text-color: #000, 7 | secondary-text-color: gray, 8 | link-color: #5d9cff, 9 | dialog-overlay-bg-color: rgba(0, 0, 0, 0.4), 10 | dialog-content-shadow: 0 6px 10px rgba(0, 0, 0, 0.1), 11 | form-value-bg-color: #fff, 12 | form-value-bg-color-disabled: rgba(239, 239, 239, 0.3), 13 | form-value-border: solid 1px rgba(0, 0, 0, 0.1), 14 | hover-bg-color: #f6f6f6, 15 | focus-bg-color: rgba(0, 0, 0, 0.08), 16 | select-bg-color: #c1ecff, 17 | thead-bg-color: #ebebeb, 18 | btn-bg-color-default: #409eff, 19 | btn-bg-color-disabled-default: #a0cfff, 20 | btn-color-default: #fff, 21 | btn-color-disabled-default: #fff, 22 | btn-bg-color-info: #909399, 23 | btn-bg-color-disabled-info: #c8c9cc, 24 | btn-color-info: #fff, 25 | btn-color-disabled-info: #fff, 26 | btn-bg-color-success: #67c23a, 27 | btn-bg-color-disabled-success: #b3e19d, 28 | btn-color-success: #fff, 29 | btn-color-disabled-success: #fff, 30 | btn-bg-color-warning: #e6a23c, 31 | btn-bg-color-disabled-warning: #f3d19e, 32 | btn-color-warning: #fff, 33 | btn-color-disabled-warning: #fff, 34 | btn-bg-color-danger: #f56c6c, 35 | btn-bg-color-disabled-danger: #fab6b6, 36 | btn-color-danger: #fff, 37 | btn-color-disabled-danger: #fff, 38 | progress-bar-color: #bcdffb, 39 | loading-overlay-bg-color: rgba(255, 255, 255, 0.6), 40 | ); 41 | -------------------------------------------------------------------------------- /web/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './model' 2 | 3 | export interface ApiError { 4 | message: string 5 | } 6 | 7 | export type FormItemType = 8 | | 'md' 9 | | 'textarea' 10 | | 'text' 11 | | 'password' 12 | | 'checkbox' 13 | | 'select' 14 | | 'path' 15 | | 'form' 16 | | 'code' 17 | 18 | export interface FormItemOption { 19 | name: I18nText 20 | title?: I18nText 21 | value: string 22 | disabled?: boolean 23 | } 24 | 25 | export interface FormItemPathOptions { 26 | filter?: string 27 | } 28 | 29 | export interface FormItemForm { 30 | key: string 31 | name?: I18nText 32 | form: FormItem[] 33 | } 34 | 35 | export interface FormItemForms { 36 | addText?: I18nText 37 | maxItems?: number 38 | forms: FormItemForm[] 39 | } 40 | 41 | export interface FormItemCode { 42 | type: string 43 | typeSelectable?: boolean 44 | height?: string 45 | } 46 | 47 | export interface BaseFormItem extends O { 48 | label?: I18nText 49 | type?: FormItemType 50 | field?: string 51 | required?: boolean 52 | description?: I18nText 53 | disabled?: boolean 54 | 55 | options?: FormItemOption[] 56 | 57 | pathOptions?: FormItemPathOptions 58 | 59 | forms?: FormItemForms 60 | 61 | code?: FormItemCode 62 | 63 | defaultValue?: string 64 | } 65 | 66 | export interface FormItem extends BaseFormItem { 67 | class?: string 68 | width?: string | number 69 | slot?: string 70 | labelSuffixSlot?: string 71 | placeholder?: I18nText 72 | validate?: (v: any) => PromiseValue 73 | } 74 | -------------------------------------------------------------------------------- /web/src/types/model/config.ts: -------------------------------------------------------------------------------- 1 | export interface SearchConfig { 2 | enabled: boolean 3 | examples: string[] 4 | } 5 | 6 | export interface ThumbnailConfig { 7 | extensions: O 8 | } 9 | 10 | export interface VersionConfig { 11 | buildAt: string 12 | rev: string 13 | version: string 14 | } 15 | 16 | export interface Config { 17 | version: VersionConfig 18 | thumbnail: ThumbnailConfig 19 | options: O 20 | 21 | search?: SearchConfig 22 | } 23 | 24 | export interface ExternalFilePreviewer { 25 | exts: string[] 26 | name: string 27 | url: string 28 | } 29 | -------------------------------------------------------------------------------- /web/src/utils/directives/focus.ts: -------------------------------------------------------------------------------- 1 | import type { Directive } from 'vue' 2 | 3 | export default { 4 | mounted(el) { 5 | el.focus() 6 | }, 7 | } as Directive 8 | -------------------------------------------------------------------------------- /web/src/utils/directives/lazy-src.ts: -------------------------------------------------------------------------------- 1 | import type { Directive } from 'vue' 2 | 3 | const callback: IntersectionObserverCallback = (entries) => { 4 | entries.forEach((e) => { 5 | if (e.isIntersecting) { 6 | const img = e.target as HTMLImageElement 7 | observer.unobserve(img) 8 | loadImage(img) 9 | } 10 | }) 11 | } 12 | 13 | const observer = new IntersectionObserver(callback, { 14 | rootMargin: '100px 0px', 15 | threshold: 0, 16 | }) 17 | 18 | function loadImage(img: HTMLImageElement) { 19 | const src = img.getAttribute('data-src') 20 | if (!src) return 21 | img.src = src 22 | img.removeAttribute('data-src') 23 | } 24 | 25 | export default { 26 | mounted(el, { value }) { 27 | el.src = 28 | 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAAtJREFUGFdjYAACAAAFAAGq1chRAAAAAElFTkSuQmCC' 29 | el.dataset.src = value 30 | if (value) { 31 | observer.observe(el) 32 | } 33 | }, 34 | updated(el, { value }) { 35 | observer.unobserve(el) 36 | el.dataset.src = value 37 | if (value) { 38 | observer.observe(el) 39 | } 40 | }, 41 | beforeUnmount(el) { 42 | observer.unobserve(el) 43 | }, 44 | } as Directive 45 | -------------------------------------------------------------------------------- /web/src/utils/directives/markdown.ts: -------------------------------------------------------------------------------- 1 | import type { Directive, DirectiveHook } from 'vue' 2 | import { T } from '@/i18n' 3 | 4 | const onAnchorClicked = function (this: HTMLAnchorElement, e: MouseEvent) { 5 | e.preventDefault() 6 | const href = this.dataset.href 7 | if (!href) return 8 | if (href.startsWith('#')) { 9 | const id = decodeURIComponent(href.substring(1)) 10 | const targetEl = document.getElementById(id) 11 | if (targetEl) { 12 | targetEl.scrollIntoView({ behavior: 'smooth' }) 13 | } 14 | } else { 15 | const a = document.createElement('a') 16 | a.target = '_blank' 17 | a.rel = 'nofollow noopener noreferrer' 18 | a.href = href 19 | a.click() 20 | } 21 | } 22 | 23 | const render: DirectiveHook = (el, binding) => { 24 | el._currentMarkdownContent = binding.value 25 | import('@/utils/marked').then( 26 | ({ default: render }) => { 27 | if (el._currentMarkdownContent === el._renderedMarkdownContent) return 28 | el.innerHTML = render(el._currentMarkdownContent) 29 | el._renderedMarkdownContent = el._currentMarkdownContent 30 | 31 | const anchors = el.querySelectorAll('a[data-href]') 32 | anchors.forEach((a: HTMLAnchorElement) => { 33 | a.addEventListener('click', onAnchorClicked) 34 | }) 35 | }, 36 | (e) => { 37 | console.error('markdown render error: ', e) 38 | el.innerHTML = `

${T('md.error')}

` 39 | } 40 | ) 41 | } 42 | 43 | export default { 44 | beforeMount: render, 45 | updated: render, 46 | } as Directive 47 | -------------------------------------------------------------------------------- /web/src/utils/dom.ts: -------------------------------------------------------------------------------- 1 | type ResizeCallback = (e: ResizeObserverEntry) => void 2 | 3 | interface ResizeObservedHTMLElement extends HTMLElement { 4 | __resizeListeners__?: ResizeCallback[] 5 | __ro__?: ResizeObserver 6 | } 7 | 8 | const resizeHandler: ResizeObserverCallback = function (entries) { 9 | for (const entry of entries) { 10 | const listeners = 11 | (entry.target as ResizeObservedHTMLElement).__resizeListeners__ || [] 12 | if (listeners.length) { 13 | listeners.forEach((fn) => { 14 | fn(entry) 15 | }) 16 | } 17 | } 18 | } 19 | 20 | export const addResizeListener = function ( 21 | element: HTMLElement, 22 | fn: ResizeCallback 23 | ) { 24 | const el = element as ResizeObservedHTMLElement 25 | if (!el.__resizeListeners__) { 26 | el.__resizeListeners__ = [] 27 | el.__ro__ = new ResizeObserver(resizeHandler) 28 | el.__ro__.observe(el) 29 | } 30 | el.__resizeListeners__.push(fn) 31 | } 32 | 33 | export const removeResizeListener = function ( 34 | element: HTMLElement, 35 | fn: ResizeCallback 36 | ) { 37 | const el = element as ResizeObservedHTMLElement 38 | if (!el || !el.__resizeListeners__) return 39 | el.__resizeListeners__.splice(el.__resizeListeners__.indexOf(fn), 1) 40 | if (!el.__resizeListeners__.length) { 41 | el.__ro__!.disconnect() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /web/src/utils/hooks/timer.ts: -------------------------------------------------------------------------------- 1 | import { onUnmounted, onMounted, Ref, watch } from 'vue' 2 | 3 | export const useInterval = ( 4 | callback: Fn, 5 | interval: number | Ref, 6 | immediate: boolean 7 | ) => { 8 | let t: number 9 | 10 | const getInterval = () => 11 | typeof interval === 'number' ? interval : interval.value 12 | 13 | const startInterval = () => { 14 | clearInterval(t) 15 | const interval = getInterval() 16 | if (interval > 0) { 17 | t = setInterval(() => { 18 | callback() 19 | }, interval) as unknown as number 20 | } 21 | } 22 | 23 | onMounted(() => { 24 | if (immediate) { 25 | callback() 26 | } 27 | startInterval() 28 | }) 29 | 30 | if (typeof interval !== 'number') { 31 | watch(interval, startInterval) 32 | } 33 | 34 | onUnmounted(() => { 35 | clearInterval(t) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /web/src/utils/http/index.ts: -------------------------------------------------------------------------------- 1 | import { createHttp } from './http' 2 | import { 3 | transformBlobResponse, 4 | transformErrorResponse, 5 | transformJSONRequest, 6 | transformJSONResponse, 7 | transformTextResponse, 8 | } from './transformers' 9 | 10 | export * from './types' 11 | export * from './utils' 12 | 13 | const textContentTypes = ['text/', 'application/json', 'application/xml'] 14 | 15 | export default createHttp({ 16 | transformRequest: [transformJSONRequest], 17 | transformResponse: [ 18 | transformBlobResponse(textContentTypes), 19 | transformTextResponse(textContentTypes), 20 | transformJSONResponse, 21 | transformErrorResponse, 22 | ], 23 | }) 24 | -------------------------------------------------------------------------------- /web/src/utils/marked.ts: -------------------------------------------------------------------------------- 1 | import { Marked } from 'marked' 2 | import { markedHighlight } from 'marked-highlight' 3 | import hljs from './highlight' 4 | import DOMPurify from 'dompurify' 5 | 6 | const marked = new Marked( 7 | markedHighlight({ 8 | langPrefix: 'hljs language-', 9 | highlight(code, lang) { 10 | const validLanguage: string = hljs.getLanguage(lang) ? lang : 'plaintext' 11 | return hljs.highlight(code, { language: validLanguage }).value 12 | }, 13 | }) 14 | ) 15 | 16 | DOMPurify.addHook('afterSanitizeAttributes', (node) => { 17 | if ('target' in node) { 18 | node.setAttribute('target', '_blank') 19 | } 20 | if ('href' in node) { 21 | const a = node as HTMLAnchorElement 22 | const href = a.getAttribute('href') ?? '' 23 | if (href.startsWith('#')) { 24 | a.dataset.href = href 25 | a.href = 'javascript:;' 26 | } 27 | } 28 | }) 29 | 30 | export default (s: string) => 31 | DOMPurify.sanitize(marked.parse(s, { async: false })) 32 | -------------------------------------------------------------------------------- /web/src/utils/theme.ts: -------------------------------------------------------------------------------- 1 | import { arrayRemove } from '.' 2 | 3 | export function isDarkMode() { 4 | return matchMedia ? matchMedia('(prefers-color-scheme: dark)').matches : false 5 | } 6 | 7 | const listeners: Fn[] = [] 8 | matchMedia && 9 | matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { 10 | listeners.forEach((fn) => { 11 | fn() 12 | }) 13 | }) 14 | 15 | export function addPreferColorListener(fn: Fn) { 16 | listeners.push(fn) 17 | } 18 | 19 | export function removePreferColorListener(fn: Fn) { 20 | arrayRemove(listeners, (e) => e === fn) 21 | } 22 | -------------------------------------------------------------------------------- /web/src/utils/ui-utils/dialog-use.ts: -------------------------------------------------------------------------------- 1 | import Utils from '@/utils' 2 | import Components from '@/components' 3 | import i18n from '@/i18n' 4 | import router from '@/router' 5 | import store from '@/store' 6 | import { Plugin } from 'vue' 7 | 8 | export default { 9 | install(app) { 10 | app.use(Utils).use(Components).use(i18n).use(router).use(store) 11 | }, 12 | } as Plugin 13 | -------------------------------------------------------------------------------- /web/src/utils/ui-utils/index.ts: -------------------------------------------------------------------------------- 1 | import showBaseDialog, { BaseDialogOptions } from './base-dialog' 2 | import showInputDialog from './input-dialog' 3 | import toggleLoadingDialog from './loading-dialog' 4 | import showOpenDialog from './open-dialog' 5 | import { showAlertDialog, showConfirmDialog } from './text-dialog' 6 | 7 | export const dialog = < 8 | OT extends BaseDialogOptions = BaseDialogOptions, 9 | RT = any 10 | >( 11 | component: any, 12 | opts: OT 13 | ) => showBaseDialog(component, opts) 14 | 15 | export const alert = showAlertDialog 16 | export const confirm = showConfirmDialog 17 | export const input = showInputDialog 18 | export const loading = toggleLoadingDialog 19 | export const open = showOpenDialog 20 | 21 | export interface UIUtils { 22 | dialog: typeof dialog 23 | open: typeof open 24 | alert: typeof alert 25 | confirm: typeof confirm 26 | input: typeof input 27 | loading: typeof loading 28 | } 29 | 30 | export default { 31 | dialog, 32 | open, 33 | alert, 34 | confirm, 35 | input, 36 | loading, 37 | } as UIUtils 38 | -------------------------------------------------------------------------------- /web/src/utils/ui-utils/input-dialog/index.ts: -------------------------------------------------------------------------------- 1 | import InputDialogInner from './InputDialog.vue' 2 | import showBaseDialog, { BaseDialogOptions, createDialog } from '../base-dialog' 3 | 4 | const InputDialog = createDialog('InputDialog', InputDialogInner) 5 | 6 | export type InputDialogValidateFunc = (v?: any) => PromiseValue 7 | 8 | export interface InputDialogValidator { 9 | trigger?: 'confirm' | 'change' 10 | validate?: InputDialogValidateFunc 11 | pattern?: RegExp 12 | message?: I18nText 13 | } 14 | 15 | export interface InputDialogOptions extends BaseDialogOptions { 16 | type?: string 17 | text?: string 18 | placeholder?: I18nText 19 | multipleLine?: boolean 20 | 21 | validator?: InputDialogValidator 22 | } 23 | 24 | export default function showInputDialog(opts: InputDialogOptions) { 25 | return showBaseDialog(InputDialog, { ...opts }) 26 | } 27 | -------------------------------------------------------------------------------- /web/src/utils/ui-utils/loading-dialog/index.ts: -------------------------------------------------------------------------------- 1 | import { SimpleButtonType } from '@/components/SimpleButton' 2 | import { isT } from '@/i18n' 3 | import { createApp } from 'vue' 4 | import dialogUse from '../dialog-use' 5 | import LoadingDialog from './LoadingDialog.vue' 6 | 7 | export interface LoadingOptions { 8 | text?: I18nText 9 | onCancel?: () => PromiseValue 10 | cancelText?: I18nText 11 | cancelType?: SimpleButtonType 12 | } 13 | 14 | let vm: any 15 | 16 | export default function toggleLoadingDialog(opts?: LoadingOptions | boolean) { 17 | if (!vm) { 18 | const div = document.createElement('div') 19 | document.body.appendChild(div) 20 | 21 | vm = createApp(LoadingDialog).use(dialogUse).mount(div) 22 | } 23 | 24 | if (opts) { 25 | vm.show(typeof opts === 'object' && !isT(opts) ? opts : {}) 26 | } else { 27 | vm.hide() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /web/src/utils/ui-utils/open-dialog/index.ts: -------------------------------------------------------------------------------- 1 | import OpenDialogInner from './OpenDialog.vue' 2 | import showBaseDialog, { BaseDialogOptions, createDialog } from '../base-dialog' 3 | import { Entry } from '@/types' 4 | 5 | export interface OpenDialogOptions 6 | extends BaseDialogOptions { 7 | type?: 'dir' | 'file' 8 | filter?: ((e: Entry) => boolean) | string 9 | max?: number 10 | } 11 | 12 | const OpenDialog = createDialog('OpenDialog', OpenDialogInner) 13 | 14 | export interface OpenDialogDirOptions extends OpenDialogOptions { 15 | type: 'dir' 16 | } 17 | 18 | export interface OpenDialogFileOptions extends OpenDialogOptions { 19 | type: 'file' 20 | } 21 | 22 | function showOpenDialog(opts: OpenDialogDirOptions): Promise 23 | function showOpenDialog(opts: OpenDialogFileOptions): Promise 24 | function showOpenDialog(opts: OpenDialogDirOptions | OpenDialogFileOptions) { 25 | return showBaseDialog(OpenDialog, { ...(opts as any) }) 26 | } 27 | 28 | export default showOpenDialog -------------------------------------------------------------------------------- /web/src/utils/ui-utils/text-dialog/TextDialog.vue: -------------------------------------------------------------------------------- 1 | 4 | 14 | 31 | -------------------------------------------------------------------------------- /web/src/utils/ui-utils/text-dialog/index.ts: -------------------------------------------------------------------------------- 1 | import { isT, T } from '@/i18n' 2 | import showBaseDialog, { BaseDialogOptions, createDialog } from '../base-dialog' 3 | import TextDialogInner from './TextDialog.vue' 4 | 5 | export interface TextDialogOptions extends BaseDialogOptions { 6 | message?: I18nText 7 | } 8 | 9 | const TextDialog = createDialog('TextDialog', TextDialogInner) 10 | 11 | export function showAlertDialog(opts: TextDialogOptions | I18nText) { 12 | if (typeof opts !== 'object' || isT(opts)) { 13 | opts = { message: opts } 14 | } 15 | return showBaseDialog(TextDialog, { 16 | ...opts, 17 | transition: opts.transition || 'scale-opacity', 18 | }) 19 | } 20 | 21 | export function showConfirmDialog(opts: TextDialogOptions | I18nText) { 22 | if (typeof opts !== 'object' || isT(opts)) { 23 | opts = { message: opts } 24 | } 25 | return showBaseDialog(TextDialog, { 26 | ...opts, 27 | transition: opts.transition || 'scale-opacity', 28 | confirmText: opts.confirmText || T('dialog.text.yes'), 29 | cancelText: opts.cancelText || T('dialog.text.no'), 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /web/src/views/Admin/Jobs/execution-log-dialog.ts: -------------------------------------------------------------------------------- 1 | import showBaseDialog, { 2 | BaseDialogOptions, 3 | createDialog, 4 | } from '@/utils/ui-utils/base-dialog' 5 | import { T } from '@/i18n' 6 | import ExecutionLogDialogInner from './ExecutionLogDialogInner.vue' 7 | import type { RequestTask } from '@/utils/http' 8 | import type { StreamHttpResponse } from '@/api/http' 9 | import type { Task } from '@/types' 10 | 11 | const ExecutionLogDialog = createDialog( 12 | 'ExecutionLogDialog', 13 | ExecutionLogDialogInner 14 | ) 15 | 16 | export interface ExecutionLogDialogOptions extends BaseDialogOptions { 17 | execute: () => RequestTask> 18 | } 19 | 20 | export const showExecutionDialog = (opts: ExecutionLogDialogOptions) => { 21 | return showBaseDialog(ExecutionLogDialog, { 22 | ...opts, 23 | closeable: false, 24 | cancelText: T('p.admin.jobs.close'), 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /web/src/views/Admin/Misc/CleanInvalid.vue: -------------------------------------------------------------------------------- 1 | 9 | 31 | -------------------------------------------------------------------------------- /web/src/views/Admin/Misc/RootPermissions.vue: -------------------------------------------------------------------------------- 1 | 20 | 44 | -------------------------------------------------------------------------------- /web/src/views/Admin/Misc/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 12 | 18 | 39 | -------------------------------------------------------------------------------- /web/src/views/EntryExplorer/TaskManager/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 21 | 41 | 59 | -------------------------------------------------------------------------------- /web/src/views/EntryExplorer/types.ts: -------------------------------------------------------------------------------- 1 | import { EntryHandlerMenuItem } from '@/handlers/types' 2 | import type { Entry } from '@/types' 3 | 4 | export interface EntryMenuClickData { 5 | entry: Entry | Entry[] 6 | menu: EntryHandlerMenuItem 7 | } 8 | -------------------------------------------------------------------------------- /web/src/views/EntryListView/types.ts: -------------------------------------------------------------------------------- 1 | import { Entry } from '@/types' 2 | 3 | export interface EntriesLoadData { 4 | entries: Entry[] 5 | entry: Entry 6 | path: string 7 | } 8 | -------------------------------------------------------------------------------- /web/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | 19 | -------------------------------------------------------------------------------- /web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": true, 12 | "esModuleInterop": true, 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | "skipLibCheck": true, 18 | "paths": { 19 | "@/*": [ 20 | "./src/*" 21 | ] 22 | } 23 | }, 24 | "include": [ 25 | "src/**/*.ts", 26 | "src/**/*.d.ts", 27 | "src/**/*.tsx", 28 | "src/**/*.vue" 29 | ], 30 | "references": [ 31 | { 32 | "path": "./tsconfig.node.json" 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /web/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": [ 9 | "vite.config.ts" 10 | ] 11 | } -------------------------------------------------------------------------------- /web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, loadEnv } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import path from 'path' 4 | import { createHtmlPlugin } from 'vite-plugin-html' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig(({ mode }) => ({ 9 | base: './', 10 | server: { 11 | port: 9803, 12 | proxy: { 13 | '/api': { 14 | target: 'http://localhost:8089', 15 | changeOrigin: true, 16 | rewrite: (path) => path.replace(/^\/api/, ''), 17 | }, 18 | }, 19 | }, 20 | define: {}, 21 | 22 | plugins: [ 23 | vue(), 24 | 25 | createHtmlPlugin({ 26 | minify: true, 27 | inject: { 28 | data: { 29 | ...loadEnv(mode, __dirname), 30 | mode, 31 | }, 32 | }, 33 | }), 34 | ], 35 | resolve: { 36 | alias: { 37 | '@': path.join(__dirname, 'src'), 38 | }, 39 | }, 40 | css: { preprocessorOptions: { scss: { api: 'modern-compiler' } } }, 41 | build: { 42 | cssCodeSplit: false, 43 | rollupOptions: { 44 | plugins: [visualizer()], 45 | output: { 46 | chunkFileNames: 'assets/[name]-[hash].js', 47 | entryFileNames: 'assets/[name]-[hash].js', 48 | assetFileNames: 'assets/[name]-[hash][extname]', 49 | manualChunks: (id) => { 50 | if (id.includes('node_modules')) { 51 | if (id.includes('vue') || id.includes('pinia')) return 'vue' 52 | } 53 | }, 54 | }, 55 | }, 56 | }, 57 | })) 58 | -------------------------------------------------------------------------------- /wire.go: -------------------------------------------------------------------------------- 1 | //go:build wireinject 2 | // +build wireinject 3 | 4 | package main 5 | 6 | import ( 7 | "context" 8 | "go-drive/common" 9 | "go-drive/common/event" 10 | "go-drive/common/i18n" 11 | "go-drive/common/registry" 12 | "go-drive/common/task" 13 | "go-drive/common/types" 14 | "go-drive/common/utils" 15 | "go-drive/drive" 16 | "go-drive/server" 17 | "go-drive/server/scheduled" 18 | "go-drive/server/search" 19 | "go-drive/server/thumbnail" 20 | "go-drive/storage" 21 | 22 | "github.com/gin-gonic/gin" 23 | "github.com/google/wire" 24 | ) 25 | 26 | func Initialize(ctx context.Context, ch *registry.ComponentsHolder) (*gin.Engine, error) { 27 | wire.Build( 28 | common.InitConfig, 29 | storage.NewDB, 30 | event.NewBus, 31 | storage.NewUserDAO, 32 | storage.NewPathPermissionDAO, 33 | storage.NewDriveCacheDAO, 34 | storage.NewGroupDAO, 35 | storage.NewPathMountDAO, 36 | storage.NewDriveDAO, 37 | storage.NewDriveDataDAO, 38 | storage.NewOptionsDAO, 39 | storage.NewScheduledDAO, 40 | storage.NewPathMetaDAO, 41 | storage.NewFileBucketDAO, 42 | wire.Bind(new(task.Runner), new(*task.TunnyRunner)), 43 | task.NewTunnyRunner, 44 | utils.NewSigner, 45 | wire.Bind(new(types.TokenStore), new(*server.FileTokenStore)), 46 | server.NewFileTokenStore, 47 | server.NewChunkUploader, 48 | thumbnail.NewMaker, 49 | drive.NewRootDrive, 50 | drive.NewAccess, 51 | search.NewService, 52 | wire.Bind(new(i18n.MessageSource), new(*i18n.FileMessageSource)), 53 | i18n.NewFileMessageSource, 54 | scheduled.NewJobExecutor, 55 | server.InitServer, 56 | ) 57 | return &gin.Engine{}, nil 58 | } 59 | --------------------------------------------------------------------------------