├── .browserslistrc ├── .editorconfig ├── .env ├── .env.development ├── .env.preview ├── .eslintrc.js ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── need-help-issue.md └── pull_request_template.md ├── .gitignore ├── .prettierrc ├── .travis.yml ├── LICENSE ├── README.md ├── babel.config.js ├── config ├── plugin.config.js └── themePluginConfig.js ├── jest.config.js ├── jsconfig.json ├── package.json ├── postcss.config.js ├── public ├── assets │ ├── bin │ │ ├── clang │ │ ├── lld │ │ ├── memfs │ │ └── sysroot.tar │ └── vditor │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── dist │ │ ├── css │ │ │ └── content-theme │ │ │ │ ├── ant-design.css │ │ │ │ ├── dark.css │ │ │ │ ├── light.css │ │ │ │ └── wechat.css │ │ ├── images │ │ │ ├── emoji │ │ │ │ ├── b3log.png │ │ │ │ ├── chainbook.png │ │ │ │ ├── doge.png │ │ │ │ ├── hacpai.png │ │ │ │ ├── huaji.gif │ │ │ │ ├── latke.png │ │ │ │ ├── lute.png │ │ │ │ ├── octocat.png │ │ │ │ ├── pipe.png │ │ │ │ ├── solo.png │ │ │ │ ├── sym.png │ │ │ │ ├── trollface.png │ │ │ │ ├── vditor.png │ │ │ │ ├── wide.png │ │ │ │ └── wulian.png │ │ │ ├── img-loading.svg │ │ │ └── logo.png │ │ ├── index.css │ │ ├── index.d.ts │ │ ├── index.min.js │ │ ├── js │ │ │ ├── abcjs │ │ │ │ └── abcjs_basic.min.js │ │ │ ├── echarts │ │ │ │ └── echarts.min.js │ │ │ ├── flowchart.js │ │ │ │ └── flowchart.min.js │ │ │ ├── graphviz │ │ │ │ ├── full.render.js │ │ │ │ └── viz.js │ │ │ ├── highlight.js │ │ │ │ ├── highlight.pack.js │ │ │ │ └── styles │ │ │ │ │ ├── abap.css │ │ │ │ │ ├── algol.css │ │ │ │ │ ├── algol_nu.css │ │ │ │ │ ├── ant-design.css │ │ │ │ │ ├── arduino.css │ │ │ │ │ ├── autumn.css │ │ │ │ │ ├── borland.css │ │ │ │ │ ├── bw.css │ │ │ │ │ ├── colorful.css │ │ │ │ │ ├── dracula.css │ │ │ │ │ ├── emacs.css │ │ │ │ │ ├── friendly.css │ │ │ │ │ ├── fruity.css │ │ │ │ │ ├── github.css │ │ │ │ │ ├── igor.css │ │ │ │ │ ├── lovelace.css │ │ │ │ │ ├── manni.css │ │ │ │ │ ├── monokai.css │ │ │ │ │ ├── monokailight.css │ │ │ │ │ ├── murphy.css │ │ │ │ │ ├── native.css │ │ │ │ │ ├── paraiso-dark.css │ │ │ │ │ ├── paraiso-light.css │ │ │ │ │ ├── pastie.css │ │ │ │ │ ├── perldoc.css │ │ │ │ │ ├── pygments.css │ │ │ │ │ ├── rainbow_dash.css │ │ │ │ │ ├── rrt.css │ │ │ │ │ ├── solarized-dark.css │ │ │ │ │ ├── solarized-dark256.css │ │ │ │ │ ├── solarized-light.css │ │ │ │ │ ├── swapoff.css │ │ │ │ │ ├── tango.css │ │ │ │ │ ├── trac.css │ │ │ │ │ ├── vim.css │ │ │ │ │ ├── vs.css │ │ │ │ │ └── xcode.css │ │ │ ├── i18n │ │ │ │ ├── en_US.js │ │ │ │ ├── ja_JP.js │ │ │ │ ├── ko_KR.js │ │ │ │ ├── ru_RU.js │ │ │ │ ├── zh_CN.js │ │ │ │ └── zh_TW.js │ │ │ ├── icons │ │ │ │ ├── ant.js │ │ │ │ └── material.js │ │ │ ├── katex │ │ │ │ ├── fonts │ │ │ │ │ ├── KaTeX_AMS-Regular.ttf │ │ │ │ │ ├── KaTeX_AMS-Regular.woff │ │ │ │ │ ├── KaTeX_AMS-Regular.woff2 │ │ │ │ │ ├── KaTeX_Caligraphic-Bold.ttf │ │ │ │ │ ├── KaTeX_Caligraphic-Bold.woff │ │ │ │ │ ├── KaTeX_Caligraphic-Bold.woff2 │ │ │ │ │ ├── KaTeX_Caligraphic-Regular.ttf │ │ │ │ │ ├── KaTeX_Caligraphic-Regular.woff │ │ │ │ │ ├── KaTeX_Caligraphic-Regular.woff2 │ │ │ │ │ ├── KaTeX_Fraktur-Bold.ttf │ │ │ │ │ ├── KaTeX_Fraktur-Bold.woff │ │ │ │ │ ├── KaTeX_Fraktur-Bold.woff2 │ │ │ │ │ ├── KaTeX_Fraktur-Regular.ttf │ │ │ │ │ ├── KaTeX_Fraktur-Regular.woff │ │ │ │ │ ├── KaTeX_Fraktur-Regular.woff2 │ │ │ │ │ ├── KaTeX_Main-Bold.ttf │ │ │ │ │ ├── KaTeX_Main-Bold.woff │ │ │ │ │ ├── KaTeX_Main-Bold.woff2 │ │ │ │ │ ├── KaTeX_Main-BoldItalic.ttf │ │ │ │ │ ├── KaTeX_Main-BoldItalic.woff │ │ │ │ │ ├── KaTeX_Main-BoldItalic.woff2 │ │ │ │ │ ├── KaTeX_Main-Italic.ttf │ │ │ │ │ ├── KaTeX_Main-Italic.woff │ │ │ │ │ ├── KaTeX_Main-Italic.woff2 │ │ │ │ │ ├── KaTeX_Main-Regular.ttf │ │ │ │ │ ├── KaTeX_Main-Regular.woff │ │ │ │ │ ├── KaTeX_Main-Regular.woff2 │ │ │ │ │ ├── KaTeX_Math-BoldItalic.ttf │ │ │ │ │ ├── KaTeX_Math-BoldItalic.woff │ │ │ │ │ ├── KaTeX_Math-BoldItalic.woff2 │ │ │ │ │ ├── KaTeX_Math-Italic.ttf │ │ │ │ │ ├── KaTeX_Math-Italic.woff │ │ │ │ │ ├── KaTeX_Math-Italic.woff2 │ │ │ │ │ ├── KaTeX_SansSerif-Bold.ttf │ │ │ │ │ ├── KaTeX_SansSerif-Bold.woff │ │ │ │ │ ├── KaTeX_SansSerif-Bold.woff2 │ │ │ │ │ ├── KaTeX_SansSerif-Italic.ttf │ │ │ │ │ ├── KaTeX_SansSerif-Italic.woff │ │ │ │ │ ├── KaTeX_SansSerif-Italic.woff2 │ │ │ │ │ ├── KaTeX_SansSerif-Regular.ttf │ │ │ │ │ ├── KaTeX_SansSerif-Regular.woff │ │ │ │ │ ├── KaTeX_SansSerif-Regular.woff2 │ │ │ │ │ ├── KaTeX_Script-Regular.ttf │ │ │ │ │ ├── KaTeX_Script-Regular.woff │ │ │ │ │ ├── KaTeX_Script-Regular.woff2 │ │ │ │ │ ├── KaTeX_Size1-Regular.ttf │ │ │ │ │ ├── KaTeX_Size1-Regular.woff │ │ │ │ │ ├── KaTeX_Size1-Regular.woff2 │ │ │ │ │ ├── KaTeX_Size2-Regular.ttf │ │ │ │ │ ├── KaTeX_Size2-Regular.woff │ │ │ │ │ ├── KaTeX_Size2-Regular.woff2 │ │ │ │ │ ├── KaTeX_Size3-Regular.ttf │ │ │ │ │ ├── KaTeX_Size3-Regular.woff │ │ │ │ │ ├── KaTeX_Size3-Regular.woff2 │ │ │ │ │ ├── KaTeX_Size4-Regular.ttf │ │ │ │ │ ├── KaTeX_Size4-Regular.woff │ │ │ │ │ ├── KaTeX_Size4-Regular.woff2 │ │ │ │ │ ├── KaTeX_Typewriter-Regular.ttf │ │ │ │ │ ├── KaTeX_Typewriter-Regular.woff │ │ │ │ │ └── KaTeX_Typewriter-Regular.woff2 │ │ │ │ ├── katex.min.css │ │ │ │ └── katex.min.js │ │ │ ├── lute │ │ │ │ └── lute.min.js │ │ │ ├── mathjax │ │ │ │ ├── a11y │ │ │ │ │ ├── assistive-mml.js │ │ │ │ │ ├── complexity.js │ │ │ │ │ ├── explorer.js │ │ │ │ │ └── semantic-enrich.js │ │ │ │ ├── adaptors │ │ │ │ │ └── liteDOM.js │ │ │ │ ├── core.js │ │ │ │ ├── input │ │ │ │ │ ├── asciimath.js │ │ │ │ │ ├── mml.js │ │ │ │ │ ├── mml │ │ │ │ │ │ └── entities.js │ │ │ │ │ ├── tex-base.js │ │ │ │ │ ├── tex-full.js │ │ │ │ │ ├── tex.js │ │ │ │ │ └── tex │ │ │ │ │ │ └── extensions │ │ │ │ │ │ ├── action.js │ │ │ │ │ │ ├── all-packages.js │ │ │ │ │ │ ├── ams.js │ │ │ │ │ │ ├── amscd.js │ │ │ │ │ │ ├── autoload.js │ │ │ │ │ │ ├── bbox.js │ │ │ │ │ │ ├── boldsymbol.js │ │ │ │ │ │ ├── braket.js │ │ │ │ │ │ ├── bussproofs.js │ │ │ │ │ │ ├── cancel.js │ │ │ │ │ │ ├── color.js │ │ │ │ │ │ ├── colorV2.js │ │ │ │ │ │ ├── configMacros.js │ │ │ │ │ │ ├── enclose.js │ │ │ │ │ │ ├── extpfeil.js │ │ │ │ │ │ ├── html.js │ │ │ │ │ │ ├── mhchem.js │ │ │ │ │ │ ├── newcommand.js │ │ │ │ │ │ ├── noerrors.js │ │ │ │ │ │ ├── noundefined.js │ │ │ │ │ │ ├── physics.js │ │ │ │ │ │ ├── require.js │ │ │ │ │ │ ├── tagFormat.js │ │ │ │ │ │ ├── textmacros.js │ │ │ │ │ │ ├── unicode.js │ │ │ │ │ │ └── verb.js │ │ │ │ ├── latest.js │ │ │ │ ├── loader.js │ │ │ │ ├── mml-chtml.js │ │ │ │ ├── mml-svg.js │ │ │ │ ├── node-main.js │ │ │ │ ├── output │ │ │ │ │ ├── chtml.js │ │ │ │ │ ├── chtml │ │ │ │ │ │ └── fonts │ │ │ │ │ │ │ ├── tex.js │ │ │ │ │ │ │ └── woff-v2 │ │ │ │ │ │ │ ├── MathJax_AMS-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Calligraphic-Bold.woff │ │ │ │ │ │ │ ├── MathJax_Calligraphic-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Fraktur-Bold.woff │ │ │ │ │ │ │ ├── MathJax_Fraktur-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Main-Bold.woff │ │ │ │ │ │ │ ├── MathJax_Main-Italic.woff │ │ │ │ │ │ │ ├── MathJax_Main-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Math-BoldItalic.woff │ │ │ │ │ │ │ ├── MathJax_Math-Italic.woff │ │ │ │ │ │ │ ├── MathJax_Math-Regular.woff │ │ │ │ │ │ │ ├── MathJax_SansSerif-Bold.woff │ │ │ │ │ │ │ ├── MathJax_SansSerif-Italic.woff │ │ │ │ │ │ │ ├── MathJax_SansSerif-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Script-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Size1-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Size2-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Size3-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Size4-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Typewriter-Regular.woff │ │ │ │ │ │ │ ├── MathJax_Vector-Bold.woff │ │ │ │ │ │ │ ├── MathJax_Vector-Regular.woff │ │ │ │ │ │ │ └── MathJax_Zero.woff │ │ │ │ │ ├── svg.js │ │ │ │ │ └── svg │ │ │ │ │ │ └── fonts │ │ │ │ │ │ └── tex.js │ │ │ │ ├── sre │ │ │ │ │ ├── mathmaps │ │ │ │ │ │ ├── de.js │ │ │ │ │ │ ├── en.js │ │ │ │ │ │ ├── es.js │ │ │ │ │ │ ├── fr.js │ │ │ │ │ │ ├── mathmaps_ie.js │ │ │ │ │ │ └── nemeth.js │ │ │ │ │ ├── sre-node.js │ │ │ │ │ └── sre_browser.js │ │ │ │ ├── startup.js │ │ │ │ ├── tex-chtml-full.js │ │ │ │ ├── tex-chtml.js │ │ │ │ ├── tex-mml-chtml.js │ │ │ │ ├── tex-mml-svg.js │ │ │ │ ├── tex-svg-full.js │ │ │ │ ├── tex-svg.js │ │ │ │ └── ui │ │ │ │ │ ├── menu.js │ │ │ │ │ └── safe.js │ │ │ ├── mermaid │ │ │ │ └── mermaid.min.js │ │ │ └── plantuml │ │ │ │ └── plantuml-encoder.min.js │ │ ├── method.d.ts │ │ ├── method.min.js │ │ ├── ts │ │ │ ├── constants.d.ts │ │ │ ├── devtools │ │ │ │ └── index.d.ts │ │ │ ├── export │ │ │ │ └── index.d.ts │ │ │ ├── hint │ │ │ │ └── index.d.ts │ │ │ ├── i18n │ │ │ │ └── index.d.ts │ │ │ ├── ir │ │ │ │ ├── expandMarker.d.ts │ │ │ │ ├── highlightToolbarIR.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── input.d.ts │ │ │ │ ├── process.d.ts │ │ │ │ └── processKeydown.d.ts │ │ │ ├── markdown │ │ │ │ ├── abcRender.d.ts │ │ │ │ ├── adapterRender.d.ts │ │ │ │ ├── anchorRender.d.ts │ │ │ │ ├── chartRender.d.ts │ │ │ │ ├── codeRender.d.ts │ │ │ │ ├── flowchartRender.d.ts │ │ │ │ ├── getHTML.d.ts │ │ │ │ ├── getMarkdown.d.ts │ │ │ │ ├── graphvizRender.d.ts │ │ │ │ ├── highlightRender.d.ts │ │ │ │ ├── lazyLoadImageRender.d.ts │ │ │ │ ├── mathRender.d.ts │ │ │ │ ├── mediaRender.d.ts │ │ │ │ ├── mermaidRender.d.ts │ │ │ │ ├── mindmapRender.d.ts │ │ │ │ ├── outlineRender.d.ts │ │ │ │ ├── plantumlRender.d.ts │ │ │ │ ├── previewRender.d.ts │ │ │ │ ├── setLute.d.ts │ │ │ │ └── speechRender.d.ts │ │ │ ├── outline │ │ │ │ └── index.d.ts │ │ │ ├── preview │ │ │ │ ├── image.d.ts │ │ │ │ └── index.d.ts │ │ │ ├── resize │ │ │ │ └── index.d.ts │ │ │ ├── sv │ │ │ │ ├── index.d.ts │ │ │ │ ├── inputEvent.d.ts │ │ │ │ ├── process.d.ts │ │ │ │ └── processKeydown.d.ts │ │ │ ├── tip │ │ │ │ └── index.d.ts │ │ │ ├── toolbar │ │ │ │ ├── Both.d.ts │ │ │ │ ├── Br.d.ts │ │ │ │ ├── CodeTheme.d.ts │ │ │ │ ├── ContentTheme.d.ts │ │ │ │ ├── Counter.d.ts │ │ │ │ ├── Custom.d.ts │ │ │ │ ├── Devtools.d.ts │ │ │ │ ├── Divider.d.ts │ │ │ │ ├── EditMode.d.ts │ │ │ │ ├── Emoji.d.ts │ │ │ │ ├── Export.d.ts │ │ │ │ ├── Fullscreen.d.ts │ │ │ │ ├── Headings.d.ts │ │ │ │ ├── Help.d.ts │ │ │ │ ├── Indent.d.ts │ │ │ │ ├── Info.d.ts │ │ │ │ ├── InsertAfter.d.ts │ │ │ │ ├── InsertBefore.d.ts │ │ │ │ ├── MenuItem.d.ts │ │ │ │ ├── Outdent.d.ts │ │ │ │ ├── Outline.d.ts │ │ │ │ ├── Preview.d.ts │ │ │ │ ├── Record.d.ts │ │ │ │ ├── Redo.d.ts │ │ │ │ ├── Undo.d.ts │ │ │ │ ├── Upload.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ └── setToolbar.d.ts │ │ │ ├── ui │ │ │ │ ├── initUI.d.ts │ │ │ │ ├── setCodeTheme.d.ts │ │ │ │ ├── setContentTheme.d.ts │ │ │ │ ├── setPreviewMode.d.ts │ │ │ │ └── setTheme.d.ts │ │ │ ├── undo │ │ │ │ └── index.d.ts │ │ │ ├── upload │ │ │ │ ├── getElement.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ └── setHeaders.d.ts │ │ │ ├── util │ │ │ │ ├── Options.d.ts │ │ │ │ ├── RecordMedia.d.ts │ │ │ │ ├── addScript.d.ts │ │ │ │ ├── addStyle.d.ts │ │ │ │ ├── code160to32.d.ts │ │ │ │ ├── compatibility.d.ts │ │ │ │ ├── editorCommonEvent.d.ts │ │ │ │ ├── fixBrowserBehavior.d.ts │ │ │ │ ├── getSelectText.d.ts │ │ │ │ ├── hasClosest.d.ts │ │ │ │ ├── hasClosestByHeadings.d.ts │ │ │ │ ├── highlightToolbar.d.ts │ │ │ │ ├── hotKey.d.ts │ │ │ │ ├── log.d.ts │ │ │ │ ├── merge.d.ts │ │ │ │ ├── processCode.d.ts │ │ │ │ ├── selection.d.ts │ │ │ │ └── toc.d.ts │ │ │ └── wysiwyg │ │ │ │ ├── afterRenderEvent.d.ts │ │ │ │ ├── highlightToolbarWYSIWYG.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ ├── inlineTag.d.ts │ │ │ │ ├── input.d.ts │ │ │ │ ├── processKeydown.d.ts │ │ │ │ ├── renderDomByMd.d.ts │ │ │ │ ├── setHeading.d.ts │ │ │ │ ├── showCode.d.ts │ │ │ │ └── toolbarEvent.d.ts │ │ └── types │ │ │ └── index.d.ts │ │ ├── package.json │ │ └── src │ │ ├── assets │ │ └── scss │ │ │ ├── _content.scss │ │ │ ├── _hint.scss │ │ │ ├── _ir.scss │ │ │ ├── _panel.scss │ │ │ ├── _reset.scss │ │ │ ├── _sv.scss │ │ │ ├── _toolbar.scss │ │ │ ├── _tooltipped.scss │ │ │ ├── _wysiwyg.scss │ │ │ └── index.scss │ │ ├── index.ts │ │ ├── method.ts │ │ └── ts │ │ ├── constants.ts │ │ ├── devtools │ │ └── index.ts │ │ ├── export │ │ └── index.ts │ │ ├── hint │ │ └── index.ts │ │ ├── i18n │ │ └── index.ts │ │ ├── ir │ │ ├── expandMarker.ts │ │ ├── highlightToolbarIR.ts │ │ ├── index.ts │ │ ├── input.ts │ │ ├── process.ts │ │ └── processKeydown.ts │ │ ├── markdown │ │ ├── abcRender.ts │ │ ├── adapterRender.ts │ │ ├── anchorRender.ts │ │ ├── chartRender.ts │ │ ├── codeRender.ts │ │ ├── flowchartRender.ts │ │ ├── getHTML.ts │ │ ├── getMarkdown.ts │ │ ├── graphvizRender.ts │ │ ├── highlightRender.ts │ │ ├── lazyLoadImageRender.ts │ │ ├── mathRender.ts │ │ ├── mediaRender.ts │ │ ├── mermaidRender.ts │ │ ├── mindmapRender.ts │ │ ├── outlineRender.ts │ │ ├── plantumlRender.ts │ │ ├── previewRender.ts │ │ ├── setLute.ts │ │ └── speechRender.ts │ │ ├── outline │ │ └── index.ts │ │ ├── preview │ │ ├── image.ts │ │ └── index.ts │ │ ├── resize │ │ └── index.ts │ │ ├── sv │ │ ├── index.ts │ │ ├── inputEvent.ts │ │ ├── process.ts │ │ └── processKeydown.ts │ │ ├── tip │ │ └── index.ts │ │ ├── toolbar │ │ ├── Both.ts │ │ ├── Br.ts │ │ ├── CodeTheme.ts │ │ ├── ContentTheme.ts │ │ ├── Counter.ts │ │ ├── Custom.ts │ │ ├── Devtools.ts │ │ ├── Divider.ts │ │ ├── EditMode.ts │ │ ├── Emoji.ts │ │ ├── Export.ts │ │ ├── Fullscreen.ts │ │ ├── Headings.ts │ │ ├── Help.ts │ │ ├── Indent.ts │ │ ├── Info.ts │ │ ├── InsertAfter.ts │ │ ├── InsertBefore.ts │ │ ├── MenuItem.ts │ │ ├── Outdent.ts │ │ ├── Outline.ts │ │ ├── Preview.ts │ │ ├── Record.ts │ │ ├── Redo.ts │ │ ├── Undo.ts │ │ ├── Upload.ts │ │ ├── index.ts │ │ └── setToolbar.ts │ │ ├── ui │ │ ├── initUI.ts │ │ ├── setCodeTheme.ts │ │ ├── setContentTheme.ts │ │ ├── setPreviewMode.ts │ │ └── setTheme.ts │ │ ├── undo │ │ └── index.ts │ │ ├── upload │ │ ├── getElement.ts │ │ ├── index.ts │ │ └── setHeaders.ts │ │ ├── util │ │ ├── Options.ts │ │ ├── RecordMedia.ts │ │ ├── addScript.ts │ │ ├── addStyle.ts │ │ ├── code160to32.ts │ │ ├── compatibility.ts │ │ ├── editorCommonEvent.ts │ │ ├── fixBrowserBehavior.ts │ │ ├── getSelectText.ts │ │ ├── hasClosest.ts │ │ ├── hasClosestByHeadings.ts │ │ ├── highlightToolbar.ts │ │ ├── hotKey.ts │ │ ├── log.ts │ │ ├── merge.ts │ │ ├── processCode.ts │ │ ├── selection.ts │ │ └── toc.ts │ │ └── wysiwyg │ │ ├── afterRenderEvent.ts │ │ ├── highlightToolbarWYSIWYG.ts │ │ ├── index.ts │ │ ├── inlineTag.ts │ │ ├── input.ts │ │ ├── processKeydown.ts │ │ ├── renderDomByMd.ts │ │ ├── setHeading.ts │ │ ├── showCode.ts │ │ └── toolbarEvent.ts ├── index.html ├── logo.png └── service_worker.js ├── src ├── App.vue ├── api │ ├── admin_logs.js │ ├── admin_manage_user.js │ ├── api.js │ ├── auth.js │ ├── class.js │ ├── manage.js │ ├── problem.js │ ├── problem_set.js │ ├── submission.js │ ├── user.js │ └── webauthn.js ├── assets │ ├── background.svg │ ├── icons │ │ └── bx-analyse.svg │ ├── logo.png │ └── logo.svg ├── components │ ├── Avatar.vue │ ├── Code.vue │ ├── Dialog.js │ ├── Diff.vue │ ├── Editor │ │ ├── Markdown.vue │ │ └── MarkdownEditor.vue │ ├── GlobalFooter │ │ └── index.vue │ ├── GlobalHeader │ │ ├── AvatarDropdown.vue │ │ └── RightContent.vue │ ├── Language.vue │ ├── Memory.vue │ ├── MultiTab │ │ ├── MultiTab.vue │ │ ├── events.js │ │ ├── index.js │ │ └── index.less │ ├── NProgress │ │ └── nprogress.less │ ├── PageLoading │ │ └── index.jsx │ ├── RunStatus.vue │ ├── SelectLang │ │ ├── index.jsx │ │ └── index.less │ ├── Table │ │ └── ResizableTableHeader.js │ ├── TestCase.vue │ ├── UserName.vue │ ├── _util │ │ └── util.js │ ├── codemirror │ │ ├── JetBrainsMono-Regular.ttf │ │ ├── JetBrainsMono-Regular.woff2 │ │ ├── codemirror.vue │ │ └── index.js │ └── index.less ├── config │ ├── .gitignore │ ├── comparerConf.js │ ├── config.example.js │ ├── languageConf.js │ └── router.config.js ├── core │ ├── bootstrap.js │ ├── directives │ │ └── action.js │ ├── icons.js │ ├── lazy_use.js │ └── use.js ├── global.less ├── layouts │ ├── BasicLayout.less │ ├── BasicLayout.vue │ ├── BlankLayout.vue │ ├── PageView.vue │ ├── RouteView.vue │ ├── UserLayout.vue │ └── index.js ├── locales │ ├── index.js │ └── lang │ │ ├── en-US.js │ │ └── zh-CN.js ├── main.js ├── permission.js ├── router │ ├── generator-routers.js │ └── index.js ├── store │ ├── app-mixin.js │ ├── device-mixin.js │ ├── getters.js │ ├── i18n-mixin.js │ ├── index.js │ ├── modules │ │ ├── app.js │ │ ├── class.js │ │ └── user.js │ └── mutation-types.js ├── utils │ ├── axios.js │ ├── domUtil.js │ ├── filter.js │ ├── helper │ │ └── permission.js │ ├── permissions.js │ ├── request.js │ ├── routeConvert.js │ ├── screenLog.js │ ├── util.js │ └── utils.less └── views │ ├── 404.vue │ ├── Home.vue │ ├── IDE.vue │ ├── Todo.vue │ ├── account │ └── settings │ │ ├── BaseSetting.vue │ │ ├── ChangePassword.vue │ │ ├── Index.vue │ │ ├── SystemSettings.vue │ │ └── Webauthn.vue │ ├── admin │ ├── Logs.vue │ └── user │ │ ├── CreateUser.vue │ │ ├── EditUser.vue │ │ └── Users.vue │ ├── class │ ├── ClassGrades.vue │ ├── ClassView.vue │ ├── CreateClass.vue │ ├── CreateProblemSet.vue │ ├── Dashboard.vue │ ├── EditClass.vue │ ├── EditProblemSet.vue │ ├── EditProblemSetProblems.vue │ ├── EditProblemSets.vue │ ├── EditStudent.vue │ ├── ProblemSetGrades.vue │ ├── ProblemSetProblem.vue │ ├── ProblemSetProblems.vue │ ├── ProblemSetSubmission.vue │ ├── ProblemSetSubmissions.vue │ ├── ProblemSetSubmit.vue │ └── ProblemSets.vue │ ├── problem │ ├── CreateProblem.vue │ ├── EditProblem.vue │ ├── Problem.vue │ ├── Problems.vue │ └── Submit.vue │ ├── submission │ ├── Submission.vue │ └── Submissions.vue │ └── user │ ├── EmailVerify.vue │ ├── Login.vue │ ├── Register.vue │ ├── RegisterResult.vue │ ├── ResetPassword.vue │ └── UpdateEmail.vue ├── tests └── unit │ └── .eslintrc.js ├── vue.config.js ├── webstorm.config.js └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | ie >= 10 3 | edge 16 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset=utf-8 3 | end_of_line=lf 4 | insert_final_newline=false 5 | indent_style=space 6 | indent_size=2 7 | 8 | [{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}] 9 | indent_style=space 10 | indent_size=2 11 | 12 | [{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}] 13 | indent_style=space 14 | indent_size=2 15 | 16 | [{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}] 17 | indent_style=space 18 | indent_size=2 19 | 20 | [*.svg] 21 | indent_style=space 22 | indent_size=2 23 | 24 | [*.js.map] 25 | indent_style=space 26 | indent_size=2 27 | 28 | [*.less] 29 | indent_style=space 30 | indent_size=2 31 | 32 | [*.vue] 33 | indent_style=space 34 | indent_size=2 35 | 36 | [{.analysis_options,*.yml,*.yaml}] 37 | indent_style=space 38 | indent_size=2 39 | 40 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | NODE_ENV=production 2 | VUE_APP_PREVIEW=false 3 | VUE_APP_API_BASE_URL=/api -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | NODE_ENV=development 2 | VUE_APP_PREVIEW=true 3 | VUE_APP_API_BASE_URL=/api -------------------------------------------------------------------------------- /.env.preview: -------------------------------------------------------------------------------- 1 | NODE_ENV=production 2 | VUE_APP_PREVIEW=true 3 | VUE_APP_API_BASE_URL=/api -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/strongly-recommended', 8 | '@vue/standard' 9 | ], 10 | rules: { 11 | 'no-console': 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 13 | 'generator-star-spacing': 'off', 14 | 'no-mixed-operators': 0, 15 | 'vue/max-attributes-per-line': [ 16 | 2, 17 | { 18 | 'singleline': 5, 19 | 'multiline': { 20 | 'max': 1, 21 | 'allowFirstLine': false 22 | } 23 | } 24 | ], 25 | 'vue/attribute-hyphenation': 0, 26 | 'vue/html-self-closing': 0, 27 | 'vue/component-name-in-template-casing': 0, 28 | 'vue/html-closing-bracket-spacing': 0, 29 | 'vue/singleline-html-element-content-newline': 0, 30 | 'vue/no-unused-components': 0, 31 | 'vue/multiline-html-element-content-newline': 0, 32 | 'vue/no-use-v-if-with-v-for': 0, 33 | 'vue/html-closing-bracket-newline': 0, 34 | 'vue/no-parsing-error': 0, 35 | 'no-tabs': 0, 36 | 'quotes': [ 37 | 2, 38 | 'single', 39 | { 40 | 'avoidEscape': true, 41 | 'allowTemplateLiterals': true 42 | } 43 | ], 44 | 'semi': [ 45 | 2, 46 | 'never', 47 | { 48 | 'beforeStatementContinuationChars': 'never' 49 | } 50 | ], 51 | 'no-delete-var': 2, 52 | 'prefer-const': [ 53 | 2, 54 | { 55 | 'ignoreReadBeforeAssign': false 56 | } 57 | ], 58 | 'template-curly-spacing': 'off', 59 | 'indent': 'off' 60 | }, 61 | parserOptions: { 62 | parser: 'babel-eslint' 63 | }, 64 | overrides: [ 65 | { 66 | files: [ 67 | '**/__tests__/*.{j,t}s?(x)', 68 | '**/tests/unit/**/*.spec.{j,t}s?(x)' 69 | ], 70 | env: { 71 | jest: true 72 | } 73 | } 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | public/* linguist-vendored -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve(Bug 反馈) 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug (描述 Bug)** 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | 15 | 16 | **To Reproduce (重现步骤)** 17 | Steps to reproduce the behavior: 18 | 19 | 1. Go to '...' 20 | 2. Click on '....' 21 | 3. Scroll down to '....' 22 | 4. See error 23 | 24 | 25 | 26 | **Expected behavior(你期待的是什么?)** 27 | A clear and concise description of what you expected to happen. 28 | 29 | 30 | 31 | **Screenshots(截图)** 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | 35 | 36 | **Desktop (please complete the following information):** 37 | 38 | - OS: [e.g. iOS] 39 | - Browser [e.g. chrome, safari] 40 | - Version [e.g. 22] 41 | 42 | 43 | 44 | **Smartphone (please complete the following information):** 45 | 46 | - Device: [e.g. iPhone6] 47 | - OS: [e.g. iOS8.1] 48 | - Browser [e.g. stock browser, safari] 49 | - Version [e.g. 22] 50 | 51 | 52 | 53 | **Additional context(附加信息)** 54 | Add any other context about the problem here. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/need-help-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Need help issue 3 | about: Question for use(问题求助) 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Question (问题描述)** 11 | How to use component `s-table` paging 12 | 13 | **Describe the solution you'd like (你期待的是什么?)** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Additional context(附加信息)** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | First of all, thank you for your contribution! 😄 2 | 3 | Pull request will be merged after one of collaborators approve. 4 | Please makes sure that these form are filled before submitting your pull request, thank you! 5 | 6 | 7 | ### 这个变动的性质是 8 | 9 | - [ ] 新特性提交 10 | - [ ] 日常 bug 修复 11 | - [ ] 文档改进 12 | - [ ] 组件样式改进 13 | - [ ] 重构 14 | - [ ] 代码风格优化 15 | - [ ] 分支合并 16 | - [ ] 其他改动(是关于什么的改动?) 17 | 18 | ### 需求背景 19 | 20 | > 1. 描述相关需求的来源。 21 | > 2. 要解决的问题。 22 | > 3. 相关的 issue 讨论链接。 23 | 24 | ### 实现方案和 API(非新功能可选) 25 | 26 | > 1. 基本的解决思路和其他可选方案。 27 | > 2. 列出最终的 API 实现和用法。 28 | > 3. 涉及UI/交互变动需要有截图或 GIF。 29 | 30 | ### 对用户的影响和可能的风险(非新功能可选) 31 | 32 | > 1. 这个改动对用户端是否有影响?影响的方面有哪些? 33 | > 2. 是否有可能隐含的 break change 和其他风险? 34 | 35 | ### Changelog 描述(非新功能可选) 36 | 37 | > 1. 英文描述 38 | > 2. 中文描述(可选) 39 | 40 | ### 请求合并前的自查清单 41 | 42 | - [ ] 文档已补充或无须补充 43 | - [ ] 代码演示已提供或无须提供 44 | - [ ] Changelog 已提供或无须提供 45 | 46 | ### 后续计划(非新功能可选) 47 | 48 | > 如果这个提交后面还有相关的其他提交和跟进信息,可以写在这里。 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": false, 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 10.15.0 4 | cache: yarn 5 | script: 6 | - yarn 7 | - yarn run lint --no-fix && yarn run build 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EduOJ Frontend 2 | 3 | 这个仓库存储EduOJ的前端代码。 4 | 5 | EduOJ是一个面向教学的在线评测系统,将程序在线评测和编辑管理功能结合到一起,实现高效的班级、作业管理,作业自动检验。 6 | 7 | > 目前应用于北京工业大学。 8 | 9 | ## 部署 10 | 11 | ### 下载 & 构建 12 | 13 | ```sh 14 | sudo apt-get update 15 | sudo apt-get install -y git 16 | git clone https://github.com/EduOJ/frontend.git 17 | cd frontend 18 | yarn build 19 | ``` 20 | 21 | ### 配置 22 | 23 | 复制`frontend/src/config/config.example.js`,如有需要可修改其中的`title`和`apiUrl` 24 | 25 | ``` 26 | cp src/config/config.example.js src/config/config.js 27 | ``` 28 | 29 | ### 部署 30 | 31 | 把`dist`部署到`nginx`根目录,并配置`/api`目录到后端的反向代理 32 | 33 | ### 文档 34 | 35 | 我们的文档还在施工中。 -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV) 2 | 3 | const plugins = [] 4 | if (IS_PROD) { 5 | plugins.push('transform-remove-console') 6 | } 7 | 8 | // lazy load ant-design-vue 9 | // if your use import on Demand, Use this code 10 | plugins.push(['import', { 11 | 'libraryName': 'ant-design-vue', 12 | 'libraryDirectory': 'es', 13 | 'style': true // `style: true` 会加载 less 文件 14 | }]) 15 | 16 | module.exports = { 17 | presets: [ 18 | '@vue/cli-plugin-babel/preset', 19 | [ 20 | '@babel/preset-env', 21 | { 22 | 'useBuiltIns': 'entry', 23 | 'corejs': 3 24 | } 25 | ] 26 | ], 27 | plugins 28 | } 29 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": ["src/*"] 7 | } 8 | }, 9 | "exclude": ["node_modules", "dist"], 10 | "include": ["src/**/*"] 11 | } 12 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/bin/clang: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/bin/clang -------------------------------------------------------------------------------- /public/assets/bin/lld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/bin/lld -------------------------------------------------------------------------------- /public/assets/bin/memfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/bin/memfs -------------------------------------------------------------------------------- /public/assets/bin/sysroot.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/bin/sysroot.tar -------------------------------------------------------------------------------- /public/assets/vditor/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 B3log 开源, b3log.org 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 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/b3log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/b3log.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/chainbook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/chainbook.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/doge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/doge.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/hacpai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/hacpai.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/huaji.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/huaji.gif -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/latke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/latke.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/lute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/lute.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/octocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/octocat.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/pipe.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/solo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/solo.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/sym.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/sym.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/trollface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/trollface.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/vditor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/vditor.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/wide.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/emoji/wulian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/emoji/wulian.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/img-loading.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/images/logo.png -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_AMS-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_AMS-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_AMS-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_AMS-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_AMS-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_AMS-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Bold.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Caligraphic-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Bold.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Fraktur-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Bold.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-BoldItalic.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-BoldItalic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Italic.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Italic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Italic.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Main-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-BoldItalic.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-BoldItalic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-Italic.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-Italic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Math-Italic.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Bold.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Bold.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Italic.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Italic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Italic.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_SansSerif-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Script-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Script-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Script-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Script-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Script-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Script-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size1-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size1-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size1-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size1-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size1-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size1-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size2-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size2-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size2-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size2-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size2-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size2-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size3-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size3-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size3-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size3-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size3-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size3-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size4-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size4-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size4-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size4-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Size4-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Size4-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Typewriter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Typewriter-Regular.ttf -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Typewriter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Typewriter-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/katex/fonts/KaTeX_Typewriter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/katex/fonts/KaTeX_Typewriter-Regular.woff2 -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Zero.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/assets/vditor/dist/js/mathjax/output/chtml/fonts/woff-v2/MathJax_Zero.woff -------------------------------------------------------------------------------- /public/assets/vditor/dist/js/mathjax/sre/sre-node.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var SRE = require("speech-rule-engine"); 4 | global.SRE = SRE; 5 | global.sre = Object.create(SRE); 6 | global.sre.Engine = { 7 | isReady: function () { 8 | return SRE.engineReady(); 9 | } 10 | }; 11 | //# sourceMappingURL=sre-node.js.map -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/constants.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare const _VDITOR_VERSION: string; 3 | export { _VDITOR_VERSION as VDITOR_VERSION }; 4 | export declare abstract class Constants { 5 | static readonly ZWSP: string; 6 | static readonly DROP_EDITOR: string; 7 | static readonly MOBILE_WIDTH: number; 8 | static readonly CLASS_MENU_DISABLED: string; 9 | static readonly EDIT_TOOLBARS: string[]; 10 | static readonly CODE_THEME: string[]; 11 | static readonly CODE_LANGUAGES: string[]; 12 | static readonly CDN: string; 13 | static readonly MARKDOWN_OPTIONS: { 14 | autoSpace: boolean; 15 | codeBlockPreview: boolean; 16 | fixTermTypo: boolean; 17 | footnotes: boolean; 18 | linkBase: string; 19 | linkPrefix: string; 20 | listStyle: boolean; 21 | mark: boolean; 22 | mathBlockPreview: boolean; 23 | paragraphBeginningSpace: boolean; 24 | sanitize: boolean; 25 | toc: boolean; 26 | }; 27 | static readonly HLJS_OPTIONS: { 28 | enable: boolean; 29 | lineNumber: boolean; 30 | style: string; 31 | }; 32 | static readonly MATH_OPTIONS: IMath; 33 | static readonly THEME_OPTIONS: { 34 | current: string; 35 | list: { 36 | "ant-design": string; 37 | dark: string; 38 | light: string; 39 | wechat: string; 40 | }; 41 | path: string; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/devtools/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class DevTools { 3 | element: HTMLDivElement; 4 | private ASTChart; 5 | constructor(); 6 | renderEchart(vditor: IVditor): void; 7 | } 8 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/export/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const download: (vditor: IVditor, content: string, filename: string) => void; 3 | export declare const exportMarkdown: (vditor: IVditor) => void; 4 | export declare const exportPDF: (vditor: IVditor) => void; 5 | export declare const exportHTML: (vditor: IVditor) => void; 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/hint/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Hint { 3 | timeId: number; 4 | element: HTMLDivElement; 5 | recentLanguage: string; 6 | private splitChar; 7 | private lastIndex; 8 | constructor(hintExtends: IHintExtend[]); 9 | render(vditor: IVditor): void; 10 | genHTML(data: IHintData[], key: string, vditor: IVditor): void; 11 | fillEmoji: (element: HTMLElement, vditor: IVditor) => void; 12 | select(event: KeyboardEvent, vditor: IVditor): boolean; 13 | private getKey; 14 | } 15 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/i18n/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const i18n: II18n; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ir/expandMarker.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const expandMarker: (range: Range, vditor: IVditor) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ir/highlightToolbarIR.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const highlightToolbarIR: (vditor: IVditor) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ir/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare class IR { 3 | range: Range; 4 | element: HTMLPreElement; 5 | processTimeoutId: number; 6 | hlToolbarTimeoutId: number; 7 | composingLock: boolean; 8 | preventInput: boolean; 9 | constructor(vditor: IVditor); 10 | private copy; 11 | private bindEvent; 12 | } 13 | export { IR }; 14 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ir/input.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const input: (vditor: IVditor, range: Range, ignoreSpace?: boolean, event?: InputEvent) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ir/process.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const processHint: (vditor: IVditor) => void; 3 | export declare const processAfterRender: (vditor: IVditor, options?: { 4 | enableAddUndoStack: boolean; 5 | enableHint: boolean; 6 | enableInput: boolean; 7 | }) => void; 8 | export declare const processHeading: (vditor: IVditor, value: string) => void; 9 | export declare const processToolbar: (vditor: IVditor, actionBtn: Element, prefix: string, suffix: string) => void; 10 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ir/processKeydown.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const processKeydown: (vditor: IVditor, event: KeyboardEvent) => boolean; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/abcRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const abcRender: (element?: (HTMLElement | Document), cdn?: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/adapterRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const mathRenderAdapter: { 2 | getCode: (mathElement: Element) => string; 3 | getElements: (element: HTMLElement) => NodeListOf; 4 | }; 5 | export declare const mermaidRenderAdapter: { 6 | /** 不仅要返回code,并且需要将 code 设置为 el 的 innerHTML */ 7 | getCode: (el: Element) => string; 8 | getElements: (element: HTMLElement) => NodeListOf; 9 | }; 10 | export declare const mindmapRenderAdapter: { 11 | getCode: (el: Element) => string; 12 | getElements: (el: HTMLElement | Document) => NodeListOf; 13 | }; 14 | export declare const chartRenderAdapter: { 15 | getCode: (el: HTMLElement) => string; 16 | getElements: (el: HTMLElement | Document) => NodeListOf; 17 | }; 18 | export declare const abcRenderAdapter: { 19 | getCode: (el: Element) => string; 20 | getElements: (el: HTMLElement | Document) => NodeListOf; 21 | }; 22 | export declare const graphvizRenderAdapter: { 23 | getCode: (el: Element) => string; 24 | getElements: (el: HTMLElement | Document) => NodeListOf; 25 | }; 26 | export declare const flowchartRenderAdapter: { 27 | getCode: (el: Element) => string; 28 | getElements: (el: HTMLElement | Document) => NodeListOf; 29 | }; 30 | export declare const plantumlRenderAdapter: { 31 | getCode: (el: Element) => string; 32 | getElements: (el: HTMLElement | Document) => NodeListOf; 33 | }; 34 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/anchorRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const anchorRender: (type: number) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/chartRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const chartRender: (element: (HTMLElement | Document), cdn: string, theme: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/codeRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const codeRender: (element: HTMLElement) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/flowchartRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const flowchartRender: (element: HTMLElement, cdn?: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/getHTML.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const getHTML: (vditor: IVditor) => string; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/getMarkdown.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const getMarkdown: (vditor: IVditor) => string; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/graphvizRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const graphvizRender: (element: HTMLElement, cdn?: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/highlightRender.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const highlightRender: (hljsOption?: IHljs, element?: HTMLElement | Document, cdn?: string) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/lazyLoadImageRender.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { 3 | vditorImageIntersectionObserver: IntersectionObserver; 4 | } 5 | } 6 | export declare const lazyLoadImageRender: (element?: (HTMLElement | Document)) => boolean; 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/mathRender.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare global { 3 | interface Window { 4 | MathJax: any; 5 | } 6 | } 7 | export declare const mathRender: (element: HTMLElement, options?: { 8 | cdn?: string; 9 | math?: IMath; 10 | }) => void; 11 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/mediaRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const mediaRender: (element: HTMLElement) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/mermaidRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const mermaidRender: (element: HTMLElement, cdn: string, theme: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/mindmapRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const mindmapRender: (element: (HTMLElement | Document), cdn: string, theme: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/outlineRender.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const outlineRender: (contentElement: HTMLElement, targetElement: Element, vditor?: IVditor) => string; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/plantumlRender.d.ts: -------------------------------------------------------------------------------- 1 | export declare const plantumlRender: (element?: (HTMLElement | Document), cdn?: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/previewRender.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const md2html: (mdText: string, options?: IPreviewOptions) => Promise; 3 | export declare const previewRender: (previewElement: HTMLDivElement, markdown: string, options?: IPreviewOptions) => Promise; 4 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/setLute.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const setLute: (options: ILuteOptions) => Lute; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/markdown/speechRender.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare global { 3 | interface Window { 4 | vditorSpeechRange: Range; 5 | } 6 | } 7 | export declare const speechRender: (element: HTMLElement, lang?: keyof II18n) => void; 8 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/outline/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Outline { 3 | element: HTMLElement; 4 | constructor(outlineLabel: string); 5 | render(vditor: IVditor): string; 6 | toggle(vditor: IVditor, show?: boolean): void; 7 | } 8 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/preview/image.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const previewImage: (oldImgElement: HTMLImageElement, lang?: keyof II18n, theme?: string) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/preview/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Preview { 3 | element: HTMLElement; 4 | private mdTimeoutId; 5 | constructor(vditor: IVditor); 6 | render(vditor: IVditor, value?: string): void; 7 | private afterRender; 8 | private copyToX; 9 | } 10 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/resize/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Resize { 3 | element: HTMLElement; 4 | constructor(vditor: IVditor); 5 | private bindEvent; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/sv/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare class Editor { 3 | range: Range; 4 | element: HTMLPreElement; 5 | composingLock: boolean; 6 | processTimeoutId: number; 7 | hlToolbarTimeoutId: number; 8 | preventInput: boolean; 9 | constructor(vditor: IVditor); 10 | private copy; 11 | private bindEvent; 12 | } 13 | export { Editor }; 14 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/sv/inputEvent.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const inputEvent: (vditor: IVditor, event?: InputEvent) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/sv/process.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const processPaste: (vditor: IVditor, text: string) => void; 3 | export declare const getSideByType: (spanNode: Node, type: string, isPrevious?: boolean) => false | Element; 4 | export declare const processSpinVditorSVDOM: (html: string, vditor: IVditor) => string; 5 | export declare const processPreviousMarkers: (spanElement: HTMLElement) => string; 6 | export declare const processAfterRender: (vditor: IVditor, options?: { 7 | enableAddUndoStack: boolean; 8 | enableHint: boolean; 9 | enableInput: boolean; 10 | }) => void; 11 | export declare const processHeading: (vditor: IVditor, value: string) => void; 12 | export declare const processToolbar: (vditor: IVditor, actionBtn: Element, prefix: string, suffix: string) => void; 13 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/sv/processKeydown.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const processKeydown: (vditor: IVditor, event: KeyboardEvent) => boolean; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/tip/index.d.ts: -------------------------------------------------------------------------------- 1 | export declare class Tip { 2 | element: HTMLElement; 3 | constructor(); 4 | show(text: string, time?: number): void; 5 | hide(): void; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Both.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Both extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Br.d.ts: -------------------------------------------------------------------------------- 1 | export declare class Br { 2 | element: HTMLElement; 3 | constructor(); 4 | } 5 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/CodeTheme.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class CodeTheme extends MenuItem { 4 | element: HTMLElement; 5 | constructor(vditor: IVditor, menuItem: IMenuItem); 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/ContentTheme.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class ContentTheme extends MenuItem { 4 | element: HTMLElement; 5 | constructor(vditor: IVditor, menuItem: IMenuItem); 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Counter.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Counter { 3 | element: HTMLElement; 4 | constructor(vditor: IVditor); 5 | render(vditor: IVditor, mdText: string): void; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Custom.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Custom extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Devtools.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Devtools extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Divider.d.ts: -------------------------------------------------------------------------------- 1 | export declare class Divider { 2 | element: HTMLElement; 3 | constructor(); 4 | } 5 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/EditMode.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare const setEditMode: (vditor: IVditor, type: string, event: Event | string) => void; 4 | export declare class EditMode extends MenuItem { 5 | element: HTMLElement; 6 | constructor(vditor: IVditor, menuItem: IMenuItem); 7 | _bindEvent(vditor: IVditor, panelElement: HTMLElement, menuItem: IMenuItem): void; 8 | } 9 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Emoji.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Emoji extends MenuItem { 4 | element: HTMLElement; 5 | constructor(vditor: IVditor, menuItem: IMenuItem); 6 | _bindEvent(vditor: IVditor, panelElement: HTMLElement): void; 7 | } 8 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Export.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Export extends MenuItem { 4 | element: HTMLElement; 5 | constructor(vditor: IVditor, menuItem: IMenuItem); 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Fullscreen.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Fullscreen extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | _bindEvent(vditor: IVditor, menuItem: IMenuItem): void; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Headings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Headings extends MenuItem { 4 | element: HTMLElement; 5 | constructor(vditor: IVditor, menuItem: IMenuItem); 6 | _bindEvent(vditor: IVditor, panelElement: HTMLElement): void; 7 | } 8 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Help.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Help extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Indent.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Indent extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Info.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Info extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/InsertAfter.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class InsertAfter extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/InsertBefore.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class InsertBefore extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/MenuItem.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class MenuItem { 3 | element: HTMLElement; 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Outdent.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Outdent extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Outline.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Outline extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Preview.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Preview extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | _bindEvent(vditor: IVditor): void; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Record.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Record extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | _bindEvent(vditor: IVditor): void; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Redo.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Redo extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Undo.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Undo extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/Upload.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { MenuItem } from "./MenuItem"; 3 | export declare class Upload extends MenuItem { 4 | constructor(vditor: IVditor, menuItem: IMenuItem); 5 | _bindEvent(vditor: IVditor): void; 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Toolbar { 3 | elements: { 4 | [key: string]: HTMLElement; 5 | }; 6 | element: HTMLElement; 7 | constructor(vditor: IVditor); 8 | private genItem; 9 | } 10 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/toolbar/setToolbar.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const removeCurrentToolbar: (toolbar: { 3 | [key: string]: HTMLElement; 4 | }, names: string[]) => void; 5 | export declare const setCurrentToolbar: (toolbar: { 6 | [key: string]: HTMLElement; 7 | }, names: string[]) => void; 8 | export declare const enableToolbar: (toolbar: { 9 | [key: string]: HTMLElement; 10 | }, names: string[]) => void; 11 | export declare const disableToolbar: (toolbar: { 12 | [key: string]: HTMLElement; 13 | }, names: string[]) => void; 14 | export declare const hideToolbar: (toolbar: { 15 | [key: string]: HTMLElement; 16 | }, names: string[]) => void; 17 | export declare const showToolbar: (toolbar: { 18 | [key: string]: HTMLElement; 19 | }, names: string[]) => void; 20 | export declare const hidePanel: (vditor: IVditor, panels: string[], exceptElement?: HTMLElement) => void; 21 | export declare const toggleSubMenu: (vditor: IVditor, panelElement: HTMLElement, actionBtn: Element, level: number) => void; 22 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ui/initUI.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare global { 3 | interface Window { 4 | visualViewport: HTMLElement; 5 | } 6 | } 7 | export declare const initUI: (vditor: IVditor) => void; 8 | export declare const setPadding: (vditor: IVditor) => void; 9 | export declare const setTypewriterPosition: (vditor: IVditor) => void; 10 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ui/setCodeTheme.d.ts: -------------------------------------------------------------------------------- 1 | export declare const setCodeTheme: (codeTheme: string, cdn?: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ui/setContentTheme.d.ts: -------------------------------------------------------------------------------- 1 | export declare const setContentTheme: (contentTheme: string, path: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ui/setPreviewMode.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const setPreviewMode: (mode: "both" | "editor", vditor: IVditor) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/ui/setTheme.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const setTheme: (vditor: IVditor) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/undo/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare class Undo { 3 | private stackSize; 4 | private dmp; 5 | private wysiwyg; 6 | private ir; 7 | private sv; 8 | constructor(); 9 | clearStack(vditor: IVditor): void; 10 | resetIcon(vditor: IVditor): void; 11 | undo(vditor: IVditor): void; 12 | redo(vditor: IVditor): void; 13 | recordFirstPosition(vditor: IVditor, event: KeyboardEvent): void; 14 | addToUndoStack(vditor: IVditor): void; 15 | private renderDiff; 16 | private resetStack; 17 | private addCaret; 18 | } 19 | export { Undo }; 20 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/upload/getElement.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const getElement: (vditor: IVditor) => HTMLPreElement; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/upload/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare class Upload { 3 | element: HTMLElement; 4 | isUploading: boolean; 5 | range: Range; 6 | constructor(); 7 | } 8 | declare const uploadFiles: (vditor: IVditor, files: FileList | DataTransferItemList | File[], element?: HTMLInputElement) => Promise; 9 | export { Upload, uploadFiles }; 10 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/upload/setHeaders.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const setHeaders: (vditor: IVditor, xhr: XMLHttpRequest) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/Options.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare class Options { 3 | options: IOptions; 4 | private defaultOptions; 5 | constructor(options: IOptions); 6 | merge(): IOptions; 7 | private mergeToolbar; 8 | } 9 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/RecordMedia.d.ts: -------------------------------------------------------------------------------- 1 | export declare class RecordMedia { 2 | SAMPLE_RATE: number; 3 | DEFAULT_SAMPLE_RATE: number; 4 | isRecording: boolean; 5 | readyFlag: boolean; 6 | leftChannel: Float32List[]; 7 | rightChannel: Float32List[]; 8 | recordingLength: number; 9 | recorder: ScriptProcessorNode; 10 | constructor(e: MediaStream); 11 | cloneChannelData(leftChannelData: Float32List, rightChannelData: Float32List): void; 12 | startRecordingNewWavFile(): void; 13 | stopRecording(): void; 14 | buildWavFileBlob(): Blob; 15 | private downSampleBuffer; 16 | private mergeBuffers; 17 | private writeUTFBytes; 18 | } 19 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/addScript.d.ts: -------------------------------------------------------------------------------- 1 | export declare const addScriptSync: (path: string, id: string) => boolean; 2 | export declare const addScript: (path: string, id: string) => Promise; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/addStyle.d.ts: -------------------------------------------------------------------------------- 1 | export declare const addStyle: (url: string, id: string) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/code160to32.d.ts: -------------------------------------------------------------------------------- 1 | export declare const code160to32: (text: string) => string; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/compatibility.d.ts: -------------------------------------------------------------------------------- 1 | export declare const isSafari: () => boolean; 2 | export declare const isFirefox: () => boolean; 3 | export declare const accessLocalStorage: () => boolean; 4 | export declare const getEventName: () => "click" | "touchstart"; 5 | export declare const isCtrl: (event: KeyboardEvent) => boolean; 6 | export declare const updateHotkeyTip: (hotkey: string) => string; 7 | export declare const isChrome: () => boolean; 8 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/editorCommonEvent.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const focusEvent: (vditor: IVditor, editorElement: HTMLElement) => void; 3 | export declare const dblclickEvent: (vditor: IVditor, editorElement: HTMLElement) => void; 4 | export declare const blurEvent: (vditor: IVditor, editorElement: HTMLElement) => void; 5 | export declare const dropEvent: (vditor: IVditor, editorElement: HTMLElement) => void; 6 | export declare const copyEvent: (vditor: IVditor, editorElement: HTMLElement, copy: (event: ClipboardEvent, vditor: IVditor) => void) => void; 7 | export declare const cutEvent: (vditor: IVditor, editorElement: HTMLElement, copy: (event: ClipboardEvent, vditor: IVditor) => void) => void; 8 | export declare const scrollCenter: (vditor: IVditor) => void; 9 | export declare const hotkeyEvent: (vditor: IVditor, editorElement: HTMLElement) => void; 10 | export declare const selectEvent: (vditor: IVditor, editorElement: HTMLElement) => void; 11 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/getSelectText.d.ts: -------------------------------------------------------------------------------- 1 | export declare const getSelectText: (editor: HTMLElement, range?: Range) => string; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/hasClosest.d.ts: -------------------------------------------------------------------------------- 1 | export declare const hasTopClosestByClassName: (element: Node, className: string) => false | HTMLElement; 2 | export declare const hasTopClosestByAttribute: (element: Node, attr: string, value: string) => false | HTMLElement; 3 | export declare const hasTopClosestByTag: (element: Node, nodeName: string) => false | HTMLElement; 4 | export declare const getTopList: (element: Node) => false | HTMLElement; 5 | export declare const hasClosestByAttribute: (element: Node, attr: string, value: string) => false | HTMLElement; 6 | export declare const hasClosestBlock: (element: Node) => false | HTMLElement; 7 | export declare const hasClosestByMatchTag: (element: Node, nodeName: string) => false | HTMLElement; 8 | export declare const hasClosestByClassName: (element: Node, className: string) => false | HTMLElement; 9 | export declare const getLastNode: (node: Node) => Node; 10 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/hasClosestByHeadings.d.ts: -------------------------------------------------------------------------------- 1 | export declare const hasClosestByTag: (element: Node, nodeName: string) => false | HTMLElement; 2 | export declare const hasClosestByHeadings: (element: Node) => false | HTMLElement; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/highlightToolbar.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const highlightToolbar: (vditor: IVditor) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/hotKey.d.ts: -------------------------------------------------------------------------------- 1 | export declare const matchHotKey: (hotKey: string, event: KeyboardEvent) => boolean; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/log.d.ts: -------------------------------------------------------------------------------- 1 | export declare const log: (method: string, content: string, type: string, print: boolean) => void; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/merge.d.ts: -------------------------------------------------------------------------------- 1 | export declare const merge: (...options: any[]) => any; 2 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/processCode.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const processPasteCode: (html: string, text: string, type?: string) => string | false; 3 | export declare const processCodeRender: (previewPanel: HTMLElement, vditor: IVditor) => void; 4 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/selection.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const getEditorRange: (vditor: IVditor) => Range; 3 | export declare const getCursorPosition: (editor: HTMLElement) => { 4 | left: number; 5 | top: number; 6 | }; 7 | export declare const selectIsEditor: (editor: HTMLElement, range?: Range) => boolean; 8 | export declare const setSelectionFocus: (range: Range) => void; 9 | export declare const getSelectPosition: (selectElement: HTMLElement, editorElement: HTMLElement, range?: Range) => { 10 | end: number; 11 | start: number; 12 | }; 13 | export declare const setSelectionByPosition: (start: number, end: number, editor: HTMLElement) => Range; 14 | export declare const setRangeByWbr: (element: HTMLElement, range: Range) => void; 15 | export declare const insertHTML: (html: string, vditor: IVditor) => void; 16 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/util/toc.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const renderToc: (vditor: IVditor) => void; 3 | export declare const clickToc: (event: MouseEvent & { 4 | target: HTMLElement; 5 | }, vditor: IVditor) => void; 6 | export declare const keydownToc: (blockElement: HTMLElement, vditor: IVditor, event: KeyboardEvent, range: Range) => boolean; 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/afterRenderEvent.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const afterRenderEvent: (vditor: IVditor, options?: { 3 | enableAddUndoStack: boolean; 4 | enableHint: boolean; 5 | enableInput: boolean; 6 | }) => void; 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/highlightToolbarWYSIWYG.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const highlightToolbarWYSIWYG: (vditor: IVditor) => void; 3 | export declare const genLinkRefPopover: (vditor: IVditor, linkRefElement: HTMLElement) => void; 4 | export declare const genAPopover: (vditor: IVditor, aElement: HTMLElement) => void; 5 | export declare const genImagePopover: (event: Event, vditor: IVditor) => void; 6 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare class WYSIWYG { 3 | range: Range; 4 | element: HTMLPreElement; 5 | popover: HTMLDivElement; 6 | selectPopover: HTMLDivElement; 7 | afterRenderTimeoutId: number; 8 | hlToolbarTimeoutId: number; 9 | preventInput: boolean; 10 | composingLock: boolean; 11 | commentIds: string[]; 12 | constructor(vditor: IVditor); 13 | getComments(vditor: IVditor, getData?: boolean): ICommentsData[]; 14 | triggerRemoveComment(vditor: IVditor): void; 15 | showComment(): void; 16 | hideComment(): void; 17 | private copy; 18 | private bindEvent; 19 | } 20 | export { WYSIWYG }; 21 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/inlineTag.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const previoueIsEmptyA: (node: Node) => false | HTMLElement; 3 | export declare const nextIsCode: (range: Range) => boolean; 4 | export declare const getNextHTML: (node: Node) => string; 5 | export declare const getPreviousHTML: (node: Node) => string; 6 | export declare const getRenderElementNextNode: (blockCodeElement: HTMLElement) => ChildNode; 7 | export declare const splitElement: (range: Range) => { 8 | afterHTML: string; 9 | beforeHTML: string; 10 | }; 11 | export declare const modifyPre: (vditor: IVditor, range: Range) => void; 12 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/input.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const input: (vditor: IVditor, range: Range, event?: InputEvent) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/processKeydown.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const processKeydown: (vditor: IVditor, event: KeyboardEvent) => boolean; 3 | export declare const removeBlockElement: (vditor: IVditor, event: KeyboardEvent) => boolean; 4 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/renderDomByMd.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const renderDomByMd: (vditor: IVditor, md: string, options?: { 3 | enableAddUndoStack: boolean; 4 | enableHint: boolean; 5 | enableInput: boolean; 6 | }) => void; 7 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/setHeading.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const setHeading: (vditor: IVditor, tagName: string) => void; 3 | export declare const removeHeading: (vditor: IVditor) => void; 4 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/showCode.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const showCode: (previewElement: HTMLElement, vditor: IVditor, first?: boolean) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/dist/ts/wysiwyg/toolbarEvent.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare const toolbarEvent: (vditor: IVditor, actionBtn: Element, event: Event) => void; 3 | -------------------------------------------------------------------------------- /public/assets/vditor/src/assets/scss/_hint.scss: -------------------------------------------------------------------------------- 1 | .vditor-hint { 2 | background-color: var(--panel-background-color); 3 | position: absolute; 4 | box-shadow: var(--panel-shadow); 5 | border-radius: 3px; 6 | padding: 5px 0; 7 | z-index: 4; 8 | line-height: 20px; 9 | list-style: none; 10 | font-size: 12px; 11 | margin: 0; 12 | max-width: 250px; 13 | min-width: 80px; 14 | display: none; 15 | 16 | .vditor-hint { 17 | margin-top: -31px; 18 | left: 100%; 19 | right: auto; 20 | 21 | &.vditor-panel--left { 22 | right: 100%; 23 | left: auto; 24 | } 25 | } 26 | 27 | button { 28 | color: var(--toolbar-icon-color); 29 | display: block; 30 | padding: 3px 10px; 31 | border: 0; 32 | border-radius: 0; 33 | line-height: 20px; 34 | width: 100%; 35 | box-sizing: border-box; 36 | text-align: left; 37 | margin: 0; 38 | background-color: transparent; 39 | cursor: pointer; 40 | white-space: nowrap; 41 | text-overflow: ellipsis; 42 | overflow: hidden; 43 | 44 | &:focus { 45 | outline: none; 46 | } 47 | } 48 | 49 | &--current, 50 | button:not(.vditor-menu--disabled):hover { 51 | background-color: var(--toolbar-background-color) !important; 52 | color: var(--toolbar-icon-hover-color) !important; 53 | } 54 | 55 | &__emoji { 56 | font-size: 16px; 57 | float: left; 58 | margin-right: 3px; 59 | } 60 | 61 | img { 62 | height: 20px; 63 | width: 20px; 64 | float: left; 65 | margin-right: 3px; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/abcRender.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {addScript} from "../util/addScript"; 3 | import {abcRenderAdapter} from "./adapterRender"; 4 | 5 | declare const ABCJS: { 6 | renderAbc(element: HTMLElement, text: string): void; 7 | }; 8 | 9 | export const abcRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN) => { 10 | const abcElements = abcRenderAdapter.getElements(element); 11 | if (abcElements.length > 0) { 12 | addScript(`${cdn}/dist/js/abcjs/abcjs_basic.min.js`, "vditorAbcjsScript").then(() => { 13 | abcElements.forEach((item: HTMLDivElement) => { 14 | if (item.parentElement.classList.contains("vditor-wysiwyg__pre") || 15 | item.parentElement.classList.contains("vditor-ir__marker--pre")) { 16 | return; 17 | } 18 | if (item.getAttribute("data-processed") === "true") { 19 | return; 20 | } 21 | ABCJS.renderAbc(item, abcRenderAdapter.getCode(item).trim()); 22 | item.style.overflowX = "auto"; 23 | item.setAttribute("data-processed", "true"); 24 | }); 25 | }); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/adapterRender.ts: -------------------------------------------------------------------------------- 1 | export const mathRenderAdapter = { 2 | getCode: (mathElement: Element) => mathElement.textContent, 3 | getElements: (element: HTMLElement) => element.querySelectorAll(".language-math"), 4 | }; 5 | export const mermaidRenderAdapter = { 6 | /** 不仅要返回code,并且需要将 code 设置为 el 的 innerHTML */ 7 | getCode: (el: Element) => el.textContent, 8 | getElements: (element: HTMLElement) => element.querySelectorAll(".language-mermaid"), 9 | }; 10 | export const mindmapRenderAdapter = { 11 | getCode: (el: Element) => el.getAttribute("data-code"), 12 | getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-mindmap"), 13 | }; 14 | export const chartRenderAdapter = { 15 | getCode: (el: HTMLElement) => el.innerText, 16 | getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-echarts"), 17 | }; 18 | export const abcRenderAdapter = { 19 | getCode: (el: Element) => el.textContent, 20 | getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-abc"), 21 | }; 22 | export const graphvizRenderAdapter = { 23 | getCode: (el: Element) => el.textContent, 24 | getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-graphviz"), 25 | }; 26 | export const flowchartRenderAdapter = { 27 | getCode: (el: Element) => el.textContent, 28 | getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-flowchart"), 29 | }; 30 | export const plantumlRenderAdapter = { 31 | getCode: (el: Element) => el.textContent, 32 | getElements: (el: HTMLElement | Document) => el.querySelectorAll(".language-plantuml"), 33 | }; 34 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/anchorRender.ts: -------------------------------------------------------------------------------- 1 | export const anchorRender = (type: number) => { 2 | document.querySelectorAll(".vditor-anchor").forEach((anchor: HTMLLinkElement) => { 3 | if (type === 1) { 4 | anchor.classList.add("vditor-anchor--left"); 5 | } 6 | anchor.onclick = () => { 7 | const id = anchor.getAttribute("href").substr(1); 8 | const top = document.getElementById("vditorAnchor-" + id).offsetTop; 9 | document.querySelector("html").scrollTop = top; 10 | }; 11 | }); 12 | 13 | window.onhashchange = () => { 14 | const element = document.getElementById("vditorAnchor-" + decodeURIComponent(window.location.hash.substr(1))); 15 | if (element) { 16 | document.querySelector("html").scrollTop = element.offsetTop; 17 | } 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/chartRender.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {addScript} from "../util/addScript"; 3 | import {chartRenderAdapter} from "./adapterRender"; 4 | 5 | declare const echarts: { 6 | init(element: HTMLElement, theme?: string): IEChart; 7 | }; 8 | 9 | export const chartRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN, theme: string) => { 10 | const echartsElements = chartRenderAdapter.getElements(element); 11 | if (echartsElements.length > 0) { 12 | addScript(`${cdn}/dist/js/echarts/echarts.min.js`, "vditorEchartsScript").then(() => { 13 | echartsElements.forEach((e: HTMLDivElement) => { 14 | if (e.parentElement.classList.contains("vditor-wysiwyg__pre") || 15 | e.parentElement.classList.contains("vditor-ir__marker--pre")) { 16 | return; 17 | } 18 | 19 | const text = chartRenderAdapter.getCode(e).trim(); 20 | if (!text) { 21 | return; 22 | } 23 | try { 24 | if (e.getAttribute("data-processed") === "true") { 25 | return; 26 | } 27 | const option = JSON.parse(text); 28 | echarts.init(e, theme === "dark" ? "dark" : undefined).setOption(option); 29 | e.setAttribute("data-processed", "true"); 30 | } catch (error) { 31 | e.className = "vditor-reset--error"; 32 | e.innerHTML = `echarts render error:
${error}`; 33 | } 34 | }); 35 | }); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/flowchartRender.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {addScript} from "../util/addScript"; 3 | import {flowchartRenderAdapter} from "./adapterRender"; 4 | 5 | declare const flowchart: { 6 | parse(text: string): { drawSVG: (type: HTMLElement) => void }; 7 | }; 8 | 9 | export const flowchartRender = (element: HTMLElement, cdn = Constants.CDN) => { 10 | const flowchartElements = flowchartRenderAdapter.getElements(element); 11 | if (flowchartElements.length === 0) { 12 | return; 13 | } 14 | addScript(`${cdn}/dist/js/flowchart.js/flowchart.min.js`, "vditorFlowchartScript").then(() => { 15 | flowchartElements.forEach((item: HTMLElement) => { 16 | if (item.getAttribute("data-processed") === "true") { 17 | return; 18 | } 19 | const flowchartObj = flowchart.parse(flowchartRenderAdapter.getCode(item)); 20 | item.innerHTML = ""; 21 | flowchartObj.drawSVG(item); 22 | item.setAttribute("data-processed", "true"); 23 | }); 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/getHTML.ts: -------------------------------------------------------------------------------- 1 | import {getMarkdown} from "./getMarkdown"; 2 | 3 | export const getHTML = (vditor: IVditor) => { 4 | if (vditor.currentMode === "sv") { 5 | return vditor.lute.Md2HTML(getMarkdown(vditor)); 6 | } else if (vditor.currentMode === "wysiwyg") { 7 | return vditor.lute.VditorDOM2HTML(vditor.wysiwyg.element.innerHTML); 8 | } else if (vditor.currentMode === "ir") { 9 | return vditor.lute.VditorIRDOM2HTML(vditor.ir.element.innerHTML); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/getMarkdown.ts: -------------------------------------------------------------------------------- 1 | import {code160to32} from "../util/code160to32"; 2 | 3 | export const getMarkdown = (vditor: IVditor) => { 4 | if (vditor.currentMode === "sv") { 5 | return code160to32(`${vditor.sv.element.textContent}\n`.replace(/\n\n$/, "\n")); 6 | } else if (vditor.currentMode === "wysiwyg") { 7 | return vditor.lute.VditorDOM2Md(vditor.wysiwyg.element.innerHTML); 8 | } else if (vditor.currentMode === "ir") { 9 | return vditor.lute.VditorIRDOM2Md(vditor.ir.element.innerHTML); 10 | } 11 | return ""; 12 | }; 13 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/plantumlRender.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {addScript} from "../util/addScript"; 3 | import {plantumlRenderAdapter} from "./adapterRender"; 4 | 5 | declare const plantumlEncoder: { 6 | encode(options: string): string, 7 | }; 8 | 9 | export const plantumlRender = (element: (HTMLElement | Document) = document, cdn = Constants.CDN) => { 10 | const plantumlElements = plantumlRenderAdapter.getElements(element); 11 | if (plantumlElements.length === 0) { 12 | return; 13 | } 14 | addScript(`${cdn}/dist/js/plantuml/plantuml-encoder.min.js`, "vditorPlantumlScript").then(() => { 15 | plantumlElements.forEach((e: HTMLDivElement) => { 16 | if (e.parentElement.classList.contains("vditor-wysiwyg__pre") || 17 | e.parentElement.classList.contains("vditor-ir__marker--pre")) { 18 | return; 19 | } 20 | const text = plantumlRenderAdapter.getCode(e).trim(); 21 | if (!text) { 22 | return; 23 | } 24 | try { 25 | e.innerHTML = ``; 26 | } catch (error) { 27 | e.className = "vditor-reset--error"; 28 | e.innerHTML = `plantuml render error:
${error}`; 29 | } 30 | }); 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/markdown/setLute.ts: -------------------------------------------------------------------------------- 1 | export const setLute = (options: ILuteOptions) => { 2 | const lute: Lute = Lute.New(); 3 | lute.PutEmojis(options.emojis); 4 | lute.SetEmojiSite(options.emojiSite); 5 | lute.SetHeadingAnchor(options.headingAnchor); 6 | lute.SetInlineMathAllowDigitAfterOpenMarker(options.inlineMathDigit); 7 | lute.SetAutoSpace(options.autoSpace); 8 | lute.SetToC(options.toc); 9 | lute.SetFootnotes(options.footnotes); 10 | lute.SetFixTermTypo(options.fixTermTypo); 11 | lute.SetVditorCodeBlockPreview(options.codeBlockPreview); 12 | lute.SetVditorMathBlockPreview(options.mathBlockPreview); 13 | lute.SetSanitize(options.sanitize); 14 | lute.SetChineseParagraphBeginningSpace(options.paragraphBeginningSpace); 15 | lute.SetRenderListStyle(options.listStyle); 16 | lute.SetLinkBase(options.linkBase); 17 | lute.SetLinkPrefix(options.linkPrefix); 18 | lute.SetMark(options.mark); 19 | if (options.lazyLoadImage) { 20 | lute.SetImageLazyLoading(options.lazyLoadImage); 21 | } 22 | return lute; 23 | }; 24 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/outline/index.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {outlineRender} from "../markdown/outlineRender"; 3 | import {setPadding} from "../ui/initUI"; 4 | import {setSelectionFocus} from "../util/selection"; 5 | 6 | export class Outline { 7 | public element: HTMLElement; 8 | 9 | constructor(outlineLabel: string) { 10 | this.element = document.createElement("div"); 11 | this.element.className = "vditor-outline"; 12 | this.element.innerHTML = `
${outlineLabel}
13 |
`; 14 | } 15 | 16 | public render(vditor: IVditor) { 17 | let html = ""; 18 | if (vditor.preview.element.style.display === "block") { 19 | html = outlineRender(vditor.preview.element.lastElementChild as HTMLElement, 20 | this.element.lastElementChild, vditor); 21 | } else { 22 | html = outlineRender(vditor[vditor.currentMode].element, this.element.lastElementChild, vditor); 23 | } 24 | return html; 25 | } 26 | 27 | public toggle(vditor: IVditor, show = true) { 28 | const btnElement = vditor.toolbar.elements.outline?.firstElementChild; 29 | if (show && window.innerWidth >= Constants.MOBILE_WIDTH) { 30 | this.element.style.display = "block"; 31 | this.render(vditor); 32 | btnElement?.classList.add("vditor-menu--current"); 33 | } else { 34 | this.element.style.display = "none"; 35 | btnElement?.classList.remove("vditor-menu--current"); 36 | } 37 | if (getSelection().rangeCount > 0) { 38 | const range = getSelection().getRangeAt(0); 39 | if (vditor[vditor.currentMode].element.contains(range.startContainer)) { 40 | setSelectionFocus(range); 41 | } else { 42 | vditor[vditor.currentMode].element.focus(); 43 | } 44 | } 45 | setPadding(vditor); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/tip/index.ts: -------------------------------------------------------------------------------- 1 | export class Tip { 2 | public element: HTMLElement; 3 | 4 | constructor() { 5 | this.element = document.createElement("div"); 6 | this.element.className = "vditor-tip"; 7 | } 8 | 9 | public show(text: string, time: number = 6000) { 10 | this.element.className = "vditor-tip vditor-tip--show"; 11 | 12 | if (time === 0) { 13 | this.element.innerHTML = `
${text} 14 |
X
`; 15 | this.element.querySelector(".vditor-tip__close").addEventListener("click", () => { 16 | this.hide(); 17 | }); 18 | return; 19 | } 20 | 21 | this.element.innerHTML = `
${text}
`; 22 | setTimeout(() => { 23 | this.hide(); 24 | }, time); 25 | } 26 | 27 | public hide() { 28 | this.element.className = "vditor-messageElementtip"; 29 | this.element.innerHTML = ""; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Both.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {setPreviewMode} from "../ui/setPreviewMode"; 3 | import {getEventName} from "../util/compatibility"; 4 | import {MenuItem} from "./MenuItem"; 5 | 6 | export class Both extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | if (vditor.options.preview.mode === "both") { 10 | this.element.children[0].classList.add("vditor-menu--current"); 11 | } 12 | this.element.children[0].addEventListener(getEventName(), (event) => { 13 | const btnElement = this.element.firstElementChild; 14 | if (btnElement.classList.contains(Constants.CLASS_MENU_DISABLED)) { 15 | return; 16 | } 17 | event.preventDefault(); 18 | if (vditor.currentMode !== "sv") { 19 | return; 20 | } 21 | if (vditor.options.preview.mode === "both") { 22 | setPreviewMode("editor", vditor); 23 | } else { 24 | setPreviewMode("both", vditor); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Br.ts: -------------------------------------------------------------------------------- 1 | export class Br { 2 | public element: HTMLElement; 3 | 4 | constructor() { 5 | this.element = document.createElement("div"); 6 | this.element.className = "vditor-toolbar__br"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/CodeTheme.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {setCodeTheme} from "../ui/setCodeTheme"; 3 | import {getEventName} from "../util/compatibility"; 4 | import {MenuItem} from "./MenuItem"; 5 | import {hidePanel, toggleSubMenu} from "./setToolbar"; 6 | 7 | export class CodeTheme extends MenuItem { 8 | public element: HTMLElement; 9 | 10 | constructor(vditor: IVditor, menuItem: IMenuItem) { 11 | super(vditor, menuItem); 12 | 13 | const actionBtn = this.element.children[0] as HTMLElement; 14 | 15 | const panelElement = document.createElement("div"); 16 | panelElement.className = `vditor-hint${menuItem.level === 2 ? "" : " vditor-panel--arrow"}`; 17 | let innerHTML = ""; 18 | Constants.CODE_THEME.forEach((theme) => { 19 | innerHTML += ``; 20 | }); 21 | panelElement.innerHTML = 22 | `
${innerHTML}
`; 23 | panelElement.addEventListener(getEventName(), (event: MouseEvent & { target: HTMLElement }) => { 24 | if (event.target.tagName === "BUTTON") { 25 | hidePanel(vditor, ["subToolbar"]); 26 | vditor.options.preview.hljs.style = event.target.textContent; 27 | setCodeTheme(event.target.textContent, vditor.options.cdn); 28 | event.preventDefault(); 29 | event.stopPropagation(); 30 | } 31 | }); 32 | this.element.appendChild(panelElement); 33 | 34 | toggleSubMenu(vditor, panelElement, actionBtn, menuItem.level); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/ContentTheme.ts: -------------------------------------------------------------------------------- 1 | import {setContentTheme} from "../ui/setContentTheme"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | import {hidePanel, toggleSubMenu} from "./setToolbar"; 5 | 6 | export class ContentTheme extends MenuItem { 7 | public element: HTMLElement; 8 | 9 | constructor(vditor: IVditor, menuItem: IMenuItem) { 10 | super(vditor, menuItem); 11 | 12 | const actionBtn = this.element.children[0] as HTMLElement; 13 | 14 | const panelElement = document.createElement("div"); 15 | panelElement.className = `vditor-hint${menuItem.level === 2 ? "" : " vditor-panel--arrow"}`; 16 | let innerHTML = ""; 17 | Object.keys(vditor.options.preview.theme.list).forEach((key) => { 18 | innerHTML += ``; 19 | }); 20 | panelElement.innerHTML = 21 | `
${innerHTML}
`; 22 | panelElement.addEventListener(getEventName(), (event: MouseEvent & { target: HTMLElement }) => { 23 | if (event.target.tagName === "BUTTON") { 24 | hidePanel(vditor, ["subToolbar"]); 25 | vditor.options.preview.theme.current = event.target.getAttribute("data-type"); 26 | setContentTheme(vditor.options.preview.theme.current, vditor.options.preview.theme.path); 27 | event.preventDefault(); 28 | event.stopPropagation(); 29 | } 30 | }); 31 | this.element.appendChild(panelElement); 32 | 33 | toggleSubMenu(vditor, panelElement, actionBtn, menuItem.level); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Counter.ts: -------------------------------------------------------------------------------- 1 | export class Counter { 2 | public element: HTMLElement; 3 | 4 | constructor(vditor: IVditor) { 5 | this.element = document.createElement("span"); 6 | this.element.className = "vditor-counter vditor-tooltipped vditor-tooltipped__nw"; 7 | 8 | this.render(vditor, ""); 9 | 10 | } 11 | 12 | public render(vditor: IVditor, mdText: string) { 13 | let length = mdText.endsWith("\n") ? mdText.length - 1 : mdText.length; 14 | if (vditor.options.counter.type === "text" && vditor[vditor.currentMode]) { 15 | const tempElement = vditor[vditor.currentMode].element.cloneNode(true) as HTMLElement; 16 | tempElement.querySelectorAll(".vditor-wysiwyg__preview").forEach((item) => { 17 | item.remove(); 18 | }); 19 | length = tempElement.textContent.length; 20 | } 21 | if (typeof vditor.options.counter.max === "number") { 22 | if (length > vditor.options.counter.max) { 23 | this.element.className = "vditor-counter vditor-counter--error"; 24 | } else { 25 | this.element.className = "vditor-counter"; 26 | } 27 | this.element.innerHTML = `${length}/${vditor.options.counter.max}`; 28 | } else { 29 | this.element.innerHTML = `${length}`; 30 | } 31 | this.element.setAttribute("aria-label", vditor.options.counter.type); 32 | if (vditor.options.counter.after) { 33 | vditor.options.counter.after(length, { 34 | enable: vditor.options.counter.enable, 35 | max: vditor.options.counter.max, 36 | type: vditor.options.counter.type, 37 | }); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Custom.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | 5 | export class Custom extends MenuItem { 6 | constructor(vditor: IVditor, menuItem: IMenuItem) { 7 | super(vditor, menuItem); 8 | this.element.children[0].innerHTML = menuItem.icon; 9 | this.element.children[0].addEventListener(getEventName(), (event: Event & { currentTarget: HTMLElement }) => { 10 | event.preventDefault(); 11 | if (event.currentTarget.classList.contains(Constants.CLASS_MENU_DISABLED)) { 12 | return; 13 | } 14 | menuItem.click(event, vditor); 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Devtools.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {setPadding} from "../ui/initUI"; 3 | import {getEventName} from "../util/compatibility"; 4 | import {MenuItem} from "./MenuItem"; 5 | 6 | export class Devtools extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | this.element.firstElementChild.addEventListener(getEventName(), (event) => { 10 | const btnElement = this.element.firstElementChild; 11 | if (btnElement.classList.contains(Constants.CLASS_MENU_DISABLED)) { 12 | return; 13 | } 14 | 15 | event.preventDefault(); 16 | if (btnElement.classList.contains("vditor-menu--current")) { 17 | btnElement.classList.remove("vditor-menu--current"); 18 | vditor.devtools.element.style.display = "none"; 19 | setPadding(vditor); 20 | } else { 21 | btnElement.classList.add("vditor-menu--current"); 22 | vditor.devtools.element.style.display = "block"; 23 | setPadding(vditor); 24 | vditor.devtools.renderEchart(vditor); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Divider.ts: -------------------------------------------------------------------------------- 1 | export class Divider { 2 | public element: HTMLElement; 3 | 4 | constructor() { 5 | this.element = document.createElement("div"); 6 | this.element.className = "vditor-toolbar__divider"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Export.ts: -------------------------------------------------------------------------------- 1 | import {exportHTML, exportMarkdown, exportPDF} from "../export"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | import {hidePanel, toggleSubMenu} from "./setToolbar"; 5 | 6 | export class Export extends MenuItem { 7 | public element: HTMLElement; 8 | 9 | constructor(vditor: IVditor, menuItem: IMenuItem) { 10 | super(vditor, menuItem); 11 | const actionBtn = this.element.children[0] as HTMLElement; 12 | const panelElement = document.createElement("div"); 13 | panelElement.className = `vditor-hint${menuItem.level === 2 ? "" : " vditor-panel--arrow"}`; 14 | panelElement.innerHTML = ` 15 | 16 | `; 17 | panelElement.addEventListener(getEventName(), (event: MouseEvent & { target: HTMLElement }) => { 18 | const btnElement = event.target; 19 | if (btnElement.tagName === "BUTTON") { 20 | switch (btnElement.getAttribute("data-type")) { 21 | case "markdown": 22 | exportMarkdown(vditor); 23 | break; 24 | case "pdf": 25 | exportPDF(vditor); 26 | break; 27 | case "html": 28 | exportHTML(vditor); 29 | break; 30 | default: 31 | break; 32 | } 33 | hidePanel(vditor, ["subToolbar"]); 34 | event.preventDefault(); 35 | event.stopPropagation(); 36 | } 37 | }); 38 | this.element.appendChild(panelElement); 39 | toggleSubMenu(vditor, panelElement, actionBtn, menuItem.level); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Help.ts: -------------------------------------------------------------------------------- 1 | import {getEventName} from "../util/compatibility"; 2 | import {MenuItem} from "./MenuItem"; 3 | 4 | export class Help extends MenuItem { 5 | constructor(vditor: IVditor, menuItem: IMenuItem) { 6 | super(vditor, menuItem); 7 | this.element.children[0].addEventListener(getEventName(), (event) => { 8 | event.preventDefault(); 9 | vditor.tip.show(`
10 |
11 |
Markdown 使用指南
12 | 18 |
19 |
20 |
Vditor 支持
21 | 27 |
`, 0); 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Indent.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {listIndent} from "../util/fixBrowserBehavior"; 4 | import {hasClosestByMatchTag} from "../util/hasClosest"; 5 | import {getEditorRange} from "../util/selection"; 6 | import {MenuItem} from "./MenuItem"; 7 | 8 | export class Indent extends MenuItem { 9 | constructor(vditor: IVditor, menuItem: IMenuItem) { 10 | super(vditor, menuItem); 11 | 12 | this.element.children[0].addEventListener(getEventName(), (event) => { 13 | event.preventDefault(); 14 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED) || 15 | vditor.currentMode === "sv") { 16 | return; 17 | } 18 | const range = getEditorRange(vditor); 19 | const liElement = hasClosestByMatchTag(range.startContainer, "LI"); 20 | if (liElement) { 21 | listIndent(vditor, liElement, range); 22 | } 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Info.ts: -------------------------------------------------------------------------------- 1 | import {VDITOR_VERSION} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | 5 | export class Info extends MenuItem { 6 | constructor(vditor: IVditor, menuItem: IMenuItem) { 7 | super(vditor, menuItem); 8 | this.element.children[0].addEventListener(getEventName(), (event) => { 9 | event.preventDefault(); 10 | vditor.tip.show(`
11 |

12 | 下一代的 Markdown 编辑器,为未来而构建 13 |

14 |
15 | 16 |
  
17 |
18 | Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。 19 | 它使用 TypeScript 实现,支持原生 JavaScript、Vue、React、Angular,提供桌面版。 20 |
21 |
22 |
23 |
    24 |
  • 25 | 项目地址:b3log.org/vditor 26 |
  • 27 |
  • 28 | 开源协议:MIT 29 |
  • 30 |
31 |
    32 |
  • 33 | 组件版本:Vditor v${VDITOR_VERSION} / Lute v${Lute.Version} 34 |
  • 35 |
  • 36 | 赞助捐赠:https://ld246.com/sponsor 37 |
  • 38 |
39 |
40 |
`, 0); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/InsertAfter.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {insertEmptyBlock} from "../util/fixBrowserBehavior"; 4 | import {MenuItem} from "./MenuItem"; 5 | 6 | export class InsertAfter extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | this.element.children[0].addEventListener(getEventName(), (event) => { 10 | event.preventDefault(); 11 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED) || 12 | vditor.currentMode === "sv") { 13 | return; 14 | } 15 | insertEmptyBlock(vditor, "afterend"); 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/InsertBefore.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {insertEmptyBlock} from "../util/fixBrowserBehavior"; 4 | import {MenuItem} from "./MenuItem"; 5 | 6 | export class InsertBefore extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | this.element.children[0].addEventListener(getEventName(), (event) => { 10 | event.preventDefault(); 11 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED) || 12 | vditor.currentMode === "sv") { 13 | return; 14 | } 15 | insertEmptyBlock(vditor, "beforebegin"); 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Outdent.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import { listOutdent} from "../util/fixBrowserBehavior"; 4 | import {hasClosestByMatchTag} from "../util/hasClosest"; 5 | import {getEditorRange} from "../util/selection"; 6 | import {MenuItem} from "./MenuItem"; 7 | 8 | export class Outdent extends MenuItem { 9 | constructor(vditor: IVditor, menuItem: IMenuItem) { 10 | super(vditor, menuItem); 11 | this.element.children[0].addEventListener(getEventName(), (event) => { 12 | event.preventDefault(); 13 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED) || 14 | vditor.currentMode === "sv") { 15 | return; 16 | } 17 | const range = getEditorRange(vditor); 18 | const liElement = hasClosestByMatchTag(range.startContainer, "LI"); 19 | if (liElement) { 20 | listOutdent(vditor, liElement, range, liElement.parentElement); 21 | } 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Outline.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | 5 | export class Outline extends MenuItem { 6 | constructor(vditor: IVditor, menuItem: IMenuItem) { 7 | super(vditor, menuItem); 8 | if (vditor.options.outline) { 9 | this.element.firstElementChild.classList.add("vditor-menu--current"); 10 | } 11 | this.element.children[0].addEventListener(getEventName(), (event) => { 12 | event.preventDefault(); 13 | const btnElement = vditor.toolbar.elements.outline.firstElementChild; 14 | if (btnElement.classList.contains(Constants.CLASS_MENU_DISABLED)) { 15 | return; 16 | } 17 | vditor.options.outline.enable = !this.element.firstElementChild.classList.contains("vditor-menu--current"); 18 | vditor.outline.toggle(vditor, vditor.options.outline.enable); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Redo.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | import {disableToolbar} from "./setToolbar"; 5 | 6 | export class Redo extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | disableToolbar({redo: this.element}, ["redo"]); 10 | this.element.children[0].addEventListener(getEventName(), (event) => { 11 | event.preventDefault(); 12 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED)) { 13 | return; 14 | } 15 | vditor.undo.redo(vditor); 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Undo.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {getEventName} from "../util/compatibility"; 3 | import {MenuItem} from "./MenuItem"; 4 | import {disableToolbar} from "./setToolbar"; 5 | 6 | export class Undo extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | disableToolbar({undo: this.element}, ["undo"]); 10 | this.element.children[0].addEventListener(getEventName(), (event) => { 11 | event.preventDefault(); 12 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED)) { 13 | return; 14 | } 15 | vditor.undo.undo(vditor); 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/toolbar/Upload.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {uploadFiles} from "../upload"; 3 | import {getEventName} from "../util/compatibility"; 4 | import {MenuItem} from "./MenuItem"; 5 | 6 | export class Upload extends MenuItem { 7 | constructor(vditor: IVditor, menuItem: IMenuItem) { 8 | super(vditor, menuItem); 9 | let inputHTML = '')}${inputHTML}>`; 17 | this._bindEvent(vditor); 18 | } 19 | 20 | public _bindEvent(vditor: IVditor) { 21 | this.element.children[0].addEventListener(getEventName(), (event) => { 22 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED)) { 23 | event.stopPropagation(); 24 | event.preventDefault(); 25 | return; 26 | } 27 | }); 28 | this.element.querySelector("input").addEventListener("change", 29 | (event: InputEvent & { target: HTMLInputElement }) => { 30 | if (this.element.firstElementChild.classList.contains(Constants.CLASS_MENU_DISABLED)) { 31 | event.stopPropagation(); 32 | event.preventDefault(); 33 | return; 34 | } 35 | if (event.target.files.length === 0) { 36 | return; 37 | } 38 | uploadFiles(vditor, event.target.files, event.target); 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/ui/setCodeTheme.ts: -------------------------------------------------------------------------------- 1 | import {Constants} from "../constants"; 2 | import {addStyle} from "../util/addStyle"; 3 | 4 | export const setCodeTheme = (codeTheme: string, cdn = Constants.CDN) => { 5 | if (!Constants.CODE_THEME.includes(codeTheme)) { 6 | codeTheme = "github"; 7 | } 8 | const vditorHljsStyle = document.getElementById("vditorHljsStyle") as HTMLLinkElement; 9 | const href = `${cdn}/dist/js/highlight.js/styles/${codeTheme}.css`; 10 | if (!vditorHljsStyle) { 11 | addStyle(href, "vditorHljsStyle"); 12 | } else if (vditorHljsStyle.href !== href) { 13 | vditorHljsStyle.remove(); 14 | addStyle(href, "vditorHljsStyle"); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/ui/setContentTheme.ts: -------------------------------------------------------------------------------- 1 | import {addStyle} from "../util/addStyle"; 2 | 3 | export const setContentTheme = (contentTheme: string, path: string) => { 4 | if (!contentTheme || !path) { 5 | return; 6 | } 7 | const vditorContentTheme = document.getElementById("vditorContentTheme") as HTMLLinkElement; 8 | const cssPath = `${path}/${contentTheme}.css`; 9 | if (!vditorContentTheme) { 10 | addStyle(cssPath, "vditorContentTheme"); 11 | } else if (vditorContentTheme.href !== cssPath) { 12 | vditorContentTheme.remove(); 13 | addStyle(cssPath, "vditorContentTheme"); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/ui/setPreviewMode.ts: -------------------------------------------------------------------------------- 1 | import {removeCurrentToolbar} from "../toolbar/setToolbar"; 2 | import {setCurrentToolbar} from "../toolbar/setToolbar"; 3 | 4 | export const setPreviewMode = (mode: "both" | "editor", vditor: IVditor) => { 5 | if (vditor.options.preview.mode === mode) { 6 | return; 7 | } 8 | vditor.options.preview.mode = mode; 9 | 10 | switch (mode) { 11 | case "both": 12 | vditor.sv.element.style.display = "block"; 13 | vditor.preview.element.style.display = "block"; 14 | vditor.preview.render(vditor); 15 | 16 | setCurrentToolbar(vditor.toolbar.elements, ["both"]); 17 | break; 18 | case "editor": 19 | vditor.sv.element.style.display = "block"; 20 | vditor.preview.element.style.display = "none"; 21 | 22 | removeCurrentToolbar(vditor.toolbar.elements, ["both"]); 23 | break; 24 | default: 25 | break; 26 | } 27 | 28 | if (vditor.devtools) { 29 | vditor.devtools.renderEchart(vditor); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/ui/setTheme.ts: -------------------------------------------------------------------------------- 1 | export const setTheme = (vditor: IVditor) => { 2 | if (vditor.options.theme === "dark") { 3 | vditor.element.classList.add("vditor--dark"); 4 | } else { 5 | vditor.element.classList.remove("vditor--dark"); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/upload/getElement.ts: -------------------------------------------------------------------------------- 1 | export const getElement = (vditor: IVditor) => { 2 | switch (vditor.currentMode) { 3 | case "ir": 4 | return vditor.ir.element; 5 | case "wysiwyg": 6 | return vditor.wysiwyg.element; 7 | case "sv": 8 | return vditor.sv.element; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/upload/setHeaders.ts: -------------------------------------------------------------------------------- 1 | export const setHeaders = (vditor: IVditor, xhr: XMLHttpRequest) => { 2 | if (vditor.options.upload.setHeaders) { 3 | vditor.options.upload.headers = vditor.options.upload.setHeaders(); 4 | } 5 | if (vditor.options.upload.headers) { 6 | Object.keys(vditor.options.upload.headers).forEach((key) => { 7 | xhr.setRequestHeader(key, vditor.options.upload.headers[key]); 8 | }); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/addScript.ts: -------------------------------------------------------------------------------- 1 | export const addScriptSync = (path: string, id: string) => { 2 | if (document.getElementById(id)) { 3 | return false; 4 | } 5 | const xhrObj = new XMLHttpRequest(); 6 | xhrObj.open("GET", path, false); 7 | xhrObj.setRequestHeader("Accept", 8 | "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"); 9 | xhrObj.send(""); 10 | const scriptElement = document.createElement("script"); 11 | scriptElement.type = "text/javascript"; 12 | scriptElement.text = xhrObj.responseText; 13 | scriptElement.id = id; 14 | document.head.appendChild(scriptElement); 15 | }; 16 | 17 | export const addScript = (path: string, id: string) => { 18 | return new Promise((resolve, reject) => { 19 | if (document.getElementById(id)) { 20 | // 脚本加载后再次调用直接返回 21 | resolve(); 22 | return false; 23 | } 24 | const scriptElement = document.createElement("script"); 25 | scriptElement.src = path; 26 | scriptElement.async = true; 27 | // 循环调用时 Chrome 不会重复请求 js 28 | document.head.appendChild(scriptElement); 29 | scriptElement.onload = () => { 30 | if (document.getElementById(id)) { 31 | // 循环调用需清除 DOM 中的 script 标签 32 | scriptElement.remove(); 33 | resolve(); 34 | return false; 35 | } 36 | scriptElement.id = id; 37 | resolve(); 38 | }; 39 | }); 40 | }; 41 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/addStyle.ts: -------------------------------------------------------------------------------- 1 | export const addStyle = (url: string, id: string) => { 2 | if (!document.getElementById(id)) { 3 | const styleElement = document.createElement("link"); 4 | styleElement.id = id; 5 | styleElement.rel = "stylesheet"; 6 | styleElement.type = "text/css"; 7 | styleElement.href = url; 8 | document.getElementsByTagName("head")[0].appendChild(styleElement); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/code160to32.ts: -------------------------------------------------------------------------------- 1 | export const code160to32 = (text: string) => { 2 | // 非打断空格转换为空格 3 | return text.replace(/\u00a0/g, " "); 4 | }; 5 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/getSelectText.ts: -------------------------------------------------------------------------------- 1 | import {selectIsEditor} from "./selection"; 2 | 3 | export const getSelectText = (editor: HTMLElement, range?: Range) => { 4 | if (selectIsEditor(editor, range)) { 5 | return getSelection().toString(); 6 | } 7 | return ""; 8 | }; 9 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/hasClosestByHeadings.ts: -------------------------------------------------------------------------------- 1 | // NOTE: 减少 method.ts 打包,故从 hasClosest.ts 中拆分 2 | export const hasClosestByTag = (element: Node, nodeName: string) => { 3 | if (!element) { 4 | return false; 5 | } 6 | if (element.nodeType === 3) { 7 | element = element.parentElement; 8 | } 9 | let e = element as HTMLElement; 10 | let isClosest = false; 11 | while (e && !isClosest && !e.classList.contains("vditor-reset")) { 12 | if (e.nodeName.indexOf(nodeName) === 0) { 13 | isClosest = true; 14 | } else { 15 | e = e.parentElement; 16 | } 17 | } 18 | return isClosest && e; 19 | }; 20 | 21 | export const hasClosestByHeadings = (element: Node) => { 22 | const headingElement = hasClosestByTag(element, "H"); 23 | if (headingElement && headingElement.tagName.length === 2 && headingElement.tagName !== "HR") { 24 | return headingElement; 25 | } 26 | return false; 27 | }; 28 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/highlightToolbar.ts: -------------------------------------------------------------------------------- 1 | import {highlightToolbarIR} from "../ir/highlightToolbarIR"; 2 | import {highlightToolbarWYSIWYG} from "../wysiwyg/highlightToolbarWYSIWYG"; 3 | 4 | export const highlightToolbar = (vditor: IVditor) => { 5 | if (vditor.currentMode === "wysiwyg") { 6 | highlightToolbarWYSIWYG(vditor); 7 | } else if (vditor.currentMode === "ir") { 8 | highlightToolbarIR(vditor); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/hotKey.ts: -------------------------------------------------------------------------------- 1 | import {isCtrl, isFirefox} from "./compatibility"; 2 | 3 | // 是否匹配 ⇧⌘[] / ⌘[] / ⌥[] / ⌥⌘[] / ⇧Tab / [] 4 | export const matchHotKey = (hotKey: string, event: KeyboardEvent) => { 5 | if (hotKey === "") { 6 | return false; 7 | } 8 | 9 | // [] 10 | if (hotKey.indexOf("⇧") === -1 && hotKey.indexOf("⌘") === -1 && hotKey.indexOf("⌥") === -1) { 11 | if (!isCtrl(event) && !event.altKey && !event.shiftKey && event.code === hotKey) { 12 | return true; 13 | } 14 | return false; 15 | } 16 | 17 | // 是否匹配 ⇧Tab 18 | if (hotKey === "⇧Tab") { 19 | if (!isCtrl(event) && !event.altKey && event.shiftKey && event.code === "Tab") { 20 | return true; 21 | } 22 | return false; 23 | } 24 | 25 | let hotKeys = hotKey.split(""); 26 | if (hotKey.startsWith("⌥")) { 27 | // 是否匹配 ⌥[] / ⌥⌘[] 28 | const keyCode = hotKeys.length === 3 ? hotKeys[2] : hotKeys[1]; 29 | if ((hotKeys.length === 3 ? isCtrl(event) : !isCtrl(event)) && event.altKey && !event.shiftKey && 30 | event.code === (/^[0-9]$/.test(keyCode) ? "Digit" : "Key") + keyCode) { 31 | return true; 32 | } 33 | return false; 34 | } 35 | 36 | // 是否匹配 ⇧⌘[] / ⌘[] 37 | if (hotKey === "⌘Enter") { 38 | hotKeys = ["⌘", "Enter"]; 39 | } 40 | const hasShift = hotKeys.length > 2 && (hotKeys[0] === "⇧"); 41 | let key = (hasShift ? hotKeys[2] : hotKeys[1]); 42 | if (hasShift && (isFirefox() || !/Mac/.test(navigator.platform))) { 43 | if (key === "-") { 44 | key = "_"; 45 | } else if (key === "=") { 46 | key = "+"; 47 | } 48 | } 49 | if (isCtrl(event) && event.key.toLowerCase() === key.toLowerCase() && !event.altKey 50 | && ((!hasShift && !event.shiftKey) || (hasShift && event.shiftKey))) { 51 | return true; 52 | } 53 | return false; 54 | }; 55 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/log.ts: -------------------------------------------------------------------------------- 1 | export const log = (method: string, content: string, type: string, print: boolean) => { 2 | if (print) { 3 | // @ts-ignore 4 | console.log(`${method} - ${type}: ${content}`); 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/util/merge.ts: -------------------------------------------------------------------------------- 1 | export const merge = (...options: any[]) => { 2 | const target: any = {}; 3 | const merger = (obj: any) => { 4 | for (const prop in obj) { 5 | if (obj.hasOwnProperty(prop)) { 6 | if (Object.prototype.toString.call(obj[prop]) === "[object Object]") { 7 | target[prop] = merge(target[prop], obj[prop]); 8 | } else { 9 | target[prop] = obj[prop]; 10 | } 11 | } 12 | } 13 | }; 14 | for (let i = 0; i < options.length; i++) { 15 | merger(options[i]); 16 | } 17 | return target; 18 | }; 19 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/wysiwyg/afterRenderEvent.ts: -------------------------------------------------------------------------------- 1 | import {getMarkdown} from "../markdown/getMarkdown"; 2 | import {accessLocalStorage} from "../util/compatibility"; 3 | 4 | export const afterRenderEvent = (vditor: IVditor, options = { 5 | enableAddUndoStack: true, 6 | enableHint: false, 7 | enableInput: true, 8 | }) => { 9 | if (options.enableHint) { 10 | vditor.hint.render(vditor); 11 | } 12 | clearTimeout(vditor.wysiwyg.afterRenderTimeoutId); 13 | vditor.wysiwyg.afterRenderTimeoutId = window.setTimeout(() => { 14 | if (vditor.wysiwyg.composingLock) { 15 | return; 16 | } 17 | const text = getMarkdown(vditor); 18 | if (typeof vditor.options.input === "function" && options.enableInput) { 19 | vditor.options.input(text); 20 | } 21 | 22 | if (vditor.options.counter.enable) { 23 | vditor.counter.render(vditor, text); 24 | } 25 | 26 | if (vditor.options.cache.enable && accessLocalStorage()) { 27 | localStorage.setItem(vditor.options.cache.id, text); 28 | if (vditor.options.cache.after) { 29 | vditor.options.cache.after(text); 30 | } 31 | } 32 | 33 | if (vditor.devtools) { 34 | vditor.devtools.renderEchart(vditor); 35 | } 36 | 37 | if (options.enableAddUndoStack) { 38 | vditor.undo.addToUndoStack(vditor); 39 | } 40 | }, vditor.options.undoDelay); 41 | }; 42 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/wysiwyg/renderDomByMd.ts: -------------------------------------------------------------------------------- 1 | import {processCodeRender} from "../util/processCode"; 2 | import {afterRenderEvent} from "./afterRenderEvent"; 3 | 4 | export const renderDomByMd = (vditor: IVditor, md: string, options = { 5 | enableAddUndoStack: true, 6 | enableHint: false, 7 | enableInput: true, 8 | }) => { 9 | const editorElement = vditor.wysiwyg.element; 10 | editorElement.innerHTML = vditor.lute.Md2VditorDOM(md); 11 | 12 | editorElement.querySelectorAll(".vditor-wysiwyg__preview[data-render='2']").forEach((item: HTMLElement) => { 13 | processCodeRender(item, vditor); 14 | item.previousElementSibling.setAttribute("style", "display:none"); 15 | }); 16 | 17 | afterRenderEvent(vditor, options); 18 | }; 19 | -------------------------------------------------------------------------------- /public/assets/vditor/src/ts/wysiwyg/showCode.ts: -------------------------------------------------------------------------------- 1 | import {scrollCenter} from "../util/editorCommonEvent"; 2 | import {setSelectionFocus} from "../util/selection"; 3 | 4 | export const showCode = (previewElement: HTMLElement, vditor: IVditor, first = true) => { 5 | const previousElement = previewElement.previousElementSibling as HTMLElement; 6 | const range = previousElement.ownerDocument.createRange(); 7 | if (previousElement.tagName === "CODE") { 8 | previousElement.style.display = "inline-block"; 9 | if (first) { 10 | range.setStart(previousElement.firstChild, 1); 11 | } else { 12 | range.selectNodeContents(previousElement); 13 | } 14 | } else { 15 | previousElement.style.display = "block"; 16 | 17 | if (!previousElement.firstChild.firstChild) { 18 | previousElement.firstChild.appendChild(document.createTextNode("")); 19 | } 20 | range.selectNodeContents(previousElement.firstChild); 21 | } 22 | if (first) { 23 | range.collapse(true); 24 | } else { 25 | range.collapse(false); 26 | } 27 | setSelectionFocus(range); 28 | if (previewElement.firstElementChild.classList.contains("language-mindmap")) { 29 | return; 30 | } 31 | scrollCenter(vditor); 32 | }; 33 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/public/logo.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 29 | 30 | 34 | -------------------------------------------------------------------------------- /src/api/admin_logs.js: -------------------------------------------------------------------------------- 1 | import api from '@/api/api' 2 | const logApi = { 3 | GetLogs: '/api/admin/logs' 4 | } 5 | 6 | export function getLogs (param) { 7 | return api({ 8 | url: logApi.GetLogs, 9 | method: 'get', 10 | params: { 11 | ...param 12 | } 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /src/api/admin_manage_user.js: -------------------------------------------------------------------------------- 1 | import api from '@/api/api' 2 | 3 | const userApi = { 4 | GetUsers: '/api/admin/users', 5 | User: '/api/admin/user/', 6 | CreateUser: '/api/admin/user' 7 | } 8 | 9 | export function getUser (id) { 10 | return api({ 11 | url: userApi.User + id, 12 | method: 'get' 13 | }) 14 | } 15 | 16 | export function deleteUser (id) { 17 | return api({ 18 | url: userApi.User + id, 19 | method: 'delete' 20 | }) 21 | } 22 | 23 | export function updateUser (id, param) { 24 | return api({ 25 | url: userApi.User + id, 26 | method: 'put', 27 | data: { 28 | ...param 29 | } 30 | }) 31 | } 32 | 33 | export function createUser (param) { 34 | return api({ 35 | url: userApi.CreateUser, 36 | method: 'post', 37 | data: { 38 | ...param 39 | } 40 | }) 41 | } 42 | 43 | export function getUsers (param) { 44 | return api({ 45 | url: userApi.GetUsers, 46 | method: 'get', 47 | params: { 48 | ...param 49 | } 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /src/api/api.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request.js' 2 | import router from '@/router' 3 | import store from '@/store' 4 | import storage from 'store' 5 | import { ACCESS_TOKEN } from '@/store/mutation-types' 6 | import { notification } from 'ant-design-vue' 7 | 8 | const api = req => { 9 | return new Promise((resolve, reject) => { 10 | request(req).then(resp => { 11 | if (resp.message && resp.message === 'SUCCESS') { 12 | resolve(resp.data) 13 | } else { 14 | if (resp.message === 'AUTH_NEED_TOKEN' || resp.message === 'AUTH_SESSION_EXPIRED') { 15 | store.commit('SET_TOKEN', storage.get(ACCESS_TOKEN)) 16 | store.dispatch('GetInfo').then(data => { 17 | store.commit('SET_INFO', data) 18 | }) 19 | notification.error({ 20 | message: '错误', 21 | description: resp.message === 'AUTH_NEED_TOKEN' ? '本页面需要登录才能访问' : '你的登录状态已经过期' 22 | }) 23 | router.push({ name: 'login', query: { redirect: router.history.current.path } }) 24 | } else if (resp.message === 'PERMISSION_DENIED') { 25 | router.push({ path: '/403' }) 26 | notification.error({ 27 | message: '错误', 28 | description: `你没有这么做的权限` 29 | }) 30 | } else if (resp.message === 'AUTH_NEED_EMAIL_VERIFICATION') { 31 | router.push({ name: 'verify_email' }) 32 | notification.warning({ 33 | message: '警告', 34 | description: '请验证邮箱' 35 | }) 36 | } else { 37 | const err = new Error(resp.message) 38 | err.response = resp 39 | reject(err) 40 | } 41 | } 42 | }).catch(err => { 43 | alert('这不应该发生! 只应该是网络错误!') 44 | alert(JSON.stringify(err)) 45 | reject(err) 46 | }) 47 | }) 48 | } 49 | 50 | export default api 51 | -------------------------------------------------------------------------------- /src/api/auth.js: -------------------------------------------------------------------------------- 1 | import api from './api' 2 | 3 | const authApi = { 4 | Login: '/api/auth/login', 5 | Register: '/api/auth/register', 6 | EmailRegistered: '/api/auth/email_registered' 7 | } 8 | 9 | export function login (parameter) { 10 | return api({ 11 | url: authApi.Login, 12 | method: 'post', 13 | data: parameter 14 | }) 15 | } 16 | 17 | export function register (parameter) { 18 | return api({ 19 | url: authApi.Register, 20 | method: 'post', 21 | data: parameter 22 | }) 23 | } 24 | 25 | export function emailRegistered (email) { 26 | return api({ 27 | url: authApi.EmailRegistered, 28 | method: 'get', 29 | params: { 30 | email: email 31 | } 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /src/api/manage.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | const api = { 4 | user: '/api/user', 5 | role: '/api/role', 6 | service: '/api/service', 7 | permission: '/permission', 8 | permissionNoPager: '/permission/no-pager', 9 | orgTree: '/org/tree' 10 | } 11 | 12 | export default api 13 | 14 | export function getUserList (parameter) { 15 | return request({ 16 | url: api.user, 17 | method: 'get', 18 | params: parameter 19 | }) 20 | } 21 | 22 | export function getRoleList (parameter) { 23 | return request({ 24 | url: api.role, 25 | method: 'get', 26 | params: parameter 27 | }) 28 | } 29 | 30 | export function getServiceList (parameter) { 31 | return request({ 32 | url: api.service, 33 | method: 'get', 34 | params: parameter 35 | }) 36 | } 37 | 38 | export function getPermissions (parameter) { 39 | return request({ 40 | url: api.permissionNoPager, 41 | method: 'get', 42 | params: parameter 43 | }) 44 | } 45 | 46 | export function getOrgTree (parameter) { 47 | return request({ 48 | url: api.orgTree, 49 | method: 'get', 50 | params: parameter 51 | }) 52 | } 53 | 54 | // id == 0 add post 55 | // id != 0 update put 56 | export function saveService (parameter) { 57 | return request({ 58 | url: api.service, 59 | method: parameter.id === 0 ? 'post' : 'put', 60 | data: parameter 61 | }) 62 | } 63 | 64 | export function saveSub (sub) { 65 | return request({ 66 | url: '/sub', 67 | method: sub.id === 0 ? 'post' : 'put', 68 | data: sub 69 | }) 70 | } 71 | -------------------------------------------------------------------------------- /src/api/problem_set.js: -------------------------------------------------------------------------------- 1 | import api from '@/api/api' 2 | 3 | const problemSetApi = { 4 | Problem: '/api/class/:classID/problem_set/:problemSetID/problem/:id', 5 | Submit: '/api/class/:classID/problem_set/:problemSetID/problem/:id/submission', 6 | GetSubmissions: '/api/class/:classID/problem_set/:problemSetID/submissions', 7 | GetSubmission: '/api/class/:classID/problem_set/:problemSetID/submission/:submissionID' 8 | } 9 | 10 | export function getSubmission (classID, problemSetID, submissionID, poll = false, before = null) { 11 | return api({ 12 | url: problemSetApi.GetSubmission.replace(':classID', classID).replace(':problemSetID', problemSetID).replace(':submissionID', submissionID), 13 | method: 'get', 14 | params: { 15 | poll: poll ? 1 : 0, 16 | before: before 17 | }, 18 | timeout: poll ? -1 : 6000 19 | }) 20 | } 21 | 22 | export function getProblemSetProblem (classID, pid, id) { 23 | return api({ 24 | url: problemSetApi.Problem.replace(':classID', classID).replace(':problemSetID', pid).replace(':id', id), 25 | method: 'get' 26 | }) 27 | } 28 | 29 | export function getSubmissions (classID, pid, req) { 30 | return api({ 31 | url: problemSetApi.GetSubmissions.replace(':classID', classID).replace(':problemSetID', pid), 32 | method: 'get', 33 | params: req 34 | }) 35 | } 36 | 37 | export function createSubmission (param) { 38 | const formData = new FormData() 39 | for (const prop in param) { 40 | formData.append(prop, param[prop]) 41 | } 42 | return api({ 43 | url: problemSetApi.Submit.replace(':classID', param.classID) 44 | .replace(':problemSetID', param.problemSetID) 45 | .replace(':id', param.problem_id), 46 | method: 'post', 47 | data: formData 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /src/api/submission.js: -------------------------------------------------------------------------------- 1 | import api from '@/api/api' 2 | 3 | const submissionApi = { 4 | GetSubmissions: '/api/submissions', 5 | GetSubmission: '/api/submission/:id', 6 | GetSubmissionCode: '/api/submission/:id/code', 7 | GetRunOutput: '/api/submission/:id/run/:run_id/output', 8 | GetRunInput: '/api/submission/:id/run/:run_id/input', 9 | GetRunCompilerOutput: '/api/submission/:id/run/:run_id/compiler_output', 10 | GetRunComparerOutput: '/api/submission/:id/run/:run_id/comparer_output' 11 | } 12 | 13 | export function getSubmissions (req) { 14 | return api({ 15 | url: submissionApi.GetSubmissions, 16 | method: 'get', 17 | params: req 18 | }) 19 | } 20 | 21 | export function getSubmission (id, poll = false, before = null) { 22 | return api({ 23 | url: submissionApi.GetSubmission.replace(':id', id), 24 | method: 'get', 25 | params: { 26 | poll: poll ? 1 : 0, 27 | before: before 28 | }, 29 | timeout: poll ? -1 : 6000 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /src/api/webauthn.js: -------------------------------------------------------------------------------- 1 | import api from './api' 2 | 3 | const authApi = { 4 | Register: '/api/webauthn/register', 5 | Login: '/api/auth/login/webauthn' 6 | } 7 | 8 | export function beginRegister () { 9 | return api({ 10 | url: authApi.Register, 11 | method: 'get' 12 | }) 13 | } 14 | export function finishRegister (data) { 15 | return api({ 16 | url: authApi.Register, 17 | method: 'post', 18 | data: data, 19 | withCredentials: true 20 | }) 21 | } 22 | 23 | export function beginLogin (data) { 24 | return api({ 25 | url: authApi.Login, 26 | method: 'get', 27 | params: data 28 | }) 29 | } 30 | export function finishLogin (username, data) { 31 | return api({ 32 | url: authApi.Login, 33 | method: 'post', 34 | data: data, 35 | withCredentials: true, 36 | params: { 37 | username: username 38 | } 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /src/assets/icons/bx-analyse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | E 5 | 6 | -------------------------------------------------------------------------------- /src/components/Avatar.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 36 | 37 | 40 | -------------------------------------------------------------------------------- /src/components/Editor/Markdown.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 63 | 64 | 67 | -------------------------------------------------------------------------------- /src/components/GlobalFooter/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 23 | -------------------------------------------------------------------------------- /src/components/GlobalHeader/RightContent.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 58 | -------------------------------------------------------------------------------- /src/components/Language.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 25 | 26 | 29 | -------------------------------------------------------------------------------- /src/components/Memory.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 31 | 32 | 35 | -------------------------------------------------------------------------------- /src/components/MultiTab/events.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | export default new Vue() 3 | -------------------------------------------------------------------------------- /src/components/MultiTab/index.js: -------------------------------------------------------------------------------- 1 | import events from './events' 2 | import MultiTab from './MultiTab' 3 | import './index.less' 4 | 5 | const api = { 6 | /** 7 | * open new tab on route fullPath 8 | * @param config 9 | */ 10 | open: function (config) { 11 | events.$emit('open', config) 12 | }, 13 | rename: function (key, name) { 14 | events.$emit('rename', { key: key, name: name }) 15 | }, 16 | /** 17 | * close current page 18 | */ 19 | closeCurrentPage: function () { 20 | this.close() 21 | }, 22 | /** 23 | * close route fullPath tab 24 | * @param config 25 | */ 26 | close: function (config) { 27 | events.$emit('close', config) 28 | } 29 | } 30 | 31 | MultiTab.install = function (Vue) { 32 | if (Vue.prototype.$multiTab) { 33 | return 34 | } 35 | api.instance = events 36 | Vue.prototype.$multiTab = api 37 | Vue.component('multi-tab', MultiTab) 38 | } 39 | 40 | export default MultiTab 41 | -------------------------------------------------------------------------------- /src/components/MultiTab/index.less: -------------------------------------------------------------------------------- 1 | @import '../index'; 2 | 3 | @multi-tab-prefix-cls: ~"@{ant-pro-prefix}-multi-tab"; 4 | @multi-tab-wrapper-prefix-cls: ~"@{ant-pro-prefix}-multi-tab-wrapper"; 5 | 6 | /* 7 | .topmenu .@{multi-tab-prefix-cls} { 8 | max-width: 1200px; 9 | margin: -23px auto 24px auto; 10 | } 11 | */ 12 | .@{multi-tab-prefix-cls} { 13 | margin: -23px -24px 24px -24px; 14 | background: #fff; 15 | } 16 | 17 | .topmenu .@{multi-tab-wrapper-prefix-cls} { 18 | max-width: 1200px; 19 | margin: 0 auto; 20 | } 21 | 22 | .topmenu.content-width-Fluid .@{multi-tab-wrapper-prefix-cls} { 23 | max-width: 100%; 24 | margin: 0 auto; 25 | } 26 | -------------------------------------------------------------------------------- /src/components/NProgress/nprogress.less: -------------------------------------------------------------------------------- 1 | @import url('../index.less'); 2 | 3 | /* Make clicks pass-through */ 4 | #nprogress { 5 | pointer-events: none; 6 | } 7 | 8 | #nprogress .bar { 9 | background: @primary-color; 10 | 11 | position: fixed; 12 | z-index: 1031; 13 | top: 0; 14 | left: 0; 15 | 16 | width: 100%; 17 | height: 2px; 18 | } 19 | 20 | /* Fancy blur effect */ 21 | #nprogress .peg { 22 | display: block; 23 | position: absolute; 24 | right: 0px; 25 | width: 100px; 26 | height: 100%; 27 | box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; 28 | opacity: 1.0; 29 | 30 | -webkit-transform: rotate(3deg) translate(0px, -4px); 31 | -ms-transform: rotate(3deg) translate(0px, -4px); 32 | transform: rotate(3deg) translate(0px, -4px); 33 | } 34 | 35 | /* Remove these to get rid of the spinner */ 36 | #nprogress .spinner { 37 | display: block; 38 | position: fixed; 39 | z-index: 1031; 40 | top: 15px; 41 | right: 15px; 42 | } 43 | 44 | #nprogress .spinner-icon { 45 | width: 18px; 46 | height: 18px; 47 | box-sizing: border-box; 48 | 49 | border: solid 2px transparent; 50 | border-top-color: @primary-color; 51 | border-left-color: @primary-color; 52 | border-radius: 50%; 53 | 54 | -webkit-animation: nprogress-spinner 400ms linear infinite; 55 | animation: nprogress-spinner 400ms linear infinite; 56 | } 57 | 58 | .nprogress-custom-parent { 59 | overflow: hidden; 60 | position: relative; 61 | } 62 | 63 | .nprogress-custom-parent #nprogress .spinner, 64 | .nprogress-custom-parent #nprogress .bar { 65 | position: absolute; 66 | } 67 | 68 | @-webkit-keyframes nprogress-spinner { 69 | 0% { -webkit-transform: rotate(0deg); } 70 | 100% { -webkit-transform: rotate(360deg); } 71 | } 72 | @keyframes nprogress-spinner { 73 | 0% { transform: rotate(0deg); } 74 | 100% { transform: rotate(360deg); } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/components/RunStatus.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 42 | 43 | 72 | -------------------------------------------------------------------------------- /src/components/SelectLang/index.jsx: -------------------------------------------------------------------------------- 1 | import './index.less' 2 | 3 | import { Icon, Menu, Dropdown } from 'ant-design-vue' 4 | import { i18nRender } from '@/locales' 5 | import i18nMixin from '@/store/i18n-mixin' 6 | 7 | const locales = ['zh-CN', 'zh-TW', 'en-US', 'pt-BR'] 8 | const languageLabels = { 9 | 'zh-CN': '简体中文', 10 | 'zh-TW': '繁体中文', 11 | 'en-US': 'English', 12 | 'pt-BR': 'Português' 13 | } 14 | // eslint-disable-next-line 15 | const languageIcons = { 16 | 'zh-CN': '🇨🇳', 17 | 'zh-TW': '🇭🇰', 18 | 'en-US': '🇺🇸', 19 | 'pt-BR': '🇧🇷' 20 | } 21 | 22 | const SelectLang = { 23 | props: { 24 | prefixCls: { 25 | type: String, 26 | default: 'ant-pro-drop-down' 27 | } 28 | }, 29 | name: 'SelectLang', 30 | mixins: [i18nMixin], 31 | render () { 32 | const { prefixCls } = this 33 | const changeLang = ({ key }) => { 34 | this.setLang(key) 35 | } 36 | const langMenu = ( 37 | 38 | {locales.map(locale => ( 39 | 40 | 41 | {languageIcons[locale]} 42 | {' '} 43 | {languageLabels[locale]} 44 | 45 | ))} 46 | 47 | ) 48 | return ( 49 | 50 | 51 | 52 | 53 | 54 | ) 55 | } 56 | } 57 | 58 | export default SelectLang 59 | -------------------------------------------------------------------------------- /src/components/SelectLang/index.less: -------------------------------------------------------------------------------- 1 | @import "~ant-design-vue/es/style/themes/default"; 2 | 3 | @header-menu-prefix-cls: ~'@{ant-prefix}-pro-header-menu'; 4 | @header-drop-down-prefix-cls: ~'@{ant-prefix}-pro-drop-down'; 5 | 6 | .@{header-menu-prefix-cls} { 7 | 8 | .anticon { 9 | margin-right: 8px; 10 | } 11 | .ant-dropdown-menu-item { 12 | min-width: 160px; 13 | } 14 | } 15 | 16 | .@{header-drop-down-prefix-cls} { 17 | 18 | line-height: @layout-header-height; 19 | vertical-align: top; 20 | cursor: pointer; 21 | 22 | > i { 23 | font-size: 16px !important; 24 | transform: none !important; 25 | 26 | svg { 27 | position: relative; 28 | top: -1px; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/components/Table/ResizableTableHeader.js: -------------------------------------------------------------------------------- 1 | import VueDraggableResizable from 'vue-draggable-resizable' 2 | import Vue from 'vue' 3 | Vue.component('vue-draggable-resizable', VueDraggableResizable) 4 | 5 | export default function (h, props, children, columns, draggingState) { 6 | const { key, ...restProps } = props 7 | const col = columns.find(col => { 8 | const k = col.dataIndex 9 | return k === key 10 | }) 11 | if (col.last) { 12 | return {children} 13 | } 14 | if (!col.width) { 15 | Vue.set(col, 'width', -1) 16 | } 17 | const onDrag = (x) => { 18 | draggingState[key] = 0 19 | col.width = Math.max(x, 1) 20 | } 21 | const onDragStop = () => { 22 | for (const c of columns) { 23 | console.log(c) 24 | if (c && c.thDom) { 25 | draggingState[key] = c.thDom.getBoundingClientRect().width 26 | Vue.set(c, 'width', c.thDom.getBoundingClientRect().width) 27 | } 28 | } 29 | } 30 | return ( 31 | { col.thDom = r }} width={col.width !== -1 ? col.width : undefined} style={{ position: 'relative' }}> 32 | {children} 33 |
e.stopPropagation()} 35 | > 36 | 58 | 59 |
60 | 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /src/components/UserName.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 33 | 34 | 37 | -------------------------------------------------------------------------------- /src/components/_util/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * components util 3 | */ 4 | 5 | /** 6 | * 清理空值,对象 7 | * @param children 8 | * @returns {*[]} 9 | */ 10 | export function filterEmpty (children = []) { 11 | return children.filter(c => c.tag || (c.text && c.text.trim() !== '')) 12 | } 13 | 14 | /** 15 | * 获取字符串长度,英文字符 长度1,中文字符长度2 16 | * @param {*} str 17 | */ 18 | export const getStrFullLength = (str = '') => 19 | str.split('').reduce((pre, cur) => { 20 | const charCode = cur.charCodeAt(0) 21 | if (charCode >= 0 && charCode <= 128) { 22 | return pre + 1 23 | } 24 | return pre + 2 25 | }, 0) 26 | 27 | /** 28 | * 截取字符串,根据 maxLength 截取后返回 29 | * @param {*} str 30 | * @param {*} maxLength 31 | */ 32 | export const cutStrByFullLength = (str = '', maxLength) => { 33 | let showLength = 0 34 | return str.split('').reduce((pre, cur) => { 35 | const charCode = cur.charCodeAt(0) 36 | if (charCode >= 0 && charCode <= 128) { 37 | showLength += 1 38 | } else { 39 | showLength += 2 40 | } 41 | if (showLength <= maxLength) { 42 | return pre + cur 43 | } 44 | return pre 45 | }, '') 46 | } 47 | -------------------------------------------------------------------------------- /src/components/codemirror/JetBrainsMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/src/components/codemirror/JetBrainsMono-Regular.ttf -------------------------------------------------------------------------------- /src/components/codemirror/JetBrainsMono-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/src/components/codemirror/JetBrainsMono-Regular.woff2 -------------------------------------------------------------------------------- /src/components/codemirror/index.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Vue-CodeMirror 4 | * Author: surmon@foxmail.com 5 | * Github: https://github.com/surmon-china/vue-codemirror 6 | */ 7 | 8 | import _CodeMirror from 'codemirror/lib/codemirror.js' 9 | import codemirror from './codemirror.vue' 10 | 11 | const CodeMirror = window.CodeMirror || _CodeMirror 12 | const install = (Vue, config) => { 13 | if (config) { 14 | if (config.options) { 15 | codemirror.props.globalOptions.default = () => config.options 16 | } 17 | if (config.events) { 18 | codemirror.props.globalEvents.default = () => config.events 19 | } 20 | } 21 | Vue.component(codemirror.name, codemirror) 22 | } 23 | 24 | const VueCodemirror = { CodeMirror, codemirror, install } 25 | 26 | export default VueCodemirror 27 | export { CodeMirror, codemirror, install } 28 | -------------------------------------------------------------------------------- /src/components/index.less: -------------------------------------------------------------------------------- 1 | @import "~ant-design-vue/lib/style/index"; 2 | 3 | // The prefix to use on all css classes from ant-pro. 4 | @ant-pro-prefix : ant-pro; 5 | @ant-global-sider-zindex : 106; 6 | @ant-global-header-zindex : 105; -------------------------------------------------------------------------------- /src/config/.gitignore: -------------------------------------------------------------------------------- 1 | config.js 2 | -------------------------------------------------------------------------------- /src/config/comparerConf.js: -------------------------------------------------------------------------------- 1 | export default { 2 | keys: ['compare_soft_match', 'compare_float', 'compare_exact_match'], 3 | compare_soft_match: { 4 | name: '忽略行末空格 + 最后回车' 5 | }, 6 | compare_float: { 7 | name: '浮点数匹配 (相差1e-5内认为正确)' 8 | }, 9 | compare_exact_match: { 10 | name: '字符级严格匹配' 11 | }, 12 | '': { 13 | name: '' 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/config/config.example.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 项目默认配置项 3 | * primaryColor - 默认主题色, 如果修改颜色不生效,请清理 localStorage 4 | * navTheme - sidebar theme ['dark', 'light'] 两种主题 5 | * colorWeak - 色盲模式 6 | * layout - 整体布局方式 ['sidemenu', 'topmenu'] 两种布局 7 | * fixedHeader - 固定 Header : boolean 8 | * fixSiderbar - 固定左侧菜单栏 : boolean 9 | * autoHideHeader - 向下滚动时,隐藏 Header : boolean 10 | * contentWidth - 内容区布局: 流式 | 固定 11 | * 12 | * storageOptions: {} - Vue-ls 插件配置项 (localStorage/sessionStorage) 13 | * 14 | */ 15 | 16 | export default { 17 | apiUrl: '', 18 | navTheme: 'realDark', // theme for nav menu 19 | primaryColor: '#52C41A', // primary color of ant design 20 | layout: 'sidemenu', // nav menu position: `sidemenu` or `topmenu` 21 | contentWidth: 'Fixed', // layout of content: `Fluid` or `Fixed`, only works when layout is topmenu 22 | fixedHeader: false, // sticky header 23 | autoHideHeader: false, // auto hide header 24 | fixSiderbar: false, // sticky siderbar 25 | colorWeak: false, 26 | menu: { 27 | locale: true 28 | }, 29 | title: 'EduOJ', 30 | multiTab: false, 31 | production: process.env.NODE_ENV === 'production' && process.env.VUE_APP_PREVIEW !== 'true', 32 | message_on_first_accepted: (h) => ( 33 |
34 | 给个star吧! 35 | EduOJ 36 |
37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /src/config/languageConf.js: -------------------------------------------------------------------------------- 1 | export default { 2 | c: { 3 | displayName: 'C', 4 | mimeType: 'text/x-csrc', 5 | hljsLanguage: 'c', 6 | color: 'green' 7 | }, 8 | cpp: { 9 | displayName: 'C++', 10 | mimeType: 'text/x-c++src', 11 | hljsLanguage: 'cpp', 12 | color: 'cyan' 13 | }, 14 | java: { 15 | displayName: 'Java', 16 | mimeType: 'text/x-java', 17 | hljsLanguage: 'java', 18 | color: 'red' 19 | }, 20 | python3: { 21 | displayName: 'Python3', 22 | mimeType: 'text/x-python', 23 | hljsLanguage: 'python', 24 | color: 'orange' 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/core/bootstrap.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | import storage from 'store' 3 | import { 4 | ACCESS_TOKEN, 5 | APP_LANGUAGE, 6 | TOGGLE_CONTENT_WIDTH, 7 | TOGGLE_FIXED_HEADER, 8 | TOGGLE_FIXED_SIDEBAR, TOGGLE_HIDE_HEADER, 9 | TOGGLE_LAYOUT, TOGGLE_NAV_THEME, TOGGLE_WEAK, 10 | TOGGLE_COLOR, TOGGLE_MULTI_TAB 11 | } from '@/store/mutation-types' 12 | import config from '@/config/config' 13 | 14 | export default function Initializer () { 15 | store.commit(TOGGLE_LAYOUT, storage.get(TOGGLE_LAYOUT, config.layout)) 16 | store.commit(TOGGLE_FIXED_HEADER, storage.get(TOGGLE_FIXED_HEADER, config.fixedHeader)) 17 | store.commit(TOGGLE_FIXED_SIDEBAR, storage.get(TOGGLE_FIXED_SIDEBAR, config.fixSiderbar)) 18 | store.commit(TOGGLE_CONTENT_WIDTH, storage.get(TOGGLE_CONTENT_WIDTH, config.contentWidth)) 19 | store.commit(TOGGLE_HIDE_HEADER, storage.get(TOGGLE_HIDE_HEADER, config.autoHideHeader)) 20 | store.commit(TOGGLE_NAV_THEME, storage.get(TOGGLE_NAV_THEME, config.navTheme)) 21 | store.commit(TOGGLE_WEAK, storage.get(TOGGLE_WEAK, config.colorWeak)) 22 | store.commit(TOGGLE_COLOR, storage.get(TOGGLE_COLOR, config.primaryColor)) 23 | store.commit(TOGGLE_MULTI_TAB, storage.get(TOGGLE_MULTI_TAB, config.multiTab)) 24 | store.commit('SET_TOKEN', storage.get(ACCESS_TOKEN)) 25 | store.dispatch('GetInfo').then(data => { 26 | store.commit('SET_INFO', data) 27 | }) 28 | 29 | store.dispatch('setLang', storage.get(APP_LANGUAGE, 'zh-CN')) 30 | // last step 31 | if (navigator.serviceWorker) { 32 | navigator.serviceWorker.register('/service_worker.js', { scope: '/' }) 33 | .then(reg => { 34 | console.log('Registration succeeded. Scope is ' + reg.scope) 35 | }).catch(error => { 36 | console.log('Registration failed with ' + error) 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/core/directives/action.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/store' 3 | 4 | /** 5 | * Action 权限指令 6 | * 指令用法: 7 | * - 在需要控制 action 级别权限的组件上使用 v-action:[method] , 如下: 8 | * 添加用户 9 | * 删除用户 10 | * 修改 11 | * 12 | * - 当前用户没有权限时,组件上使用了该指令则会被隐藏 13 | * - 当后台权限跟 pro 提供的模式不同时,只需要针对这里的权限过滤进行修改即可 14 | * 15 | * @see https://github.com/sendya/ant-design-pro-vue/pull/53 16 | */ 17 | const action = Vue.directive('action', { 18 | inserted: function (el, binding, vnode) { 19 | const actionName = binding.arg 20 | const roles = store.getters.roles 21 | const elVal = vnode.context.$route.meta.permission 22 | const permissionId = elVal instanceof String && [elVal] || elVal 23 | roles.permissions.forEach(p => { 24 | if (!permissionId.includes(p.permissionId)) { 25 | return 26 | } 27 | if (p.actionList && !p.actionList.includes(actionName)) { 28 | el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none') 29 | } 30 | }) 31 | } 32 | }) 33 | 34 | export default action 35 | -------------------------------------------------------------------------------- /src/core/icons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom icon list 3 | * All icons are loaded here for easy management 4 | * @see https://vue.ant.design/components/icon/#Custom-Font-Icon 5 | * 6 | * 自定义图标加载表 7 | * 所有图标均从这里加载,方便管理 8 | */ 9 | import bxAnaalyse from '@/assets/icons/bx-analyse.svg?inline' // path to your '*.svg?inline' file. 10 | 11 | export { bxAnaalyse } 12 | -------------------------------------------------------------------------------- /src/core/use.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | // base library 4 | import Antd from 'ant-design-vue' 5 | import Viser from 'viser-vue' 6 | import VueCropper from 'vue-cropper' 7 | import 'ant-design-vue/dist/antd.less' 8 | 9 | // ext library 10 | import VueClipboard from 'vue-clipboard2' 11 | // import MultiTab from '@/components/MultiTab' 12 | import PageLoading from '@/components/PageLoading' 13 | import PermissionHelper from '@/utils/helper/permission' 14 | // import '@/components/use' 15 | import './directives/action' 16 | 17 | VueClipboard.config.autoSetContainer = true 18 | 19 | Vue.use(Antd) 20 | Vue.use(Viser) 21 | // Vue.use(MultiTab) 22 | Vue.use(PageLoading) 23 | Vue.use(VueClipboard) 24 | Vue.use(PermissionHelper) 25 | Vue.use(VueCropper) 26 | 27 | process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] WARNING: Antd now use fulled imported.') 28 | -------------------------------------------------------------------------------- /src/global.less: -------------------------------------------------------------------------------- 1 | @import '~ant-design-vue/es/style/themes/default.less'; 2 | 3 | html, 4 | body, 5 | #app, #root { 6 | height: 100%; 7 | } 8 | 9 | .colorWeak { 10 | filter: invert(80%); 11 | } 12 | 13 | .ant-layout.layout-basic { 14 | height: 100vh; 15 | min-height: 100vh; 16 | } 17 | 18 | canvas { 19 | display: block; 20 | } 21 | 22 | body { 23 | text-rendering: optimizeLegibility; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | ul, 29 | ol { 30 | list-style: none; 31 | } 32 | 33 | // 数据列表 样式 34 | .table-alert { 35 | margin-bottom: 16px; 36 | } 37 | // 数据列表 操作 38 | .table-operator { 39 | margin-bottom: 18px; 40 | 41 | button { 42 | margin-right: 8px; 43 | } 44 | } 45 | // 数据列表 搜索条件 46 | .table-page-search-wrapper { 47 | 48 | .ant-form-inline { 49 | .ant-form-item { 50 | display: flex; 51 | margin-bottom: 24px; 52 | margin-right: 0; 53 | 54 | .ant-form-item-control-wrapper { 55 | flex: 1 1; 56 | display: inline-block; 57 | vertical-align: middle; 58 | } 59 | 60 | > .ant-form-item-label { 61 | line-height: 32px; 62 | padding-right: 8px; 63 | width: auto; 64 | } 65 | .ant-form-item-control { 66 | height: 32px; 67 | line-height: 32px; 68 | } 69 | } 70 | } 71 | 72 | .table-page-search-submitButtons { 73 | display: block; 74 | margin-bottom: 24px; 75 | white-space: nowrap; 76 | } 77 | } 78 | 79 | @media (max-width: @screen-xs) { 80 | .ant-table { 81 | width: 100%; 82 | overflow-x: auto; 83 | &-thead > tr, 84 | &-tbody > tr { 85 | > th, 86 | > td { 87 | white-space: pre; 88 | > span { 89 | display: block; 90 | } 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/layouts/BasicLayout.less: -------------------------------------------------------------------------------- 1 | @import "~ant-design-vue/es/style/themes/default.less"; 2 | 3 | .ant-pro-global-header-index-right { 4 | margin-right: 8px; 5 | 6 | &.ant-pro-global-header-index-dark { 7 | .ant-pro-global-header-index-action { 8 | color: hsla(0, 0%, 100%, .85); 9 | 10 | &:hover { 11 | background: #1890ff; 12 | } 13 | } 14 | } 15 | 16 | .ant-pro-account-avatar { 17 | .antd-pro-global-header-index-avatar { 18 | margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0; 19 | margin-right: 8px; 20 | color: @primary-color; 21 | vertical-align: top; 22 | background: rgba(255, 255, 255, 0.85); 23 | } 24 | } 25 | 26 | .menu { 27 | .anticon { 28 | margin-right: 8px; 29 | } 30 | 31 | .ant-dropdown-menu-item { 32 | min-width: 100px; 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/layouts/BlankLayout.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /src/layouts/PageView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /src/layouts/RouteView.vue: -------------------------------------------------------------------------------- 1 | 33 | -------------------------------------------------------------------------------- /src/layouts/index.js: -------------------------------------------------------------------------------- 1 | import UserLayout from './UserLayout' 2 | import BlankLayout from './BlankLayout' 3 | import BasicLayout from './BasicLayout' 4 | import RouteView from './RouteView' 5 | import PageView from './PageView' 6 | 7 | export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView } 8 | -------------------------------------------------------------------------------- /src/locales/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import storage from 'store' 4 | import moment from 'moment' 5 | 6 | // default lang 7 | import enUS from './lang/en-US' 8 | 9 | Vue.use(VueI18n) 10 | 11 | export const defaultLang = 'en-US' 12 | 13 | const messages = { 14 | 'en-US': { 15 | ...enUS 16 | } 17 | } 18 | 19 | const i18n = new VueI18n({ 20 | silentTranslationWarn: true, 21 | locale: defaultLang, 22 | fallbackLocale: defaultLang, 23 | messages 24 | }) 25 | 26 | const loadedLanguages = [defaultLang] 27 | 28 | function setI18nLanguage (lang) { 29 | i18n.locale = lang 30 | // request.headers['Accept-Language'] = lang 31 | document.querySelector('html').setAttribute('lang', lang) 32 | return lang 33 | } 34 | 35 | export function loadLanguageAsync (lang = defaultLang) { 36 | return new Promise(resolve => { 37 | // 缓存语言设置 38 | storage.set('lang', lang) 39 | if (i18n.locale !== lang) { 40 | if (!loadedLanguages.includes(lang)) { 41 | return import(/* webpackChunkName: "lang-[request]" */ `./lang/${lang}`).then(msg => { 42 | const locale = msg.default 43 | i18n.setLocaleMessage(lang, locale) 44 | loadedLanguages.push(lang) 45 | moment.updateLocale(locale.momentName, locale.momentLocale) 46 | return setI18nLanguage(lang) 47 | }) 48 | } 49 | return resolve(setI18nLanguage(lang)) 50 | } 51 | return resolve(lang) 52 | }) 53 | } 54 | 55 | export function i18nRender (key) { 56 | return i18n.t(`${key}`) 57 | } 58 | 59 | export default i18n 60 | -------------------------------------------------------------------------------- /src/locales/lang/en-US.js: -------------------------------------------------------------------------------- 1 | import antdEnUS from 'ant-design-vue/es/locale-provider/en_US' 2 | import momentEU from 'moment/locale/eu' 3 | 4 | const components = { 5 | antLocale: antdEnUS, 6 | momentName: 'eu', 7 | momentLocale: momentEU 8 | } 9 | 10 | const locale = { 11 | 'message': '-', 12 | 'menu.home': 'Home', 13 | 'menu.dashboard': 'Dashboard', 14 | 'menu.dashboard.analysis': 'Analysis', 15 | 'menu.dashboard.monitor': 'Monitor', 16 | 'menu.dashboard.workplace': 'Workplace', 17 | 18 | 'layouts.usermenu.dialog.title': 'Message', 19 | 'layouts.usermenu.dialog.content': 'Do you really log-out.', 20 | 21 | 'app.setting.pagestyle': 'Page style setting', 22 | 'app.setting.pagestyle.light': 'Light style', 23 | 'app.setting.pagestyle.dark': 'Dark style', 24 | 'app.setting.pagestyle.realdark': 'RealDark style', 25 | 'app.setting.themecolor': 'Theme Color', 26 | 'app.setting.navigationmode': 'Navigation Mode', 27 | 'app.setting.content-width': 'Content Width', 28 | 'app.setting.fixedheader': 'Fixed Header', 29 | 'app.setting.fixedsidebar': 'Fixed Sidebar', 30 | 'app.setting.sidemenu': 'Side Menu Layout', 31 | 'app.setting.topmenu': 'Top Menu Layout', 32 | 'app.setting.content-width.fixed': 'Fixed', 33 | 'app.setting.content-width.fluid': 'Fluid', 34 | 'app.setting.othersettings': 'Other Settings', 35 | 'app.setting.weakmode': 'Weak Mode', 36 | 'app.setting.copy': 'Copy Setting', 37 | 'app.setting.loading': 'Loading theme', 38 | 'app.setting.copyinfo': 'copy success,please replace defaultSettings in src/models/setting.js', 39 | 'app.setting.production.hint': 'Setting panel shows in development environment only, please manually modify' 40 | } 41 | 42 | export default { 43 | ...components, 44 | ...locale 45 | } 46 | -------------------------------------------------------------------------------- /src/locales/lang/zh-CN.js: -------------------------------------------------------------------------------- 1 | import antd from 'ant-design-vue/es/locale-provider/zh_CN' 2 | import momentCN from 'moment/locale/zh-cn' 3 | 4 | const components = { 5 | antLocale: antd, 6 | momentName: 'zh-cn', 7 | momentLocale: momentCN 8 | } 9 | 10 | const locale = { 11 | 'message': '-', 12 | 'menu.home': '主页', 13 | 'menu.dashboard': '仪表盘', 14 | 'menu.dashboard.analysis': '分析页', 15 | 'menu.dashboard.monitor': '监控页', 16 | 'menu.dashboard.workplace': '工作台' 17 | } 18 | 19 | export default { 20 | ...components, 21 | ...locale 22 | } 23 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // with polyfills 2 | import 'core-js/stable' 3 | import 'regenerator-runtime/runtime' 4 | 5 | import Vue from 'vue' 6 | import App from './App.vue' 7 | import router from './router' 8 | import store from './store/' 9 | import i18n from './locales' 10 | import { VueAxios } from './utils/request' 11 | import ProLayout, { PageHeaderWrapper } from '@ant-design-vue/pro-layout' 12 | import themePluginConfig from '../config/themePluginConfig' 13 | import { FormModel, Space } from 'ant-design-vue' 14 | import PerfectScrollbar from 'vue2-perfect-scrollbar' 15 | import VueClipboard from 'vue-clipboard2' 16 | import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css' 17 | 18 | import bootstrap from './core/bootstrap' 19 | import './core/lazy_use' 20 | import './permission' // permission control 21 | import './utils/filter' // global filter 22 | import './global.less' 23 | 24 | import JsonExcel from 'vue-json-excel' 25 | 26 | // import ElementUI from 'element-ui' 27 | // import 'element-ui/lib/theme-chalk/index.css' 28 | Vue.component('downloadExcel', JsonExcel) 29 | 30 | // Vue.use(ElementUI) 31 | 32 | Vue.config.productionTip = false 33 | 34 | // mount axios to `Vue.$http` and `this.$http` 35 | Vue.use(VueAxios) 36 | Vue.use(FormModel) 37 | Vue.use(Space) 38 | Vue.use(VueClipboard) 39 | 40 | Vue.use(PerfectScrollbar) 41 | Vue.component('pro-layout', ProLayout) 42 | Vue.component('page-header-wrapper', PageHeaderWrapper) 43 | 44 | window.umi_plugin_ant_themeVar = themePluginConfig.theme 45 | bootstrap() 46 | new Vue({ 47 | router, 48 | store, 49 | i18n, 50 | render: h => h(App) 51 | }).$mount('#app') 52 | -------------------------------------------------------------------------------- /src/router/generator-routers.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduOJ/frontend/b074b9a70a99f32daa9028453837a7528fd14048/src/router/generator-routers.js -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import { constantRouterMap } from '@/config/router.config' 4 | 5 | // hack router push callback 6 | const originalPush = Router.prototype.push 7 | Router.prototype.push = function push (location, onResolve, onReject) { 8 | if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) 9 | return originalPush.call(this, location).catch(err => err) 10 | } 11 | 12 | Vue.use(Router) 13 | 14 | export default new Router({ 15 | mode: 'history', 16 | base: process.env.BASE_URL, 17 | scrollBehavior: () => ({ y: 0 }), 18 | routes: constantRouterMap 19 | }) 20 | -------------------------------------------------------------------------------- /src/store/app-mixin.js: -------------------------------------------------------------------------------- 1 | import { mapState } from 'vuex' 2 | 3 | const baseMixin = { 4 | computed: { 5 | ...mapState({ 6 | layout: state => state.app.layout, 7 | navTheme: state => state.app.theme, 8 | primaryColor: state => state.app.color, 9 | colorWeak: state => state.app.weak, 10 | fixedHeader: state => state.app.fixedHeader, 11 | fixedSidebar: state => state.app.fixedSidebar, 12 | contentWidth: state => state.app.contentWidth, 13 | autoHideHeader: state => state.app.autoHideHeader, 14 | 15 | isMobile: state => state.app.isMobile, 16 | sideCollapsed: state => state.app.sideCollapsed, 17 | multiTab: state => state.app.multiTab 18 | }), 19 | isTopMenu () { 20 | return this.layout === 'topmenu' 21 | } 22 | }, 23 | methods: { 24 | isSideMenu () { 25 | return !this.isTopMenu 26 | } 27 | } 28 | } 29 | 30 | export { 31 | baseMixin 32 | } 33 | -------------------------------------------------------------------------------- /src/store/device-mixin.js: -------------------------------------------------------------------------------- 1 | import { mapState } from 'vuex' 2 | 3 | const deviceMixin = { 4 | computed: { 5 | ...mapState({ 6 | isMobile: state => state.app.isMobile 7 | }) 8 | } 9 | } 10 | 11 | export { deviceMixin } 12 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | isMobile: state => state.app.isMobile, 3 | lang: state => state.app.lang, 4 | theme: state => state.app.theme, 5 | color: state => state.app.color, 6 | token: state => state.user.token, 7 | avatar: state => state.user.avatar, 8 | nickname: state => state.user.name, 9 | welcome: state => state.user.welcome, 10 | roles: state => state.user.roles, 11 | userInfo: state => state.user.info, 12 | multiTab: state => state.app.multiTab, 13 | can: state => (permission, target, id) => { 14 | id = +id // convert id to integer. 15 | for (const role of state.user.info.roles) { 16 | if (target !== undefined && id !== undefined) { 17 | if (role.target && role.target === target && role.target_id === id) { 18 | for (const p of role.permissions) { 19 | if (p.name === 'all' || p.name === permission) { 20 | return true 21 | } 22 | } 23 | } else if (!role.target && !target) { 24 | for (const permission of role.permissions) { 25 | if (permission.name === 'all' || permission.name === permission) { 26 | return true 27 | } 28 | } 29 | } 30 | } else { 31 | if (role.target === null) { 32 | for (const p of role.permissions) { 33 | if (p.name === 'all' || p.name === permission) { 34 | return true 35 | } 36 | } 37 | } 38 | } 39 | } 40 | return false 41 | } 42 | } 43 | 44 | export default getters 45 | -------------------------------------------------------------------------------- /src/store/i18n-mixin.js: -------------------------------------------------------------------------------- 1 | import { mapState } from 'vuex' 2 | 3 | const i18nMixin = { 4 | computed: { 5 | ...mapState({ 6 | currentLang: state => state.app.lang 7 | }) 8 | }, 9 | methods: { 10 | setLang (lang) { 11 | this.$store.dispatch('setLang', lang) 12 | } 13 | } 14 | } 15 | 16 | export default i18nMixin 17 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | import app from './modules/app' 5 | import user from './modules/user' 6 | import clazz from './modules/class' 7 | 8 | // dynamic router permission control (Experimental) 9 | // import permission from './modules/async-router' 10 | import getters from './getters' 11 | 12 | Vue.use(Vuex) 13 | 14 | export default new Vuex.Store({ 15 | modules: { 16 | app, 17 | user, 18 | class: clazz 19 | }, 20 | state: { 21 | 22 | }, 23 | mutations: { 24 | 25 | }, 26 | actions: { 27 | 28 | }, 29 | getters 30 | }) 31 | -------------------------------------------------------------------------------- /src/store/modules/class.js: -------------------------------------------------------------------------------- 1 | const Class = { 2 | state: { 3 | info: { 4 | id: '', 5 | name: '', 6 | course_name: '', 7 | description: '', 8 | invite_code: '', 9 | managers: [], 10 | students: [], 11 | problem_sets: [] 12 | } 13 | }, 14 | mutations: { 15 | SET_CLASS: (state, Class) => { 16 | state.info = Object.assign({}, state.info, Class) 17 | } 18 | }, 19 | getters: { 20 | class: state => state.info 21 | } 22 | } 23 | 24 | export default Class 25 | -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const ACCESS_TOKEN = 'Access-Token' 2 | 3 | export const SIDEBAR_TYPE = 'sidebar_type' 4 | export const TOGGLE_MOBILE_TYPE = 'is_mobile' 5 | export const TOGGLE_NAV_THEME = 'nav_theme' 6 | export const TOGGLE_LAYOUT = 'layout' 7 | export const TOGGLE_FIXED_HEADER = 'fixed_header' 8 | export const TOGGLE_FIXED_SIDEBAR = 'fixed_sidebar' 9 | export const TOGGLE_CONTENT_WIDTH = 'content_width' 10 | export const TOGGLE_HIDE_HEADER = 'auto_hide_header' 11 | export const TOGGLE_COLOR = 'color' 12 | export const TOGGLE_WEAK = 'weak' 13 | export const TOGGLE_MULTI_TAB = 'multi_tab' 14 | export const APP_LANGUAGE = 'app_language' 15 | 16 | export const CONTENT_WIDTH_TYPE = { 17 | Fluid: 'Fluid', 18 | Fixed: 'Fixed' 19 | } 20 | 21 | export const NAV_THEME = { 22 | LIGHT: 'light', 23 | DARK: 'dark' 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/axios.js: -------------------------------------------------------------------------------- 1 | const VueAxios = { 2 | vm: {}, 3 | // eslint-disable-next-line no-unused-vars 4 | install (Vue, instance) { 5 | if (this.installed) { 6 | return 7 | } 8 | this.installed = true 9 | 10 | if (!instance) { 11 | // eslint-disable-next-line no-console 12 | console.error('You have to install axios') 13 | return 14 | } 15 | 16 | Vue.axios = instance 17 | 18 | Object.defineProperties(Vue.prototype, { 19 | axios: { 20 | get: function get () { 21 | return instance 22 | } 23 | }, 24 | $http: { 25 | get: function get () { 26 | return instance 27 | } 28 | } 29 | }) 30 | } 31 | } 32 | 33 | export { 34 | VueAxios 35 | } 36 | -------------------------------------------------------------------------------- /src/utils/domUtil.js: -------------------------------------------------------------------------------- 1 | import config from '@/config/config' 2 | 3 | export const setDocumentTitle = function (title) { 4 | document.title = title 5 | const ua = navigator.userAgent 6 | // eslint-disable-next-line 7 | const regex = /\bMicroMessenger\/([\d\.]+)/ 8 | if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) { 9 | const i = document.createElement('iframe') 10 | i.src = '/favicon.ico' 11 | i.style.display = 'none' 12 | i.onload = function () { 13 | setTimeout(function () { 14 | i.remove() 15 | }, 9) 16 | } 17 | document.body.appendChild(i) 18 | } 19 | } 20 | 21 | export const domTitle = config.title 22 | -------------------------------------------------------------------------------- /src/utils/filter.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import moment from 'moment' 3 | import 'moment/locale/zh-cn' 4 | moment.locale('zh-cn') 5 | 6 | Vue.filter('NumberFormat', function (value) { 7 | if (!value) { 8 | return '0' 9 | } 10 | const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断 11 | return intPartFormat 12 | }) 13 | 14 | Vue.filter('dayjs', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { 15 | return moment(dataStr).format(pattern) 16 | }) 17 | 18 | Vue.filter('moment', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { 19 | return moment(dataStr).format(pattern) 20 | }) 21 | -------------------------------------------------------------------------------- /src/utils/helper/permission.js: -------------------------------------------------------------------------------- 1 | export const PERMISSION_ENUM = { 2 | 'add': { key: 'add', label: '新增' }, 3 | 'delete': { key: 'delete', label: '删除' }, 4 | 'edit': { key: 'edit', label: '修改' }, 5 | 'query': { key: 'query', label: '查询' }, 6 | 'get': { key: 'get', label: '详情' }, 7 | 'enable': { key: 'enable', label: '启用' }, 8 | 'disable': { key: 'disable', label: '禁用' }, 9 | 'import': { key: 'import', label: '导入' }, 10 | 'export': { key: 'export', label: '导出' } 11 | } 12 | 13 | function plugin (Vue) { 14 | if (plugin.installed) { 15 | return 16 | } 17 | 18 | !Vue.prototype.$auth && Object.defineProperties(Vue.prototype, { 19 | $auth: { 20 | get () { 21 | const _this = this 22 | return (permissions) => { 23 | const [permission, action] = permissions.split('.') 24 | const permissionList = _this.$store.getters.roles.permissions 25 | return permissionList.find((val) => { 26 | return val.permissionId === permission 27 | }).actionList.findIndex((val) => { 28 | return val === action 29 | }) > -1 30 | } 31 | } 32 | } 33 | }) 34 | 35 | !Vue.prototype.$enum && Object.defineProperties(Vue.prototype, { 36 | $enum: { 37 | get () { 38 | // const _this = this; 39 | return (val) => { 40 | let result = PERMISSION_ENUM 41 | val && val.split('.').forEach(v => { 42 | result = result && result[v] || null 43 | }) 44 | return result 45 | } 46 | } 47 | } 48 | }) 49 | } 50 | 51 | export default plugin 52 | -------------------------------------------------------------------------------- /src/utils/permissions.js: -------------------------------------------------------------------------------- 1 | export function actionToObject (json) { 2 | try { 3 | return JSON.parse(json) 4 | } catch (e) { 5 | console.log('err', e.message) 6 | } 7 | return [] 8 | } 9 | -------------------------------------------------------------------------------- /src/utils/routeConvert.js: -------------------------------------------------------------------------------- 1 | import cloneDeep from 'lodash.clonedeep' 2 | 3 | export function convertRoutes (nodes) { 4 | if (!nodes) return null 5 | 6 | nodes = cloneDeep(nodes) 7 | 8 | let queue = Array.isArray(nodes) ? nodes.concat() : [nodes] 9 | 10 | while (queue.length) { 11 | const levelSize = queue.length 12 | 13 | for (let i = 0; i < levelSize; i++) { 14 | const node = queue.shift() 15 | 16 | if (!node.children || !node.children.length) continue 17 | 18 | node.children.forEach(child => { 19 | // 转化相对路径 20 | if (child.path[0] !== '/' && !child.path.startsWith('http')) { 21 | child.path = node.path.replace(/(\w*)[/]*$/, `$1/${child.path}`) 22 | } 23 | }) 24 | 25 | queue = queue.concat(node.children) 26 | } 27 | } 28 | 29 | return nodes 30 | } 31 | -------------------------------------------------------------------------------- /src/utils/screenLog.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export const printANSI = () => { 3 | // console.clear() 4 | console.log('[Antd Pro] created()') 5 | // ASCII - ANSI Shadow 6 | let text = ` 7 | █████╗ ███╗ ██╗████████╗██████╗ ██████╗ ██████╗ ██████╗ 8 | ██╔══██╗████╗ ██║╚══██╔══╝██╔══██╗ ██╔══██╗██╔══██╗██╔═══██╗ 9 | ███████║██╔██╗ ██║ ██║ ██║ ██║ ██████╔╝██████╔╝██║ ██║ 10 | ██╔══██║██║╚██╗██║ ██║ ██║ ██║ ██╔═══╝ ██╔══██╗██║ ██║ 11 | ██║ ██║██║ ╚████║ ██║ ██████╔╝ ██║ ██║ ██║╚██████╔╝ 12 | ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ 13 | \t\t\t\t\tPublished ${APP_VERSION}-${GIT_HASH} @ antdv.com 14 | \t\t\t\t\tBuild date: ${BUILD_DATE}` 15 | console.log(`%c${text}`, 'color: #fc4d50') 16 | console.log('%c感谢使用 Antd Vue Pro!', 'color: #000; font-size: 14px; font-family: Hiragino Sans GB,Microsoft YaHei,\\\\5FAE\\8F6F\\96C5\\9ED1,Droid Sans Fallback,Source Sans,Wenquanyi Micro Hei,WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei,Apple LiGothic Medium,SimHei,ST Heiti,WenQuanYi Zen Hei Sharp,sans-serif;') 17 | console.log('%cThanks for using Antd Vue Pro!', 'color: #fff; font-size: 14px; font-weight: 300; text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;') 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/util.js: -------------------------------------------------------------------------------- 1 | export function timeFix () { 2 | const time = new Date() 3 | const hour = time.getHours() 4 | return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好' 5 | } 6 | 7 | export function welcome () { 8 | const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 DOTA', '我猜你可能累了'] 9 | const index = Math.floor(Math.random() * arr.length) 10 | return arr[index] 11 | } 12 | 13 | /** 14 | * 触发 window.resize 15 | */ 16 | export function triggerWindowResizeEvent () { 17 | const event = document.createEvent('HTMLEvents') 18 | event.initEvent('resize', true, true) 19 | event.eventType = 'message' 20 | window.dispatchEvent(event) 21 | } 22 | 23 | export function handleScrollHeader (callback) { 24 | let timer = 0 25 | 26 | let beforeScrollTop = window.pageYOffset 27 | callback = callback || function () {} 28 | window.addEventListener( 29 | 'scroll', 30 | event => { 31 | clearTimeout(timer) 32 | timer = setTimeout(() => { 33 | let direction = 'up' 34 | const afterScrollTop = window.pageYOffset 35 | const delta = afterScrollTop - beforeScrollTop 36 | if (delta === 0) { 37 | return false 38 | } 39 | direction = delta > 0 ? 'down' : 'up' 40 | callback(direction) 41 | beforeScrollTop = afterScrollTop 42 | }, 50) 43 | }, 44 | false 45 | ) 46 | } 47 | 48 | export function isIE () { 49 | const bw = window.navigator.userAgent 50 | const compare = (s) => bw.indexOf(s) >= 0 51 | const ie11 = (() => 'ActiveXObject' in window)() 52 | return compare('MSIE') || ie11 53 | } 54 | 55 | /** 56 | * Remove loading animate 57 | * @param id parent element id or class 58 | * @param timeout 59 | */ 60 | export function removeLoadingAnimate (id = '', timeout = 1500) { 61 | if (id === '') { 62 | return 63 | } 64 | setTimeout(() => { 65 | document.body.removeChild(document.getElementById(id)) 66 | }, timeout) 67 | } 68 | -------------------------------------------------------------------------------- /src/utils/utils.less: -------------------------------------------------------------------------------- 1 | .textOverflow() { 2 | overflow: hidden; 3 | white-space: nowrap; 4 | text-overflow: ellipsis; 5 | word-break: break-all; 6 | } 7 | 8 | .textOverflowMulti(@line: 3, @bg: #fff) { 9 | position: relative; 10 | max-height: @line * 1.5em; 11 | margin-right: -1em; 12 | padding-right: 1em; 13 | overflow: hidden; 14 | line-height: 1.5em; 15 | text-align: justify; 16 | &::before { 17 | position: absolute; 18 | right: 14px; 19 | bottom: 0; 20 | padding: 0 1px; 21 | background: @bg; 22 | content: '...'; 23 | } 24 | &::after { 25 | position: absolute; 26 | right: 14px; 27 | width: 1em; 28 | height: 1em; 29 | margin-top: 0.2em; 30 | background: white; 31 | content: ''; 32 | } 33 | } 34 | 35 | // mixins for clearfix 36 | // ------------------------ 37 | .clearfix() { 38 | zoom: 1; 39 | &::before, 40 | &::after { 41 | display: table; 42 | content: ' '; 43 | } 44 | &::after { 45 | clear: both; 46 | height: 0; 47 | font-size: 0; 48 | visibility: hidden; 49 | } 50 | } -------------------------------------------------------------------------------- /src/views/404.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 21 | -------------------------------------------------------------------------------- /src/views/user/RegisterResult.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 41 | 42 | 45 | -------------------------------------------------------------------------------- /tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /webstorm.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const webpackConfig = require('@vue/cli-service/webpack.config.js') 3 | module.exports = webpackConfig 4 | --------------------------------------------------------------------------------