Copy disabled (too large)
Download .txt
Showing preview only (31,245K chars total). Download the full file to get everything.
Repository: mindoc-org/mindoc
Branch: master
Commit: bec17630274e
Files: 1184
Total size: 46.9 MB
Directory structure:
gitextract_8kp_8qo8/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE.md
├── README.md
├── appveyor.yml
├── build_amd64.sh
├── build_musl_amd64.sh
├── cache/
│ ├── cache.go
│ └── cache_null.go
├── commands/
│ ├── command.go
│ ├── daemon/
│ │ └── daemon.go
│ ├── install.go
│ ├── migrate/
│ │ ├── migrate.go
│ │ └── migrate_v03.go
│ └── update.go
├── conf/
│ ├── app.conf.example
│ ├── enumerate.go
│ ├── lang/
│ │ ├── en-us.ini
│ │ ├── ru-ru.ini
│ │ └── zh-cn.ini
│ ├── mail.go
│ └── workweixin.go
├── controllers/
│ ├── AccountController.go
│ ├── BaseController.go
│ ├── BlogController.go
│ ├── BookController.go
│ ├── BookMemberController.go
│ ├── CommentController.go
│ ├── DocumentController.go
│ ├── ErrorController.go
│ ├── HomeController.go
│ ├── ItemsetsController.go
│ ├── LabelController.go
│ ├── ManagerController.go
│ ├── SearchController.go
│ ├── SettingController.go
│ ├── TemplateController.go
│ └── const.go
├── converter/
│ ├── converter.go
│ └── util.go
├── database/
│ └── clean.py
├── dev-win-build.cmd
├── docker-compose.yml
├── go.mod
├── go.sum
├── graphics/
│ ├── copy.go
│ └── file.go
├── lib/
│ └── time/
│ ├── README
│ └── update.bash
├── mail/
│ ├── smtp.go
│ ├── smtp_test.go
│ └── util.go
├── main.go
├── mcp/
│ ├── handler.go
│ ├── mcp.go
│ └── middleware.go
├── models/
│ ├── AttachmentModel.go
│ ├── AttachmentResult.go
│ ├── Auth2Account.go
│ ├── Base.go
│ ├── Blog.go
│ ├── BlogResult.go
│ ├── BookModel.go
│ ├── BookResult.go
│ ├── CommentModel.go
│ ├── ContentReverseIndex.go
│ ├── ConvertBookResult.go
│ ├── Dashboard.go
│ ├── DocumentHistory.go
│ ├── DocumentModel.go
│ ├── DocumentSearchResult.go
│ ├── DocumentTree.go
│ ├── Errors.go
│ ├── Itemsets.go
│ ├── LabelModel.go
│ ├── Logs.go
│ ├── Member.go
│ ├── MemberResult.go
│ ├── MemberToken.go
│ ├── Migrations.go
│ ├── Options.go
│ ├── Relationship.go
│ ├── Team.go
│ ├── TeamMember.go
│ ├── TeamRelationship.go
│ ├── Template.go
│ ├── comment_result.go
│ └── comment_vote.go
├── routers/
│ ├── filter.go
│ └── router.go
├── simsun.ttc
├── start.sh
├── static/
│ ├── bootstrap/
│ │ ├── css/
│ │ │ ├── bootstrap-theme.css
│ │ │ └── bootstrap.css
│ │ ├── js/
│ │ │ ├── bootstrap.js
│ │ │ └── npm.js
│ │ └── plugins/
│ │ ├── bootstrap-fileinput/
│ │ │ └── 4.4.7/
│ │ │ ├── css/
│ │ │ │ ├── fileinput-rtl.css
│ │ │ │ └── fileinput.css
│ │ │ ├── js/
│ │ │ │ ├── fileinput.js
│ │ │ │ ├── locales/
│ │ │ │ │ ├── LANG.js
│ │ │ │ │ ├── ar.js
│ │ │ │ │ ├── az.js
│ │ │ │ │ ├── bg.js
│ │ │ │ │ ├── ca.js
│ │ │ │ │ ├── cr.js
│ │ │ │ │ ├── cs.js
│ │ │ │ │ ├── da.js
│ │ │ │ │ ├── de.js
│ │ │ │ │ ├── el.js
│ │ │ │ │ ├── es.js
│ │ │ │ │ ├── et.js
│ │ │ │ │ ├── fa.js
│ │ │ │ │ ├── fi.js
│ │ │ │ │ ├── fr.js
│ │ │ │ │ ├── gl.js
│ │ │ │ │ ├── hu.js
│ │ │ │ │ ├── id.js
│ │ │ │ │ ├── it.js
│ │ │ │ │ ├── ja.js
│ │ │ │ │ ├── ka.js
│ │ │ │ │ ├── kr.js
│ │ │ │ │ ├── kz.js
│ │ │ │ │ ├── lt.js
│ │ │ │ │ ├── nl.js
│ │ │ │ │ ├── no.js
│ │ │ │ │ ├── pl.js
│ │ │ │ │ ├── pt-BR.js
│ │ │ │ │ ├── pt.js
│ │ │ │ │ ├── ro.js
│ │ │ │ │ ├── ru.js
│ │ │ │ │ ├── sk.js
│ │ │ │ │ ├── sl.js
│ │ │ │ │ ├── sv.js
│ │ │ │ │ ├── th.js
│ │ │ │ │ ├── tr.js
│ │ │ │ │ ├── uk.js
│ │ │ │ │ ├── vi.js
│ │ │ │ │ ├── zh-TW.js
│ │ │ │ │ └── zh.js
│ │ │ │ └── plugins/
│ │ │ │ ├── piexif.js
│ │ │ │ ├── purify.js
│ │ │ │ └── sortable.js
│ │ │ └── themes/
│ │ │ ├── explorer/
│ │ │ │ ├── theme.css
│ │ │ │ └── theme.js
│ │ │ ├── explorer-fa/
│ │ │ │ ├── theme.css
│ │ │ │ └── theme.js
│ │ │ ├── fa/
│ │ │ │ └── theme.js
│ │ │ └── gly/
│ │ │ └── theme.js
│ │ ├── bootstrap-switch/
│ │ │ ├── css/
│ │ │ │ ├── bootstrap2/
│ │ │ │ │ └── bootstrap-switch.css
│ │ │ │ └── bootstrap3/
│ │ │ │ └── bootstrap-switch.css
│ │ │ └── js/
│ │ │ └── bootstrap-switch.js
│ │ ├── bootstrap-wysiwyg/
│ │ │ ├── bootstrap-wysiwyg.js
│ │ │ └── external/
│ │ │ ├── google-code-prettify/
│ │ │ │ ├── lang-apollo.js
│ │ │ │ ├── lang-basic.js
│ │ │ │ ├── lang-clj.js
│ │ │ │ ├── lang-css.js
│ │ │ │ ├── lang-dart.js
│ │ │ │ ├── lang-erlang.js
│ │ │ │ ├── lang-go.js
│ │ │ │ ├── lang-hs.js
│ │ │ │ ├── lang-lisp.js
│ │ │ │ ├── lang-llvm.js
│ │ │ │ ├── lang-lua.js
│ │ │ │ ├── lang-matlab.js
│ │ │ │ ├── lang-ml.js
│ │ │ │ ├── lang-mumps.js
│ │ │ │ ├── lang-n.js
│ │ │ │ ├── lang-pascal.js
│ │ │ │ ├── lang-proto.js
│ │ │ │ ├── lang-r.js
│ │ │ │ ├── lang-rd.js
│ │ │ │ ├── lang-scala.js
│ │ │ │ ├── lang-sql.js
│ │ │ │ ├── lang-tcl.js
│ │ │ │ ├── lang-tex.js
│ │ │ │ ├── lang-vb.js
│ │ │ │ ├── lang-vhdl.js
│ │ │ │ ├── lang-wiki.js
│ │ │ │ ├── lang-xq.js
│ │ │ │ ├── lang-yaml.js
│ │ │ │ ├── prettify.css
│ │ │ │ ├── prettify.js
│ │ │ │ └── run_prettify.js
│ │ │ └── jquery.hotkeys.js
│ │ └── tagsinput/
│ │ ├── bootstrap-tagsinput.css
│ │ ├── bootstrap-tagsinput.js
│ │ └── bootstrap-tagsinput.less
│ ├── bootstrap-paginator/
│ │ └── bootstrap-paginator.js
│ ├── cherry/
│ │ ├── addons/
│ │ │ ├── cherry-code-block-mermaid-plugin.d.ts
│ │ │ ├── cherry-code-block-mermaid-plugin.js
│ │ │ ├── cherry-code-block-plantuml-plugin.d.ts
│ │ │ └── cherry-code-block-plantuml-plugin.js
│ │ ├── cherry-markdown.css
│ │ ├── cherry-markdown.js
│ │ ├── drawio-demo.js
│ │ ├── drawio_demo/
│ │ │ ├── Actions.js
│ │ │ ├── Dialogs.js
│ │ │ ├── Editor.js
│ │ │ ├── EditorUi.js
│ │ │ ├── Format.js
│ │ │ ├── Graph.js
│ │ │ ├── Init.js
│ │ │ ├── Menus.js
│ │ │ ├── Shapes.js
│ │ │ ├── Sidebar.js
│ │ │ ├── Toolbar.js
│ │ │ ├── atlas.css
│ │ │ ├── dark-default.xml
│ │ │ ├── dark.css
│ │ │ ├── default-old.xml
│ │ │ ├── default.xml
│ │ │ ├── drawio-demo.js
│ │ │ ├── font/
│ │ │ │ └── graph.iconfont.less
│ │ │ ├── grapheditor.css
│ │ │ ├── image/
│ │ │ │ └── stencils/
│ │ │ │ ├── arrows.xml
│ │ │ │ ├── basic.xml
│ │ │ │ ├── bpmn.xml
│ │ │ │ └── flowchart.xml
│ │ │ ├── jscolor/
│ │ │ │ └── jscolor.js
│ │ │ ├── lib/
│ │ │ │ └── base64.js
│ │ │ ├── resources/
│ │ │ │ ├── en.txt
│ │ │ │ └── zh.txt
│ │ │ └── src/
│ │ │ ├── css/
│ │ │ │ ├── common.css
│ │ │ │ └── explorer.css
│ │ │ ├── grapheditor.less
│ │ │ ├── js/
│ │ │ │ ├── editor/
│ │ │ │ │ ├── mxDefaultKeyHandler.js
│ │ │ │ │ ├── mxDefaultPopupMenu.js
│ │ │ │ │ ├── mxDefaultToolbar.js
│ │ │ │ │ └── mxEditor.js
│ │ │ │ ├── handler/
│ │ │ │ │ ├── mxCellHighlight.js
│ │ │ │ │ ├── mxCellMarker.js
│ │ │ │ │ ├── mxCellTracker.js
│ │ │ │ │ ├── mxConnectionHandler.js
│ │ │ │ │ ├── mxConstraintHandler.js
│ │ │ │ │ ├── mxEdgeHandler.js
│ │ │ │ │ ├── mxEdgeSegmentHandler.js
│ │ │ │ │ ├── mxElbowEdgeHandler.js
│ │ │ │ │ ├── mxGraphHandler.js
│ │ │ │ │ ├── mxHandle.js
│ │ │ │ │ ├── mxKeyHandler.js
│ │ │ │ │ ├── mxPanningHandler.js
│ │ │ │ │ ├── mxPopupMenuHandler.js
│ │ │ │ │ ├── mxRubberband.js
│ │ │ │ │ ├── mxSelectionCellsHandler.js
│ │ │ │ │ ├── mxTooltipHandler.js
│ │ │ │ │ └── mxVertexHandler.js
│ │ │ │ ├── index.txt
│ │ │ │ ├── io/
│ │ │ │ │ ├── mxCellCodec.js
│ │ │ │ │ ├── mxChildChangeCodec.js
│ │ │ │ │ ├── mxCodec.js
│ │ │ │ │ ├── mxCodecRegistry.js
│ │ │ │ │ ├── mxDefaultKeyHandlerCodec.js
│ │ │ │ │ ├── mxDefaultPopupMenuCodec.js
│ │ │ │ │ ├── mxDefaultToolbarCodec.js
│ │ │ │ │ ├── mxEditorCodec.js
│ │ │ │ │ ├── mxGenericChangeCodec.js
│ │ │ │ │ ├── mxGraphCodec.js
│ │ │ │ │ ├── mxGraphViewCodec.js
│ │ │ │ │ ├── mxModelCodec.js
│ │ │ │ │ ├── mxObjectCodec.js
│ │ │ │ │ ├── mxRootChangeCodec.js
│ │ │ │ │ ├── mxStylesheetCodec.js
│ │ │ │ │ └── mxTerminalChangeCodec.js
│ │ │ │ ├── layout/
│ │ │ │ │ ├── hierarchical/
│ │ │ │ │ │ ├── model/
│ │ │ │ │ │ │ ├── mxGraphAbstractHierarchyCell.js
│ │ │ │ │ │ │ ├── mxGraphHierarchyEdge.js
│ │ │ │ │ │ │ ├── mxGraphHierarchyModel.js
│ │ │ │ │ │ │ ├── mxGraphHierarchyNode.js
│ │ │ │ │ │ │ └── mxSwimlaneModel.js
│ │ │ │ │ │ ├── mxHierarchicalLayout.js
│ │ │ │ │ │ ├── mxSwimlaneLayout.js
│ │ │ │ │ │ └── stage/
│ │ │ │ │ │ ├── mxCoordinateAssignment.js
│ │ │ │ │ │ ├── mxHierarchicalLayoutStage.js
│ │ │ │ │ │ ├── mxMedianHybridCrossingReduction.js
│ │ │ │ │ │ ├── mxMinimumCycleRemover.js
│ │ │ │ │ │ └── mxSwimlaneOrdering.js
│ │ │ │ │ ├── mxCircleLayout.js
│ │ │ │ │ ├── mxCompactTreeLayout.js
│ │ │ │ │ ├── mxCompositeLayout.js
│ │ │ │ │ ├── mxEdgeLabelLayout.js
│ │ │ │ │ ├── mxFastOrganicLayout.js
│ │ │ │ │ ├── mxGraphLayout.js
│ │ │ │ │ ├── mxParallelEdgeLayout.js
│ │ │ │ │ ├── mxPartitionLayout.js
│ │ │ │ │ ├── mxRadialTreeLayout.js
│ │ │ │ │ └── mxStackLayout.js
│ │ │ │ ├── model/
│ │ │ │ │ ├── mxCell.js
│ │ │ │ │ ├── mxCellPath.js
│ │ │ │ │ ├── mxGeometry.js
│ │ │ │ │ └── mxGraphModel.js
│ │ │ │ ├── mxClient.js
│ │ │ │ ├── shape/
│ │ │ │ │ ├── mxActor.js
│ │ │ │ │ ├── mxArrow.js
│ │ │ │ │ ├── mxArrowConnector.js
│ │ │ │ │ ├── mxCloud.js
│ │ │ │ │ ├── mxConnector.js
│ │ │ │ │ ├── mxCylinder.js
│ │ │ │ │ ├── mxDoubleEllipse.js
│ │ │ │ │ ├── mxEllipse.js
│ │ │ │ │ ├── mxHexagon.js
│ │ │ │ │ ├── mxImageShape.js
│ │ │ │ │ ├── mxLabel.js
│ │ │ │ │ ├── mxLine.js
│ │ │ │ │ ├── mxMarker.js
│ │ │ │ │ ├── mxPolyline.js
│ │ │ │ │ ├── mxRectangleShape.js
│ │ │ │ │ ├── mxRhombus.js
│ │ │ │ │ ├── mxShape.js
│ │ │ │ │ ├── mxStencil.js
│ │ │ │ │ ├── mxStencilRegistry.js
│ │ │ │ │ ├── mxSwimlane.js
│ │ │ │ │ ├── mxText.js
│ │ │ │ │ └── mxTriangle.js
│ │ │ │ ├── util/
│ │ │ │ │ ├── mxAbstractCanvas2D.js
│ │ │ │ │ ├── mxAnimation.js
│ │ │ │ │ ├── mxAutoSaveManager.js
│ │ │ │ │ ├── mxClipboard.js
│ │ │ │ │ ├── mxConstants.js
│ │ │ │ │ ├── mxDictionary.js
│ │ │ │ │ ├── mxDivResizer.js
│ │ │ │ │ ├── mxDragSource.js
│ │ │ │ │ ├── mxEffects.js
│ │ │ │ │ ├── mxEvent.js
│ │ │ │ │ ├── mxEventObject.js
│ │ │ │ │ ├── mxEventSource.js
│ │ │ │ │ ├── mxForm.js
│ │ │ │ │ ├── mxGuide.js
│ │ │ │ │ ├── mxImage.js
│ │ │ │ │ ├── mxImageBundle.js
│ │ │ │ │ ├── mxImageExport.js
│ │ │ │ │ ├── mxLog.js
│ │ │ │ │ ├── mxMorphing.js
│ │ │ │ │ ├── mxMouseEvent.js
│ │ │ │ │ ├── mxObjectIdentity.js
│ │ │ │ │ ├── mxPanningManager.js
│ │ │ │ │ ├── mxPoint.js
│ │ │ │ │ ├── mxPopupMenu.js
│ │ │ │ │ ├── mxRectangle.js
│ │ │ │ │ ├── mxResources.js
│ │ │ │ │ ├── mxSvgCanvas2D.js
│ │ │ │ │ ├── mxToolbar.js
│ │ │ │ │ ├── mxUndoManager.js
│ │ │ │ │ ├── mxUndoableEdit.js
│ │ │ │ │ ├── mxUrlConverter.js
│ │ │ │ │ ├── mxUtils.js
│ │ │ │ │ ├── mxVmlCanvas2D.js
│ │ │ │ │ ├── mxWindow.js
│ │ │ │ │ ├── mxXmlCanvas2D.js
│ │ │ │ │ └── mxXmlRequest.js
│ │ │ │ └── view/
│ │ │ │ ├── mxCellEditor.js
│ │ │ │ ├── mxCellOverlay.js
│ │ │ │ ├── mxCellRenderer.js
│ │ │ │ ├── mxCellState.js
│ │ │ │ ├── mxCellStatePreview.js
│ │ │ │ ├── mxConnectionConstraint.js
│ │ │ │ ├── mxEdgeStyle.js
│ │ │ │ ├── mxGraph.js
│ │ │ │ ├── mxGraphSelectionModel.js
│ │ │ │ ├── mxGraphView.js
│ │ │ │ ├── mxLayoutManager.js
│ │ │ │ ├── mxMultiplicity.js
│ │ │ │ ├── mxOutline.js
│ │ │ │ ├── mxPerimeter.js
│ │ │ │ ├── mxPrintPreview.js
│ │ │ │ ├── mxStyleRegistry.js
│ │ │ │ ├── mxStylesheet.js
│ │ │ │ ├── mxSwimlaneManager.js
│ │ │ │ └── mxTemporaryCellStates.js
│ │ │ └── resources/
│ │ │ ├── editor.txt
│ │ │ ├── editor_de.txt
│ │ │ ├── editor_zh.txt
│ │ │ ├── graph.txt
│ │ │ ├── graph_de.txt
│ │ │ └── graph_zh.txt
│ │ ├── drawio_demo.html
│ │ ├── mxgraph/
│ │ │ ├── css/
│ │ │ │ ├── common.css
│ │ │ │ └── explorer.css
│ │ │ └── mxClient.js
│ │ └── pinyin/
│ │ ├── README.md
│ │ ├── hanziPinyin.js
│ │ ├── hanziPinyinWithoutYin.js
│ │ ├── pinyin.js
│ │ └── pinyin_dist.js
│ ├── cropper/
│ │ └── 2.3.4/
│ │ ├── cropper.css
│ │ └── cropper.js
│ ├── css/
│ │ ├── export.css
│ │ ├── jstree.css
│ │ ├── kancloud.css
│ │ ├── main.css
│ │ ├── markdown.css
│ │ ├── markdown.preview.css
│ │ └── print.css
│ ├── editor.md/
│ │ ├── css/
│ │ │ ├── editormd.css
│ │ │ ├── editormd.logo.css
│ │ │ └── editormd.preview.css
│ │ ├── editormd.amd.js
│ │ ├── editormd.js
│ │ ├── fonts/
│ │ │ └── FontAwesome.otf
│ │ ├── languages/
│ │ │ ├── en.js
│ │ │ └── zh-tw.js
│ │ ├── lib/
│ │ │ ├── codemirror/
│ │ │ │ ├── AUTHORS
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── addon/
│ │ │ │ │ ├── comment/
│ │ │ │ │ │ ├── comment.js
│ │ │ │ │ │ └── continuecomment.js
│ │ │ │ │ ├── dialog/
│ │ │ │ │ │ ├── dialog.css
│ │ │ │ │ │ └── dialog.js
│ │ │ │ │ ├── display/
│ │ │ │ │ │ ├── fullscreen.css
│ │ │ │ │ │ ├── fullscreen.js
│ │ │ │ │ │ ├── panel.js
│ │ │ │ │ │ ├── placeholder.js
│ │ │ │ │ │ └── rulers.js
│ │ │ │ │ ├── edit/
│ │ │ │ │ │ ├── closebrackets.js
│ │ │ │ │ │ ├── closetag.js
│ │ │ │ │ │ ├── continuelist.js
│ │ │ │ │ │ ├── matchbrackets.js
│ │ │ │ │ │ ├── matchtags.js
│ │ │ │ │ │ └── trailingspace.js
│ │ │ │ │ ├── fold/
│ │ │ │ │ │ ├── brace-fold.js
│ │ │ │ │ │ ├── comment-fold.js
│ │ │ │ │ │ ├── foldcode.js
│ │ │ │ │ │ ├── foldgutter.css
│ │ │ │ │ │ ├── foldgutter.js
│ │ │ │ │ │ ├── indent-fold.js
│ │ │ │ │ │ ├── markdown-fold.js
│ │ │ │ │ │ └── xml-fold.js
│ │ │ │ │ ├── hint/
│ │ │ │ │ │ ├── anyword-hint.js
│ │ │ │ │ │ ├── css-hint.js
│ │ │ │ │ │ ├── html-hint.js
│ │ │ │ │ │ ├── javascript-hint.js
│ │ │ │ │ │ ├── show-hint.css
│ │ │ │ │ │ ├── show-hint.js
│ │ │ │ │ │ ├── sql-hint.js
│ │ │ │ │ │ └── xml-hint.js
│ │ │ │ │ ├── lint/
│ │ │ │ │ │ ├── coffeescript-lint.js
│ │ │ │ │ │ ├── css-lint.js
│ │ │ │ │ │ ├── javascript-lint.js
│ │ │ │ │ │ ├── json-lint.js
│ │ │ │ │ │ ├── lint.css
│ │ │ │ │ │ ├── lint.js
│ │ │ │ │ │ └── yaml-lint.js
│ │ │ │ │ ├── merge/
│ │ │ │ │ │ ├── merge.css
│ │ │ │ │ │ └── merge.js
│ │ │ │ │ ├── mode/
│ │ │ │ │ │ ├── loadmode.js
│ │ │ │ │ │ ├── multiplex.js
│ │ │ │ │ │ ├── multiplex_test.js
│ │ │ │ │ │ ├── overlay.js
│ │ │ │ │ │ └── simple.js
│ │ │ │ │ ├── runmode/
│ │ │ │ │ │ ├── colorize.js
│ │ │ │ │ │ ├── runmode-standalone.js
│ │ │ │ │ │ ├── runmode.js
│ │ │ │ │ │ └── runmode.node.js
│ │ │ │ │ ├── scroll/
│ │ │ │ │ │ ├── annotatescrollbar.js
│ │ │ │ │ │ ├── scrollpastend.js
│ │ │ │ │ │ ├── simplescrollbars.css
│ │ │ │ │ │ └── simplescrollbars.js
│ │ │ │ │ ├── search/
│ │ │ │ │ │ ├── match-highlighter.js
│ │ │ │ │ │ ├── matchesonscrollbar.css
│ │ │ │ │ │ ├── matchesonscrollbar.js
│ │ │ │ │ │ ├── search.js
│ │ │ │ │ │ └── searchcursor.js
│ │ │ │ │ ├── selection/
│ │ │ │ │ │ ├── active-line.js
│ │ │ │ │ │ ├── mark-selection.js
│ │ │ │ │ │ └── selection-pointer.js
│ │ │ │ │ ├── tern/
│ │ │ │ │ │ ├── tern.css
│ │ │ │ │ │ ├── tern.js
│ │ │ │ │ │ └── worker.js
│ │ │ │ │ └── wrap/
│ │ │ │ │ └── hardwrap.js
│ │ │ │ ├── bower.json
│ │ │ │ ├── lib/
│ │ │ │ │ ├── codemirror.css
│ │ │ │ │ └── codemirror.js
│ │ │ │ ├── mode/
│ │ │ │ │ ├── apl/
│ │ │ │ │ │ ├── apl.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── asterisk/
│ │ │ │ │ │ ├── asterisk.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── clike/
│ │ │ │ │ │ ├── clike.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── scala.html
│ │ │ │ │ ├── clojure/
│ │ │ │ │ │ ├── clojure.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── cobol/
│ │ │ │ │ │ ├── cobol.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── coffeescript/
│ │ │ │ │ │ ├── coffeescript.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── commonlisp/
│ │ │ │ │ │ ├── commonlisp.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── css/
│ │ │ │ │ │ ├── css.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── less.html
│ │ │ │ │ │ ├── less_test.js
│ │ │ │ │ │ ├── scss.html
│ │ │ │ │ │ ├── scss_test.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── cypher/
│ │ │ │ │ │ ├── cypher.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── d/
│ │ │ │ │ │ ├── d.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dart/
│ │ │ │ │ │ ├── dart.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── diff/
│ │ │ │ │ │ ├── diff.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── django/
│ │ │ │ │ │ ├── django.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dockerfile/
│ │ │ │ │ │ ├── dockerfile.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dtd/
│ │ │ │ │ │ ├── dtd.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dylan/
│ │ │ │ │ │ ├── dylan.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── ebnf/
│ │ │ │ │ │ ├── ebnf.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── ecl/
│ │ │ │ │ │ ├── ecl.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── eiffel/
│ │ │ │ │ │ ├── eiffel.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── erlang/
│ │ │ │ │ │ ├── erlang.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── forth/
│ │ │ │ │ │ ├── forth.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── fortran/
│ │ │ │ │ │ ├── fortran.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── gas/
│ │ │ │ │ │ ├── gas.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── gfm/
│ │ │ │ │ │ ├── gfm.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── gherkin/
│ │ │ │ │ │ ├── gherkin.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── go/
│ │ │ │ │ │ ├── go.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── groovy/
│ │ │ │ │ │ ├── groovy.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── haml/
│ │ │ │ │ │ ├── haml.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── haskell/
│ │ │ │ │ │ ├── haskell.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── haxe/
│ │ │ │ │ │ ├── haxe.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── htmlembedded/
│ │ │ │ │ │ ├── htmlembedded.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── htmlmixed/
│ │ │ │ │ │ ├── htmlmixed.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── http/
│ │ │ │ │ │ ├── http.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── idl/
│ │ │ │ │ │ ├── idl.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── jade/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── jade.js
│ │ │ │ │ ├── javascript/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── javascript.js
│ │ │ │ │ │ ├── json-ld.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── typescript.html
│ │ │ │ │ ├── jinja2/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── jinja2.js
│ │ │ │ │ ├── julia/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── julia.js
│ │ │ │ │ ├── kotlin/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── kotlin.js
│ │ │ │ │ ├── livescript/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── livescript.js
│ │ │ │ │ ├── lua/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── lua.js
│ │ │ │ │ ├── markdown/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── markdown.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── meta.js
│ │ │ │ │ ├── mirc/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── mirc.js
│ │ │ │ │ ├── mllike/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── mllike.js
│ │ │ │ │ ├── modelica/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── modelica.js
│ │ │ │ │ ├── nginx/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── nginx.js
│ │ │ │ │ ├── ntriples/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── ntriples.js
│ │ │ │ │ ├── octave/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── octave.js
│ │ │ │ │ ├── pascal/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── pascal.js
│ │ │ │ │ ├── pegjs/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── pegjs.js
│ │ │ │ │ ├── perl/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── perl.js
│ │ │ │ │ ├── php/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── php.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── pig/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── pig.js
│ │ │ │ │ ├── properties/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── properties.js
│ │ │ │ │ ├── puppet/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── puppet.js
│ │ │ │ │ ├── python/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── python.js
│ │ │ │ │ ├── q/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── q.js
│ │ │ │ │ ├── r/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── r.js
│ │ │ │ │ ├── rpm/
│ │ │ │ │ │ ├── changes/
│ │ │ │ │ │ │ └── index.html
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── rpm.js
│ │ │ │ │ ├── rst/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── rst.js
│ │ │ │ │ ├── ruby/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── ruby.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── rust/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── rust.js
│ │ │ │ │ ├── sass/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sass.js
│ │ │ │ │ ├── scheme/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── scheme.js
│ │ │ │ │ ├── shell/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── shell.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── sieve/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sieve.js
│ │ │ │ │ ├── slim/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── slim.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── smalltalk/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── smalltalk.js
│ │ │ │ │ ├── smarty/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── smarty.js
│ │ │ │ │ ├── smartymixed/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── smartymixed.js
│ │ │ │ │ ├── solr/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── solr.js
│ │ │ │ │ ├── soy/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── soy.js
│ │ │ │ │ ├── sparql/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sparql.js
│ │ │ │ │ ├── spreadsheet/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── spreadsheet.js
│ │ │ │ │ ├── sql/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sql.js
│ │ │ │ │ ├── stex/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── stex.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── stylus/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── stylus.js
│ │ │ │ │ ├── tcl/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── tcl.js
│ │ │ │ │ ├── textile/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── textile.js
│ │ │ │ │ ├── tiddlywiki/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── tiddlywiki.css
│ │ │ │ │ │ └── tiddlywiki.js
│ │ │ │ │ ├── tiki/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── tiki.css
│ │ │ │ │ │ └── tiki.js
│ │ │ │ │ ├── toml/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── toml.js
│ │ │ │ │ ├── tornado/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── tornado.js
│ │ │ │ │ ├── turtle/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── turtle.js
│ │ │ │ │ ├── vb/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── vb.js
│ │ │ │ │ ├── vbscript/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── vbscript.js
│ │ │ │ │ ├── velocity/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── velocity.js
│ │ │ │ │ ├── verilog/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── verilog.js
│ │ │ │ │ ├── xml/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── xml.js
│ │ │ │ │ ├── xquery/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── xquery.js
│ │ │ │ │ ├── yaml/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── yaml.js
│ │ │ │ │ └── z80/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── z80.js
│ │ │ │ ├── package.json
│ │ │ │ └── theme/
│ │ │ │ ├── 3024-day.css
│ │ │ │ ├── 3024-night.css
│ │ │ │ ├── ambiance-mobile.css
│ │ │ │ ├── ambiance.css
│ │ │ │ ├── base16-dark.css
│ │ │ │ ├── base16-light.css
│ │ │ │ ├── blackboard.css
│ │ │ │ ├── cobalt.css
│ │ │ │ ├── colorforth.css
│ │ │ │ ├── eclipse.css
│ │ │ │ ├── elegant.css
│ │ │ │ ├── erlang-dark.css
│ │ │ │ ├── lesser-dark.css
│ │ │ │ ├── mbo.css
│ │ │ │ ├── mdn-like.css
│ │ │ │ ├── midnight.css
│ │ │ │ ├── monokai.css
│ │ │ │ ├── neat.css
│ │ │ │ ├── neo.css
│ │ │ │ ├── night.css
│ │ │ │ ├── paraiso-dark.css
│ │ │ │ ├── paraiso-light.css
│ │ │ │ ├── pastel-on-dark.css
│ │ │ │ ├── rubyblue.css
│ │ │ │ ├── solarized.css
│ │ │ │ ├── the-matrix.css
│ │ │ │ ├── tomorrow-night-bright.css
│ │ │ │ ├── tomorrow-night-eighties.css
│ │ │ │ ├── twilight.css
│ │ │ │ ├── vibrant-ink.css
│ │ │ │ ├── xq-dark.css
│ │ │ │ ├── xq-light.css
│ │ │ │ └── zenburn.css
│ │ │ ├── highlight/
│ │ │ │ ├── highlight.js
│ │ │ │ ├── languages/
│ │ │ │ │ ├── 1c.js
│ │ │ │ │ ├── abnf.js
│ │ │ │ │ ├── accesslog.js
│ │ │ │ │ ├── actionscript.js
│ │ │ │ │ ├── ada.js
│ │ │ │ │ ├── apache.js
│ │ │ │ │ ├── applescript.js
│ │ │ │ │ ├── arduino.js
│ │ │ │ │ ├── armasm.js
│ │ │ │ │ ├── asciidoc.js
│ │ │ │ │ ├── aspectj.js
│ │ │ │ │ ├── autohotkey.js
│ │ │ │ │ ├── autoit.js
│ │ │ │ │ ├── avrasm.js
│ │ │ │ │ ├── awk.js
│ │ │ │ │ ├── axapta.js
│ │ │ │ │ ├── bash.js
│ │ │ │ │ ├── basic.js
│ │ │ │ │ ├── bnf.js
│ │ │ │ │ ├── brainfuck.js
│ │ │ │ │ ├── cal.js
│ │ │ │ │ ├── capnproto.js
│ │ │ │ │ ├── ceylon.js
│ │ │ │ │ ├── clean.js
│ │ │ │ │ ├── clojure-repl.js
│ │ │ │ │ ├── clojure.js
│ │ │ │ │ ├── cmake.js
│ │ │ │ │ ├── coffeescript.js
│ │ │ │ │ ├── coq.js
│ │ │ │ │ ├── cos.js
│ │ │ │ │ ├── cpp.js
│ │ │ │ │ ├── crmsh.js
│ │ │ │ │ ├── crystal.js
│ │ │ │ │ ├── cs.js
│ │ │ │ │ ├── csp.js
│ │ │ │ │ ├── css.js
│ │ │ │ │ ├── d.js
│ │ │ │ │ ├── dart.js
│ │ │ │ │ ├── delphi.js
│ │ │ │ │ ├── diff.js
│ │ │ │ │ ├── django.js
│ │ │ │ │ ├── dns.js
│ │ │ │ │ ├── dockerfile.js
│ │ │ │ │ ├── dos.js
│ │ │ │ │ ├── dsconfig.js
│ │ │ │ │ ├── dts.js
│ │ │ │ │ ├── dust.js
│ │ │ │ │ ├── ebnf.js
│ │ │ │ │ ├── elixir.js
│ │ │ │ │ ├── elm.js
│ │ │ │ │ ├── erb.js
│ │ │ │ │ ├── erlang-repl.js
│ │ │ │ │ ├── erlang.js
│ │ │ │ │ ├── excel.js
│ │ │ │ │ ├── fix.js
│ │ │ │ │ ├── flix.js
│ │ │ │ │ ├── fortran.js
│ │ │ │ │ ├── fsharp.js
│ │ │ │ │ ├── gams.js
│ │ │ │ │ ├── gauss.js
│ │ │ │ │ ├── gcode.js
│ │ │ │ │ ├── gherkin.js
│ │ │ │ │ ├── glsl.js
│ │ │ │ │ ├── go.js
│ │ │ │ │ ├── golo.js
│ │ │ │ │ ├── gradle.js
│ │ │ │ │ ├── groovy.js
│ │ │ │ │ ├── haml.js
│ │ │ │ │ ├── handlebars.js
│ │ │ │ │ ├── haskell.js
│ │ │ │ │ ├── haxe.js
│ │ │ │ │ ├── hsp.js
│ │ │ │ │ ├── htmlbars.js
│ │ │ │ │ ├── http.js
│ │ │ │ │ ├── inform7.js
│ │ │ │ │ ├── ini.js
│ │ │ │ │ ├── irpf90.js
│ │ │ │ │ ├── java.js
│ │ │ │ │ ├── javascript.js
│ │ │ │ │ ├── json.js
│ │ │ │ │ ├── julia.js
│ │ │ │ │ ├── kotlin.js
│ │ │ │ │ ├── lasso.js
│ │ │ │ │ ├── ldif.js
│ │ │ │ │ ├── less.js
│ │ │ │ │ ├── lisp.js
│ │ │ │ │ ├── livecodeserver.js
│ │ │ │ │ ├── livescript.js
│ │ │ │ │ ├── lsl.js
│ │ │ │ │ ├── lua.js
│ │ │ │ │ ├── makefile.js
│ │ │ │ │ ├── markdown.js
│ │ │ │ │ ├── mathematica.js
│ │ │ │ │ ├── matlab.js
│ │ │ │ │ ├── maxima.js
│ │ │ │ │ ├── mel.js
│ │ │ │ │ ├── mercury.js
│ │ │ │ │ ├── mipsasm.js
│ │ │ │ │ ├── mizar.js
│ │ │ │ │ ├── mojolicious.js
│ │ │ │ │ ├── monkey.js
│ │ │ │ │ ├── moonscript.js
│ │ │ │ │ ├── nginx.js
│ │ │ │ │ ├── nimrod.js
│ │ │ │ │ ├── nix.js
│ │ │ │ │ ├── nsis.js
│ │ │ │ │ ├── objectivec.js
│ │ │ │ │ ├── ocaml.js
│ │ │ │ │ ├── openscad.js
│ │ │ │ │ ├── oxygene.js
│ │ │ │ │ ├── parser3.js
│ │ │ │ │ ├── perl.js
│ │ │ │ │ ├── pf.js
│ │ │ │ │ ├── php.js
│ │ │ │ │ ├── pony.js
│ │ │ │ │ ├── powershell.js
│ │ │ │ │ ├── processing.js
│ │ │ │ │ ├── profile.js
│ │ │ │ │ ├── prolog.js
│ │ │ │ │ ├── protobuf.js
│ │ │ │ │ ├── puppet.js
│ │ │ │ │ ├── purebasic.js
│ │ │ │ │ ├── python.js
│ │ │ │ │ ├── q.js
│ │ │ │ │ ├── qml.js
│ │ │ │ │ ├── r.js
│ │ │ │ │ ├── rib.js
│ │ │ │ │ ├── roboconf.js
│ │ │ │ │ ├── rsl.js
│ │ │ │ │ ├── ruby.js
│ │ │ │ │ ├── ruleslanguage.js
│ │ │ │ │ ├── rust.js
│ │ │ │ │ ├── scala.js
│ │ │ │ │ ├── scheme.js
│ │ │ │ │ ├── scilab.js
│ │ │ │ │ ├── scss.js
│ │ │ │ │ ├── smali.js
│ │ │ │ │ ├── smalltalk.js
│ │ │ │ │ ├── sml.js
│ │ │ │ │ ├── sqf.js
│ │ │ │ │ ├── sql.js
│ │ │ │ │ ├── stan.js
│ │ │ │ │ ├── stata.js
│ │ │ │ │ ├── step21.js
│ │ │ │ │ ├── stylus.js
│ │ │ │ │ ├── subunit.js
│ │ │ │ │ ├── swift.js
│ │ │ │ │ ├── taggerscript.js
│ │ │ │ │ ├── tap.js
│ │ │ │ │ ├── tcl.js
│ │ │ │ │ ├── tex.js
│ │ │ │ │ ├── thrift.js
│ │ │ │ │ ├── tp.js
│ │ │ │ │ ├── twig.js
│ │ │ │ │ ├── typescript.js
│ │ │ │ │ ├── vala.js
│ │ │ │ │ ├── vbnet.js
│ │ │ │ │ ├── vbscript-html.js
│ │ │ │ │ ├── vbscript.js
│ │ │ │ │ ├── verilog.js
│ │ │ │ │ ├── vhdl.js
│ │ │ │ │ ├── vim.js
│ │ │ │ │ ├── x86asm.js
│ │ │ │ │ ├── xl.js
│ │ │ │ │ ├── xml.js
│ │ │ │ │ ├── xquery.js
│ │ │ │ │ ├── yaml.js
│ │ │ │ │ └── zephir.js
│ │ │ │ └── styles/
│ │ │ │ ├── agate.css
│ │ │ │ ├── androidstudio.css
│ │ │ │ ├── arduino-light.css
│ │ │ │ ├── arta.css
│ │ │ │ ├── ascetic.css
│ │ │ │ ├── atelier-cave-dark.css
│ │ │ │ ├── atelier-cave-light.css
│ │ │ │ ├── atelier-dune-dark.css
│ │ │ │ ├── atelier-dune-light.css
│ │ │ │ ├── atelier-estuary-dark.css
│ │ │ │ ├── atelier-estuary-light.css
│ │ │ │ ├── atelier-forest-dark.css
│ │ │ │ ├── atelier-forest-light.css
│ │ │ │ ├── atelier-heath-dark.css
│ │ │ │ ├── atelier-heath-light.css
│ │ │ │ ├── atelier-lakeside-dark.css
│ │ │ │ ├── atelier-lakeside-light.css
│ │ │ │ ├── atelier-plateau-dark.css
│ │ │ │ ├── atelier-plateau-light.css
│ │ │ │ ├── atelier-savanna-dark.css
│ │ │ │ ├── atelier-savanna-light.css
│ │ │ │ ├── atelier-seaside-dark.css
│ │ │ │ ├── atelier-seaside-light.css
│ │ │ │ ├── atelier-sulphurpool-dark.css
│ │ │ │ ├── atelier-sulphurpool-light.css
│ │ │ │ ├── atom-one-dark.css
│ │ │ │ ├── atom-one-light.css
│ │ │ │ ├── brown-paper.css
│ │ │ │ ├── codepen-embed.css
│ │ │ │ ├── color-brewer.css
│ │ │ │ ├── darcula.css
│ │ │ │ ├── dark.css
│ │ │ │ ├── darkula.css
│ │ │ │ ├── default.css
│ │ │ │ ├── docco.css
│ │ │ │ ├── dracula.css
│ │ │ │ ├── far.css
│ │ │ │ ├── foundation.css
│ │ │ │ ├── github-gist.css
│ │ │ │ ├── github.css
│ │ │ │ ├── googlecode.css
│ │ │ │ ├── grayscale.css
│ │ │ │ ├── gruvbox-dark.css
│ │ │ │ ├── gruvbox-light.css
│ │ │ │ ├── hopscotch.css
│ │ │ │ ├── hybrid.css
│ │ │ │ ├── idea.css
│ │ │ │ ├── ir-black.css
│ │ │ │ ├── kimbie.dark.css
│ │ │ │ ├── kimbie.light.css
│ │ │ │ ├── magula.css
│ │ │ │ ├── mono-blue.css
│ │ │ │ ├── monokai-sublime.css
│ │ │ │ ├── monokai.css
│ │ │ │ ├── obsidian.css
│ │ │ │ ├── ocean.css
│ │ │ │ ├── paraiso-dark.css
│ │ │ │ ├── paraiso-light.css
│ │ │ │ ├── pojoaque.css
│ │ │ │ ├── purebasic.css
│ │ │ │ ├── qtcreator_dark.css
│ │ │ │ ├── qtcreator_light.css
│ │ │ │ ├── railscasts.css
│ │ │ │ ├── rainbow.css
│ │ │ │ ├── school-book.css
│ │ │ │ ├── solarized-dark.css
│ │ │ │ ├── solarized-light.css
│ │ │ │ ├── sunburst.css
│ │ │ │ ├── tomorrow-night-blue.css
│ │ │ │ ├── tomorrow-night-bright.css
│ │ │ │ ├── tomorrow-night-eighties.css
│ │ │ │ ├── tomorrow-night.css
│ │ │ │ ├── tomorrow.css
│ │ │ │ ├── vs.css
│ │ │ │ ├── xcode.css
│ │ │ │ ├── xt256.css
│ │ │ │ └── zenburn.css
│ │ │ ├── marked.js
│ │ │ ├── mermaid/
│ │ │ │ └── mermaid.js
│ │ │ ├── mindmap/
│ │ │ │ ├── d3@5.js
│ │ │ │ ├── transform.js
│ │ │ │ └── view.js
│ │ │ └── sequence/
│ │ │ ├── sequence-diagram-min.css
│ │ │ ├── sequence-diagram-min.js
│ │ │ ├── sequence-diagram-raphael-min.js
│ │ │ ├── sequence-diagram-raphael.js
│ │ │ ├── sequence-diagram-snap-min.js
│ │ │ ├── snap.svg-min.js
│ │ │ ├── underscore-min.js
│ │ │ └── webfont.js
│ │ └── plugins/
│ │ ├── code-block-dialog/
│ │ │ └── code-block-dialog.js
│ │ ├── emoji-dialog/
│ │ │ ├── emoji-dialog.js
│ │ │ └── emoji.json
│ │ ├── file-dialog/
│ │ │ └── file-dialog.js
│ │ ├── goto-line-dialog/
│ │ │ └── goto-line-dialog.js
│ │ ├── help-dialog/
│ │ │ ├── help-dialog.js
│ │ │ └── help.md
│ │ ├── html-entities-dialog/
│ │ │ ├── html-entities-dialog.js
│ │ │ └── html-entities.json
│ │ ├── image-dialog/
│ │ │ └── image-dialog.js
│ │ ├── link-dialog/
│ │ │ └── link-dialog.js
│ │ ├── plugin-template.js
│ │ ├── preformatted-text-dialog/
│ │ │ └── preformatted-text-dialog.js
│ │ ├── reference-link-dialog/
│ │ │ └── reference-link-dialog.js
│ │ ├── table-dialog/
│ │ │ └── table-dialog.js
│ │ └── test-plugin/
│ │ └── test-plugin.js
│ ├── font-awesome/
│ │ ├── css/
│ │ │ └── font-awesome.css
│ │ └── fonts/
│ │ └── FontAwesome.otf
│ ├── fonts/
│ │ ├── lato-100.css
│ │ └── notosans.css
│ ├── jquery/
│ │ └── 1.12.4/
│ │ └── jquery.js
│ ├── js/
│ │ ├── array.js
│ │ ├── blog.js
│ │ ├── cherry_markdown.js
│ │ ├── class2browser.js
│ │ ├── dingtalk-ddlogin.js
│ │ ├── dingtalk-jsapi.js
│ │ ├── editor.js
│ │ ├── froala-editor.js
│ │ ├── html-editor.js
│ │ ├── html-to-markdown.js
│ │ ├── jquery.form.js
│ │ ├── jquery.highlight.js
│ │ ├── kancloud.js
│ │ ├── main.js
│ │ ├── markdown.js
│ │ ├── quill.js
│ │ ├── sort.js
│ │ ├── splitbar.js
│ │ ├── wangEditor-plugins/
│ │ │ ├── attach-menu.js
│ │ │ ├── history-menu.js
│ │ │ ├── release-menu.js
│ │ │ └── save-menu.js
│ │ ├── word-to-html.js
│ │ └── x-frame-bypass-1.0.2.js
│ ├── jstree/
│ │ └── 3.3.4/
│ │ ├── jstree.js
│ │ └── themes/
│ │ ├── default/
│ │ │ └── style.css
│ │ └── default-dark/
│ │ └── style.css
│ ├── katex/
│ │ ├── README.md
│ │ ├── katex.css
│ │ └── katex.js
│ ├── layer/
│ │ ├── layer.js
│ │ ├── mobile/
│ │ │ ├── layer.js
│ │ │ └── need/
│ │ │ └── layer.css
│ │ └── skin/
│ │ └── default/
│ │ └── layer.css
│ ├── mammoth/
│ │ └── mammoth.browser.js
│ ├── mergely/
│ │ ├── editor/
│ │ │ ├── editor.css
│ │ │ ├── editor.js
│ │ │ ├── editor.php
│ │ │ └── lib/
│ │ │ ├── farbtastic/
│ │ │ │ ├── LICENSE.txt
│ │ │ │ ├── farbtastic.css
│ │ │ │ ├── farbtastic.js
│ │ │ │ └── index.html
│ │ │ ├── gatag.js
│ │ │ ├── tipsy/
│ │ │ │ ├── jquery.tipsy.js
│ │ │ │ └── tipsy.css
│ │ │ ├── wicked-ui.css
│ │ │ └── wicked-ui.js
│ │ └── lib/
│ │ ├── codemirror.css
│ │ ├── codemirror.js
│ │ ├── mergely.css
│ │ ├── mergely.js
│ │ └── searchcursor.js
│ ├── nprogress/
│ │ ├── nprogress.css
│ │ └── nprogress.js
│ ├── prettify/
│ │ └── themes/
│ │ └── prettify.css
│ ├── prismjs/
│ │ ├── prismjs.css
│ │ └── prismjs.js
│ ├── quill/
│ │ ├── quill.bubble.css
│ │ ├── quill.core.css
│ │ ├── quill.core.js
│ │ ├── quill.icons.js
│ │ ├── quill.js
│ │ └── quill.snow.css
│ ├── table-editor/
│ │ ├── .gitignore
│ │ ├── dist/
│ │ │ └── index.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── main.js
│ │ └── webpack.config.js
│ ├── to-markdown/
│ │ ├── dist/
│ │ │ └── to-markdown.js
│ │ └── lib/
│ │ ├── gfm-converters.js
│ │ ├── html-parser.js
│ │ └── md-converters.js
│ ├── turndown/
│ │ └── turndown.js
│ ├── vuejs/
│ │ ├── vue.common.js
│ │ ├── vue.esm.js
│ │ ├── vue.js
│ │ ├── vue.runtime.common.js
│ │ ├── vue.runtime.esm.js
│ │ └── vue.runtime.js
│ ├── wangEditor/
│ │ ├── wangEditor.d.ts
│ │ └── wangEditor.js
│ └── webuploader/
│ ├── README.md
│ ├── Uploader.swf
│ ├── webuploader.css
│ ├── webuploader.custom.js
│ ├── webuploader.fis.js
│ ├── webuploader.flashonly.js
│ ├── webuploader.html5nodepend.js
│ ├── webuploader.html5only.js
│ ├── webuploader.js
│ ├── webuploader.noimage.js
│ ├── webuploader.nolog.js
│ └── webuploader.withoutimage.js
├── uploads/
│ └── .gitkeep
├── utils/
│ ├── auth2/
│ │ ├── auth2.go
│ │ ├── dingtalk/
│ │ │ └── dingtalk.go
│ │ └── wecom/
│ │ └── wecom.go
│ ├── cryptil/
│ │ └── cryptil.go
│ ├── dingtalk/
│ │ └── dingtalk.go
│ ├── docx2md.go
│ ├── filetil/
│ │ └── filetil.go
│ ├── gob.go
│ ├── gopool/
│ │ └── gopool.go
│ ├── html.go
│ ├── krand.go
│ ├── ldap.go
│ ├── pagination/
│ │ └── pagination.go
│ ├── password.go
│ ├── requests/
│ │ └── requests.go
│ ├── segmenter/
│ │ └── segmenter.go
│ ├── sqltil/
│ │ └── sql.go
│ ├── template_fun.go
│ ├── url.go
│ ├── wkhtmltopdf/
│ │ ├── options.go
│ │ └── wkhtmltopdf.go
│ ├── workweixin/
│ │ └── workweixin.go
│ └── ziptil/
│ └── ziptil.go
└── views/
├── account/
│ ├── auth2_callback.tpl
│ ├── find_password_setp1.tpl
│ ├── find_password_setp2.tpl
│ ├── login.tpl
│ ├── mail_template.tpl
│ └── register.tpl
├── blog/
│ ├── index.tpl
│ ├── index_password.tpl
│ ├── list.tpl
│ ├── manage_edit.tpl
│ ├── manage_list.tpl
│ └── manage_setting.tpl
├── book/
│ ├── dashboard.tpl
│ ├── index.tpl
│ ├── setting.tpl
│ ├── team.tpl
│ └── users.tpl
├── comment/
│ └── index.tpl
├── document/
│ ├── cherry_markdown_edit_template.tpl
│ ├── cherry_read.tpl
│ ├── compare.tpl
│ ├── default_read.tpl
│ ├── document_password.tpl
│ ├── export.tpl
│ ├── froala_edit_template.tpl
│ ├── history.tpl
│ ├── html_edit_template.tpl
│ ├── index.tpl
│ ├── kancloud_read_template.tpl
│ ├── markdown_edit_template.tpl
│ ├── new_html_edit_template.tpl
│ ├── template_api-en.tpl
│ ├── template_api.tpl
│ ├── template_code-en.tpl
│ ├── template_code.tpl
│ ├── template_normal-en.tpl
│ └── template_normal.tpl
├── errors/
│ ├── 403.tpl
│ ├── 404.tpl
│ └── error.tpl
├── home/
│ └── index.tpl
├── items/
│ ├── index.tpl
│ └── list.tpl
├── label/
│ ├── index.tpl
│ └── list.tpl
├── manager/
│ ├── attach_detailed.tpl
│ ├── attach_list.tpl
│ ├── books.tpl
│ ├── comments.tpl
│ ├── config.tpl
│ ├── edit_book.tpl
│ ├── edit_users.tpl
│ ├── index.tpl
│ ├── itemsets.tpl
│ ├── label_list.tpl
│ ├── setting.tpl
│ ├── team.tpl
│ ├── team_book_list.tpl
│ ├── team_member_list.tpl
│ ├── users.tpl
│ └── widgets.tpl
├── search/
│ └── index.tpl
├── setting/
│ ├── index.tpl
│ └── password.tpl
├── template/
│ └── list.tpl
├── template.tpl
└── widgets/
├── footer.tpl
├── header.tpl
└── ie.tpl
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
*.js linguist-language=Go
*.css linguist-language=Go
================================================
FILE: .github/ISSUE_TEMPLATE
================================================
请按照一下格式提交issue,谢谢!
1. 你当前使用的是哪个版本的 MinDoc(`godoc_linux_amd64 version`)?
2. 你当前使用的是什么操作系统?
3. 你是如何操作的?
4. 你期望得到什么结果?
5. 当前遇到的是什么结果?
================================================
FILE: .github/workflows/build.yml
================================================
name: Go
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
outputs:
tag: ${{ steps.git.outputs.tag }}
strategy:
fail-fast: false
matrix:
config:
- {
name: "Windows Latest MSVC",
artifact: "windows",
os: windows-latest
}
- {
name: "Ubuntu Latest GCC",
artifact: "linux",
os: ubuntu-latest
}
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24.0
- name: Build
run: |
go mod tidy
go build -v
# - name: Test
# run: go test -v ./...
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
path: |
conf/**/*
static/**/*
views/**/*
mindoc.*
name: mindoc-${{ matrix.config.artifact }}-${{ steps.git.outputs.tag }}.7z
================================================
FILE: .gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
.DS_Store
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.exe~
mindoc
mindoc_linux_amd64
mindoc_linux_musl_amd64
database/mindoc.db
*.test
*.prof
.idea
.vscode
/conf/app.conf
/vendor
/runtime
/uploads/*.*
!/uploads/.gitkeep
calibre-*.txz
================================================
FILE: .travis.yml
================================================
os: linux
dist: focal
language: go
go:
- "1.18.1"
arch:
- amd64
env:
- GO111MODULE=on CGO_ENABLED=1
install:
- go mod tidy -v
before_install:
- whereis gcc
- go env
script:
- go build -o mindoc_linux_amd64 -ldflags "-w"
- cp conf/app.conf.example conf/app.conf
- ./mindoc_linux_amd64 version
- rm conf/app.conf
before_deploy:
- go mod tidy -v && GOARCH=amd64 GOOS=linux go build -v -o mindoc_linux_amd64 -ldflags="-w -X 'github.com/mindoc-org/mindoc/conf.VERSION=$TRAVIS_TAG' -X 'github.com/mindoc-org/mindoc/conf.BUILD_TIME=`date`' -X 'conf.GO_VERSION=`go version`'"
# remove files
- rm appveyor.yml docker-compose.yml Dockerfile .travis.yml .gitattributes .gitignore go.mod go.sum main.go README.md simsun.ttc start.sh sync_host.sh build_amd64.sh build_musl_amd64.sh
# remove dirs
- rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime
- ls -alh
- cp conf/app.conf.example conf/app.conf
- zip -r mindoc_linux_amd64.zip conf static uploads views lib mindoc_linux_amd64 LICENSE.md
deploy:
provider: releases
token: $CI_USER_TOKEN
cleanup: true
overwrite: true
file:
- mindoc_linux_amd64.zip
on:
tags: true
branch: master
================================================
FILE: Dockerfile
================================================
FROM golang:bookworm AS build
ARG TAG=0.0.1
# 编译-环境变量
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct
ENV CGO_ENABLED=1
ENV GOARCH=amd64
ENV GOOS=linux
# 工作目录
ADD . /go/src/github.com/mindoc-org/mindoc
WORKDIR /go/src/github.com/mindoc-org/mindoc
# 编译
RUN go env
RUN go mod tidy -v
RUN go build -v -o mindoc_linux_amd64 -ldflags "-w -s -X 'main.VERSION=$TAG' -X 'main.BUILD_TIME=`date`' -X 'main.GO_VERSION=`go version`'"
RUN cp conf/app.conf.example conf/app.conf
# 清理不需要的文件
RUN rm appveyor.yml docker-compose.yml Dockerfile .travis.yml .gitattributes .gitignore go.mod go.sum main.go README.md simsun.ttc start.sh conf/*.go
RUN rm -rf cache commands controllers converter .git .github graphics mail models routers utils
# 测试编译的mindoc是否ok
RUN ./mindoc_linux_amd64 version
# 必要的文件复制
ADD simsun.ttc /usr/share/fonts/win/
ADD start.sh /go/src/github.com/mindoc-org/mindoc
# upgrade to the latest
FROM ubuntu:latest
# 切换默认shell为bash
SHELL ["/bin/bash", "-c"]
WORKDIR /mindoc
# 文件复制
COPY --from=build /usr/share/fonts/win/simsun.ttc /usr/share/fonts/win/
COPY --from=build /go/src/github.com/mindoc-org/mindoc/mindoc_linux_amd64 /mindoc/
COPY --from=build /go/src/github.com/mindoc-org/mindoc/start.sh /mindoc/
COPY --from=build /go/src/github.com/mindoc-org/mindoc/LICENSE.md /mindoc/
# 文件夹复制
COPY --from=build /go/src/github.com/mindoc-org/mindoc/lib /mindoc/lib
COPY --from=build /go/src/github.com/mindoc-org/mindoc/conf /mindoc/__default_assets__/conf
COPY --from=build /go/src/github.com/mindoc-org/mindoc/static /mindoc/__default_assets__/static
COPY --from=build /go/src/github.com/mindoc-org/mindoc/views /mindoc/__default_assets__/views
COPY --from=build /go/src/github.com/mindoc-org/mindoc/uploads /mindoc/__default_assets__/uploads
RUN chmod a+r /usr/share/fonts/win/simsun.ttc
RUN sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list /etc/apt/sources.list.d/*
# 更新软件包信息
RUN apt-get update
# 时区设置(如果不设置, calibre依赖的tzdata在安装过程中会要求选择时区)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# tzdata的前端类型默认为readline(Shell情况下)或dialog(支持GUI的情况下)
ARG DEBIAN_FRONTEND=noninteractive
# 安装时区信息
RUN apt install -y --no-install-recommends tzdata
# 重新配置tzdata软件包,使得时区设置生效
RUN dpkg-reconfigure --frontend noninteractive tzdata
# 安装文泉驿字体
# 安装中文语言包
RUN apt install -y fonts-wqy-microhei fonts-wqy-zenhei locales language-pack-zh-hans-base
# 设置默认编码
RUN locale-gen "zh_CN.UTF-8"
RUN update-locale LANG=zh_CN.UTF-8
ENV LANG=zh_CN.UTF-8
ENV LANGUAGE=zh_CN:en
ENV LC_ALL=zh_CN.UTF-8
# 安装必要依赖、下载、解压 calibre 并清理缓存
RUN apt-get install -y --no-install-recommends \
libglx0 libegl1 libnss3 libxcomposite1 libxkbcommon0 libxdamage1 libxrandr-dev libopengl0 libxtst6 libasound2t64 libxkbfile1\
wget xz-utils && \
mkdir -p /tmp/calibre-cache /opt/calibre && \
wget -O /tmp/calibre-cache/calibre-x86_64.txz -c https://download.calibre-ebook.com/7.26.0/calibre-7.26.0-x86_64.txz --no-check-certificate && \
tar xJof /tmp/calibre-cache/calibre-x86_64.txz -C /opt/calibre && \
rm -rf /tmp/calibre-cache && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# 设置环境变量
ENV PATH="/opt/calibre:$PATH" \
QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox" \
QT_QPA_PLATFORM="offscreen"
# 测试 calibre 是否可正常使用
RUN ebook-convert --version
# refer: https://docs.docker.com/engine/reference/builder/#volume
VOLUME ["/mindoc/conf","/mindoc/static","/mindoc/views","/mindoc/uploads","/mindoc/runtime","/mindoc/database"]
# refer: https://docs.docker.com/engine/reference/builder/#expose
EXPOSE 8181/tcp
ENV ZONEINFO=/mindoc/lib/time/zoneinfo.zip
RUN chmod +x /mindoc/start.sh
ENTRYPOINT ["/bin/bash", "/mindoc/start.sh"]
# https://docs.docker.com/engine/reference/commandline/build/#options
# docker build --progress plain --rm --build-arg TAG=2.1 --tag gsw945/mindoc:2.1 .
# https://docs.docker.com/engine/reference/commandline/run/#options
# set MINDOC=//d/mindoc # windows
# export MINDOC=/home/ubuntu/mindoc-docker # linux
# docker run -d --name=mindoc --restart=always -v /www/mindoc/uploads:/mindoc/uploads -v /www/mindoc/database:/mindoc/database -v /www/mindoc/conf:/mindoc/conf -e MINDOC_DB_ADAPTER=sqlite3 -e MINDOC_DB_DATABASE=./database/mindoc.db -e MINDOC_CACHE=true -e MINDOC_CACHE_PROVIDER=file -p 8181:8181 mindoc-org/mindoc:v2.1
================================================
FILE: LICENSE.md
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# MinDoc 简介
[](https://travis-ci.com/mindoc-org/mindoc)
[](https://ci.appveyor.com/project/mindoc-org/mindoc)
MinDoc 是一款针对IT团队开发的简单好用的文档管理系统。
MinDoc 的前身是 [SmartWiki](https://github.com/lifei6671/SmartWiki) 文档系统。SmartWiki 是基于 PHP 框架 laravel 开发的一款文档管理系统。因 PHP 的部署对普通用户来说太复杂,所以改用 Golang 开发。可以方便用户部署和实用。
开发缘起是公司IT部门需要一款简单实用的项目接口文档管理和分享的系统。其功能和界面源于 kancloud 。
可以用来储存日常接口文档,数据库字典,手册说明等文档。内置项目管理,用户管理,权限管理等功能,能够满足大部分中小团队的文档管理需求。
##### 演示站点&文档:
- https://demo.mindoc.cn/docs/mindochelp
- https://www.iminho.me/wiki/docs/mindoc/
- https://doc.gsw945.com/docs/mindoc-docs/
---
### 开发&维护&使用 悉知
- 感谢作者 [lifei6671](https://github.com/lifei6671) 创造了MinDoc,并持续维护了很久。
- 作者因工作等原因,精力有限,无法花费足够的时间来持续维护mindoc,已于北京时间2021年3月23日将mindoc交给社区(github组织[mindoc-org](https://github.com/mindoc-org))维护,期待热心开发者加入[mindoc-org](https://github.com/mindoc-org)一起来维护MinDoc。
- 遇到问题请提 [Issues](https://github.com/mindoc-org/mindoc/issues ),欢迎使用者和贡献者加入QQ群 `1051164153`
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=bHFR7P3Qp1nsSPbsTw4KN_ZpFLUAblIU&jump_from=webapi"><img border="0" src="https://pub.idqqimg.com/wpa/images/group.png" alt="MinDoc使用&开发交流群" title="MinDoc使用&开发交流群"></a>
- 对开发感兴趣请关注 [Development](https://github.com/mindoc-org/mindoc/projects/1):
- [Todo List](https://github.com/mindoc-org/mindoc/projects/1#column-13554511)
- [Work in progress](https://github.com/mindoc-org/mindoc/projects/1#column-13554512)
- [Review in progress](https://github.com/mindoc-org/mindoc/projects/1#column-13554513)
- Mindoc基于 [beeego](https://github.com/beego/beego) 开发,beego文档地址: https://github.com/beego/beego-doc/tree/main/docs/zh
- :warning: **特别声明**:
- 原作者 [lifei6671](https://github.com/lifei6671) 已于 2021-08-06 删除了个人捐赠信息,参见: [1a179179c1fe4d0d4db95e0b757d863aee5bf395](https://github.com/mindoc-org/mindoc/commit/1a179179c1fe4d0d4db95e0b757d863aee5bf395)
- 截止目前(2023-03-27),[mindoc-org](https://github.com/mindoc-org) 暂未发布任何捐赠信息,请勿轻信
---
# 安装与使用
~~如果你的服务器上没有安装golang程序请手动设置一个环境变量如下:键名为 ZONEINFO,值为MinDoc跟目录下的/lib/time/zoneinfo.zip 。~~
更多信息请查看手册: [MinDoc 使用手册](https://demo.mindoc.cn/docs/mindochelp/mindoc-summary)
对于没有Golang使用经验的用户,可以从 [https://github.com/mindoc-org/mindoc/releases](https://github.com/mindoc-org/mindoc/releases) 这里下载编译完的程序。
如果有Golang开发经验,建议通过编译安装,要求golang版本不小于1.23.0(需支持`CGO`、`go mod`和`import _ "time/tzdata"`)(推荐Go版本为1.23.x)。
> 注意: CentOS7上GLibC版本低,常规编译版本不能使用。需要自行源码编译,或使用使用musl编译版本。
## 常规编译
```bash
# 克隆源码
git clone https://github.com/mindoc-org/mindoc.git
# go包安装
go mod tidy -v
# 编译(sqlite需要CGO支持)
go build -ldflags "-w" -o mindoc main.go
# 数据库初始化(此步骤执行之前,需配置`conf/app.conf`)
./mindoc install
# 执行
./mindoc
# 开发阶段运行
bee run
```
## 旧版本运行 可更新部分数据库配置
```base
./mindoc update
```
MinDoc 如果使用MySQL储存数据,则编码必须是`utf8mb4_general_ci`。请在安装前,把数据库配置填充到项目目录下的 `conf/app.conf` 中。
如果使用 `SQLite` 数据库,则直接在配置文件中配置数据库路径即可.
如果conf目录下不存在 `app.conf` 请重命名 `app.conf.example` 为 `app.conf`。
**默认程序会自动初始化一个超级管理员用户:admin 密码:123456 。请登录后重新设置密码。**
## Linux系统中不依赖gLibC的编译方式
### 安装 musl-gcc
```bash
# 手动安装
wget -c http://musl.libc.org/releases/musl-1.2.2.tar.gz
tar -xvf musl-1.2.2.tar.gz
cd musl-1.2.2
./configure
make
sudo make install
# apt 安装
sudo apt install musl-tools
```
### 使用 musl-gcc 编译 mindoc
```bash
go mod tidy -v
export GOARCH=amd64
export GOOS=linux
# 设置使用musl-gcc
export CC=/usr/local/musl/bin/musl-gcc
# 设置版本
export TRAVIS_TAG=temp-musl-v`date +%y%m%d`
go build -v -o mindoc_linux_musl_amd64 -ldflags="-linkmode external -extldflags '-static' -w -X 'github.com/mindoc-org/mindoc/conf.VERSION=$TRAVIS_TAG' -X 'github.com/mindoc-org/mindoc/conf.BUILD_TIME=`date`' -X 'github.com/mindoc-org/mindoc/conf.GO_VERSION=`go version`'"
# 验证
./mindoc_linux_musl_amd64 version
```
## Windows 上后台运行
使用 [mindoc-daemon](https://github.com/mindoc-org/mindoc-daemon)
```ini
#邮件配置-示例
#是否启用邮件
enable_mail=true
#smtp服务器的账号
smtp_user_name=admin@iminho.me
#smtp服务器的地址
smtp_host=smtp.ym.163.com
#密码
smtp_password=1q2w3e__ABC
#端口号
smtp_port=25
#邮件发送人的地址
form_user_name=admin@iminho.me
#邮件有效期30分钟
mail_expired=30
```
# 使用Docker部署
如果是Docker用户,可参考项目内置的Dockerfile文件自行编译镜像(编译命令见Dockerfile文件底部注释,仅供参考)。
在启动镜像时需要提供如下的常用环境变量(全部支持的环境变量请参考: [`conf/app.conf.example`](https://github.com/mindoc-org/mindoc/blob/master/conf/app.conf.example)):
```ini
DB_ADAPTER 指定DB类型(默认为sqlite)
MYSQL_PORT_3306_TCP_ADDR MySQL地址
MYSQL_PORT_3306_TCP_PORT MySQL端口号
MYSQL_INSTANCE_NAME MySQL数据库名称
MYSQL_USERNAME MySQL账号
MYSQL_PASSWORD MySQL密码
HTTP_PORT 程序监听的端口号
MINDOC_ENABLE_EXPORT 开启导出(默认为false)
```
#### 举个栗子-当前(公开)镜像(信息页面: https://cr.console.aliyun.com/images/cn-hangzhou/mindoc-org/mindoc/detail , 需要登录阿里云账号才可访问列表)
##### Windows
```bash
set MINDOC=//d/mindoc
docker run -it --name=mindoc --restart=always -v "%MINDOC%/conf":"/mindoc/conf" -p 8181:8181 -e MINDOC_ENABLE_EXPORT=true -d registry.cn-hangzhou.aliyuncs.com/mindoc-org/mindoc:v2.2-beta.2
```
##### Linux、Mac
```bash
export MINDOC=/home/ubuntu/mindoc-docker
docker run -it --name=mindoc --restart=always -v "${MINDOC}/conf":"/mindoc/conf" -p 8181:8181 -e MINDOC_ENABLE_EXPORT=true -d registry.cn-hangzhou.aliyuncs.com/mindoc-org/mindoc:v2.2-beta.2
```
##### 举个栗子-更多环境变量示例(镜像已过期,仅供参考,请以当前镜像为准)
```bash
docker run -p 8181:8181 --name mindoc -e DB_ADAPTER=mysql -e MYSQL_PORT_3306_TCP_ADDR=10.xxx.xxx.xxx -e MYSQL_PORT_3306_TCP_PORT=3306 -e MYSQL_INSTANCE_NAME=mindoc -e MYSQL_USERNAME=root -e MYSQL_PASSWORD=123456 -e httpport=8181 -d daocloud.io/lifei6671/mindoc:latest
```
#### dockerfile内容参考
- [无需代理直接加速各种 GitHub 资源拉取 | 国内镜像赋能 | 助力开发](https://blog.frytea.com/archives/504/)
- [阿里云 - Ubuntu 镜像](https://developer.aliyun.com/mirror/ubuntu)
### docker-compose 一键安装
1. 修改配置文件
修改`docker-compose.yml`中的配置信息,主要修改`volumes`节点,将宿主机的两个目录映射到容器内。
`environment`节点,配置自己的环境变量。
2. 一键完成所有环境搭建
> docker-compose up -d
3. 浏览器访问
> http://localhost:8181/
整个部署完成了
4. 常用命令参考
- 启动
> docker-compose up -d
- 停止
> docker-compose stop
- 重启
> docker-compose restart
- 停止删除容器,释放所有资源
> docker-compose down
- 删除并重新创建
> docker-compose -f docker-compose.yml down && docker-compose up -d
>
> 更多 docker-compose 的使用相关的内容 请查看官网文档或百度
#### MCP服务器对接指导
1. 请在配置文件中启用MCP服务器功能
在配置文件`app.conf`中添加或修改为如下内容:
```
# MCP Server 功能
enable_mcp_server="${MINDOC_ENABLE_MCP_SERVER||true}"
mcp_api_key="${MINDOC_MCP_API_KEY||demo-mcp-api-key}"
```
说明:
`enable_mcp_server`为是否启用MCP服务器功能,默认为true。
`mcp_api_key` 为MCP服务器的API密钥,示例配置中默认为`demo-mcp-api-key`,可根据需求自行修改。
2. 在Dify等AI应用或其他可调用MCP服务器的项目配置中添加如下Mindoc配置
```json
{
"mindoc": {
"transport": "streamable_http",
"url": "http://127.0.0.1:8181/mcp/?api_key=demo-mcp-api-key",
"headers":{},
"timeout":600
}
}
```
说明:
`transport`为传输方式,目前支持`streamable_http`。
`url`为Mindoc的MCP服务地址,示例配置中Endpoint默认为`http://127.0.0.1:8181`,默认的API密钥为`demo-mcp-api-key`,可自行修改为对接时项目实际使用的Endpoint和API密钥。
# 项目截图
**创建项目**

**项目列表**

**项目概述**

**项目成员**

**项目设置**

**基于Editor.md开发的Markdown编辑器**

**基于wangEditor开发的富文本编辑器**

**基于cherryMarkdown开发的编辑器**

**项目预览**

**超级管理员后台**

# 使用的技术(TODO: 最新技术栈整理中,使用的第三方库升级中)
- [Beego](https://github.com/beego/beego) ~~1.10.0~~
- MySQL 5.6
- [editor.md](https://github.com/pandao/editor.md) Markdown 编辑器
- [cherry-markdown](https://github.com/Tencent/cherry-markdown) Cherry Markdown Writer
- [Bootstrap](https://github.com/twbs/bootstrap) 3.2
- [jQuery](https://github.com/jquery/jquery) 库
- [WebUploader](https://github.com/fex-team/webuploader) 文件上传框架
- [NProgress](https://github.com/rstacruz/nprogress) 库
- [jsTree](https://github.com/vakata/jstree) 树状结构库
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome) 字体库
- [Cropper](https://github.com/fengyuanchen/cropper) 图片剪裁库
- [layer](https://github.com/sentsin/layer) 弹出层框架
- [highlight.js](https://github.com/highlightjs/highlight.js) 代码高亮库
- ~~to-markdown~~[Turndown](https://github.com/domchristie/turndown) HTML转Markdown库
- ~~quill 富文本编辑器~~
- [wangEditor](https://github.com/wangeditor-team/wangEditor) 富文本编辑器
- 参考
- [wangEditor v4.7 富文本编辑器教程](https://www.bookstack.cn/books/wangeditor-4.7-zh)
- [扩展菜单注册太过繁琐 #2493](https://github.com/wangeditor-team/wangEditor/issues/2493)
- 工具: `https://babeljs.io/repl` + `@babel/plugin-transform-classes`
- [Vue.js](https://github.com/vuejs/vue) 框架
- [MCP-Go](https://github.com/mark3labs/mcp-go)
# 主要功能
- 项目管理,可以对项目进行编辑更改,成员添加, 项目排序等。
- 文档管理,添加和删除文档等。
- 评论管理,可以管理文档评论和自己发布的评论。
- 用户管理,添加和禁用用户,个人资料更改等。
- 用户权限管理 , 实现用户角色的变更。
- 项目加密,可以设置项目公开状态,私有项目需要通过Token访问。
- 站点配置,多语言切换, 可开启匿名访问、验证码等。
# 参与开发
我们欢迎您在 MinDoc 项目的 GitHub 上报告 issue 或者 pull request。
如果您还不熟悉GitHub的Fork and Pull开发模式,您可以阅读GitHub的文档(https://help.github.com/articles/using-pull-requests) 获得更多的信息。
# 关于作者[lifei6671](https://github.com/lifei6671)
一个不纯粹的PHPer,一个不自由的 gopher 。
# 部署补充
- 若内网部署,draw.io无法使用外网,则需要用tomcat运行war包,见(https://github.com/jgraph/drawio) 从release下载,之后修改markdown.js的TODO行对应的链接即可
- 为了护眼,简单增加了编辑界面的主题切换,见editormd.js和markdown_edit_template.tpl
- (需重新编译项)为了对已删除文档/文档引用图片删除文字后,对悬空无引用的图片/附件进行清理,增加了清理接口,需重新编译
- 编译后除二进制文件外还需更新三个文件: conf/lang/en-us.ini,zh-cn.ini; attach_list.tpl
- 若不想重新编译,也可通过database/clean.py,手动执行对无引用图片/附件的文件清理和数据库记录双向清理。
- 若采用nginx二级部署,以yourpath/为例,需修改
- conf/app.conf修改:`baseurl="/yourpath"`
- static/js/kancloud.js文件中`url: "/comment/xxxxx` => `url: "/yourpath" + "/comment/xxxxx`, 共两处
- nginx端口代理示例:
```
增加
location /yourpath/ {
rewrite ^/yourpath/(.*) /$1 break;
proxy_pass http://127.0.0.1:8181;
}
```
注意使用的是127.0.0.1,根据自身选择替换,如果nginx是docker部署,则还需要在docker中托管运行mindoc,具体参考如下配置:
- docker-compose代理示例(docker-nginx代理运行mindoc)
```
version: '3'
services:
mynginx:
image: nginx:latest
ports:
- "8880:80"
command:
- bash
- -c
- |
service nginx start
cd /src/mindoc/ && ./mindoc
volumes:
- ..:/src
- ./nginx:/etc/nginx/conf.d
```
目录结构
```
onefolder
|
- docker
|
- docker-compose.yml
- nginx
|
- mynginx.conf
- mindoc
|
- database/
- conf/
- ...
```
================================================
FILE: appveyor.yml
================================================
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2022
clone_folder: c:\gopath\src\github.com\mindoc-org\mindoc
init:
- cmd: >-
if [%tbs_arch%]==[x86] SET PATH=C:\msys64\mingw32\bin;%PATH%
if [%tbs_arch%]==[x64] SET PATH=C:\msys64\mingw64\bin;%PATH%
SET PATH=%GOPATH%\bin;%GOBIN%;%PATH%
FOR /f "delims=" %%i IN ('go version') DO (SET GO_VERSION=%%i)
git config --global --add safe.directory /cygdrive/c/gopath/src/github.com/mindoc-org/mindoc
environment:
GOPATH: c:\gopath
GOBIN: c:\gobin
GO111MODULE: on
CGO_ENABLED: 1
matrix:
- tbs_arch: x86
GOARCH: 386
job_name: job_x86
- tbs_arch: x64
GOARCH: amd64
job_name: job_x64
install:
- cmd: >-
echo %PATH%
echo %GO_VERSION%
go env
where gcc
where g++
build_script:
- cmd: >-
cd c:\gopath\src\github.com\mindoc-org\mindoc
go mod tidy -v
go build -v -o "mindoc_windows_%GOARCH%.exe" -ldflags="-w -X github.com/mindoc-org/mindoc/conf.VERSION=%APPVEYOR_REPO_TAG_NAME% -X 'github.com/mindoc-org/mindoc/conf.BUILD_TIME=%date% %time%' -X 'github.com/mindoc-org/mindoc/conf.GO_VERSION=%GO_VERSION%'"
7z a -t7z -r mindoc_windows_%GOARCH%.7z conf/*.conf* conf/lang/* static/* mindoc_windows_%GOARCH%.exe views/* uploads/* lib/* LICENSE.md
test_script:
- cmd: >-
cd c:\gopath\src\github.com\mindoc-org\mindoc
pwsh -NoProfile -ExecutionPolicy Bypass -Command "& {Copy-Item -Force -Path 'conf\app.conf.example' -Destination 'conf\app.conf'}"
mindoc_windows_%GOARCH%.exe version
artifacts:
- path: mindoc_windows_*.7z
deploy: off
================================================
FILE: build_amd64.sh
================================================
rm mindoc_linux_amd64 mindoc_linux_musl_amd64
rm -rf ../mindoc_linux_amd64/
export GOARCH=amd64
export GOOS=linux
export CC=/usr/bin/gcc
export TRAVIS_TAG=v2.1-beta.6
go mod tidy -v
go build -v -o mindoc_linux_amd64 -ldflags="-linkmode external -extldflags '-static' -w -X 'github.com/mindoc-org/mindoc/conf.VERSION=$TRAVIS_TAG' -X 'github.com/mindoc-org/mindoc/conf.BUILD_TIME=`date`' -X 'github.com/mindoc-org/mindoc/conf.GO_VERSION=`go version`'"
./mindoc_linux_amd64 version
mkdir ../mindoc_linux_amd64
cp -r * ../mindoc_linux_amd64
cd ../mindoc_linux_amd64
rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime conf/*.go
rm appveyor.yml docker-compose.yml Dockerfile .travis.yml .gitattributes .gitignore go.mod go.sum main.go README.md simsun.ttc start.sh sync_host.sh build_amd64.sh build_musl_amd64.sh
zip -r mindoc_linux_amd64.zip conf static uploads views lib mindoc_linux_amd64 LICENSE.md
mv ./mindoc_linux_amd64.zip ../
================================================
FILE: build_musl_amd64.sh
================================================
rm mindoc_linux_musl_amd64 mindoc_linux_amd64
rm -rf ../mindoc_linux_musl_amd64/
export GOARCH=amd64
export GOOS=linux
export CC=/usr/local/musl/bin/musl-gcc
export TRAVIS_TAG=v2.1-beta.6
go mod tidy -v
go build -v -o mindoc_linux_musl_amd64 -ldflags="-linkmode external -extldflags '-static' -w -X 'github.com/mindoc-org/mindoc/conf.VERSION=$TRAVIS_TAG' -X 'github.com/mindoc-org/mindoc/conf.BUILD_TIME=`date`' -X 'github.com/mindoc-org/mindoc/conf.GO_VERSION=`go version`'"
./mindoc_linux_musl_amd64 version
mkdir ../mindoc_linux_musl_amd64
cp -r * ../mindoc_linux_musl_amd64
cd ../mindoc_linux_musl_amd64
rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime conf/*.go
rm appveyor.yml docker-compose.yml Dockerfile .travis.yml .gitattributes .gitignore go.mod go.sum main.go README.md simsun.ttc start.sh sync_host.sh build_amd64.sh build_musl_amd64.sh
zip -r mindoc_linux_musl_amd64.zip conf static uploads views lib mindoc_linux_musl_amd64 LICENSE.md
mv ./mindoc_linux_musl_amd64.zip ../
================================================
FILE: cache/cache.go
================================================
package cache
import (
"bytes"
"context"
"encoding/gob"
"errors"
"time"
"github.com/beego/beego/v2/client/cache"
"github.com/beego/beego/v2/core/logs"
)
var bm cache.Cache
var nilctx = context.TODO()
func Get(key string, e interface{}) error {
val, err := bm.Get(nilctx, key)
if err != nil {
return errors.New("get cache error:" + err.Error())
}
if val == nil {
return errors.New("cache does not exist")
}
if b, ok := val.([]byte); ok {
buf := bytes.NewBuffer(b)
decoder := gob.NewDecoder(buf)
err := decoder.Decode(e)
if err != nil {
logs.Error("反序列化对象失败 ->", err)
}
return err
} else if s, ok := val.(string); ok && s != "" {
buf := bytes.NewBufferString(s)
decoder := gob.NewDecoder(buf)
err := decoder.Decode(e)
if err != nil {
logs.Error("反序列化对象失败 ->", err)
}
return err
}
return errors.New("value is not []byte or string")
}
func Put(key string, val interface{}, timeout time.Duration) error {
var buf bytes.Buffer
encoder := gob.NewEncoder(&buf)
err := encoder.Encode(val)
if err != nil {
logs.Error("序列化对象失败 ->", err)
return err
}
return bm.Put(nilctx, key, buf.String(), timeout)
}
func Delete(key string) error {
return bm.Delete(nilctx, key)
}
func Incr(key string) error {
return bm.Incr(nilctx, key)
}
func Decr(key string) error {
return bm.Decr(nilctx, key)
}
func IsExist(key string) (bool, error) {
return bm.IsExist(nilctx, key)
}
func ClearAll() error {
return bm.ClearAll(nilctx)
}
func StartAndGC(config string) error {
return bm.StartAndGC(config)
}
//Init will initialize cache
func Init(c cache.Cache) {
bm = c
}
================================================
FILE: cache/cache_null.go
================================================
package cache
import (
"context"
"time"
)
type NullCache struct {
}
func (bm *NullCache) Get(ctx context.Context, key string) (interface{}, error) {
return nil, nil
}
func (bm *NullCache)GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
return nil, nil
}
func (bm *NullCache)Put(ctx context.Context,key string, val interface{}, timeout time.Duration) error {
return nil
}
func (bm *NullCache)Delete(ctx context.Context,key string) error {
return nil
}
func (bm *NullCache)Incr(ctx context.Context,key string) error {
return nil
}
func (bm *NullCache)Decr(ctx context.Context,key string) error {
return nil
}
func (bm *NullCache)IsExist(ctx context.Context,key string) (bool, error) {
return false, nil
}
func (bm *NullCache)ClearAll(ctx context.Context) error{
return nil
}
func (bm *NullCache)StartAndGC(config string) error {
return nil
}
================================================
FILE: commands/command.go
================================================
package commands
import (
"encoding/gob"
"flag"
"fmt"
"log"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"
_ "time/tzdata"
"bytes"
"encoding/json"
"net/http"
beegoCache "github.com/beego/beego/v2/client/cache"
_ "github.com/beego/beego/v2/client/cache/memcache"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"github.com/beego/i18n"
"github.com/howeyc/fsnotify"
_ "github.com/lib/pq"
"github.com/lifei6671/gocaptcha"
"github.com/mindoc-org/mindoc/cache"
"github.com/mindoc-org/mindoc/conf"
"github.com/mindoc-org/mindoc/models"
"github.com/mindoc-org/mindoc/utils/filetil"
)
// RegisterDataBase 注册数据库
func RegisterDataBase() {
logs.Info("正在初始化数据库配置.")
dbadapter, _ := web.AppConfig.String("db_adapter")
orm.DefaultTimeLoc = time.Local
orm.DefaultRowsLimit = -1
if strings.EqualFold(dbadapter, "mysql") {
host, _ := web.AppConfig.String("db_host")
database, _ := web.AppConfig.String("db_database")
username, _ := web.AppConfig.String("db_username")
password, _ := web.AppConfig.String("db_password")
timezone, _ := web.AppConfig.String("timezone")
location, err := time.LoadLocation(timezone)
if err == nil {
orm.DefaultTimeLoc = location
} else {
logs.Error("加载时区配置信息失败,请检查是否存在 ZONEINFO 环境变量->", err)
}
port, _ := web.AppConfig.String("db_port")
dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true&loc=%s", username, password, host, port, database, url.QueryEscape(timezone))
if err := orm.RegisterDataBase("default", "mysql", dataSource); err != nil {
logs.Error("注册默认数据库失败->", err)
os.Exit(1)
}
} else if strings.EqualFold(dbadapter, "sqlite3") {
database, _ := web.AppConfig.String("db_database")
if strings.HasPrefix(database, "./") {
database = filepath.Join(conf.WorkingDirectory, string(database[1:]))
}
if p, err := filepath.Abs(database); err == nil {
database = p
}
dbPath := filepath.Dir(database)
if _, err := os.Stat(dbPath); err != nil && os.IsNotExist(err) {
_ = os.MkdirAll(dbPath, 0777)
}
err := orm.RegisterDataBase("default", "sqlite3", database)
if err != nil {
logs.Error("注册默认数据库失败->", err)
}
} else if strings.EqualFold(dbadapter, "postgres") {
host, _ := web.AppConfig.String("db_host")
database, _ := web.AppConfig.String("db_database")
username, _ := web.AppConfig.String("db_username")
password, _ := web.AppConfig.String("db_password")
sslmode, _ := web.AppConfig.String("db_sslmode")
timezone, _ := web.AppConfig.String("timezone")
location, err := time.LoadLocation(timezone)
if err == nil {
orm.DefaultTimeLoc = location
} else {
logs.Error("加载时区配置信息失败,请检查是否存在 ZONEINFO 环境变量->", err)
}
port, _ := web.AppConfig.String("db_port")
dataSource := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s", username, password, host, port, database, sslmode)
if err := orm.RegisterDataBase("default", "postgres", dataSource); err != nil {
logs.Error("注册默认数据库失败->", err)
os.Exit(1)
}
} else {
logs.Error("不支持的数据库类型.")
os.Exit(1)
}
logs.Info("数据库初始化完成.")
}
// RegisterModel 注册Model
func RegisterModel() {
orm.RegisterModelWithPrefix(conf.GetDatabasePrefix(),
new(models.Member),
new(models.Book),
new(models.Relationship),
new(models.Option),
new(models.Document),
new(models.Attachment),
new(models.Logger),
new(models.MemberToken),
new(models.DocumentHistory),
new(models.Migration),
new(models.Label),
new(models.Blog),
new(models.Template),
new(models.Team),
new(models.TeamMember),
new(models.TeamRelationship),
new(models.Itemsets),
new(models.Comment),
new(models.WorkWeixinAccount),
new(models.DingTalkAccount),
new(models.ContentReverseIndex),
)
gob.Register(models.Blog{})
gob.Register(models.Document{})
gob.Register(models.Template{})
//migrate.RegisterMigration()
err := orm.RunSyncdb("default", false, true)
if err != nil {
logs.Error("注册Model失败 ->", err)
os.Exit(1)
}
}
// RegisterLogger 注册日志
func RegisterLogger(log string) {
logs.Reset()
logs.SetLogFuncCall(true)
_ = logs.SetLogger("console")
logs.EnableFuncCallDepth(true)
if web.AppConfig.DefaultBool("log_is_async", true) {
logs.Async(1e3)
}
if log == "" {
logPath, err := filepath.Abs(web.AppConfig.DefaultString("log_path", conf.WorkingDir("runtime", "logs")))
if err == nil {
log = logPath
} else {
log = conf.WorkingDir("runtime", "logs")
}
}
logPath := filepath.Join(log, "log.log")
if _, err := os.Stat(log); os.IsNotExist(err) {
_ = os.MkdirAll(log, 0755)
}
config := make(map[string]interface{}, 1)
config["filename"] = logPath
config["perm"] = "0755"
config["rotate"] = true
if maxLines := web.AppConfig.DefaultInt("log_maxlines", 1000000); maxLines > 0 {
config["maxLines"] = maxLines
}
if maxSize := web.AppConfig.DefaultInt("log_maxsize", 1<<28); maxSize > 0 {
config["maxsize"] = maxSize
}
if !web.AppConfig.DefaultBool("log_daily", true) {
config["daily"] = false
}
if maxDays := web.AppConfig.DefaultInt("log_maxdays", 7); maxDays > 0 {
config["maxdays"] = maxDays
}
if level := web.AppConfig.DefaultString("log_level", "Trace"); level != "" {
switch level {
case "Emergency":
config["level"] = logs.LevelEmergency
case "Alert":
config["level"] = logs.LevelAlert
case "Critical":
config["level"] = logs.LevelCritical
case "Error":
config["level"] = logs.LevelError
case "Warning":
config["level"] = logs.LevelWarning
case "Notice":
config["level"] = logs.LevelNotice
case "Informational":
config["level"] = logs.LevelInformational
case "Debug":
config["level"] = logs.LevelDebug
}
}
b, err := json.Marshal(config)
if err != nil {
logs.Error("初始化文件日志时出错 ->", err)
_ = logs.SetLogger("file", `{"filename":"`+logPath+`"}`)
} else {
_ = logs.SetLogger(logs.AdapterFile, string(b))
}
logs.SetLogFuncCall(true)
}
// RunCommand 注册orm命令行工具
func RegisterCommand() {
if len(os.Args) >= 2 && os.Args[1] == "install" {
ResolveCommand(os.Args[2:])
Install()
} else if len(os.Args) >= 2 && os.Args[1] == "version" {
CheckUpdate()
os.Exit(0)
} else if len(os.Args) >= 2 && os.Args[1] == "update" {
Update()
os.Exit(0)
}
}
// 注册模板函数
func RegisterFunction() {
err := web.AddFuncMap("config", models.GetOptionValue)
if err != nil {
logs.Error("注册函数 config 出错 ->", err)
os.Exit(-1)
}
err = web.AddFuncMap("cdn", func(p string) string {
cdn := web.AppConfig.DefaultString("cdn", "")
if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p
}
//如果没有设置cdn,则使用baseURL拼接
if cdn == "" {
baseUrl := web.AppConfig.DefaultString("baseurl", "")
if strings.HasPrefix(p, "/") && strings.HasSuffix(baseUrl, "/") {
return baseUrl + p[1:]
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(baseUrl, "/") {
return baseUrl + "/" + p
}
return baseUrl + p
}
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
return cdn + string(p[1:])
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(cdn, "/") {
return cdn + "/" + p
}
return cdn + p
})
if err != nil {
logs.Error("注册函数 cdn 出错 ->", err)
os.Exit(-1)
}
err = web.AddFuncMap("cdnjs", conf.URLForWithCdnJs)
if err != nil {
logs.Error("注册函数 cdnjs 出错 ->", err)
os.Exit(-1)
}
err = web.AddFuncMap("cdncss", conf.URLForWithCdnCss)
if err != nil {
logs.Error("注册函数 cdncss 出错 ->", err)
os.Exit(-1)
}
err = web.AddFuncMap("cdnimg", conf.URLForWithCdnImage)
if err != nil {
logs.Error("注册函数 cdnimg 出错 ->", err)
os.Exit(-1)
}
//重写url生成,支持配置域名以及域名前缀
err = web.AddFuncMap("urlfor", conf.URLFor)
if err != nil {
logs.Error("注册函数 urlfor 出错 ->", err)
os.Exit(-1)
}
//读取配置值(未作任何转换)
err = web.AddFuncMap("conf", conf.CONF)
if err != nil {
logs.Error("注册函数 conf 出错 ->", err)
os.Exit(-1)
}
err = web.AddFuncMap("date_format", func(t time.Time, format string) string {
return t.Local().Format(format)
})
if err != nil {
logs.Error("注册函数 date_format 出错 ->", err)
os.Exit(-1)
}
err = web.AddFuncMap("i18n", i18n.Tr)
if err != nil {
logs.Error("注册函数 i18n 出错 ->", err)
os.Exit(-1)
}
i18nList, err := web.AppConfig.String("i18n_list")
if err != nil {
logs.Error("error : failed to read i18n_list config ->", err)
i18nList = ""
}
if i18nList == "" { // 之所以分开判断是因为读取出的配置也可能是空串
logs.Error("error : config `i18n_list` is empty, please add config item like format: `i18n_list=zh-CN:简体中文|en-US:English`")
i18nList = "zh-cn:简体中文|en-us:English|ru-ru:Русский" // 没有配置时给个默认配置,避免啥语言都没有
}
langs := strings.Split(i18nList, "|")
i18nMap := make(map[string]string)
for _, langItem := range langs {
langItemSplit := strings.Split(langItem, ":")
if len(langItemSplit) < 2 {
logs.Error("error: language config value `" + langItem + "` for `i18n_list` format error")
continue
}
lang := langItemSplit[0]
i18nMap[lang] = langItemSplit[1]
if err := i18n.SetMessage(lang, "conf/lang/"+lang+".ini"); err != nil {
logs.Error("Fail to set message file: " + err.Error())
return
}
}
i18nMapBytes, err := json.Marshal(i18nMap)
if err != nil {
logs.Error("error: Fail to marshal i18n map, " + err.Error())
i18nMapBytes = []byte("{}")
}
err = web.AppConfig.Set("i18n_map", string(i18nMapBytes))
if err != nil {
logs.Error("error: Fail to set i18n_map, " + err.Error())
}
}
// 解析命令
func ResolveCommand(args []string) {
flagSet := flag.NewFlagSet("MinDoc command: ", flag.ExitOnError)
flagSet.StringVar(&conf.ConfigurationFile, "config", "", "MinDoc configuration file.")
flagSet.StringVar(&conf.WorkingDirectory, "dir", "", "MinDoc working directory.")
flagSet.StringVar(&conf.LogFile, "log", "", "MinDoc log file path.")
if err := flagSet.Parse(args); err != nil {
log.Fatal("解析命令失败 ->", err)
}
if conf.WorkingDirectory == "" {
if p, err := filepath.Abs(os.Args[0]); err == nil {
conf.WorkingDirectory = filepath.Dir(p)
}
}
if conf.ConfigurationFile == "" {
conf.ConfigurationFile = conf.WorkingDir("conf", "app.conf")
config := conf.WorkingDir("conf", "app.conf.example")
if !filetil.FileExists(conf.ConfigurationFile) && filetil.FileExists(config) {
_ = filetil.CopyFile(conf.ConfigurationFile, config)
}
}
if err := gocaptcha.ReadFonts(conf.WorkingDir("static", "fonts"), ".ttf"); err != nil {
log.Fatal("读取字体文件时出错 -> ", err)
}
if err := web.LoadAppConfig("ini", conf.ConfigurationFile); err != nil {
log.Fatal("An error occurred:", err)
}
if conf.LogFile == "" {
logPath, err := filepath.Abs(web.AppConfig.DefaultString("log_path", conf.WorkingDir("runtime", "logs")))
if err == nil {
conf.LogFile = logPath
} else {
conf.LogFile = conf.WorkingDir("runtime", "logs")
}
}
conf.AutoLoadDelay = web.AppConfig.DefaultInt("config_auto_delay", 0)
uploads := conf.WorkingDir("uploads")
_ = os.MkdirAll(uploads, 0666)
web.BConfig.WebConfig.StaticDir["/static"] = filepath.Join(conf.WorkingDirectory, "static")
web.BConfig.WebConfig.StaticDir["/uploads"] = uploads
web.BConfig.WebConfig.ViewsPath = conf.WorkingDir("views")
web.BConfig.WebConfig.Session.SessionCookieSameSite = http.SameSiteDefaultMode
var upload_file_size = conf.GetUploadFileSize()
if upload_file_size > web.BConfig.MaxUploadSize {
web.BConfig.MaxUploadSize = upload_file_size
}
fonts := conf.WorkingDir("static", "fonts")
if !filetil.FileExists(fonts) {
log.Fatal("Font path not exist.")
}
if err := gocaptcha.ReadFonts(filepath.Join(conf.WorkingDirectory, "static", "fonts"), ".ttf"); err != nil {
log.Fatal("读取字体失败 ->", err)
}
RegisterDataBase()
RegisterCache()
RegisterModel()
RegisterLogger(conf.LogFile)
models.InitializeMissingIndexes()
ModifyPassword()
}
// 注册缓存管道
func RegisterCache() {
isOpenCache := web.AppConfig.DefaultBool("cache", false)
if !isOpenCache {
cache.Init(&cache.NullCache{})
return
}
logs.Info("正常初始化缓存配置.")
cacheProvider, _ := web.AppConfig.String("cache_provider")
if cacheProvider == "file" {
cacheFilePath := web.AppConfig.DefaultString("cache_file_path", "./runtime/cache/")
if strings.HasPrefix(cacheFilePath, "./") {
cacheFilePath = filepath.Join(conf.WorkingDirectory, string(cacheFilePath[1:]))
}
fileCache := beegoCache.NewFileCache()
fileConfig := make(map[string]string, 0)
fileConfig["CachePath"] = cacheFilePath
fileConfig["DirectoryLevel"] = web.AppConfig.DefaultString("cache_file_dir_level", "2")
fileConfig["EmbedExpiry"] = web.AppConfig.DefaultString("cache_file_expiry", "120")
fileConfig["FileSuffix"] = web.AppConfig.DefaultString("cache_file_suffix", ".bin")
bc, err := json.Marshal(&fileConfig)
if err != nil {
logs.Error("初始化file缓存失败:", err)
os.Exit(1)
}
_ = fileCache.StartAndGC(string(bc))
cache.Init(fileCache)
} else if cacheProvider == "memory" {
cacheInterval := web.AppConfig.DefaultInt("cache_memory_interval", 60)
memory := beegoCache.NewMemoryCache()
beegoCache.DefaultEvery = cacheInterval
cache.Init(memory)
} else if cacheProvider == "redis" {
var redisConfig struct {
Conn string `json:"conn"`
Password string `json:"password"`
DbNum string `json:"dbNum"`
Key string `json:"key"`
}
//设置Redis前缀
if key := web.AppConfig.DefaultString("cache_redis_prefix", ""); key != "" {
redisConfig.Key = key // 设置Redis前缀,替代原来的 redis.DefaultKey
}
redisConfig.DbNum = "0"
redisConfig.Conn = web.AppConfig.DefaultString("cache_redis_host", "")
if pwd := web.AppConfig.DefaultString("cache_redis_password", ""); pwd != "" {
redisConfig.Password = pwd
}
if dbNum := web.AppConfig.DefaultInt("cache_redis_db", 0); dbNum > 0 {
redisConfig.DbNum = strconv.Itoa(dbNum)
}
bc, err := json.Marshal(&redisConfig)
if err != nil {
logs.Error("初始化Redis缓存失败:", err)
os.Exit(1)
}
redisCache, err := beegoCache.NewCache("redis", string(bc))
if err != nil {
logs.Error("初始化Redis缓存失败:", err)
os.Exit(1)
}
cache.Init(redisCache)
} else if cacheProvider == "memcache" {
var memcacheConfig struct {
Conn string `json:"conn"`
}
memcacheConfig.Conn = web.AppConfig.DefaultString("cache_memcache_host", "")
bc, err := json.Marshal(&memcacheConfig)
if err != nil {
logs.Error("初始化 Memcache 缓存失败 ->", err)
os.Exit(1)
}
memcache, err := beegoCache.NewCache("memcache", string(bc))
if err != nil {
logs.Error("初始化 Memcache 缓存失败 ->", err)
os.Exit(1)
}
cache.Init(memcache)
} else {
cache.Init(&cache.NullCache{})
logs.Warn("不支持的缓存管道,缓存将禁用 ->", cacheProvider)
return
}
logs.Info("缓存初始化完成.")
}
// 自动加载配置文件.修改了监听端口号和数据库配置无法自动生效.
func RegisterAutoLoadConfig() {
if conf.AutoLoadDelay > 0 {
watcher, err := fsnotify.NewWatcher()
if err != nil {
logs.Error("创建配置文件监控器失败 ->", err)
}
go func() {
for {
select {
case ev := <-watcher.Event:
//如果是修改了配置文件
if ev.IsModify() {
if err := web.LoadAppConfig("ini", conf.ConfigurationFile); err != nil {
logs.Error("An error occurred ->", err)
continue
}
RegisterCache()
RegisterLogger("")
logs.Info("配置文件已加载 ->", conf.ConfigurationFile)
} else if ev.IsRename() {
_ = watcher.WatchFlags(conf.ConfigurationFile, fsnotify.FSN_MODIFY|fsnotify.FSN_RENAME)
}
logs.Info(ev.String())
case err := <-watcher.Error:
logs.Error("配置文件监控器错误 ->", err)
}
}
}()
err = watcher.WatchFlags(conf.ConfigurationFile, fsnotify.FSN_MODIFY|fsnotify.FSN_RENAME)
if err != nil {
logs.Error("监控配置文件失败 ->", err)
}
}
}
// 注册错误处理方法.
func RegisterError() {
web.ErrorHandler("404", func(writer http.ResponseWriter, request *http.Request) {
var buf bytes.Buffer
data := make(map[string]interface{})
data["ErrorCode"] = 404
data["ErrorMessage"] = "页面未找到或已删除"
if err := web.ExecuteViewPathTemplate(&buf, "errors/error.tpl", web.BConfig.WebConfig.ViewsPath, data); err == nil {
_, _ = fmt.Fprint(writer, buf.String())
} else {
_, _ = fmt.Fprint(writer, data["ErrorMessage"])
}
})
web.ErrorHandler("401", func(writer http.ResponseWriter, request *http.Request) {
var buf bytes.Buffer
data := make(map[string]interface{})
data["ErrorCode"] = 401
data["ErrorMessage"] = "请与 Web 服务器的管理员联系,以确认您是否具有访问所请求资源的权限。"
if err := web.ExecuteViewPathTemplate(&buf, "errors/error.tpl", web.BConfig.WebConfig.ViewsPath, data); err == nil {
_, _ = fmt.Fprint(writer, buf.String())
} else {
_, _ = fmt.Fprint(writer, data["ErrorMessage"])
}
})
}
func init() {
if configPath, err := filepath.Abs(conf.ConfigurationFile); err == nil {
conf.ConfigurationFile = configPath
}
if err := gocaptcha.ReadFonts(conf.WorkingDir("static", "fonts"), ".ttf"); err != nil {
log.Fatal("读取字体文件失败 ->", err)
}
gob.Register(models.Member{})
if p, err := filepath.Abs(os.Args[0]); err == nil {
conf.WorkingDirectory = filepath.Dir(p)
}
}
================================================
FILE: commands/daemon/daemon.go
================================================
package daemon
import (
"fmt"
"os"
"path/filepath"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"github.com/kardianos/service"
"github.com/mindoc-org/mindoc/commands"
"github.com/mindoc-org/mindoc/conf"
"github.com/mindoc-org/mindoc/controllers"
)
type Daemon struct {
config *service.Config
errs chan error
}
func NewDaemon() *Daemon {
config := &service.Config{
Name: "mindocd", //服务显示名称
DisplayName: "MinDoc service", //服务名称
Description: "A document online management program.", //服务描述
WorkingDirectory: conf.WorkingDirectory,
Arguments: os.Args[1:],
}
return &Daemon{
config: config,
errs: make(chan error, 100),
}
}
func (d *Daemon) Config() *service.Config {
return d.config
}
func (d *Daemon) Start(s service.Service) error {
go d.Run()
return nil
}
func (d *Daemon) Run() {
commands.ResolveCommand(d.config.Arguments)
commands.RegisterFunction()
commands.RegisterAutoLoadConfig()
commands.RegisterError()
web.ErrorController(&controllers.ErrorController{})
f, err := filepath.Abs(os.Args[0])
if err != nil {
f = os.Args[0]
}
fmt.Printf("MinDoc version => %s\nbuild time => %s\nstart directory => %s\n%s\n", conf.VERSION, conf.BUILD_TIME, f, conf.GO_VERSION)
web.Run()
}
func (d *Daemon) Stop(s service.Service) error {
if service.Interactive() {
os.Exit(0)
}
return nil
}
func Install() {
d := NewDaemon()
d.config.Arguments = os.Args[3:]
s, err := service.New(d, d.config)
if err != nil {
logs.Error("Create service error => ", err)
os.Exit(1)
}
err = s.Install()
if err != nil {
logs.Error("Install service error:", err)
os.Exit(1)
} else {
logs.Info("Service installed!")
}
os.Exit(0)
}
func Uninstall() {
d := NewDaemon()
s, err := service.New(d, d.config)
if err != nil {
logs.Error("Create service error => ", err)
os.Exit(1)
}
err = s.Uninstall()
if err != nil {
logs.Error("Install service error:", err)
os.Exit(1)
} else {
logs.Info("Service uninstalled!")
}
os.Exit(0)
}
func Restart() {
d := NewDaemon()
s, err := service.New(d, d.config)
if err != nil {
logs.Error("Create service error => ", err)
os.Exit(1)
}
err = s.Restart()
if err != nil {
logs.Error("Install service error:", err)
os.Exit(1)
} else {
logs.Info("Service Restart!")
}
os.Exit(0)
}
================================================
FILE: commands/install.go
================================================
package commands
import (
"errors"
"fmt"
"os"
"time"
"flag"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"github.com/beego/i18n"
"github.com/mindoc-org/mindoc/conf"
"github.com/mindoc-org/mindoc/models"
"github.com/mindoc-org/mindoc/utils"
)
//系统安装.
func Install() {
fmt.Println("Initializing...")
err := orm.RunSyncdb("default", false, true)
if err == nil {
initialization()
} else {
panic(err.Error())
}
fmt.Println("Install Successfully!")
os.Exit(0)
}
func Version() {
if len(os.Args) >= 2 && os.Args[1] == "version" {
fmt.Println(conf.VERSION)
os.Exit(0)
}
}
//修改用户密码
func ModifyPassword() {
var account, password string
//账号和密码需要解析参数后才能获取
if len(os.Args) >= 2 && os.Args[1] == "password" {
flagSet := flag.NewFlagSet("MinDoc command: ", flag.ExitOnError)
flagSet.StringVar(&account, "account", "", "用户账号.")
flagSet.StringVar(&password, "password", "", "用户密码.")
if err := flagSet.Parse(os.Args[2:]); err != nil {
logs.Error("解析参数失败 -> ", err)
os.Exit(1)
}
if len(os.Args) < 2 {
fmt.Println("Parameter error.")
os.Exit(1)
}
if account == "" {
fmt.Println("Account cannot be empty.")
os.Exit(1)
}
if password == "" {
fmt.Println("Password cannot be empty.")
os.Exit(1)
}
member, err := models.NewMember().FindByAccount(account)
if err != nil {
fmt.Println("Failed to change password:", err)
os.Exit(1)
}
pwd, err := utils.PasswordHash(password)
if err != nil {
fmt.Println("Failed to change password:", err)
os.Exit(1)
}
member.Password = pwd
err = member.Update("password")
if err != nil {
fmt.Println("Failed to change password:", err)
os.Exit(1)
}
fmt.Println("Successfully modified.")
os.Exit(0)
}
}
//初始化数据
func initialization() {
err := models.NewOption().Init()
if err != nil {
panic(err.Error())
}
lang, _ := web.AppConfig.String("default_lang")
err = i18n.SetMessage(lang, "conf/lang/"+lang+".ini")
if err != nil {
panic(fmt.Errorf("initialize locale error: %s", err))
}
member, err := models.NewMember().FindByFieldFirst("account", "admin")
if errors.Is(err, orm.ErrNoRows) {
// create admin user
logs.Info("creating admin user")
member.Account = "admin"
member.Avatar = conf.URLForWithCdnImage("/static/images/headimgurl.jpg")
member.Password = "123456"
member.AuthMethod = "local"
member.Role = conf.MemberSuperRole
member.Email = "admin@iminho.me"
if err := member.Add(); err != nil {
panic("Member.Add => " + err.Error())
}
// create demo book
logs.Info("creating demo book")
book := models.NewBook()
book.MemberId = member.MemberId
book.BookName = i18n.Tr(lang, "init.default_proj_name") //"MinDoc演示项目"
book.Status = 0
book.ItemId = 1
book.Description = i18n.Tr(lang, "init.default_proj_desc") //"这是一个MinDoc演示项目,该项目是由系统初始化时自动创建。"
book.CommentCount = 0
book.PrivatelyOwned = 0
book.CommentStatus = "closed"
book.Identify = "mindoc"
book.DocCount = 0
book.CommentCount = 0
book.Version = time.Now().Unix()
book.Cover = conf.GetDefaultCover()
book.Editor = "markdown"
book.Theme = "default"
if err := book.Insert(lang); err != nil {
panic("初始化项目失败 -> " + err.Error())
}
} else if err != nil {
panic(fmt.Errorf("occur errors when initialize: %s", err))
}
if !models.NewItemsets().Exist(1) {
item := models.NewItemsets()
item.ItemName = i18n.Tr(lang, "init.default_proj_space") //"默认项目空间"
item.MemberId = 1
if err := item.Save(); err != nil {
panic("初始化项目空间失败 -> " + err.Error())
}
}
}
================================================
FILE: commands/migrate/migrate.go
================================================
// Copyright 2013 bee authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package migrate
import (
"os"
"container/list"
"fmt"
"log"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/server/web"
"github.com/mindoc-org/mindoc/models"
)
var (
migrationList = &migrationCache{}
)
type MigrationDatabase interface {
//获取当前的版本
Version() int64
//校验当前是否可更新
ValidUpdate(version int64) error
//校验并备份表结构
ValidForBackupTableSchema() error
//校验并更新表结构
ValidForUpdateTableSchema() error
//恢复旧数据
MigrationOldTableData() error
//插入新数据
MigrationNewTableData() error
//增加迁移记录
AddMigrationRecord(version int64) error
//最后的清理工作
MigrationCleanup() error
//回滚本次迁移
RollbackMigration() error
}
type migrationCache struct {
items *list.List
}
func RunMigration() {
if len(os.Args) >= 2 && os.Args[1] == "migrate" {
migrate, err := models.NewMigration().FindFirst()
if err != nil {
//log.Fatalf("migrations table %s", err)
migrate = models.NewMigration()
}
fmt.Println("Start migration databae... ")
for el := migrationList.items.Front(); el != nil; el = el.Next() {
//如果存在比当前版本大的版本,则依次升级
if item, ok := el.Value.(MigrationDatabase); ok && item.Version() > migrate.Version {
err := item.ValidUpdate(migrate.Version)
if err != nil {
log.Fatal(err)
}
err = item.ValidForBackupTableSchema()
if err != nil {
item.RollbackMigration()
log.Fatal(err)
}
err = item.ValidForUpdateTableSchema()
if err != nil {
item.RollbackMigration()
log.Fatal(err)
}
err = item.MigrationOldTableData()
if err != nil {
item.RollbackMigration()
log.Fatal(err)
}
err = item.MigrationNewTableData()
if err != nil {
item.RollbackMigration()
log.Fatal(err)
}
err = item.AddMigrationRecord(item.Version())
if err != nil {
item.RollbackMigration()
log.Fatal(err)
}
err = item.MigrationCleanup()
if err != nil {
item.RollbackMigration()
log.Fatal(err)
}
}
}
fmt.Println("Migration successfull.")
os.Exit(0)
}
}
//导出数据库的表结构
func ExportDatabaseTable() ([]string, error) {
dbadapter, _ := web.AppConfig.String("db_adapter")
dbdatabase, _ := web.AppConfig.String("db_database")
tables := make([]string, 0)
o := orm.NewOrm()
switch dbadapter {
case "mysql":
{
var lists []orm.Params
_, err := o.Raw(fmt.Sprintf("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s'", dbdatabase)).Values(&lists)
if err != nil {
return tables, err
}
for _, table := range lists {
var results []orm.Params
_, err = o.Raw(fmt.Sprintf("show create table %s", table["TABLE_NAME"])).Values(&results)
if err != nil {
return tables, err
}
tables = append(tables, results[0]["Create Table"].(string))
}
break
}
case "sqlite3":
{
var results []orm.Params
_, err := o.Raw("SELECT sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rootpage ASC").Values(&results)
if err != nil {
return tables, err
}
for _, item := range results {
if sql, ok := item["sql"]; ok {
tables = append(tables, sql.(string))
}
}
break
}
}
return tables, nil
}
func RegisterMigration() {
migrationList.items = list.New()
migrationList.items.PushBack(NewMigrationVersion03())
}
================================================
FILE: commands/migrate/migrate_v03.go
================================================
package migrate
import (
"errors"
"fmt"
"strings"
"time"
"github.com/beego/beego/v2/client/orm"
"github.com/mindoc-org/mindoc/models"
)
type MigrationVersion03 struct {
isValid bool
tables []string
}
func NewMigrationVersion03() *MigrationVersion03 {
return &MigrationVersion03{isValid: false, tables: make([]string, 0)}
}
func (m *MigrationVersion03) Version() int64 {
return 201705271114
}
func (m *MigrationVersion03) ValidUpdate(version int64) error {
if m.Version() > version {
m.isValid = true
return nil
}
m.isValid = false
return errors.New("The target version is higher than the current version.")
}
func (m *MigrationVersion03) ValidForBackupTableSchema() error {
if !m.isValid {
return errors.New("The current version failed to verify.")
}
var err error
m.tables, err = ExportDatabaseTable()
return err
}
func (m *MigrationVersion03) ValidForUpdateTableSchema() error {
if !m.isValid {
return errors.New("The current version failed to verify.")
}
err := orm.RunSyncdb("default", false, true)
if err != nil {
return err
}
//_,err = o.Raw("ALTER TABLE md_members ADD auth_method VARCHAR(50) DEFAULT 'local' NULL").Exec()
return err
}
func (m *MigrationVersion03) MigrationOldTableData() error {
if !m.isValid {
return errors.New("The current version failed to verify.")
}
return nil
}
func (m *MigrationVersion03) MigrationNewTableData() error {
if !m.isValid {
return errors.New("The current version failed to verify.")
}
o := orm.NewOrm()
_, err := o.Raw("UPDATE md_members SET auth_method = 'local'").Exec()
if err != nil {
return err
}
_, err = o.Raw("INSERT INTO md_options (option_title, option_name, option_value) SELECT '是否启用文档历史','ENABLE_DOCUMENT_HISTORY','true' WHERE NOT exists(SELECT * FROM md_options WHERE option_name = 'ENABLE_DOCUMENT_HISTORY');").Exec()
if err != nil {
return err
}
return nil
}
func (m *MigrationVersion03) AddMigrationRecord(version int64) error {
o := orm.NewOrm()
tables, err := ExportDatabaseTable()
if err != nil {
return err
}
migration := models.NewMigration()
migration.Version = version
migration.Status = "update"
migration.CreateTime = time.Now()
migration.Name = fmt.Sprintf("update_%d", version)
migration.Statements = strings.Join(tables, "\r\n")
_, err = o.Insert(migration)
return err
}
func (m *MigrationVersion03) MigrationCleanup() error {
return nil
}
func (m *MigrationVersion03) RollbackMigration() error {
if !m.isValid {
return errors.New("The current version failed to verify.")
}
o := orm.NewOrm()
_, err := o.Raw("ALTER TABLE md_members DROP COLUMN auth_method").Exec()
if err != nil {
return err
}
_, err = o.Raw("DROP TABLE md_document_history").Exec()
if err != nil {
return err
}
_, err = o.Raw("DELETE md_options WHERE option_name = 'ENABLE_DOCUMENT_HISTORY'").Exec()
if err != nil {
return err
}
return nil
}
================================================
FILE: commands/update.go
================================================
package commands
import (
"encoding/json"
"fmt"
"github.com/mindoc-org/mindoc/models"
"io/ioutil"
"net/http"
"os"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/mindoc-org/mindoc/conf"
)
// 检查最新版本.
func CheckUpdate() {
fmt.Println("MinDoc current version => ", conf.VERSION)
resp, err := http.Get("https://api.github.com/repos/mindoc-org/mindoc/tags")
if err != nil {
logs.Error("CheckUpdate => ", err)
os.Exit(1)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
logs.Error("CheckUpdate => ", err)
os.Exit(1)
}
var result []*struct {
Name string `json:"name"`
}
err = json.Unmarshal(body, &result)
if err != nil {
logs.Error("CheckUpdate => ", err)
os.Exit(0)
}
if len(result) > 0 {
fmt.Println("MinDoc last version => ", result[0].Name)
}
os.Exit(0)
}
func Update() {
fmt.Println("Update...")
RegisterDataBase()
RegisterModel()
err := orm.RunSyncdb("default", false, true)
if err == nil {
UpdateInitialization()
} else {
panic(err.Error())
}
fmt.Println("Update Successfully!")
os.Exit(0)
}
func UpdateInitialization() {
err := models.NewOption().Update()
if err != nil {
panic(err.Error())
}
}
================================================
FILE: conf/app.conf.example
================================================
appname = mindoc
#默认监听的网卡,为空则监听所有
httpaddr="${MINDOC_ADDR}"
httpport = "${MINDOC_PORT||8181}"
runmode = "${MINDOC_RUN_MODE||dev}"
sessionon = true
sessionname = mindoc_id
copyrequestbody = true
enablexsrf = "${MINDOC_ENABLE_XSRF||false}"
enable_iframe = "${MINDOC_ENABLE_IFRAME||false}"
#系统完整URL(http://doc.iminho.me),如果该项不设置,会从请求头中获取地址。
baseurl="${MINDOC_BASE_URL}"
#########代码高亮样式################
#样式演示地址:https://highlightjs.org/static/demo/
highlight_style="${MINDOC_HIGHLIGHT_STYLE||github}"
########配置文件自动加载##################
#大于0时系统会自动检测配置文件是否变动,变动后自动加载并生效,单位是秒。监听端口和数据库配置无效
config_auto_delay="${MINDOC_CONFIG_AUTO_DELAY||20}"
#发布pdf时候的默认发布者(项目填写了公司名称以公司名称为准)
publisher_def =
########Session储存方式##############
#默认Session生成Key的秘钥
beegoserversessionkey=NY1B$28pms12JM&c
sessionprovider="${MINDOC_SESSION_PROVIDER||file}"
sessionproviderconfig="${MINDOC_SESSION_PROVIDER_CONFIG||./runtime/session}"
#默认的过期时间
sessiongcmaxlifetime="${MINDOC_SESSION_MAX_LIFETIME||3600}"
#以文件方式储存
#sessionprovider=file
#sessionproviderconfig=./runtime/session
#以redis方式储存
#sessionprovider=redis
#sessionproviderconfig=127.0.0.1:6379
#以memcache方式储存
#sessionprovider=memcache
#sessionproviderconfig=127.0.0.1:11211
#以内存方式托管Session
#sessionprovider=memory
#时区设置
timezone = Asia/Shanghai
####################MySQL 数据库配置###########################
#支持MySQL,sqlite3,postgres三种数据库,如果是sqlite3 则 db_database 标识数据库的物理目录
db_adapter="${MINDOC_DB_ADAPTER||sqlite3}"
db_host="${MINDOC_DB_HOST||127.0.0.1}"
db_port="${MINDOC_DB_PORT||3306}"
db_database="${MINDOC_DB_DATABASE||./database/mindoc.db}"
db_username="${MINDOC_DB_USERNAME||root}"
db_password="${MINDOC_DB_PASSWORD||123456}"
#是否使用SSL,支持posgres,可选的值有:
#disable - No SSL
#require - Always SSL (skip verification)
#verify-ca - Always SSL (verify that the certificate presented by the server was signed by a trusted CA)
#verify-full - Always SSL (verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate)
db_sslmode="${MINDOC_DB_SSLMODE||disable}"
####################sqlite3 数据库配置###########################
#db_adapter=sqlite3
#db_database=./database/mindoc.db
#项目默认封面
cover=/static/images/book.jpg
#默认头像
avatar=/static/images/headimgurl.jpg
#默认阅读令牌长度
token_size=12
#上传文件的后缀,如果不限制后缀可以设置为 *
upload_file_ext=txt|doc|docx|xls|xlsx|ppt|pptx|pdf|7z|rar|jpg|jpeg|png|gif|mp4|webm|avi
#上传的文件大小限制
# - 如果不填写, 则默认1GB,如果希望超过1GB,必须带单位
# - 如果填写,单位可以是 TB、GB、MB、KB,不带单位表示字节
upload_file_size=10MB
####################邮件配置######################
#是否启用邮件
enable_mail="${MINDOC_ENABLE_MAIL||false}"
#每小时限制指定邮箱邮件发送次数
mail_number="${MINDOC_MAIL_NUMBER||5}"
#smtp服务用户名
smtp_user_name="${MINDOC_SMTP_USER_NAME||admin@iminho.me}"
#smtp服务器地址
smtp_host="${MINDOC_SMTP_HOST||smtp.163.com}""
#smtp密码
smtp_password="${MINDOC_SMTP_PASSWORD}"
#端口号
smtp_port="${MINDOC_SMTP_PORT||25}""
#发送邮件的显示名称
form_user_name="${MINDOC_FORM_USERNAME||admin@iminho.me}"
#邮件有效期30分钟
mail_expired="${MINDOC_EXPIRED||30}"
#加密类型NONE 无认证、SSL 加密、LOGIN 普通用户登录
secure="${MINDOC_MAIL_SECURE||LOGIN}"
###############配置导出项目###################
enable_export="${MINDOC_ENABLE_EXPORT||false}"
#同一个项目同时运行导出程序的并行数量,取值1-4之间,取值越大导出速度越快,越占用资源
export_process_num="${MINDOC_EXPORT_PROCESS_NUM||1}"
#并发导出的项目限制,指同一时间限制的导出项目数量,如果为0则不限制。设置的越大,越占用资源
export_limit_num="${MINDOC_EXPORT_LIMIT_NUM||5}"
#指同时等待导出的任务数量
export_queue_limit_num="${MINDOC_EXPORT_QUEUE_LIMIT_NUM||100}"
#导出项目的缓存目录配置
export_output_path="${MINDOC_EXPORT_OUTPUT_PATH||./runtime/cache}"
################百度地图密钥#################
baidumapkey=
################Active Directory/LDAP################
#是否启用ldap
ldap_enable=${MINDOC_LDAP_ENABLE||false}
#ldap协议(ldap/ldaps)
ldap_scheme="${MINDOC_LDAP_SCHEME||ldap}"
#ldap主机名
ldap_host="${MINDOC_LDAP_HOST||127.0.0.1}"
#ldap端口
ldap_port=${MINDOC_LDAP_PORT||389}
#ldap内哪个属性作为用户名
ldap_account="${MINDOC_LDAP_ACCOUNT||sAMAccountName}"
#ldap内哪个属性作为邮箱
ldap_mail="${MINDOC_LDAP_MAIL||mail}"
#搜索范围
ldap_base="${MINDOC_LDAP_BASE||dc=example,dc=com}"
#第一次绑定ldap用户dn
ldap_user="${MINDOC_LDAP_USER||cn=ldap helper,ou=example.com,dc=example,dc=com}"
#第一次绑定ldap用户密码
ldap_password="${MINDOC_LDAP_PASSWORD||xxx}"
#自动注册用户角色:0 超级管理员 /1 管理员/ 2 普通用户/ 3 只读用户
ldap_user_role=${MINDOC_LDAP_USER_ROLE||2}
#ldap搜索filter规则,AD服务器: objectClass=User, openldap服务器: objectClass=posixAccount ,也可以定义为其他属性,如: title=mindoc
ldap_filter="${MINDOC_LDAP_FILTER||objectClass=posixAccount}"
############# HTTP自定义接口登录 ################
http_login_url=
#md5计算的秘钥
http_login_secret=hzsp*THJUqwbCU%s
##################################
###############配置CDN加速##################
cdn="${MINDOC_CDN_URL}"
cdnjs="${MINDOC_CDN_JS_URL}"
cdncss="${MINDOC_CDN_CSS_URL}"
cdnimg="${MINDOC_CDN_IMG_URL}"
######################缓存配置###############################
#是否开启缓存,true 开启/false 不开启
cache="${MINDOC_CACHE||false}"
#缓存方式:memory/memcache/redis/file
cache_provider="${MINDOC_CACHE_PROVIDER||file}"
#当配置缓存方式为memory时,内存回收时间,单位是秒
cache_memory_interval="${MINDOC_CACHE_MEMORY_INTERVAL||120}"
#当缓存方式配置为file时,缓存的储存目录
cache_file_path="${MINDOC_CACHE_FILE_PATH||./runtime/cache/}"
#缓存文件后缀
cache_file_suffix="${MINDOC_CACHE_FILE_SUFFIX||.bin}"
#文件缓存目录层级
cache_file_dir_level="${MINDOC_CACHE_FILE_DIR_LEVEL||2}"
#文件缓存的默认过期时间
cache_file_expiry="${MINDOC_CACHE_FILE_EXPIRY||3600}"
#memcache缓存服务器地址
cache_memcache_host="${MINDOC_CACHE_MEMCACHE_HOST||127.0.0.1:11211}"
#redis服务器地址
cache_redis_host="${MINDOC_CACHE_REDIS_HOST||127.0.0.1:6379}"
#redis数据库索引
cache_redis_db="${MINDOC_CACHE_REDIS_DB||0}"
#redis服务器密码
cache_redis_password="${MINDOC_CACHE_REDIS_PASSWORD}"
#缓存键的前缀
cache_redis_prefix="${MINDOC_CACHE_REDIS_PREFIX||mindoc::cache}"
#########日志储存配置##############
#日志保存路径,在linux上,自动创建的日志文件请不要删除,否则将无法写入日志
log_path="${MINDOC_LOG_PATH||./runtime/logs}"
#每个文件保存的最大行数,默认值 1000000
log_maxlines="${MINDOC_LOG_MAX_LINES||1000000}"
# 每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB
log_maxsize="${MINDOC_LOG_MAX_SIZE}"
# 是否按照每天 logrotate,默认是 true
log_daily="${MINDOC_LOG_DAILY||true}"
# 文件最多保存多少天,默认保存 7 天
log_maxdays="${MINDOC_LOG_MAX_DAYS||30}"
# 日志保存的时候的级别,默认是 Trace 级别,可选值: Emergency/Alert/Critical/Error/Warning/Notice/Informational/Debug/Trace
log_level="${MINDOC_LOG_LEVEL||Alert}"
# 是否异步生成日志,默认是 true
log_is_async="${MINDOC_LOG_IS_ASYNC||TRUE}"
##########钉钉应用相关配置##############
# 企业钉钉ID
dingtalk_corpid="${MINDOC_DINGTALK_CORPID}"
# 钉钉AppKey
dingtalk_app_key="${MINDOC_DINGTALK_APPKEY}"
# 钉钉AppSecret
dingtalk_app_secret="${MINDOC_DINGTALK_APPSECRET}"
########企业微信登录配置##############
# 企业ID
workweixin_corpid="${MINDOC_WORKWEIXIN_CORPID}"
# 应用ID
workweixin_agentid="${MINDOC_WORKWEIXIN_AGENTID}"
# 应用密钥
workweixin_secret="${MINDOC_WORKWEIXIN_SECRET}"
# i18n config
i18n_list=zh-cn:简体中文|en-us:English|ru-ru:Русский
default_lang="zh-cn"
# MCP Server 功能
enable_mcp_server="${MINDOC_ENABLE_MCP_SERVER||false}"
mcp_api_key="${MINDOC_MCP_API_KEY||demo-mcp-api-key}"
================================================
FILE: conf/enumerate.go
================================================
// package conf 为配置相关.
package conf
import (
"strings"
"fmt"
"os"
"path/filepath"
"strconv"
"github.com/beego/beego/v2/server/web"
)
// 登录用户的Session名
const LoginSessionName = "LoginSessionName"
const CaptchaSessionName = "__captcha__"
const RegexpEmail = "^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
// 允许用户名中出现点号
const RegexpAccount = `^[a-zA-Z0-9][a-zA-Z0-9\.-]{2,50}$`
// PageSize 默认分页条数.
const PageSize = 10
// 用户权限
const (
// 超级管理员.
MemberSuperRole SystemRole = iota
//普通管理员.
MemberAdminRole
//普通用户.
MemberGeneralRole
//只读用户.
MemberReaderRole
)
// 系统角色
type SystemRole int
const (
// 创始人.
BookFounder BookRole = iota
//管理者
BookAdmin
//编辑者.
BookEditor
//观察者
BookObserver
//未指定关系
BookRoleNoSpecific
)
// 项目角色
type BookRole int
const (
LoggerOperate = "operate"
LoggerSystem = "system"
LoggerException = "exception"
LoggerDocument = "document"
)
const (
//本地账户校验
AuthMethodLocal = "local"
//LDAP用户校验
AuthMethodLDAP = "ldap"
)
var (
VERSION string
BUILD_TIME string
GO_VERSION string
)
var (
ConfigurationFile = "./conf/app.conf"
WorkingDirectory = "./"
LogFile = "./runtime/logs"
BaseUrl = ""
AutoLoadDelay = 0
)
// app_key
func GetAppKey() string {
return web.AppConfig.DefaultString("app_key", "mindoc")
}
func GetDatabasePrefix() string {
return web.AppConfig.DefaultString("db_prefix", "md_")
}
// 获取默认头像
func GetDefaultAvatar() string {
return URLForWithCdnImage(web.AppConfig.DefaultString("avatar", "/static/images/headimgurl.jpg"))
}
// 获取阅读令牌长度.
func GetTokenSize() int {
return web.AppConfig.DefaultInt("token_size", 12)
}
// 获取默认文档封面.
func GetDefaultCover() string {
return URLForWithCdnImage(web.AppConfig.DefaultString("cover", "/static/images/book.jpg"))
}
// 获取允许的上传文件的类型.
func GetUploadFileExt() []string {
ext := web.AppConfig.DefaultString("upload_file_ext", "png|jpg|jpeg|gif|txt|doc|docx|pdf|mp4")
temp := strings.Split(ext, "|")
exts := make([]string, len(temp))
i := 0
for _, item := range temp {
if item != "" {
exts[i] = item
i++
}
}
return exts
}
// 获取上传文件允许的最大值
func GetUploadFileSize() int64 {
size := web.AppConfig.DefaultString("upload_file_size", "0")
if strings.HasSuffix(size, "TB") {
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024 * 1024 * 1024 * 1024
}
}
if strings.HasSuffix(size, "GB") {
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024 * 1024 * 1024
}
}
if strings.HasSuffix(size, "MB") {
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024 * 1024
}
}
if strings.HasSuffix(size, "KB") {
if s, e := strconv.ParseInt(size[0:len(size)-2], 10, 64); e == nil {
return s * 1024
}
}
if s, e := strconv.ParseInt(size, 10, 64); e == nil {
return s
}
return 0
}
// 是否启用导出
func GetEnableExport() bool {
return web.AppConfig.DefaultBool("enable_export", true)
}
// 是否启用iframe
func GetEnableIframe() bool {
return web.AppConfig.DefaultBool("enable_iframe", false)
}
// 同一项目导出线程的并发数
func GetExportProcessNum() int {
exportProcessNum := web.AppConfig.DefaultInt("export_process_num", 1)
if exportProcessNum <= 0 || exportProcessNum > 4 {
exportProcessNum = 1
}
return exportProcessNum
}
// 导出项目队列的并发数量
func GetExportLimitNum() int {
exportLimitNum := web.AppConfig.DefaultInt("export_limit_num", 1)
if exportLimitNum < 0 {
exportLimitNum = 1
}
return exportLimitNum
}
// 等待导出队列的长度
func GetExportQueueLimitNum() int {
exportQueueLimitNum := web.AppConfig.DefaultInt("export_queue_limit_num", 10)
if exportQueueLimitNum <= 0 {
exportQueueLimitNum = 100
}
return exportQueueLimitNum
}
// 默认导出项目的缓存目录
func GetExportOutputPath() string {
exportOutputPath := filepath.Join(web.AppConfig.DefaultString("export_output_path", filepath.Join(WorkingDirectory, "cache")), "books")
return exportOutputPath
}
// 判断是否是允许上传的文件类型.
func IsAllowUploadFileExt(ext string) bool {
if strings.HasPrefix(ext, ".") {
ext = string(ext[1:])
}
exts := GetUploadFileExt()
for _, item := range exts {
if item == "*" {
return true
}
if strings.EqualFold(item, ext) {
return true
}
}
return false
}
// 读取配置文件值
func CONF(key string, value ...string) string {
defaultValue := ""
if len(value) > 0 {
defaultValue = value[0]
}
return web.AppConfig.DefaultString(key, defaultValue)
}
// 重写生成URL的方法,加上完整的域名
func URLFor(endpoint string, values ...interface{}) string {
baseUrl := web.AppConfig.DefaultString("baseurl", "")
pathUrl := web.URLFor(endpoint, values...)
if baseUrl == "" {
baseUrl = BaseUrl
}
if strings.HasPrefix(pathUrl, "http://") {
return pathUrl
}
if strings.HasPrefix(pathUrl, "/") && strings.HasSuffix(baseUrl, "/") {
return baseUrl + pathUrl[1:]
}
if !strings.HasPrefix(pathUrl, "/") && !strings.HasSuffix(baseUrl, "/") {
return baseUrl + "/" + pathUrl
}
return baseUrl + web.URLFor(endpoint, values...)
}
func URLForNotHost(endpoint string, values ...interface{}) string {
baseUrl := web.AppConfig.DefaultString("baseurl", "")
pathUrl := web.URLFor(endpoint, values...)
if baseUrl == "" {
baseUrl = "/"
}
if strings.HasPrefix(pathUrl, "http://") {
return pathUrl
}
if strings.HasPrefix(pathUrl, "/") && strings.HasSuffix(baseUrl, "/") {
return baseUrl + pathUrl[1:]
}
if !strings.HasPrefix(pathUrl, "/") && !strings.HasSuffix(baseUrl, "/") {
return baseUrl + "/" + pathUrl
}
return baseUrl + web.URLFor(endpoint, values...)
}
func URLForWithCdnImage(p string) string {
if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p
}
cdn := web.AppConfig.DefaultString("cdnimg", "")
//如果没有设置cdn,则使用baseURL拼接
if cdn == "" {
baseUrl := web.AppConfig.DefaultString("baseurl", "/")
if strings.HasPrefix(p, "/") && strings.HasSuffix(baseUrl, "/") {
return baseUrl + p[1:]
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(baseUrl, "/") {
return baseUrl + "/" + p
}
return baseUrl + p
}
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
return cdn + string(p[1:])
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(cdn, "/") {
return cdn + "/" + p
}
return cdn + p
}
func URLForWithCdnCss(p string, v ...string) string {
cdn := web.AppConfig.DefaultString("cdncss", "")
if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p
}
filePath := WorkingDir(p)
if f, err := os.Stat(filePath); err == nil && !strings.Contains(p, "?") && len(v) > 0 && v[0] == "version" {
p = p + fmt.Sprintf("?v=%s", f.ModTime().Format("20060102150405"))
}
//如果没有设置cdn,则使用baseURL拼接
if cdn == "" {
baseUrl := web.AppConfig.DefaultString("baseurl", "/")
if strings.HasPrefix(p, "/") && strings.HasSuffix(baseUrl, "/") {
return baseUrl + p[1:]
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(baseUrl, "/") {
return baseUrl + "/" + p
}
return baseUrl + p
}
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
return cdn + string(p[1:])
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(cdn, "/") {
return cdn + "/" + p
}
return cdn + p
}
func URLForWithCdnJs(p string, v ...string) string {
cdn := web.AppConfig.DefaultString("cdnjs", "")
if strings.HasPrefix(p, "http://") || strings.HasPrefix(p, "https://") {
return p
}
filePath := WorkingDir(p)
if f, err := os.Stat(filePath); err == nil && !strings.Contains(p, "?") && len(v) > 0 && v[0] == "version" {
p = p + fmt.Sprintf("?v=%s", f.ModTime().Format("20060102150405"))
}
//如果没有设置cdn,则使用baseURL拼接
if cdn == "" {
baseUrl := web.AppConfig.DefaultString("baseurl", "/")
if strings.HasPrefix(p, "/") && strings.HasSuffix(baseUrl, "/") {
return baseUrl + p[1:]
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(baseUrl, "/") {
return baseUrl + "/" + p
}
return baseUrl + p
}
if strings.HasPrefix(p, "/") && strings.HasSuffix(cdn, "/") {
return cdn + string(p[1:])
}
if !strings.HasPrefix(p, "/") && !strings.HasSuffix(cdn, "/") {
return cdn + "/" + p
}
return cdn + p
}
func WorkingDir(elem ...string) string {
elems := append([]string{WorkingDirectory}, elem...)
return filepath.Join(elems...)
}
func init() {
if p, err := filepath.Abs("./conf/app.conf"); err == nil {
ConfigurationFile = p
}
if p, err := filepath.Abs("./"); err == nil {
WorkingDirectory = p
}
if p, err := filepath.Abs("./runtime/logs"); err == nil {
LogFile = p
}
}
================================================
FILE: conf/lang/en-us.ini
================================================
[common]
title = mindoc
home = Home
blog = Blog
project_space = Project Space
person_center = Personal Center
my_project = My Project
my_blog = My Article
manage = Management
login = Log In
logout = Log Out
official_website = Official Website
feedback = Feedback
source_code = Source Code
manual = Manual
username = Username
account = Account
email = Email
password = Password
role = Role
captcha = Captcha
keep_login = Stay signed in
forgot_password = Forgot password?
register = Create New Account
third_party_login = Third Party Login
dingtalk_login = DingTalk Login
wecom_login = WeCom Login
account_recovery = Account recovery
new_password = New password
confirm_password = Confirm password
new_account = Create New Account
setting = Setting
save = Save
edit = Edit
delete = Delete
cancel = Cancel
create = Create
confirm_delete = Confirm
upload_lang = en
js_lang = en
remove = Remove
operate = Operate
confirm = Confirm
creator = Creator
administrator = Administrator
editor = Editor
observer = Observer
back = Back
detail = Detail
admin_right = Reading, writing and management
editor_right = Reading and writing
observer_right = Reading only
yes = yes
no = no
read = Read
generate = Generate
clean = Clean
[init]
default_proj_name = MinDoc Demo Project
default_proj_desc = This is a MinDoc demo project, which is automatically created when the system is initialized.
default_proj_space = Default Project Space
blank_doc = Blank document
[message]
tips = Tips
page_not_existed = The page does not exist
no_permission = No enough permissions
keyword_placeholder = input keyword please...
wrong_account_password = Incorrect username or password
wrong_password = Wrong password
click_to_change = Click to change one
logging_in = logging in...
need_relogin = Relogin please.
return_account_login = Return account password login
no_account_yet = No account yet?
has_account = Already have an account?
account_empty = Account cannot be empty
email_empty = Email cannot be empty
password_empty = Password cannot be empty
captcha_empty = Captcha cannot be empty
system_error = System error
processing = Processing...
email_sent = The email is sent successfully, please log in to check it.
confirm_password_empty = Confirm password cannot be empty
incorrect_confirm_password = Incorrect confirm password
illegal_request = Illegal request
account_or_password_empty = Account or Password cannot be empty
captcha_wrong = Incorrect captcha
password_length_invalid = The password cannot be empty and must be between 6-50 characters
mail_expired = Mail has expired
captcha_expired = The verification code has expired, please try again.
user_not_existed = User does not exist
readusr_only_observer = Read only users can only be set as observers
email_not_exist = Email does not exist
failed_save_password = Failed to save password
mail_service_not_enable = Mail service is not enabled
account_disable = Account has been disabled
failed_send_mail = Failed to send mail
sent_too_many_times = Send too many times, please try again later
account_not_support_retrieval = The current user does not support password retrieval
username_invalid_format = The account number can only be composed of English alphanumerics and 3-50 characters
email_invalid_format = Email format is incorrect
account_existed = Username already existed
failed_register = Registration failed, please contact the system administrator
failed_obtain_user_info = Failed to obtain identity information
dingtalk_auto_login_not_enable = DingTalk automatic login function is not enabled
failed_auto_login = Automatic login failed
no_project = No Project
item_not_exist = Item does not exist or has been deleted
item_not_exist_or_no_permit = Item does not exist or has insufficient permissions
doc_not_exist = Document does not exist or has been deleted
doc_not_exist_or_no_permit = Document does not exist or has insufficient permissions
unknown_exception = Unknown Exception
no_data = No Data
project_must_belong_space = Project must belong to a project space, and the administrator can manage it
project_title_placeholder = Title (limit in 30 words)
project_title_tips = Project name cannot exceed 100 characters
project_id_placeholder = Project ID (limit in 30 characters)
project_id_tips = The ID can only contain lowercase letters, numbers, and "-", "." and "_" symbols.
project_desc_placeholder = Project description cannot exceed 500 characters
project_public_desc = (Anyone can access)
project_private_desc = (Only participants or use tokens can access)
project_cover_desc = The Cover can be edit in the settings
confirm_delete_project = Are you sure you want to delete the project?
warning_delete_project = Remove items will not be retrieved.
project_space_empty = Please select project space
project_title_empty = Project title cannot be empty
project_id_empty = Project ID cannot be empty
project_id_existed = Project ID already in use
project_id_error = Project ID error
project_id_length = Project ID must be less than 50 characters
import_file_empty = Please select the file to upload
file_type_placeholder = Please select a Zip file
publish_to_queue = The publish task has been pushed to the task queue and will be executed soon.
team_name_empty = Team name cannot be empty
operate_failed = Operation failed
project_id_desc = The project ID is used to mark the uniqueness of the item and cannot be modified.
history_record_amount_desc = When document history enabled, this value limits the number of history saved per document
corp_id_desc = The footer that appears when the document PDF document is exported
project_desc_desc = The description information is no more than 500 characters, supports markdown syntax
project_desc_tips = The description information is no more than 500 characters
access_pass_desc = The password that needs to be provided to access the project without permit
auto_publish_desc = Enable for each save is automatically published to the latest version
enable_export_desc = Configure the exporter before you start the export, also enable the export function in the profile
enable_share_desc = Sharing is only available for public projects, and private projects do not support sharing
auto_save_desc = Save automatically every 30 seconds
confirm_into_private = Are you sure you want to make your project private?
into_private_notice = Private project need provide access token
confirm_into_public = Are you sure you want to make your project public?
into_public_notice = Public project could be visit by anyone
project_name_empty = Project name cannot be empty
success = Success
failed = Failed
receive_account_empty = The recipient account cannot be empty
receive_account_not_exist = The recipient account not exist
receive_account_disabled = The recipient account disable
cannot_preview = Cannot preview
upload_failed = Upload failed
upload_file_size_limit = The file must be less than 2MB
upload_file_empty = Upload file is empty
uploda_file_type_error = upload file type is wrong
choose_pic_file = Please select a picture
no_doc_in_cur_proj = No documents for the current project
build_doc_tree_error = There was an error building the project document tree
param_error = Parameter error
doc_name_empty = Document name cannot empty
parent_id_not_existed = Parent ID not existed
doc_not_belong_project = The document does not belong to the specified project`
attachment_not_exist = Attachment does not exist
read_file_error = Load file error
confirm_override_doc = The document has been modified, are you sure to override it?
doc_auto_published = The document was automatically published
export_func_disable = The export function is disable
cur_project_export_func_disable = The export function is disable for current Project
cur_project_not_support_md = The Markdown editor is not supported for the current project
export_failed = The export failed, check the system logs
file_converting = The document is being converted in the background, please download it later
unsupport_file_type = Unsupport file type
no_exportable_file = The project has no exportable file
gen_qrcode_failed = Generate QrCode failed
search_result_error = Search error
get_doc_his_failed = Fail to get document history
project_space_not_exist = Project space does not exist
search_placeholder = input keyword please
no_search_result = No search results!
user_exist_in_proj = The user already exists in the project
cannot_change_own_priv = Cannot change own permissions
cannot_delete_self = Cannot delete myself
cannot_handover_myself = Cannot handover to myself
confirm_delete_blog = Confirm delete blog?
delete_blog_tips = Deleted blog cannot be retrieved.
input_proj_id_pls = input project ID please
input_doc_id_pls = input document ID please
blog_digest_tips = blog digest cannot exceed 500 characters
blog_title_empty = blog title cannot be empty
blog_not_exist = Blog does not exist or has been deleted
blog_pwd_incorrect = Access password incorrect
set_pwd_pls = please set password for encrypt blog
unknown_blog_type = unknown blog type
blog_title_tips = blog title cannot exceed 200 characters
ref_doc_prj_not_existed = The Project of reference document not existed
query_ref_doc_error = query reference document failed
ref_doc_not_exist_or_no_permit = reference document does not exist or has insufficient permissions
blog_id_existed = blog id already existed
query_failed = query failed
blog_has_modified = The article has been modified
cur_user_cannot_change_pwd = The current user does not support changing the password
origin_pwd_empty = The origin password cannot be empty
new_pwd_empty = The new password cannot be empty
confirm_pwd_empty = The confirm password cannot be empty
pwd_length = Password must be between 6-18 characters
pwd_length_tips = Password must be between 6-50 characters
wrong_origin_pwd = The origin password incorrect
wrong_confirm_pwd = The confirm passwrod incorrect
same_pwd = The new password must different from the origin
pwd_encrypt_failed = Password encryption failed
team_name_empty = Team name cannot be emtpy
proj_empty = Project cannot be empty
site_name_empty = Site name cannot be empty
proj_space_name_empty = Project space name cannot be empty
proj_space_id_empty = Project space id cannot be empty
proj_space_id_tips = The project space id can only consist of letters and numbers and be between 2-100 characters
project_order_desc = Number only, sort from largest to smallest
project_label_desc = Allows up to 10 labels, use ";" to separate multiple tags
cannot_change_own_status = Cannot change own status
cannot_change_super_status = Cannot change super administrator status
cannot_change_super_priv = Cannot change super administrator permissions
editors_not_compatible = two editors are not compatible
[blog]
author = Author
project_list = Project List
add_project = Add Project
import_project = Import Project
delete_project = Delete Project
project_summary = Project summary
read = Read
edit = Edit
delete = Delete
copy = Copy
view = View
publish = Publish
edit_doc = Edit Document
default_cover = Default Cover
create_time = Create Time
update_time = Update Time
creator = Creator
doc_amount = Number of documents
doc_unit =
project_role = Project Role
last_edit = Last Edited
project_title = Project Title
project_id = Project ID
project_desc = Project description
public = Public
private = Private
public_project = Public Project
private_project = Private Project
summary = Summary
member = Member
team = Team
comment_amount = Number of comments
comment_unit =
member_manage = Member Manage
add_member = Add Member
administrator = Administrator
editor = Editor
observer = Observer
team_manage = Team Manage
add_team = Add Team
team_name = Team name
member_amount = Number of members
join_time = Join Time
project_setting = Project setting
handover_project = Handover
make_public = Into Public
make_private = Into Privete
history_record_amount = Number of history records
corp_id = corp name
text_editor = editor
project_label = Project Label
project_order = Project Order
access_pass = Access Password
access_token = Access Token
auto_publish = Auto publish
enable_export = Enable Export
enable_share = Enable Share
set_first_as_home = Set the first document as the default homepage
auto_save = Auto Save
cover = Cover
click_change_cover = Click to change the cover
change_cover = Change Cover
preview = Preview
choose = Choose
upload = Upload
recipient_account = Recipient
blog_list = Blog List
add_blog = Add Blog
encryption = encryption
encrypt = encrypt
edit_blog = Edit blog
delete_blog = Delete blog
setting_blog = Setting Blog
no_blog = No Blog
blog_setting = Blog Setting
title = Blog Title
type = Blog Type
normal_blog = Normal Blog
link_blog = Link Blog
ref_doc = Reference Document
blog_status = Blog Status
blog_pwd = Blog Password
blog_digest = Blog Digest
posted_on = Posted on
modified_on = Modified on
prev = prev
next = next
no = no
edit_title = Edit Blog
private_blog_tips = Private blog, please enter password to access
print_text = Enable Printing
[doc]
word_to_html = Word to HTML
html_to_markdown = HTML to Markdown
modify_doc = Modify Document
comparison = Comparison
save_merge = Save Merge
prev_diff = Previous difference
next_diff = Next difference
merge_to_left = Merge to left
merge_to_right = Merge to right
exchange_left_right = Exchange left and right
print = Print
download = Download
share = Share
share_project = Share project
share_url = Project URL
contents = Contents
search = Search
expand = Unfold
fold = Fold
close = Close
doc_publish_by = Document is Published by
doc_publish =
edit_doc = Edit Document
backward = backward
save = save
save_as_tpl = save as template
undo = undo
redo = redo
bold = bold
italic = italic
strikethrough = strikethrough
h1 = head 1
h2 = head 2
h3 = head 3
h4 = head 4
h5 = head 5
h6 = head 6
unorder_list = disorder list
order_list = order list
hline = horizontal line
link = link
ref_link = reference link
add_pic = add picture
code = code
code_block = code block
table = add table
quote = quote
gfm_task = GFM task
attachment = attachment
json_to_table = Json converted to table
template = template
draw = draw
close_preview = disable preview
modify_history = modify history
sidebar = sidebar
help = help
publish = publish
document = document
create_doc = create document
attachments = attachments
doc_name = Document name
doc_name_tips = Right-click on the document name of the directory to delete and modify the document name and add subordinate documents
doc_id = Document ID
doc_id_tips = The document ID can only contain lowercase letters, numbers, and "-" and "_" symbols, and can only start with a lowercase letter
expand_desc = (Expand nodes when reading)
fold_desc = (Fold nodes when reading)
empty_contents = Empty contents
empty_contents_desc = Click to expand the subordinate nodes
upload_attachment = Upload attachment
doc_history = Document history
choose_template_type = Choose template type please
normal_tpl = Normal
api_tpl = API
data_dict = Data Dictionary
custom_tpl = Custom
tpl_default_type = Default type
tpl_plain_text = Plain Text
for_api_doc = Used for API Document
code_highlight = support code highlighting
for_data_dict = Used for data dictionary
form_support = Form Support
any_type_doc = Support any type of document
as_global_tpl = Can be set as a global template
tpl_name = Template name
tpl_type = Template type
creator = Creator
create_time = Create time
operation = Operation
global_tpl = Global
global_tpl_desc = (Any Project is available)
project_tpl = Project
project_tpl_desc = (Only the current Project is available)
insert = insert
uploading = Uploading
his_ver = Historic version
update_time = Update time
updater = Updater
version = Version
delete = Delete
recover = Recover
merge = Merge
comparison_title = Document comparison [the left is the historical document, the right is the current document, please merge the documents to the right]
font_size = font size
underscore = underscore
right_intent = right intent
left_intent = left intent
subscript = subscript
superscript = superscript
clean_format = clear format
add_video = add video
formula = formula
font_color = font color
bg_color = background color
input_pwd = input password please
read_pwd = read password
commit = commit
ft_author = Author:
ft_last_editor = Last editor:
ft_create_time = Create time:
ft_update_time = Update time:
view_count = Number of views
changetheme = Switch themes
prev = prev
next = next
[project]
prj_space_list = Project Space List
prj_space_list_of = List of Project Space %s
search_title = Show Items of Project Space "%s"
author = Author
no_project = No Project
prj_amount = Project Count
creator = Creator
create_time = Create time
no_project_space = No Project Space
[search]
title = Search
search_title = Show search result for %s
doc = document
prj = project
blog = blog
from_proj = from project
from_blog = from blog
author = author
update_time = update time
no_result = No search result
[page]
first = first
last = last
prev = prev
next = next
[uc]
user_center = User Center
base_info = Basic Info
change_pwd = Change Password
username = Username
nickname = Nickname
realname = Real name
email = Email
mobile = Mobile
description = Description
description_tips = Description cannot exceed 500 characters
avatar = Avatar
change_avatar = Change avatar
password = Password
origin_pwd = Origin password
new_pwd = New password
confirm_pwd = Confirm password
role = Role
type = Type
status = Status
super_admin = Super administrator
admin = Administrator
user = User
read_usr = Read-Only User
normal = Normal
disable = Disable
enable = Enable
create_user = Create User
edit_user = Edit User
pwd_tips = Please leave it blank if you do not change the password, only local users can change the password
[mgr]
language = Default Language
zh_cn = 简体中文
en_us = English
dashboard_menu = Dashboard
user_menu = User
team_menu = Team
project_menu = Project
project_space_menu = Project Space
comment_menu = Comment
config_menu = Configure
attachment_menu = Attachment
label_menu = Label
dashboard_mgr = Dashboard
user_mgr = User Management
team_mgr = Team Management
project_mgr = Project Management
project_space_mgr = Project Space Management
comment_mgr = Comment Management
config_mgr = Configure Management
config_file = Configure File
attachment_mgr = Attachment Management
label_mgr = Label Management
label_name = Label name
used_quantity = Used Quantity
proj_amount = Number Of Project
blog_amount = Number Of Blog
member_amount = Number Of Member
comment_amount = Number Of Comment
attachment_amount = Number Of Attachment
member_mgr = Member Management
add_member = Add Member
create_team = Create Team
team_name = Team Name
proj = Project
member = Member
edit_team = Edit Team
team_member_mgr = Team Member Management
team_proj = Team Project
add_proj = Add Project
proj_name = Project name
proj_author = Project author
join_time = Join Time
join_proj = Join
file_name = File name
is_exist = Is Exist
exist = Exist
deleted = Deleted
proj_blog_name = Project/Blog name
doc_name = Document name
file_path = File path
download_url = Download URL
file_size = File size
upload_time = Upload time
download = Download
download_title = Download to local
attachment_name = Attachment name
site_name = Site Name
domain_icp = Domain ICP
site_desc = Site Description
site_desc_tips = Description cannot exceed 500 characters
enable_anonymous_access = Enable anonymous access
enable = Enable
disable = Disable
enable_register = Enable Registration
enable_captcha = Enable Captcha
enable_doc_his = Enable Document Historic
proj_space_name = Project space name
proj_space_id = Project space ID
create_proj_space = Create Project Space
edit_proj_space = Edit Project Space
proj_list = Project List
edit_proj = Edit Project
create_time = Create Time
creator = Creator
doc_amount = Number of Document
last_edit = Last Edit
delete_project = Delete Project
================================================
FILE: conf/lang/ru-ru.ini
================================================
[common]
title = MinDoc
home = Домашняя
blog = Блог
project_space = Проекты
person_center = Профиль
my_project = Мои проекты
my_blog = Моя статья
manage = Управление
login = Войти
logout = Выйти
official_website = Официальный сайт
feedback = Обратная связь
source_code = Исходный код
manual = Руководство пользователя
username = Имя пользователя
account = Аккаунт
email = Email
password = Пароль
role = Роль
captcha = Капча
keep_login = Оставайтесь в системе
forgot_password = забыл пароль?
register = Создать новый аккаунт
third_party_login = Вход третьей стороны
dingtalk_login = Войти с помощью DingTalk
wecom_login = Войти через Wecom
account_recovery = Восстановление аккаунта
new_password = Новый пароль
confirm_password = Подтвердите пароль
new_account = Создать новую учетную запись
setting = Настройка
save = Сохранить
edit = Изменить
delete = Удалить
cancel = Отмена
create = Создать
confirm_delete = Подтверждать
upload_lang = ru
js_lang = ru-RU
remove = Удалять
operate = Оперировать
confirm = Подтверждать
creator = Создатель
administrator = Администратор
editor = Редактор
observer = Наблюдатель
back = Назад
detail = Деталь
admin_right = Чтение, письмо и управление
editor_right = Чтение и письмо
observer_right = Только чтение
yes = Да
no = Нет
read = Читать
generate = Генерировать
clean = Чистый
[init]
default_proj_name = Демонстрационный проект MinDoc
default_proj_desc = Это демонстрационный проект MinDoc, который автоматически создается при инициализации системы
default_proj_space = Пространство проекта по умолчанию
blank_doc = Пустой документ
[message]
tips = Советы
page_not_existed = Эта страница не существует
no_permission = доступ запрещен
keyword_placeholder = введите ключевое слово, пожалуйста...
wrong_account_password = Неправильное имя пользователя или пароль
wrong_password = Неправильный пароль
click_to_change = Нажмите, чтобы изменить один
logging_in = Вход в систему...
need_relogin = Пожалуйста, войдите снова
return_account_login = вернуться к входу с учетной записью и паролем
no_account_yet = У вас еще нет аккаунта?
has_account = У вас уже есть аккаунт?
account_empty = Счет не может быть пустым
email_empty = Электронная почта не может быть пустой
password_empty = Пароль не может быть пустым
captcha_empty = Капча не может быть пустой
system_error = Система обнаружила ошибку
processing = Обработка...
email_sent = Письмо успешно отправлено, пожалуйста, проверьте его
confirm_password_empty = Подтвержденный пароль не может быть пустым
incorrect_confirm_password = Неверный подтвержденный пароль
illegal_request = Незаконный запрос
account_or_password_empty = Учетная запись или пароль не могут быть пустыми
captcha_wrong = Неправильная капча
password_length_invalid = Пароль не может быть пустым и должен содержать от 6 до 50 символов
mail_expired = почта просрочена
captcha_expired = Срок действия капчи истек, попробуйте еще раз
user_not_existed = этот пользователь не существует
readusr_only_observer = Толькі для чытання карыстальнікаў можна ўсталяваць толькі як назіральнікі
email_not_exist = этот адрес электронной почты не существует
failed_save_password = Не удалось сохранить пароль
mail_service_not_enable = Служба электронной почты не включена
account_disable = эта учетная запись была отключена
failed_send_mail = Не удалось отправить электронное письмо
sent_too_many_times = Отправьте слишком много раз, попробуйте еще раз позже
account_not_support_retrieval = Текущий пользователь не поддерживает восстановление пароля
username_invalid_format = Имя учетной записи может состоять только из английских букв, цифр и 3–50 символов
email_invalid_format = Неверный формат электронной почты
account_existed = Имя пользователя уже существует
failed_register = Регистрация не удалась, обратитесь к системному администратору
failed_obtain_user_info = Не удалось получить идентификационную информацию
dingtalk_auto_login_not_enable = Функция автоматического входа в DingTalk не включена
failed_auto_login = Автоматический вход не удался
no_project = Нет проекта
item_not_exist = Элемент не существует или был удален
item_not_exist_or_no_permit = Элемент не существует или имеет недостаточно прав
doc_not_exist = Документ не существует или был удален
doc_not_exist_or_no_permit = Документ не существует или имеет недостаточно прав
unknown_exception = Неизвестное исключение
no_data = Нет данных
project_must_belong_space = Каждый проект должен принадлежать к проектному пространству, и его администратор может им управлять
project_title_placeholder = Название (ограничение в 30 слов)
project_title_tips = Название проекта не может превышать 100 символов
project_id_placeholder = Идентификатор проекта (ограничение в 30 символов)
project_id_tips = Идентификатор может содержать только строчные буквы, цифры и символы «-», «.» и «_»
project_desc_placeholder = Описание проекта не может превышать 500 символов
project_public_desc = (Доступ возможен для всех)
project_private_desc = (Доступ возможен только участникам или пользователям токенов)
project_cover_desc = Изображение обложки проекта можно изменить в настройках проекта
confirm_delete_project = Вы уверены, что хотите удалить проект?
warning_delete_project = После удаления проекта его невозможно восстановить
project_space_empty = Пожалуйста, выберите проектное пространство
project_title_empty = Название проекта не может быть пустым
project_id_empty = ID проекта не может быть пустым
project_id_existed = Идентификатор проекта уже используется
project_id_error = Неверный идентификатор проекта
project_id_length = Идентификатор проекта должен быть менее 50 символов
import_file_empty = Пожалуйста, выберите файл для загрузки
file_type_placeholder = Пожалуйста, выберите файл zip/docx
publish_to_queue = Задача публикации помещена в очередь задач и будет выполнена в ближайшее время
team_name_empty = Название команды не может быть пустым
operate_failed = Операция не удалась
project_id_desc = Идентификатор проекта используется для обозначения уникальности элемента и не может быть изменен
history_record_amount_desc = Если включена история документа, это значение ограничивает количество сохраненных историй для каждого документа
corp_id_desc = Нижний колонтитул, который появляется при экспорте документа PDF
project_desc_desc = Описание информации не более 500 символов, поддерживает синтаксис markdown
project_desc_tips = Описательная информация не более 500 символов
access_pass_desc = Пароль, который вам необходимо указать, если у вас нет разрешения на доступ к проекту
auto_publish_desc = После включения каждое сохранение будет автоматически публиковаться в последней версии
enable_export_desc = Перед включением экспорта настройте программу экспорта и одновременно включите функцию экспорта в файле конфигурации
enable_share_desc = Совместное использование доступно только для публичных проектов. Частные проекты не поддерживают совместное использование
auto_save_desc = Сохранять автоматически каждые 30 секунд
confirm_into_private = Вы уверены, что хотите сделать проект приватным?
into_private_notice = Частный проект должен предоставить токен доступа
confirm_into_public = Вы уверены, что хотите сделать свой проект публичным?
into_public_notice = Публичный проект может посетить любой желающий
project_name_empty = Название проекта не может быть пустым
success = Успех
failed = Неуспешный
receive_account_empty = Счет получателя не может быть пустым
receive_account_not_exist = Учетная запись получателя не существует
receive_account_disabled = Отключить учетную запись получателя
cannot_preview = Невозможно просмотреть
upload_failed = Загрузка не удалась
upload_file_size_limit = Файл должен быть меньше 2MB
upload_file_empty = Загруженный файл пуст
uploda_file_type_error = Неправильный тип загруженного файла
choose_pic_file = Пожалуйста, выберите изображение
no_doc_in_cur_proj = Нет документов по текущему проекту
build_doc_tree_error = Произошла ошибка при построении дерева документов проекта
param_error = Ошибка параметра
doc_name_empty = Имя документа не может быть пустым
parent_id_not_existed = Родительский идентификатор не существует
doc_not_belong_project = Документ не принадлежит указанному проекту
attachment_not_exist = Вложение не существует
read_file_error = Ошибка чтения документа
confirm_override_doc = Документ был изменен. Вы уверены, что хотите его отменить?
doc_auto_published = Документ был автоматически успешно опубликован
export_func_disable = Функция экспорта отключена
cur_project_export_func_disable = Функция экспорта отключена для текущего проекта
cur_project_not_support_md = Редактор Markdown не поддерживается для текущего проекта
export_failed = Экспорт не удался, проверьте системный журнал
file_converting = Документ конвертируется в фоновом режиме, пожалуйста, загрузите его позже
unsupport_file_type = Неподдерживаемый тип файла
no_exportable_file = Проект не имеет экспортируемого файла
gen_qrcode_failed = Сгенерировать QR-код не удалось
search_result_error = Ошибка поиска
get_doc_his_failed = Не удалось получить историю документа
project_space_not_exist = Проектное пространство не существует
search_placeholder = введите ключевое слово пожалуйста
no_search_result = Результаты поиска отсутствуют!
user_exist_in_proj = Пользователь уже существует в проекте
cannot_change_own_priv = Невозможно изменить собственные разрешения
cannot_delete_self = Невозможно удалить себя
cannot_handover_myself = Cannot be transferred to yourself
confirm_delete_blog = Подтвердить удаление блога?
delete_blog_tips = Удаленный блог не может быть восстановлен
input_proj_id_pls = введите идентификатор проекта, пожалуйста
input_doc_id_pls = введите идентификатор документа, пожалуйста
blog_digest_tips = Дайджест блога не может превышать 500 символов
blog_title_empty = название блога не может быть пустым
blog_not_exist = Блог не существует или был удален
blog_pwd_incorrect = Неверный пароль доступа
set_pwd_pls = пожалуйста, установите пароль для шифрования блога
unknown_blog_type = неизвестный тип блога
blog_title_tips = Название блога не может превышать 200 символов
ref_doc_prj_not_existed = Проект справочного документа не существует
query_ref_doc_error = запрос справочного документа не удался
ref_doc_not_exist_or_no_permit = справочный документ не существует или имеет недостаточные разрешения
blog_id_existed = идентификатор блога уже существует
query_failed = запрос не удался
blog_has_modified = Статья была изменена
cur_user_cannot_change_pwd = Текущий пользователь не поддерживает смену пароля
origin_pwd_empty = Исходный пароль не может быть пустым
new_pwd_empty = Новый пароль не может быть пустым
confirm_pwd_empty = Подтверждение пароля не может быть пустым
pwd_length = Пароль должен содержать от 6 до 18 символов
pwd_length_tips = Пароль должен содержать от 6 до 50 символов
wrong_origin_pwd = Неверный пароль источника
wrong_confirm_pwd = Подтверждение пароля неверное
same_pwd = Новый пароль должен отличаться от исходного
pwd_encrypt_failed = Шифрование пароля не удалось
team_name_empty = Название команды не может быть пустым
proj_empty = Проект не может быть пустым
site_name_empty = Имя сайта не может быть пустым
proj_space_name_empty = Имя пространства проекта не может быть пустым
proj_space_id_empty = Идентификатор пространства проекта не может быть пустым
proj_space_id_tips = Идентификатор пространства проекта может состоять только из букв и цифр и содержать от 2 до 100 символов
project_order_desc = Только число, сортировать от большего к меньшему
project_label_desc = Максимально допустимое количество тегов — 10. Разделяйте несколько тегов знаком «;»
cannot_change_own_status = Невозможно изменить свой статус
cannot_change_super_status = Невозможно изменить статус суперадминистратора
cannot_change_super_priv = Невозможно изменить права суперадминистратора
editors_not_compatible = Эти два редактора несовместимы
[blog]
author = Автор
project_list = Список проектов
add_project = Добавить проект
import_project = Импорт проекта
delete_project = Удалить проект
project_summary = Резюме проекта
read = Читать
edit = Редактировать
delete = Удалить
copy = Копировать
view = Вид
publish = Публиковать
edit_doc = Редактировать документ
default_cover = Обложка по умолчанию
create_time = Время создания
update_time = Время обновления
creator = Создатель
doc_amount = Количество документов
doc_unit =
project_role = Роль проекта
last_edit = последний раз редактировалось
project_title = Название проекта
project_id = Идентификатор проекта
project_desc = Описание проекта
public = общественный
private = Частный
public_project = Общественный проект
private_project = Частный проект
summary = Краткое содержание
member = Член
team = Команда
comment_amount = Количество комментариев
comment_unit =
member_manage = управление членами
add_member = Добавить участника
administrator = Администратор
editor = Редактор
observer = Наблюдатель
team_manage = управление командой
add_team = Добавить команду
team_name = Название команды
member_amount = Количество членов
join_time = Присоединился Время
project_setting = Настройка проекта
handover_project = Проект передачи
make_public = В общественность
make_private = В частную жизнь
history_record_amount = Количество исторических записей
corp_id = название корпорации
text_editor = монтажер
project_label = Метка проекта
project_order = Сортировка проекта
access_pass = Пароль доступа
access_token = Токен доступа
auto_publish = Автоматическая публикация
enable_export = Включить экспорт
enable_share = Включить Поделиться
set_first_as_home = Установить первый документ в качестве домашней страницы по умолчанию
auto_save = Автоматическое сохранение
cover = крышка
click_change_cover = Нажмите, чтобы изменить обложку проекта
change_cover = сменить обложку
preview = Предварительный просмотр
choose = Выбирать
upload = Загрузить
recipient_account = Получатель
blog_list = Список блогов
add_blog = Добавить блог
encryption = шифрование
encrypt = шифровать
edit_blog = Редактировать блог
delete_blog = Удалить блог
setting_blog = Настройка блога
no_blog = Нет блога
blog_setting = Настройка блога
title = Название блога
type = Тип блога
normal_blog = Обычный блог
link_blog = Связанный блог
ref_doc = Справочный документ
blog_status = Статус блога
blog_pwd = Пароль блога
blog_digest = Блог Дайджест
posted_on = Опубликовано
modified_on = Изменено
prev = предыдущий
next = следующий
no = нет
edit_title = Редактировать блог
private_blog_tips = Это частный блог, введите пароль для доступа
print_text = Включить печать
[doc]
word_to_html = Word в HTML
html_to_markdown = HTML в Markdown
modify_doc = Изменить документ
comparison = Сравнение
save_merge = Сохранить Объединить
prev_diff = Предыдущая разница
next_diff = Следующее отличие
merge_to_left = Объединить слева
merge_to_right = Объединить справа
exchange_left_right = Обмен левого и правого
print = Печать
download = Скачать
share = Делиться
share_project = Поделиться проектом
share_url = URL-адрес проекта
contents = Каталог
search = Поиск
expand = Расширять
fold = Складывать
close = Закрывать
doc_publish_by = Документ опубликован
doc_publish = выпускать
edit_doc = Редактировать документ
backward = назад
save = Сохранять
save_as_tpl = Сохранить как шаблон
undo = Отменить
redo = Переделать
bold = жирный
italic = курсив
strikethrough = зачеркивание
h1 = H1
h2 = H2
h3 = H3
h4 = H4
h5 = H5
h6 = H6
unorder_list = Неупорядоченный список
order_list = Упорядоченный список
hline = Горизонтальная линия
link = Связь
ref_link = Ссылка на ссылку
add_pic = добавить картинку
code = код
code_block = блок кода
table = Добавить таблицу
quote = цитировать
gfm_task = Задача GFM
attachment = вложение
json_to_table = конвертировать json в таблицу
template = шаблон
draw = нарисовать
close_preview = отключить предварительный просмотр
modify_history = История модификаций
sidebar = боковая панель
help = помощь
publish = публиковать
document = документ
create_doc = создать документ
attachments = вложения
doc_name = Название документа
doc_name_tips = Щелкните правой кнопкой мыши по имени документа в каталоге, чтобы удалить и изменить имя документа, а также добавить подчиненные документы.
doc_id = Идентификатор документа
doc_id_tips = Идентификатор документа может содержать только строчные буквы, цифры, символы «-» и «_» и может начинаться только со строчной буквы.
expand_desc = (Расширять узлы при чтении)
fold_desc = (Сворачивайте узлы при чтении)
empty_contents = Пустой каталог
empty_contents_desc = Нажмите, чтобы развернуть подчиненные узлы
upload_attachment = Загрузить вложение
doc_history = История документа
choose_template_type = Выберите тип шаблона, пожалуйста
normal_tpl = Нормальный
api_tpl = API
data_dict = Словарь данных
custom_tpl = Обычай
tpl_default_type = Тип по умолчанию
tpl_plain_text = Обычный текст
for_api_doc = Используется для API-документа
code_highlight = поддержка подсветки кода
for_data_dict = Используется для словаря данных
form_support = Поддержка формы
any_type_doc = Поддержка любого типа документа
as_global_tpl = Можно установить как глобальный шаблон
tpl_name = Имя шаблона
tpl_type = Тип шаблона
creator = Создатель
create_time = Время создания
operation = Операция
global_tpl = Глобальный
global_tpl_desc = (Любой проект доступен)
project_tpl = Проект
project_tpl_desc = (Доступен только текущий проект)
insert = вставлять
uploading = Загрузка
his_ver = Историческая версия
update_time = Время обновления
updater = Обновление
version = Версия
delete = Удалить
recover = Восстанавливаться
merge = Слияние
comparison_title = Сравнение документов [слева — исторический документ, справа — текущий документ, пожалуйста, объедините документы справа]
font_size = размер шрифта
underscore = подчеркивание
right_intent = правильное намерение
left_intent = левое намерение
subscript = нижний индекс
superscript = верхний индекс
clean_format = очистить формат
add_video = добавить видео
formula = формула
font_color = цвет шрифта
bg_color = цвет фона
input_pwd = введите пароль пожалуйста
read_pwd = прочитать пароль
commit = совершить
ft_author = Автор:
ft_last_editor = Последний редактор:
ft_create_time = Время создания:
ft_update_time = Время обновления:
view_count = Количество просмотров
changetheme = Переключить темы
[project]
prj_space_list = Список проектных пространств
prj_space_list_of = Список проектного пространства %s
search_title = Показать элементы пространства проекта "%s"
author = Автор
no_project = Нет проекта
prj_amount = Количество проектов
creator = Создатель
create_time = Время создания
no_project_space = Нет места для проекта
[search]
title = Поиск
search_title = Показать результат поиска для "%s"
doc = документ
prj = проект
blog = блог
from_proj = из проекта
from_blog = из блога
author = автор
update_time = время обновления
no_result = Нет результатов поиска
[page]
first = первый
last = последний
prev = предыдущий
next = следующий
[uc]
user_center = Центр пользователя
base_info = основная информация
change_pwd = Изменить пароль
username = Имя пользователя
nickname = Псевдоним
realname = Настоящее имя
email = Email
mobile = Номер телефона
description = Описание
description_tips = Описание не может превышать 500 символов.
avatar = Аватар
change_avatar = Изменить аватар
password = Пароль
origin_pwd = Исходный пароль
new_pwd = Новый пароль
confirm_pwd = Подтвердите пароль
role = Роль
type = Тип
status = Статус
super_admin = Супер администратор
admin = Администратор
user = Пользователь
read_usr = Пользователи только для чтения
normal = Нормальный
disable = Отключено
enable = Включено
create_user = Добавить пользователя
edit_user = Редактировать пользователя
pwd_tips = Пожалуйста, оставьте поле пустым, если вы не меняете пароль. Изменить пароль могут только локальные пользователи.
[mgr]
language = Язык по умолчанию
zh_cn = 简体中文
en_us = English
dashboard_menu = Приборная панель
user_menu = Пользователи
team_menu = Команды
project_menu = Проекты
project_space_menu = Проектные пространства
comment_menu = Комментарии
config_menu = Конфигурирует
attachment_menu = Вложения
label_menu = Этикетки
dashboard_mgr = Приборная панель
user_mgr = Управление пользователями
team_mgr = Управление командой
project_mgr = Управление проектом
project_space_mgr = Управление пространством проекта
comment_mgr = Управление комментариями
config_mgr = Конфигурирует управление
config_file = Настроить файл
attachment_mgr = Управление вложениями
label_mgr = Управление этикетками
label_name = Название этикетки
used_quantity = Использованное количество
proj_amount = Количество проектов
blog_amount = Количество блогов
member_amount = Количество членов
comment_amount = Количество комментариев
attachment_amount = Количество вложений
member_mgr = Управление участниками
add_member = Добавить участника
create_team = Создать команду
team_name = Название команды
proj = Проект
member = Член
edit_team = Редактировать информацию о команде
team_member_mgr = Управление членами команды
team_proj = Командный проект
add_proj = Добавить проект
proj_name = Название проекта
proj_author = Автор проекта
join_time = Присоединяйтесь Время
join_proj = Присоединиться
file_name = Имя файла
is_exist = Существует
exist = Существовать
deleted = Удалено
proj_blog_name = Название проекта/блога
doc_name = Название документа
file_path = Путь файла
download_url = URL для загрузки файла
file_size = Размер файла
upload_time = Время, когда файл был загружен
download = Скачать
download_title = Загрузить на локальный путь
attachment_name = Имя вложения
site_name = Название сайта
domain_icp = Регистрационный номер доменного имени ICP
site_desc = Описание веб-сайта
site_desc_tips = Описание не может превышать 500 символов
enable_anonymous_access = Включить анонимный доступ
enable = Включить
disable = Отключить
enable_register = Включить регистрацию
enable_captcha = Включить капчу
enable_doc_his = Включить историю документов
proj_space_name = Название пространства проекта
proj_space_id = Идентификатор пространства проекта
create_proj_space = Создать пространство проекта
edit_proj_space = Редактировать пространство проекта
proj_list = Список проектов
edit_proj = Редактировать проект
create_time = Время создания
creator = Создатель
doc_amount = Количество документов
last_edit = Последний редактор
delete_project = Удалить проект
================================================
FILE: conf/lang/zh-cn.ini
================================================
[common]
title = 文档在线管理系统
home = 首页
blog = 文章
project_space = 项目空间
person_center = 个人中心
my_project = 我的项目
my_blog = 我的文章
manage = 管理后台
login = 登录
logout = 退出登录
official_website = 官方网站
feedback = 意见反馈
source_code = 项目源码
manual = 使用手册
username = 用户名
account = 账号
email = 邮箱
password = 密码
role = 角色
captcha = 验证码
keep_login = 保持登录
forgot_password = 忘记密码?
register = 立即注册
third_party_login = 第三方登录
dingtalk_login = 钉钉登录
wecom_login = 企业微信登录
account_recovery = 找回密码
new_password = 新密码
confirm_password = 确认密码
new_account = 用户注册
setting = 设置
save = 保存
edit = 编辑
delete = 删除
cancel = 取消
create = 创建
confirm_delete = 确定删除
upload_lang = zh
js_lang = zh-CN
remove = 移除
operate = 操作
confirm = 确定
creator = 创始人
administrator = 管理员
editor = 编辑者
observer = 观察者
back = 返回
detail = 详情
admin_right = 拥有阅读、写作和管理权限
editor_right = 拥有阅读和写作权限
observer_right = 拥有阅读权限
yes = 是
no = 否
read = 阅读
generate = 生成
clean = 清理
[init]
default_proj_name = MinDoc演示项目
default_proj_desc = 这是一个MinDoc演示项目,该项目是由系统初始化时自动创建。
default_proj_space = 默认项目空间
blank_doc = 空白文档
[message]
tips = 友情提示
page_not_existed = 页面不存在
no_permission = 权限不足
keyword_placeholder = 请输入关键词...
wrong_account_password = 账号或密码错误
wrong_password = 密码错误
click_to_change = 点击换一张
logging_in = 正在登录...
need_relogin = 请重新登录。
return_account_login = 返回账号密码登录
no_account_yet = 还没有账号?
has_account = 已有账号?
account_empty = 账号不能为空
email_empty = 邮箱不能为空
password_empty = 密码不能为空
captcha_empty = 验证码不能为空
system_error = 系统错误
processing = 正在处理...
email_sent = 邮件发送成功,请登录邮箱查看。
confirm_password_empty = 确认密码不能为空
incorrect_confirm_password = 确认密码输入不正确
illegal_request = 非法请求
account_or_password_empty = 账号或密码不能为空
captcha_wrong = 验证码不正确
password_length_invalid = 密码不能为空且必须在6-50个字符之间
mail_expired = 邮件已失效
captcha_expired = 验证码已过期,请重新操作。
user_not_existed = 用户不存在
readusr_only_observer = 只读用户只能设置为观察者
email_not_exist = 邮箱不存在
failed_save_password = 保存密码失败
mail_service_not_enable = 未启用邮件服务
account_disable = 账号已被禁用
failed_send_mail = 发送邮件失败
sent_too_many_times = 发送次数太多,请稍候再试
account_not_support_retrieval = 当前用户不支持找回密码
username_invalid_format = 账号只能由英文字母数字组成,且在3-50个字符
email_invalid_format = 邮箱格式不正确
account_existed = 账号已存在
failed_register = 注册失败,请联系管理员
failed_obtain_user_info = 获取身份信息失败
dingtalk_auto_login_not_enable = 未开启钉钉自动登录功能
failed_auto_login = 自动登录失败
no_project = 暂无项目
item_not_exist = 项目不存在或已删除
item_not_exist_or_no_permit = 项目不存在或权限不足
doc_not_exist = 文档不存在或已删除
doc_not_exist_or_no_permit = 文档不存在或权限不足
unknown_exception = 未知异常
no_data = 暂无数据
project_must_belong_space = 每个项目必须归属一个项目空间,超级管理员可在后台管理和维护
project_title_placeholder = 项目标题(不超过100字)
project_title_tips = 项目标题不能超过100字符
project_id_placeholder = 项目唯一标识(不超过50字)
project_id_tips = 文档标识只能包含小写字母、数字,以及“-”、“.”和“_”符号.
project_desc_placeholder = 描述信息不超过500个字符
project_public_desc = (任何人都可以访问)
project_private_desc = (只有参与者或使用令牌才能访问)
project_cover_desc = 项目图片可在项目设置中修改
confirm_delete_project = 确定删除项目吗?
warning_delete_project = 删除项目后将无法找回。
project_space_empty = 请选择项目空间
project_title_empty = 项目标题不能为空
project_id_empty = 项目标识不能为空
project_id_existed = 文档标识已被使用
project_id_error = 项目标识有误
project_id_length = 项目标识必须小于50字符
import_file_empty = 请选择需要上传的文件
file_type_placeholder = 请选择Zip或Docx文件
publish_to_queue = 发布任务已推送到任务队列,稍后将在后台执行。
team_name_empty = 团队名称不能为空
operate_failed = 操作失败
project_id_desc = 项目标识用来标记项目的唯一性,不可修改。
history_record_amount_desc = 当开启文档历史时,该值会限制每个文档保存的历史数量
corp_id_desc = 导出文档PDF文档时显示的页脚
project_desc_desc = 描述信息不超过500个字符,支持Markdown语法
project_desc_tips = 项目描述不能大于500字
access_pass_desc = 没有访问权限访问项目时需要提供的密码
auto_publish_desc = 开启后,每次保存会自动发布到最新版本
enable_export_desc = 开启导出前请先配置导出程序,并在配置文件中同时开启导出功能
enable_share_desc = 分享只对公开项目生效,私有项目不支持分享
auto_save_desc = 开启后每隔30秒会自动保存
confirm_into_private = 确定将项目转为私有吗?
into_private_notice = 转为私有后需要通过阅读令牌才能访问该项目。
confirm_into_public = 确定将项目转为公有吗?
into_public_notice = 转为公有后所有人都可以访问该项目。
project_name_empty = 项目名称不能为空
success = 成功
failed = 失败
receive_account_empty = 接受者账号不能为空
receive_account_not_exist = 接受用户不存在
receive_account_disabled = 接受用户已被禁用
cannot_preview = 不能预览
upload_failed = 上传失败
upload_file_size_limit = 文件必须小于2MB
upload_file_empty = 上传文件为空
uploda_file_type_error = 文件类型有误
choose_pic_file = 请选择图片
no_doc_in_cur_proj = 当前项目没有文档
build_doc_tree_error = 生成项目文档树时出错
param_error = 参数错误
doc_name_empty = 文档名称不能为空
parent_id_not_existed = 父分类不存在
doc_not_belong_project = 文档不属于指定的项目
attachment_not_exist = 附件不存在或已删除
read_file_error = 读取文档错误
confirm_override_doc = 文档已被修改确定要覆盖吗?
doc_auto_published = 文档自动发布成功
export_func_disable = 系统没有开启导出功能
cur_project_export_func_disable = 当前项目没有开启导出功能
cur_project_not_support_md = 当前项目不支持Markdown编辑器
export_failed = 导出失败,请查看系统日志
file_converting = 文档正在后台转换,请稍后再下载
unsupport_file_type = 不支持的文件格式
no_exportable_file = 项目没有导出文件
gen_qrcode_failed = 生成二维码失败
search_result_error = 搜索结果错误
get_doc_his_failed = 获取历史失败
project_space_not_exist = 项目空间不存在
search_placeholder = 请输入搜索关键字
no_search_result = 暂无相关搜索结果!
user_exist_in_proj = 用户已存在该项目中
cannot_change_own_priv = 不能变更自己的权限
cannot_delete_self = 不能删除自己
cannot_handover_myself = 不能转让给自己
confirm_delete_blog = 确定删除文章吗?
delete_blog_tips = 删除文章后将无法找回。
input_proj_id_pls = 请输入项目标识
input_doc_id_pls = 请输入文档标识
blog_digest_tips = 文章摘要不超过500个字符
blog_title_empty = 文章标题不能为空
blog_not_exist = 文章不存在或已删除
blog_pwd_incorrect = 文章密码不正确
set_pwd_pls = 加密文章请设置密码
unknown_blog_type = 未知的文章类型
blog_title_tips = 文章标题不能大于200个字符
ref_doc_prj_not_existed = 关联文档的项目不存在
query_ref_doc_error = 查询关联项目文档时出错
ref_doc_not_exist_or_no_permit = 关联文档不存在或权限不足
blog_id_existed = 文章标识已存在
query_failed = 查询失败
blog_has_modified = 文章已被修改
cur_user_cannot_change_pwd = 当前用户不支持修改密码
origin_pwd_empty = 原密码不能为空
new_pwd_empty = 新密码不能为空
confirm_pwd_empty = 确认密码不能为空
pwd_length = 密码必须在6-18字之间
pwd_length_tips = 密码必须在6-50个字符之间
wrong_origin_pwd = 原始密码不正确
wrong_confirm_pwd = 确认密码不正确
same_pwd = 新密码不能和原始密码相同
pwd_encrypt_failed = 密码加密失败
team_name_empty = 团队名称不能为空
proj_empty = 项目不能为空
site_name_empty = 网站标题不能为空
proj_space_name_empty = 项目空间名称不能为空
proj_space_id_empty = 项目空间标识不能为空
proj_space_id_tips = 项目空间标识只能由字母和数字组成且在2-100字符之间
project_order_desc = 只能是数字,序号越大排序越靠前
project_label_desc = 最多允许添加10个标签,多个标签请用“;”分割
cannot_change_own_status = 不能变更自己的状态
cannot_change_super_status = 不能变更超级管理员的状态
cannot_change_super_priv = 不能变更超级管理员的权限
editors_not_compatible = 两种编辑器不兼容
[blog]
author = 作者
project_list = 项目列表
add_project = 添加项目
import_project = 导入项目
delete_project = 删除项目
project_summary = 项目概要
read = 阅读
edit = 编辑
delete = 删除
copy = 复制
view = 查看文档
publish = 发布
edit_doc = 编辑文档
default_cover = 默认封面
create_time = 创建时间
update_time = 修改时间
creator = 创建者
doc_amount = 文档数量
doc_unit = 篇
project_role = 项目角色
last_edit = 最后编辑
project_title = 项目标题
project_id = 项目标识
project_desc = 项目描述
public = 公开
private = 私有
public_project = 公开项目
private_project = 私有项目
summary = 概要
member = 成员
team = 团队
comment_amount = 评论数量
comment_unit = 条
member_manage = 成员管理
add_member = 添加成员
administrator = 管理员
editor = 编辑者
observer = 观察者
team_manage = 团队管理
add_team = 添加团队
team_name = 团队名称
member_amount = 成员数量
join_time = 加入时间
project_setting = 项目设置
handover_project = 转让项目
make_public = 转为公有
make_private = 转为私有
history_record_amount = 历史记录数量
corp_id = 公司名称
text_editor = 编辑器
project_label = 项目标签
project_order = 项目排序
access_pass = 访问密码
access_token = 访问令牌
auto_publish = 自动发布
enable_export = 开启导出
enable_share = 开启分享
set_first_as_home = 设置第一篇文档为默认首页
auto_save = 自动保存
cover = 封面
click_change_cover = 点击图片可修改项目封面
change_cover = 修改封面
preview = 预览
choose = 选择
upload = 上传
recipient_account = 接收者账号
blog_list = 文章列表
add_blog = 添加文章
encryption = 加密
encrypt = 密
edit_blog = 文章编辑
delete_blog = 删除文章
setting_blog = 文章设置
no_blog = 暂无文章
blog_setting = 文章设置
title = 文章标题
type = 文章类型
normal_blog = 普通文章
link_blog = 链接文章
ref_doc = 关联文档
blog_status = 文章状态
blog_pwd = 文章密码
blog_digest = 文章摘要
posted_on = 发布于
modified_on = 修改于
prev = 上一篇
next = 下一篇
no = 无
edit_title = 编辑文章
private_blog_tips = 加密文章,请输入密码访问
print_text = 开启打印
[doc]
word_to_html = Word转笔记
html_to_markdown = HTML转Markdown
modify_doc = 修改文档
comparison = 文档比较
save_merge = 保存合并
prev_diff = 上一处差异
next_diff = 下一处差异
merge_to_left = 合并到左侧
merge_to_right = 合并到右侧
exchange_left_right = 左右切换
print = 打印
download = 下载
share = 分享
share_project = 项目分享
share_url = 项目地址
contents = 目录
search = 搜索
expand = 展开
fold = 收起
close = 关闭
doc_publish_by = 本文档使用
doc_publish = 发布
edit_doc = 编辑文档
backward = 返回
save = 保存
save_as_tpl = 保存为模板
undo = 撤销
redo = 重做
bold = 粗体
italic = 斜体
strikethrough = 删除线
h1 = 标题一
h2 = 标题二
h3 = 标题三
h4 = 标题四
h5 = 标题五
h6 = 标题六
unorder_list = 无序列表
order_list = 有序列表
hline = Horizontal line
link = 链接
ref_link = 引用链接
add_pic = 添加图片
code = 行内代码
code_block = 代码块
table = 添加表格
quote = 引用
gfm_task = GFM 任务列表
attachment = 附件
json_to_table = Json转换为表格
template = 模板
draw = 画图
close_preview = 关闭实时预览
modify_history = 修改历史
sidebar = 边栏
help = 使用帮助
publish = 发布
document = 文档
create_doc = 创建文档
attachments = 个附件
doc_name = 文档名称
doc_name_tips = 在目录的文档名上右键可以删除和修改文档名称以及添加下级文档
doc_id = 文档标识
doc_id_tips = 文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头
expand_desc = (在阅读时会自动展开节点)
fold_desc = (在阅读时会关闭节点)
empty_contents = 空目录
empty_contents_desc = (单击时会展开下级节点)
upload_attachment = 上传附件
doc_history = 文档历史记录
choose_template_type = 请选择模板类型
normal_tpl = 普通文档
api_tpl = API文档
data_dict = 数据字典
custom_tpl = 自定义模板
tpl_default_type = 默认类型
tpl_plain_text = 简单的文本文档
for_api_doc = 用于API文档速写
code_highlight = 支持代码高亮
for_data_dict = 用于数据字典显示
form_support = 表格支持
any_type_doc = 支持任意类型文档
as_global_tpl = 可以设置为全局模板
tpl_name = 模板名称
tpl_type = 模板类型
creator = 创建人
create_time = 创建时间
operation = 操作
global_tpl = 全局
global_tpl_desc = (任何项目都可用)
project_tpl = 项目
project_tpl_desc = (只有当前项目可用)
insert = 插入
uploading = 正在上传
his_ver = 历史版本
update_time = 修改时间
updater = 修改人
version = 版本
delete = 删除
recover = 恢复
merge = 合并
comparison_title = 文档比较【左侧为历史文档,右侧为当前文档,请将文档合并到右侧】
font_size = 字号
underscore = 下划线
right_intent = 右缩进
left_intent = 左缩进
subscript = 下标
superscript = 上标
clean_format = 清空格式
add_video = 添加视频
formula = 公式
font_color = 字体颜色
bg_color = 背景颜色
input_pwd = 请输入密码
read_pwd = 浏览密码
commit = 提交
ft_author = 作者:
ft_last_editor = 最后编辑:
ft_create_time = 创建时间:
ft_update_time = 更新时间:
view_count = 阅读次数
changetheme = 切换主题
prev = 上一篇
next = 下一篇
[project]
prj_space_list = 项目空间列表
prj_space_list_of = 项目空间%s的项目列表
search_title = 显示项目空间为"%s"的项目
author = 作者
no_project = 暂无项目
prj_amount = 项目数量
creator = 创建人
create_time = 创建时间
no_project_space = 没有项目空间
[search]
title = 搜索
search_title = 显示"%s"的搜索结果
doc = 文档
prj = 项目
blog = 文章
from_proj = 来自项目
from_blog = 来自文章
author = 作者
update_time = 更新时间
no_result = 暂无相关搜索结果
[page]
first = 首页
last = 末页
prev = 上一页
next = 下一页
[uc]
user_center = 用户中心
base_info = 基本信息
change_pwd = 修改密码
username = 用户名
nickname = 昵称
realname = 真实姓名
email = 邮箱
mobile = 手机号
description = 描述
description_tips = 描述不能超过500字
avatar = 头像
change_avatar = 修改头像
password = 密码
origin_pwd = 原始密码
new_pwd = 新密码
confirm_pwd = 确认密码
role = 角色
type = 类型
status = 状态
super_admin = 超级管理员
admin = 管理员
user = 普通用户
read_usr = 只读用户
normal = 正常
disable = 禁用
enable = 启用
create_user = 创建用户
edit_user = 编辑用户
pwd_tips = 不修改密码请留空,只支持本地用户修改密码
[mgr]
language = 默认语言
zh_cn = 简体中文
en_us = English
dashboard_menu = 仪表盘
user_menu = 用户管理
team_menu = 团队管理
project_menu = 项目管理
project_space_menu = 项目空间管理
comment_menu = 评论管理
config_menu = 配置管理
attachment_menu = 附件管理
label_menu = 标签管理
dashboard_mgr = 仪表盘
user_mgr = 用户管理
team_mgr = 团队管理
project_mgr = 项目管理
project_space_mgr = 项目空间管理
comment_mgr = 评论管理
config_mgr = 配置管理
config_file = 配置文件
attachment_mgr = 附件管理
label_mgr = 标签管理
label_name = 标签名称
used_quantity = 使用数量
proj_amount = 项目数量
blog_amount = 文章数量
member_amount = 成员数量
comment_amount = 评论数量
attachment_amount = 附件数量
member_mgr = 成员管理
add_member = 添加成员
create_team = 创建团队
team_name = 团队名称
proj = 项目
member = 成员
edit_team = 编辑团队
team_member_mgr = 团队用户管理
team_proj = 团队项目
add_proj = 添加项目
proj_name = 项目名称
proj_author = 项目作者
join_time = 加入时间
join_proj = 加入项目
file_name = 文件名称
is_exist = 是否存在
exist = 存在
deleted = 已删除
proj_blog_name = 项目/文章名称
doc_name = 文档名称
file_path = 文件路径
download_url = 下载路径
file_size = 文件大小
upload_time = 上传时间
download = 下载
download_title = 下载到本地
attachment_name = 附件名称
site_name = 网站标题
domain_icp = 域名备案
site_desc = 网站描述
site_desc_tips = 描述信息不超过500个字符
enable_anonymous_access = 启用匿名访问
enable = 开启
disable = 关闭
enable_register = 启用注册
enable_captcha = 启用验证码
enable_doc_his = 启用文档历史
proj_space_name = 项目空间名称
proj_space_id = 项目空间标识
create_proj_space = 创建项目空间
edit_proj_space = 编辑项目空间
proj_list = 项目列表
edit_proj = 编辑项目
create_time = 创建时间
creator = 创建者
doc_amount = 文档数量
last_edit = 最后编辑
delete_project = 删除项目
================================================
FILE: conf/mail.go
================================================
package conf
import (
"strings"
"github.com/beego/beego/v2/server/web"
)
type SmtpConf struct {
EnableMail bool
MailNumber int
SmtpUserName string
SmtpHost string
SmtpPassword string
SmtpPort int
FormUserName string
MailExpired int
Secure string
}
func GetMailConfig() *SmtpConf {
user_name, _ := web.AppConfig.String("smtp_user_name")
password, _ := web.AppConfig.String("smtp_password")
smtp_host, _ := web.AppConfig.String("smtp_host")
smtp_port := web.AppConfig.DefaultInt("smtp_port", 25)
form_user_name, _ := web.AppConfig.String("form_user_name")
enable_mail, _ := web.AppConfig.String("enable_mail")
mail_number := web.AppConfig.DefaultInt("mail_number", 5)
secure := web.AppConfig.DefaultString("secure", "NONE")
if secure != "NONE" && secure != "LOGIN" && secure != "SSL" {
secure = "NONE"
}
c := &SmtpConf{
EnableMail: strings.EqualFold(enable_mail, "true"),
MailNumber: mail_number,
SmtpUserName: user_name,
SmtpHost: smtp_host,
SmtpPassword: password,
FormUserName: form_user_name,
SmtpPort: smtp_port,
Secure: secure,
}
return c
}
================================================
FILE: conf/workweixin.go
================================================
package conf
import (
"github.com/beego/beego/v2/server/web"
)
type WorkWeixinConf struct {
CorpId string // 企业ID
AgentId string // 应用ID
Secret string // 应用密钥
// ContactSecret string // 通讯录密钥
}
func GetWorkWeixinConfig() *WorkWeixinConf {
corpid, _ := web.AppConfig.String("workweixin_corpid")
agentid, _ := web.AppConfig.String("workweixin_agentid")
secret, _ := web.AppConfig.String("workweixin_secret")
// contact_secret, _ := web.AppConfig.String("workweixin_contact_secret")
c := &WorkWeixinConf{
CorpId: corpid,
AgentId: agentid,
Secret: secret,
// ContactSecret: contact_secret,
}
return c
}
================================================
FILE: controllers/AccountController.go
================================================
package controllers
import (
"context"
"encoding/json"
"errors"
"github.com/mindoc-org/mindoc/cache"
"github.com/mindoc-org/mindoc/utils/auth2"
"github.com/mindoc-org/mindoc/utils/auth2/dingtalk"
"github.com/mindoc-org/mindoc/utils/auth2/wecom"
"html/template"
"math/rand"
"net/http"
"net/url"
"regexp"
"strings"
"time"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"github.com/beego/i18n"
"github.com/lifei6671/gocaptcha"
"github.com/mindoc-org/mindoc/conf"
"github.com/mindoc-org/mindoc/mail"
"github.com/mindoc-org/mindoc/models"
"github.com/mindoc-org/mindoc/utils"
)
const (
SessionUserInfoKey = "session-user-info-key"
AccessTokenCacheKey = "access-token-cache-key"
)
var src = rand.New(rand.NewSource(time.Now().UnixNano()))
// AccountController 用户登录与注册
type AccountController struct {
BaseController
}
func (c *AccountController) referer() string {
u, _ := url.PathUnescape(c.GetString("url"))
if u == "" {
u = conf.URLFor("HomeController.Index")
}
return u
}
func (c *AccountController) IsInWorkWeixin() bool {
ua := c.Ctx.Input.UserAgent()
var wechatRule = regexp.MustCompile(`\bMicroMessenger\/\d+(\.\d+)*\b`)
var wxworkRule = regexp.MustCompile(`\bwxwork\/\d+(\.\d+)*\b`)
return wechatRule.MatchString(ua) && wxworkRule.MatchString(ua)
}
func (c *AccountController) Prepare() {
c.BaseController.Prepare()
c.EnableXSRF = web.AppConfig.DefaultBool("enablexsrf", true)
c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML())
c.Data["CanLoginWorkWeixin"] = len(web.AppConfig.DefaultString("workweixin_corpid", "")) > 0
c.Data["CanLoginDingTalk"] = len(web.AppConfig.DefaultString("dingtalk_app_key", "")) > 0
if !c.EnableXSRF {
return
}
if c.Ctx.Input.IsPost() {
token := c.Ctx.Input.Query("_xsrf")
if token == "" {
token = c.Ctx.Request.Header.Get("X-Xsrftoken")
}
if token == "" {
token = c.Ctx.Request.Header.Get("X-Csrftoken")
}
if token == "" {
if c.IsAjax() {
c.JsonResult(403, i18n.Tr(c.Lang, "message.illegal_request"))
} else {
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.illegal_request"))
}
}
xsrfToken := c.XSRFToken()
if xsrfToken != token {
if c.IsAjax() {
c.JsonResult(403, i18n.Tr(c.Lang, "message.illegal_request"))
} else {
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.illegal_request"))
}
}
}
}
// Login 用户登录
func (c *AccountController) Login() {
c.TplName = "account/login.tpl"
if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
u := c.GetString("url")
if u == "" {
u = c.Ctx.Request.Header.Get("Referer")
}
if u == "" {
u = conf.URLFor("HomeController.Index")
}
c.Redirect(u, 302)
}
var remember CookieRemember
// 如果 Cookie 中存在登录信息
if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
if err := utils.Decode(cookie, &remember); err == nil {
if member, err := models.NewMember().Find(remember.MemberId); err == nil {
c.SetMember(*member)
c.LoggedIn(false)
c.StopRun()
}
}
}
if c.Ctx.Input.IsPost() {
account := c.GetString("account")
password := c.GetString("password")
captcha := c.GetString("code")
isRemember := c.GetString("is_remember")
// 如果开启了验证码
if v, ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v, "true") {
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
if !ok || !strings.EqualFold(v, captcha) {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
}
}
if account == "" || password == "" {
c.JsonResult(6002, i18n.Tr(c.Lang, "message.account_or_password_empty"))
}
member, err := models.NewMember().Login(account, password)
if err == nil {
member.LastLoginTime = time.Now()
_ = member.Update("last_login_time")
c.SetMember(*member)
if strings.EqualFold(isRemember, "yes") {
remember.MemberId = member.MemberId
remember.Account = member.Account
remember.Time = time.Now()
v, err := utils.Encode(remember)
if err == nil {
c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30).Unix())
}
}
c.JsonResult(0, "ok", c.referer())
} else {
logs.Error("用户登录 ->", err)
c.JsonResult(500, i18n.Tr(c.Lang, "message.wrong_account_password"), nil)
}
return
}
referer := c.referer()
u := c.GetString("url")
if u == "" {
u = referer
if u == "" {
u = conf.BaseUrl
}
} else {
var schemaRule = regexp.MustCompile(`^https?\:\/\/`)
if !schemaRule.MatchString(u) {
u = conf.BaseUrl + u
}
}
c.Data["url"] = referer
auth2Redirect := "AccountController.Auth2Redirect"
if can, _ := c.Data["CanLoginWorkWeixin"].(bool); can {
c.Data["workweixin_login_url"] = conf.URLFor(auth2Redirect, ":app", wecom.AppName, "url", url.PathEscape(u))
}
if can, _ := c.Data["CanLoginDingTalk"].(bool); can {
c.Data["dingtalk_login_url"] = conf.URLFor(auth2Redirect, ":app", dingtalk.AppName, "url", url.PathEscape(u))
}
return
}
/*
Auth2.0 第三方对接思路:
1. Auth2Redirect: 点击相应第三方接口,路由重定向至第三方提供的Auth2.0地址
2. Auth2Callback: 第三方回调处理,接收回调的授权码,并获取用户信息
已绑定: 则读取用户信息,直接登录
未绑定: 则弹窗提示(需要敏感信息)
a) Auth2BindAccount: 绑定已有账户(用户名+密码)
b) Auth2AutoAccount: 自动创建账户,以第三方用户ID作为用户名,密码123456。
用该方式创建的账户,无法使用账号密码登录,需要修改一次密码后才可以进行账号密码登录。
*/
func (c *AccountController) getAuth2Client() (auth2.Client, error) {
app := c.Ctx.Input.Param(":app")
var client auth2.Client
tokenKey := AccessTokenCacheKey + "-" + app
switch app {
case wecom.AppName:
if can, _ := c.Data["CanLoginWorkWeixin"].(bool); !can {
return nil, errors.New("auth2.client.wecom.disabled")
}
corpId, _ := web.AppConfig.String("workweixin_corpid")
agentId, _ := web.AppConfig.String("workweixin_agentid")
secret, _ := web.AppConfig.String("workweixin_secret")
client = wecom.NewClient(corpId, agentId, secret)
case dingtalk.AppName:
if can, _ := c.Data["CanLoginDingTalk"].(bool); !can {
return nil, errors.New("auth2.client.dingtalk.disabled")
}
appKey, _ := web.AppConfig.String("dingtalk_app_key")
appSecret, _ := web.AppConfig.String("dingtalk_app_secret")
client = dingtalk.NewClient(appSecret, appKey)
default:
return nil, errors.New("auth2.client.notsupported")
}
var tokenCache auth2.AccessTokenCache
err := cache.Get(tokenKey, &tokenCache)
if err != nil {
logs.Info("AccessToken从缓存读取失败")
token, err := client.GetAccessToken(context.Background())
if err != nil {
return client, nil
}
tokenCache = auth2.NewAccessToken(token)
cache.Put(tokenKey, tokenCache, tokenCache.GetExpireIn())
}
// 处理过期Token
if tokenCache.IsExpired() {
token, err := client.GetAccessToken(context.Background())
if err != nil {
return client, nil
}
tokenCache = auth2.NewAccessToken(token)
cache.Put(tokenKey, tokenCache, tokenCache.GetExpireIn())
}
client.SetAccessToken(tokenCache)
return client, nil
}
func (c *AccountController) parseAuth2CallbackParam() (code, state string) {
switch c.Ctx.Input.Param(":app") {
case wecom.AppName:
code = c.GetString("code")
state = c.GetString("state")
case dingtalk.AppName:
code = c.GetString("authCode")
state = c.GetString("state")
}
logs.Debug("code: ", code)
logs.Debug("state: ", state)
return
}
func (c *AccountController) getAuth2Account() (models.Auth2Account, error) {
switch c.Ctx.Input.Param(":app") {
case wecom.AppName:
return models.NewWorkWeixinAccount(), nil
case dingtalk.AppName:
return models.NewDingTalkAccount(), nil
}
return nil, errors.New("auth2.account.notsupported")
}
// Auth2Redirect 第三方auth2.0登录: 钉钉、企业微信
func (c *AccountController) Auth2Redirect() {
client, err := c.getAuth2Client()
if err != nil {
c.DelSession(conf.LoginSessionName)
c.SetMember(models.Member{})
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
c.StopRun()
return
}
app := c.Ctx.Input.Param(":app")
var isAppBrowser bool
switch app {
case wecom.AppName:
isAppBrowser = c.IsInWorkWeixin()
}
var callback string
u := c.GetString("url")
if u == "" {
u = c.referer()
callback = conf.URLFor("AccountController.Auth2Callback", ":app", app)
}
if u != "" {
var schemaRule = regexp.MustCompile(`^https?\:\/\/`)
if !schemaRule.MatchString(u) {
u = strings.TrimRight(conf.BaseUrl, "/") + strings.TrimLeft(u, "/")
}
callback = conf.URLFor("AccountController.Auth2Callback", ":app", app, "url", url.PathEscape(u))
}
logs.Debug("callback: ", callback) // debug
c.Redirect(client.BuildURL(callback, isAppBrowser), http.StatusFound)
}
// Auth2Callback 第三方auth2.0回调
func (c *AccountController) Auth2Callback() {
client, err := c.getAuth2Client()
if err != nil {
c.DelSession(conf.LoginSessionName)
c.SetMember(models.Member{})
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
c.StopRun()
logs.Error(err)
return
}
if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
u := c.GetString("url")
if u == "" {
u = c.Ctx.Request.Header.Get("Referer")
}
if u == "" {
u = conf.URLFor("HomeController.Index")
}
member, err := models.NewMember().Find(member.MemberId)
if err != nil {
c.DelSession(conf.LoginSessionName)
c.SetMember(models.Member{})
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
} else {
c.SetMember(*member)
}
c.Redirect(u, 302)
}
var remember CookieRemember
// 如果 Cookie 中存在登录信息
if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
if err := utils.Decode(cookie, &remember); err == nil {
if member, err := models.NewMember().Find(remember.MemberId); err == nil {
c.SetMember(*member)
c.LoggedIn(false)
c.StopRun()
}
}
}
c.TplName = "account/auth2_callback.tpl"
bindExisted := "false"
errMsg := ""
userInfoJson := "{}"
defer func() {
c.Data["bind_existed"] = template.JS(bindExisted)
logs.Debug("bind_existed: ", bindExisted)
c.Data["error_msg"] = template.JS(errMsg)
c.Data["user_info_json"] = template.JS(userInfoJson)
c.Data["app"] = template.JS(c.Ctx.Input.Param(":app"))
}()
// 请求参数获取
code, state := c.parseAuth2CallbackParam()
if err := client.ValidateCallback(state); err != nil {
c.DelSession(conf.LoginSessionName)
c.SetMember(models.Member{})
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
errMsg = err.Error()
logs.Error(err)
return
}
userInfo, err := client.GetUserInfo(context.Background(), code)
if err != nil {
c.DelSession(conf.LoginSessionName)
c.SetMember(models.Member{})
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
errMsg = err.Error()
logs.Error(err)
return
}
account, err := c.getAuth2Account()
if err != nil {
logs.Error("获取Auth2用户失败 ->", err)
c.JsonResult(500, "不支持的第三方用户", nil)
return
}
member, err := account.ExistedMember(userInfo.UserId)
if err != nil {
if err == orm.ErrNoRows {
if userInfo.Mobile == "" {
errMsg = "请到应用浏览器中登录,并授权获取敏感信息。"
} else {
jsonInfo, _ := json.Marshal(userInfo)
userInfoJson = string(jsonInfo)
errMsg = ""
c.SetSession(SessionUserInfoKey, userInfo)
}
} else {
logs.Error("Error: ", err)
errMsg = "登录错误: " + err.Error()
}
return
}
bindExisted = "true"
errMsg = ""
member.LastLoginTime = time.Now()
_ = member.Update("last_login_time")
c.SetMember(*member)
remember.MemberId = member.MemberId
remember.Account = member.Account
remember.Time = time.Now()
v, err := utils.Encode(remember)
if err == nil {
c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30*5).Unix())
}
u := c.GetString("url")
if u == "" {
u = conf.URLFor("HomeController.Index")
}
c.Redirect(u, 302)
}
// Auth2BindAccount 第三方auth2.0绑定已有账号
func (c *AccountController) Auth2BindAccount() {
userInfo, ok := c.GetSession(SessionUserInfoKey).(auth2.UserInfo)
if !ok || len(userInfo.UserId) <= 0 {
c.DelSession(SessionUserInfoKey)
c.JsonResult(400, "请求错误, 请从首页重新登录")
return
}
account := c.GetString("account")
password := c.GetString("password")
if account == "" || password == "" {
c.JsonResult(400, "账号或密码不能为空")
return
}
member, err := models.NewMember().Login(account, password)
if err != nil {
logs.Error("用户登录 ->", err)
c.JsonResult(500, "账号或密码错误", nil)
return
}
bindAccount, err := c.getAuth2Account()
if err != nil {
logs.Error("获取Auth2用户失败 ->", err)
c.JsonResult(500, "不支持的第三方用户", nil)
return
}
member.CreateAt = 0
ormer := orm.NewOrm()
o, err := ormer.Begin()
if err != nil {
logs.Error("开启事务时出错 -> ", err)
c.JsonResult(500, "开启事务时出错: ", err.Error())
return
}
if err := bindAccount.AddBind(ormer, userInfo, member); err != nil {
logs.Error(err)
o.Rollback()
c.JsonResult(500, "绑定失败,数据库错误: "+err.Error())
return
}
// 绑定成功之后修改用户信息
member.LastLoginTime = time.Now()
//member.RealName = user_info.Name
//member.Avatar = user_info.Avatar
if len(member.Avatar) < 1 {
member.Avatar = conf.GetDefaultAvatar()
}
//member.Email = user_info.Email
//member.Phone = user_info.Mobile
if _, err := ormer.Update(member, "last_login_time", "real_name", "avatar", "email", "phone"); err != nil {
o.Rollback()
logs.Error("保存用户信息失败=>", err)
c.JsonResult(500, "绑定失败,现有账户信息更新失败: "+err.Error())
return
}
if err := o.Commit(); err != nil {
logs.Error("开启事务时出错 -> ", err)
c.JsonResult(500, "开启事务时出错: ", err.Error())
return
}
c.DelSession(SessionUserInfoKey)
c.SetMember(*member)
var remember CookieRemember
remember.MemberId = member.MemberId
remember.Account = member.Account
remember.Time = time.Now()
v, err := utils.Encode(remember)
if err != nil {
c.JsonResult(500, "绑定成功, 但自动登录失败, 请返回首页重新登录", nil)
return
}
c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30*5).Unix())
c.JsonResult(0, "绑定成功", nil)
}
// Auth2AutoAccount auth2.0自动创建账号
func (c *AccountController) Auth2AutoAccount() {
app := c.Ctx.Input.Param(":app")
logs.Debug("app: ", app)
userInfo, ok := c.GetSession(SessionUserInfoKey).(auth2.UserInfo)
if !ok || len(userInfo.UserId) <= 0 {
c.DelSession(SessionUserInfoKey)
c.JsonResult(400, "请求错误, 请从首页重新登录")
return
}
c.DelSession(SessionUserInfoKey)
member := models.NewMember()
if _, err := member.FindByAccount(userInfo.UserId); err == nil && member.MemberId > 0 {
c.JsonResult(400, "账号已存在")
return
}
ormer := orm.NewOrm()
o, err := ormer.Begin()
if err != nil {
logs.Error("开启事务时出错 -> ", err)
c.JsonResult(500, "开启事务时出错: ", err.Error())
return
}
member.Account = userInfo.UserId
member.RealName = userInfo.Name
member.Password = "123456" // 强制设置默认密码,需修改一次密码后,才可以进行账号密码登录
hash, err := utils.PasswordHash(member.Password)
if err != nil {
logs.Error("加密用户密码失败 =>", err)
c.JsonResult(500, "加密用户密码失败"+err.Error())
return
}
logs.Debug("member.Password: ", member.Password)
logs.Debug("hash: ", hash)
member.Password = hash
member.Role = conf.MemberGeneralRole
member.Avatar = userInfo.Avatar
if len(member.Avatar) < 1 {
member.Avatar = conf.GetDefaultAvatar()
}
member.CreateAt = 0
member.Email = userInfo.Mail
member.Phone = userInfo.Mobile
member.Status = 0
if _, err = ormer.Insert(member); err != nil {
o.Rollback()
c.JsonResult(500, "注册失败,数据库错误: "+err.Error())
return
}
account, err := c.getAuth2Account()
if err != nil {
logs.Error("获取Auth2用户失败 ->", err)
c.JsonResult(500, "不支持的第三方用户", nil)
return
}
member.CreateAt = 0
if err := account.AddBind(ormer, userInfo, member); err != nil {
logs.Error(err)
o.Rollback()
c.JsonResult(500, "注册失败,数据库错误: "+err.Error())
return
}
if err := o.Commit(); err != nil {
logs.Error("提交事务时出错 -> ", err)
c.JsonResult(500, "提交事务时出错: ", err.Error())
return
}
member.LastLoginTime = time.Now()
_ = member.Update("last_login_time")
c.SetMember(*member)
var remember CookieRemember
remember.MemberId = member.MemberId
remember.Account = member.Account
remember.Time = time.Now()
v, err := utils.Encode(remember)
if err != nil {
c.JsonResult(500, "绑定成功, 但自动登录失败, 请返回首页重新登录", nil)
return
}
c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30*5).Unix())
c.JsonResult(0, "绑定成功", nil)
}
// 钉钉登录
//func (c *AccountController) DingTalkLogin() {
// code := c.GetString("dingtalk_code")
// if code == "" {
// c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_obtain_user_info"), nil)
// }
//
// appKey, _ := web.AppConfig.String("dingtalk_app_key")
// appSecret, _ := web.AppConfig.String("dingtalk_app_secret")
// tmpReader, _ := web.AppConfig.String("dingtalk_tmp_reader")
//
// if appKey == "" || appSecret == "" || tmpReader == "" {
// c.JsonResult(500, i18n.Tr(c.Lang, "message.dingtalk_auto_login_not_enable"), nil)
// c.StopRun()
// }
//
// dingtalkAgent := dingtalk.NewDingTalkAgent(appSecret, appKey)
// err := dingtalkAgent.GetAccesstoken()
// if err != nil {
// logs.Warn("获取钉钉临时Token失败 ->", err)
// c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_auto_login"), nil)
// c.StopRun()
// }
//
// userid, err := dingtalkAgent.GetUserIDByCode(code)
// if err != nil {
// logs.Warn("获取钉钉用户ID失败 ->", err)
// c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_auto_login"), nil)
// c.StopRun()
// }
//
// username, avatar, err := dingtalkAgent.GetUserNameAndAvatarByUserID(userid)
// if err != nil {
// logs.Warn("获取钉钉用户信息失败 ->", err)
// c.JsonResult(500, i18n.Tr(c.Lang, "message.failed_auto_login"), nil)
// c.StopRun()
// }
//
// member, err := models.NewMember().TmpLogin(tmpReader)
// if err == nil {
// member.LastLoginTime = time.Now()
// _ = member.Update("last_login_time")
// member.Account = username
// if avatar != "" {
// member.Avatar = avatar
// }
//
// c.SetMember(*member)
// }
// c.JsonResult(0, "ok", username)
//}
// WorkWeixinLogin 用户企业微信登录
//func (c *AccountController) WorkWeixinLogin() {
// logs.Info("UserAgent: ", c.Ctx.Input.UserAgent()) // debug
//
// if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
// u := c.GetString("url")
// if u == "" {
// u = c.Ctx.Request.Header.Get("Referer")
// if u == "" {
// u = conf.URLFor("HomeController.Index")
// }
// }
// // session自动登录时刷新session内容
// member, err := models.NewMember().Find(member.MemberId)
// if err != nil {
// c.DelSession(conf.LoginSessionName)
// c.SetMember(models.Member{})
// c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
// } else {
// c.SetMember(*member)
// }
// c.Redirect(u, 302)
// }
// var remember CookieRemember
// // 如果 Cookie 中存在登录信息
// if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
// if err := utils.Decode(cookie, &remember); err == nil {
// if member, err := models.NewMember().Find(remember.MemberId); err == nil {
// c.SetMember(*member)
// c.LoggedIn(false)
// c.StopRun()
// }
// }
// }
//
// if c.Ctx.Input.IsPost() {
// // account := c.GetString("account")
// // password := c.GetString("password")
// // captcha := c.GetString("code")
// // isRemember := c.GetString("is_remember")
// c.JsonResult(400, "request method not allowed", nil)
// } else {
// var callback_u string
// u := c.GetString("url")
// if u == "" {
// u = c.referer()
// }
// if u != "" {
// var schemaRule = regexp.MustCompile(`^https?\:\/\/`)
// if !schemaRule.MatchString(u) {
// u = strings.TrimRight(conf.BaseUrl, "/") + strings.TrimLeft(u, "/")
// }
// }
// if u == "" {
// callback_u = conf.URLFor("AccountController.WorkWeixinLoginCallback")
// } else {
// callback_u = conf.URLFor("AccountController.WorkWeixinLoginCallback", "url", url.PathEscape(u))
// }
// logs.Info("callback_u: ", callback_u) // debug
//
// state := "mindoc"
// workweixinConf := conf.GetWorkWeixinConfig()
// appid := workweixinConf.CorpId
// agentid := workweixinConf.AgentId
// var redirect_uri string
//
// isInWorkWeixin := c.IsInWorkWeixin()
// c.Data["IsInWorkWeixin"] = isInWorkWeixin
// if isInWorkWeixin {
// // 企业微信内-网页授权登录
// urlFmt := "%s?appid=%s&agentid=%s&redirect_uri=%s&response_type=code&scope=snsapi_privateinfo&state=%s#wechat_redirect"
// redirect_uri = fmt.Sprintf(urlFmt, WorkWeixin_AuthorizeUrlBase, appid, agentid, url.PathEscape(callback_u), state)
// } else {
// // 浏览器内-扫码授权登录
// urlFmt := "%s?login_type=CorpApp&appid=%s&agentid=%s&redirect_uri=%s&state=%s"
// redirect_uri = fmt.Sprintf(urlFmt, WorkWeixin_QRConnectUrlBase, appid, agentid, url.PathEscape(callback_u), state)
// }
// logs.Info("redirect_uri: ", redirect_uri) // debug
// c.Redirect(redirect_uri, 302)
// }
//}
/*
思路:
1. 浏览器打开
用户名+密码 登录 与企业微信没有交集
手机企业微信登录->扫码页面->扫码后获取用户信息, 判断是否绑定了企业微信
已绑定,则读取用户信息,直接登录
未绑定,则弹窗提示[未绑定企业微信,请先在企业微信中打开,完成绑定]
2. 企业微信打开->自动登录->判断是否绑定了企业微信
已绑定,则读取用户信息,直接登录
未绑定,则弹窗提示
是否已有账户(用户名+密码方式)
有: 弹窗输入[用户名+密码+验证码]校验
无: 直接以企业UserId作为用户名(小写),创建随机密码
*/
// WorkWeixinLoginCallback 用户企业微信登录-回调
//func (c *AccountController) WorkWeixinLoginCallback() {
// c.TplName = "account/auth2_callback.tpl"
//
// if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
// u := c.GetString("url")
// if u == "" {
// u = c.Ctx.Request.Header.Get("Referer")
// }
// if u == "" {
// u = conf.URLFor("HomeController.Index")
// }
// member, err := models.NewMember().Find(member.MemberId)
// if err != nil {
// c.DelSession(conf.LoginSessionName)
// c.SetMember(models.Member{})
// c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
// } else {
// c.SetMember(*member)
// }
// c.Redirect(u, 302)
// }
//
// var remember CookieRemember
// // 如果 Cookie 中存在登录信息
// if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
// if err := utils.Decode(cookie, &remember); err == nil {
// if member, err := models.NewMember().Find(remember.MemberId); err == nil {
// c.SetMember(*member)
// c.LoggedIn(false)
// c.StopRun()
// }
// }
// }
//
// // 请求参数获取
// req_code := c.GetString("code")
// logs.Warning("req_code: ", req_code)
// req_state := c.GetString("state")
// logs.Warning("req_state: ", req_state)
// var user_info_json string
// var error_msg string
// var bind_existed string
// if len(req_code) > 0 && req_state == "mindoc" {
// // 获取当前应用的access_token
// access_token, ok := workweixin.GetAccessToken()
// if ok {
// logs.Warning("access_token: ", access_token)
// // 获取当前请求的userid
// user_id, ticket, ok := workweixin.RequestUserId(access_token, req_code)
// if ok {
// logs.Warning("user_id: ", user_id)
// // 查询系统现有数据,是否绑定了当前请求用户的企业微信
// member, err := models.NewWorkWeixinAccount().ExistedMember(user_id)
// if err == nil {
// member.LastLoginTime = time.Now()
// _ = member.Update("last_login_time")
//
// c.SetMember(*member)
//
// var remember CookieRemember
// remember.MemberId = member.MemberId
// remember.Account = member.Account
// remember.Time = time.Now()
// v, err := utils.Encode(remember)
// if err == nil {
// c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30*5).Unix())
// }
// bind_existed = "true"
// error_msg = ""
// u := c.GetString("url")
// if u == "" {
// u = conf.URLFor("HomeController.Index")
// }
// c.Redirect(u, 302)
// } else if err == orm.ErrNoRows {
// bind_existed = "false"
// if ticket == "" {
// error_msg = "请到企业微信中登录,并授权获取敏感信息。"
// } else {
// user_info, err := workweixin.RequestUserPrivateInfo(access_token, user_id, ticket)
// if err != nil {
// error_msg = "获取敏感信息错误: " + err.Error()
// } else {
// json_info, _ := json.Marshal(user_info)
// user_info_json = string(json_info)
// error_msg = ""
// c.SetSession(SessionUserInfoKey, user_info)
// }
// }
// } else {
// logs.Error("Error: ", err)
// error_msg = "登录错误: " + err.Error()
// }
// } else {
// error_msg = "获取用户Id失败: " + user_id
// }
// } else {
// error_msg = "应用凭据获取失败: " + access_token
// }
// } else {
// error_msg = "参数错误"
// }
// if user_info_json == "" {
// user_info_json = "{}"
// }
// if bind_existed == "" {
// bind_existed = "null"
// }
// // refer & doc:
// // - https://golang.org/pkg/html/template/#HTML
// // - https://stackoverflow.com/questions/24411880/go-html-templates-can-i-stop-the-templates-package-inserting-quotes-around-stri
// // - https://stackoverflow.com/questions/38035176/insert-javascript-snippet-inside-template-with-beego-golang
// c.Data["bind_existed"] = template.JS(bind_existed)
// logs.Debug("bind_existed: ", bind_existed)
// c.Data["error_msg"] = template.JS(error_msg)
// c.Data["user_info_json"] = template.JS(user_info_json)
// /*
// // 调试: 显示源码
// result, err := c.RenderString()
// if err != nil {
// logs.Error(err)
// } else {
// logs.Warning(result)
// }
// */
//}
// WorkWeixinLoginBind 用户企业微信登录-绑定
//func (c *AccountController) WorkWeixinLoginBind() {
// if user_info, ok := c.GetSession(SessionUserInfoKey).(workweixin.WorkWeixinUserPrivateInfo); ok && len(user_info.UserId) > 0 {
// req_account := c.GetString("account")
// req_password := c.GetString("password")
// if req_account == "" || req_password == "" {
// c.JsonResult(400, "账号或密码不能为空")
// } else {
// member, err := models.NewMember().Login(req_account, req_password)
// if err == nil {
// account := models.NewWorkWeixinAccount()
// account.MemberId = member.MemberId
// account.WorkWeixin_UserId = user_info.UserId
// member.CreateAt = 0
// ormer := orm.NewOrm()
// o, err := ormer.Begin()
// if err != nil {
// logs.Error("开启事务时出错 -> ", err)
// c.JsonResult(500, "开启事务时出错: ", err.Error())
// }
// if err := account.AddBind(ormer); err != nil {
// o.Rollback()
// c.JsonResult(500, "绑定失败,数据库错误: "+err.Error())
// } else {
// // 绑定成功之后修改用户信息
// member.LastLoginTime = time.Now()
// //member.RealName = user_info.Name
// //member.Avatar = user_info.Avatar
// if len(member.Avatar) < 1 {
// member.Avatar = conf.GetDefaultAvatar()
// }
// //member.Email = user_info.Email
// //member.Phone = user_info.Mobile
// if _, err := ormer.Update(member, "last_login_time", "real_name", "avatar", "email", "phone"); err != nil {
// o.Rollback()
// logs.Error("保存用户信息失败=>", err)
// c.JsonResult(500, "绑定失败,现有账户信息更新失败: "+err.Error())
// } else {
// if err := o.Commit(); err != nil {
// logs.Error("开启事务时出错 -> ", err)
// c.JsonResult(500, "开启事务时出错: ", err.Error())
// } else {
// c.DelSession(SessionUserInfoKey)
// c.SetMember(*member)
//
// var remember CookieRemember
// remember.MemberId = member.MemberId
// remember.Account = member.Account
// remember.Time = time.Now()
// v, err := utils.Encode(remember)
// if err == nil {
// c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30*5).Unix())
// c.JsonResult(0, "绑定成功", nil)
// } else {
// c.JsonResult(500, "绑定成功, 但自动登录失败, 请返回首页重新登录", nil)
// }
// }
// }
//
// }
//
// } else {
// logs.Error("用户登录 ->", err)
// c.JsonResult(500, "账号或密码错误", nil)
// }
// c.JsonResult(500, "TODO: 绑定以后账号功能开发中")
// }
// } else {
// if ok {
// c.DelSession(SessionUserInfoKey)
// }
// c.JsonResult(400, "请求错误, 请从首页重新登录")
// }
//
//}
// WorkWeixinLoginIgnore 用户企业微信登录-忽略
//func (c *AccountController) WorkWeixinLoginIgnore() {
// if user_info, ok := c.GetSession(SessionUserInfoKey).(workweixin.WorkWeixinUserPrivateInfo); ok && len(user_info.UserId) > 0 {
// c.DelSession(SessionUserInfoKey)
// member := models.NewMember()
//
// if _, err := member.FindByAccount(user_info.UserId); err == nil && member.MemberId > 0 {
// c.JsonResult(400, "账号已存在")
// }
//
// ormer := orm.NewOrm()
// o, err := ormer.Begin()
// if err != nil {
// logs.Error("开启事务时出错 -> ", err)
// c.JsonResult(500, "开启事务时出错: ", err.Error())
// }
//
// member.Account = user_info.UserId
// member.RealName = user_info.Name
// var rnd = rand.New(src)
// // fmt.Sprintf("%x", rnd.Uint64())
// // strconv.FormatUint(rnd.Uint64(), 16)
// member.Password = user_info.UserId + strconv.FormatUint(rnd.Uint64(), 16)
// member.Password = "123456" // 强制设置默认密码,需修改一次密码后,才可以进行账号密码登录
// hash, err := utils.PasswordHash(member.Password)
// if err != nil {
// logs.Error("加密用户密码失败 =>", err)
// c.JsonResult(500, "加密用户密码失败"+err.Error())
// } else {
// logs.Error("member.Password: ", member.Password)
// logs.Error("hash: ", hash)
// member.Password = hash
// }
// member.Role = conf.MemberGeneralRole
// member.Avatar = user_info.Avatar
// if len(member.Avatar) < 1 {
// member.Avatar = conf.GetDefaultAvatar()
// }
// member.CreateAt = 0
// member.Email = user_info.BizMail
// member.Phone = user_info.Mobile
// member.Status = 0
// if _, err = ormer.Insert(member); err != nil {
// o.Rollback()
// c.JsonResult(500, "注册失败,数据库错误: "+err.Error())
// } else {
// account := models.NewWorkWeixinAccount()
// account.MemberId = member.MemberId
// account.WorkWeixin_UserId = user_info.UserId
// member.CreateAt = 0
// if err := account.AddBind(ormer); err != nil {
// o.Rollback()
// c.JsonResult(500, "注册失败,数据库错误: "+err.Error())
// } else {
// if err := o.Commit(); err != nil {
// logs.Error("提交事务时出错 -> ", err)
// c.JsonResult(500, "提交事务时出错: ", err.Error())
// } else {
// member.LastLoginTime = time.Now()
// _ = member.Update("last_login_time")
//
// c.SetMember(*member)
//
// var remember CookieRemember
// remember.MemberId = member.MemberId
// remember.Account = member.Account
// remember.Time = time.Now()
// v, err := utils.Encode(remember)
// if err == nil {
// c.SetSecureCookie(conf.GetAppKey(), "login", v, time.Now().Add(time.Hour*24*30*5).Unix())
// c.JsonResult(0, "绑定成功", nil)
// } else {
// c.JsonResult(500, "绑定成功, 但自动登录失败, 请返回首页重新登录", nil)
// }
// }
// }
// }
// } else {
// if ok {
// c.DelSession(SessionUserInfoKey)
// }
// c.JsonResult(400, "请求错误, 请从首页重新登录")
// }
//}
// QR二维码登录
//func (c *AccountController) QRLogin() {
// appName := c.Ctx.Input.Param(":app")
//
// switch appName {
// // 钉钉扫码登录
// case "dingtalk":
// code := c.GetString("code")
// state := c.GetString("state")
// if state != "1" || code == "" {
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
// c.StopRun()
// }
// appKey, _ := web.AppConfig.String("dingtalk_qr_key")
// appSecret, _ := web.AppConfig.String("dingtalk_qr_secret")
//
// qrDingtalk := dingtalk.NewDingtalkQRLogin(appSecret, appKey)
// unionID, err := qrDingtalk.GetUnionIDByCode(code)
// if err != nil {
// logs.Warn("获取钉钉临时UnionID失败 ->", err)
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
// c.StopRun()
// }
//
// appKey, _ = web.AppConfig.String("dingtalk_app_key")
// appSecret, _ = web.AppConfig.String("dingtalk_app_secret")
// tmpReader, _ := web.AppConfig.String("dingtalk_tmp_reader")
//
// dingtalkAgent := dingtalk.NewDingTalkAgent(appSecret, appKey)
// err = dingtalkAgent.GetAccesstoken()
// if err != nil {
// logs.Warn("获取钉钉临时Token失败 ->", err)
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
// c.StopRun()
// }
//
// userid, err := dingtalkAgent.GetUserIDByUnionID(unionID)
// if err != nil {
// logs.Warn("获取钉钉用户ID失败 ->", err)
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
// c.StopRun()
// }
//
// username, avatar, err := dingtalkAgent.GetUserNameAndAvatarByUserID(userid)
// if err != nil {
// logs.Warn("获取钉钉用户信息失败 ->", err)
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
// c.StopRun()
// }
//
// member, err := models.NewMember().TmpLogin(tmpReader)
// if err == nil {
// member.LastLoginTime = time.Now()
// _ = member.Update("last_login_time")
// member.Account = username
// if avatar != "" {
// member.Avatar = avatar
// }
//
// c.SetMember(*member)
// c.LoggedIn(false)
// c.StopRun()
// }
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
//
// // 企业微信扫码登录
// case "workweixin":
// //
//
// default:
// c.Redirect(conf.URLFor("AccountController.Login"), 302)
// c.StopRun()
// }
//}
// 登录成功后的操作,如重定向到原始请求页面
func (c *AccountController) LoggedIn(isPost bool) interface{} {
turl := c.referer()
if !isPost {
c.Redirect(turl, 302)
return nil
} else {
var data struct {
TURL string `json:"url"`
}
data.TURL = turl
return data
}
}
// 用户注册
func (c *AccountController) Register() {
c.TplName = "account/register.tpl"
//如果用户登录了,则跳转到网站首页
if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
c.Redirect(conf.URLFor("HomeController.Index"), 302)
}
// 如果没有开启用户注册
if v, ok := c.Option["ENABLED_REGISTER"]; ok && !strings.EqualFold(v, "true") {
c.Abort("404")
}
if c.Ctx.Input.IsPost() {
account := c.GetString("account")
password1 := c.GetString("password1")
password2 := c.GetString("password2")
email := c.GetString("email")
captcha := c.GetString("code")
if ok, err := regexp.MatchString(conf.RegexpAccount, account); account == "" || !ok || err != nil {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.username_invalid_format"))
}
if l := strings.Count(password1, ""); password1 == "" || l > 50 || l < 6 {
c.JsonResult(6002, i18n.Tr(c.Lang, "message.password_length_invalid"))
}
if password1 != password2 {
c.JsonResult(6003, i18n.Tr(c.Lang, "message.incorrect_confirm_password"))
}
if ok, err := regexp.MatchString(conf.RegexpEmail, email); !ok || err != nil || email == "" {
c.JsonResult(6004, i18n.Tr(c.Lang, "message.email_invalid_format"))
}
// 如果开启了验证码
if v, ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v, "true") {
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
if !ok || !strings.EqualFold(v, captcha) {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
}
}
member := models.NewMember()
if _, err := member.FindByAccount(account); err == nil && member.MemberId > 0 {
c.JsonResult(6005, i18n.Tr(c.Lang, "message.account_existed"))
}
member.Account = account
member.Password = password1
member.Role = conf.MemberGeneralRole
member.Avatar = conf.GetDefaultAvatar()
member.CreateAt = 0
member.Email = email
member.Status = 0
if err := member.Add(); err != nil {
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed_register"))
}
c.JsonResult(0, "ok", member)
}
}
// 找回密码
func (c *AccountController) FindPassword() {
c.TplName = "account/find_password_setp1.tpl"
mailConf := conf.GetMailConfig()
if c.Ctx.Input.IsPost() {
email := c.GetString("email")
captcha := c.GetString("code")
if email == "" {
c.JsonResult(6005, i18n.Tr(c.Lang, "message.email_empty"))
}
if !mailConf.EnableMail {
c.JsonResult(6004, i18n.Tr(c.Lang, "message.mail_service_not_enable"))
}
// 如果开启了验证码
if v, ok := c.Option["ENABLED_CAPTCHA"]; ok && strings.EqualFold(v, "true") {
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
if !ok || !strings.EqualFold(v, captcha) {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
}
}
member, err := models.NewMember().FindByFieldFirst("email", email)
if err != nil {
c.JsonResult(6006, i18n.Tr(c.Lang, "message.email_not_exist"))
}
if member == nil || member.Status != 0 {
c.JsonResult(6007, i18n.Tr(c.Lang, "message.account_disable"))
}
if member == nil || member.AuthMethod == conf.AuthMethodLDAP {
c.JsonResult(6011, i18n.Tr(c.Lang, "message.account_not_support_retrieval"))
}
count, err := models.NewMemberToken().FindSendCount(email, time.Now().Add(-1*time.Hour), time.Now())
if err != nil {
logs.Error(err)
c.JsonResult(6008, i18n.Tr(c.Lang, "message.failed_send_mail"))
}
if count > mailConf.MailNumber {
c.JsonResult(6008, i18n.Tr(c.Lang, "message.sent_too_many_times"))
}
memberToken := models.NewMemberToken()
memberToken.Token = string(utils.Krand(32, utils.KC_RAND_KIND_ALL))
memberToken.Email = email
memberToken.MemberId = member.MemberId
memberToken.IsValid = false
if _, err := memberToken.InsertOrUpdate(); err != nil {
c.JsonResult(6009, i18n.Tr(c.Lang, "message.failed_send_mail"))
}
data := map[string]interface{}{
"SITE_NAME": c.Option["SITE_NAME"],
"url": conf.URLFor("AccountController.FindPassword", "token", memberToken.Token, "mail", email),
"BaseUrl": c.BaseUrl(),
}
body, err := c.ExecuteViewPathTemplate("account/mail_template.tpl", data)
if err != nil {
logs.Error(err)
c.JsonResult(6003, i18n.Tr(c.Lang, "message.failed_send_mail"))
}
go func(mailConf *conf.SmtpConf, email string, body string) {
mailConfig := &mail.SMTPConfig{
Username: mailConf.SmtpUserName,
Password: mailConf.SmtpPassword,
Host: mailConf.SmtpHost,
Port: mailConf.SmtpPort,
Secure: mailConf.Secure,
Identity: "",
}
logs.Info(mailConfig)
c := mail.NewSMTPClient(mailConfig)
m := mail.NewMail()
m.AddFrom(mailConf.FormUserName)
m.AddFromName(mailConf.FormUserName)
m.AddSubject("找回密码")
m.AddHTML(body)
m.AddTo(email)
if e := c.Send(m); e != nil {
logs.Error("发送邮件失败:" + e.Error())
} else {
logs.Info("邮件发送成功:" + email)
}
//auth := smtp.PlainAuth(
// "",
// mail_conf.SmtpUserName,
// mail_conf.SmtpPassword,
// mail_conf.SmtpHost,
//)
//
//mime := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
//subject := "Subject: 找回密码!\n"
//
//err = smtp.SendMail(
// mail_conf.SmtpHost+":"+strconv.Itoa(mail_conf.SmtpPort),
// auth,
// mail_conf.FormUserName,
// []string{email},
// []byte(subject+mime+"\n"+body),
//)
//if err != nil {
// logs.Error("邮件发送失败 => ", email, err)
//}
}(mailConf, email, body)
c.JsonResult(0, "ok", conf.URLFor("AccountController.Login"))
}
token := c.GetString("token")
email := c.GetString("mail")
if token != "" && email != "" {
memberToken, err := models.NewMemberToken().FindByFieldFirst("token", token)
if err != nil {
logs.Error(err)
c.Data["ErrorMessage"] = i18n.Tr(c.Lang, "message.mail_expired")
c.TplName = "errors/error.tpl"
return
}
subTime := time.Until(memberToken.SendTime)
if !strings.EqualFold(memberToken.Email, email) || subTime.Minutes() > float64(mailConf.MailExpired) || !memberToken.ValidTime.IsZero() {
c.Data["ErrorMessage"] = i18n.Tr(c.Lang, "message.captcha_expired")
c.TplName = "errors/error.tpl"
return
}
c.Data["Email"] = memberToken.Email
c.Data["Token"] = memberToken.Token
c.TplName = "account/find_password_setp2.tpl"
}
}
// 校验邮件并修改密码
func (c *AccountController) ValidEmail() {
password1 := c.GetString("password1")
password2 := c.GetString("password2")
captcha := c.GetString("code")
token := c.GetString("token")
email := c.GetString("mail")
if password1 == "" {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.password_empty"))
}
if l := strings.Count(password1, ""); l < 6 || l > 50 {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.password_length_invalid"))
}
if password2 == "" {
c.JsonResult(6002, i18n.Tr(c.Lang, "message.confirm_password_empty"))
}
if password1 != password2 {
c.JsonResult(6003, i18n.Tr(c.Lang, "message.incorrect_confirm_password"))
}
if captcha == "" {
c.JsonResult(6004, i18n.Tr(c.Lang, "message.captcha_empty"))
}
v, ok := c.GetSession(conf.CaptchaSessionName).(string)
if !ok || !strings.EqualFold(v, captcha) {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.captcha_wrong"))
}
mailConf := conf.GetMailConfig()
memberToken, err := models.NewMemberToken().FindByFieldFirst("token", token)
if err != nil {
logs.Error(err)
c.JsonResult(6007, i18n.Tr(c.Lang, "message.mail_expired"))
}
subTime := time.Until(memberToken.SendTime)
if !strings.EqualFold(memberToken.Email, email) || subTime.Minutes() > float64(mailConf.MailExpired) || !memberToken.ValidTime.IsZero() {
c.JsonResult(6008, i18n.Tr(c.Lang, "message.captcha_expired"))
}
member, err := models.NewMember().Find(memberToken.MemberId)
if err != nil {
logs.Error(err)
c.JsonResult(6005, i18n.Tr(c.Lang, "message.user_not_existed"))
}
hash, err := utils.PasswordHash(password1)
if err != nil {
logs.Error(err)
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed_save_password"))
}
member.Password = hash
err = member.Update("password")
memberToken.ValidTime = time.Now()
memberToken.IsValid = true
memberToken.InsertOrUpdate()
if err != nil {
logs.Error(err)
c.JsonResult(6006, i18n.Tr(c.Lang, "message.failed_save_password"))
}
c.JsonResult(0, "ok", conf.URLFor("AccountController.Login"))
}
// Logout 退出登录
func (c *AccountController) Logout() {
c.SetMember(models.Member{})
c.SetSecureCookie(conf.GetAppKey(), "login", "", -3600)
u := c.Ctx.Request.Header.Get("Referer")
c.Redirect(conf.URLFor("AccountController.Login", "url", u), 302)
}
// 验证码
func (c *AccountController) Captcha() {
captchaImage := gocaptcha.NewCaptchaImage(140, 40, gocaptcha.RandLightColor())
captchaImage.DrawNoise(gocaptcha.CaptchaComplexLower)
// captchaImage.DrawTextNoise(gocaptcha.CaptchaComplexHigh)
txt := gocaptcha.RandText(4)
c.SetSession(conf.CaptchaSessionName, txt)
captchaImage.DrawText(txt)
// captchaImage.Drawline(3);
captchaImage.DrawBorder(gocaptcha.ColorToRGB(0x17A7A7A))
// captchaImage.DrawHollowLine()
captchaImage.SaveImage(c.Ctx.ResponseWriter, gocaptcha.ImageFormatJpeg)
c.StopRun()
}
================================================
FILE: controllers/BaseController.go
================================================
package controllers
import (
"bytes"
"encoding/json"
"io"
"strings"
"time"
"html/template"
"io/ioutil"
"path/filepath"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"github.com/beego/i18n"
"github.com/mindoc-org/mindoc/conf"
"github.com/mindoc-org/mindoc/models"
"github.com/mindoc-org/mindoc/utils"
)
type BaseController struct {
web.Controller
Member *models.Member
Option map[string]string
EnableAnonymous bool
EnableDocumentHistory bool
Lang string
}
type CookieRemember struct {
MemberId int
Account string
Time time.Time
}
// Prepare 预处理.
func (c *BaseController) Prepare() {
c.Data["SiteName"] = "MinDoc"
c.Data["Member"] = models.NewMember()
controller, action := c.GetControllerAndAction()
c.Data["ActionName"] = action
c.Data["ControllerName"] = controller
c.EnableAnonymous = false
c.EnableDocumentHistory = false
if member, ok := c.GetSession(conf.LoginSessionName).(models.Member); ok && member.MemberId > 0 {
c.Member = &member
c.Data["Member"] = c.Member
} else {
var remember CookieRemember
// //如果Cookie中存在登录信息,从cookie中获取用户信息
if cookie, ok := c.GetSecureCookie(conf.GetAppKey(), "login"); ok {
if err := utils.Decode(cookie, &remember); err == nil {
if member, err := models.NewMember().Find(remember.MemberId); err == nil {
c.Member = member
c.Data["Member"] = member
c.SetMember(*member)
}
}
}
}
conf.BaseUrl = c.BaseUrl()
c.Data["BaseUrl"] = c.BaseUrl()
if options, err := models.NewOption().All(); err == nil {
c.Option = make(map[string]string, len(options))
for _, item := range options {
c.Data[item.OptionName] = item.OptionValue
c.Option[item.OptionName] = item.OptionValue
}
c.EnableAnonymous = strings.EqualFold(c.Option["ENABLE_ANONYMOUS"], "true")
c.EnableDocumentHistory = strings.EqualFold(c.Option["ENABLE_DOCUMENT_HISTORY"], "true")
}
c.Data["HighlightStyle"] = web.AppConfig.DefaultString("highlight_style", "github")
if b, err := ioutil.ReadFile(filepath.Join(web.BConfig.WebConfig.ViewsPath, "widgets", "scripts.tpl")); err == nil {
c.Data["Scripts"] = template.HTML(string(b))
}
c.SetLang()
}
// 判断用户是否登录.
func (c *BaseController) isUserLoggedIn() bool {
return c.Member != nil && c.Member.MemberId > 0
}
// SetMember 获取或设置当前登录用户信息,如果 MemberId 小于 0 则标识删除 Session
func (c *BaseController) SetMember(member models.Member) {
if member.MemberId <= 0 {
c.DelSession(conf.LoginSessionName)
c.DelSession("uid")
c.DestroySession()
} else {
c.SetSession(conf.LoginSessionName, member)
c.SetSession("uid", member.MemberId)
}
}
// JsonResult 响应 json 结果
func (c *BaseController) JsonResult(errCode int, errMsg string, data ...interface{}) {
jsonData := make(map[string]interface{}, 3)
jsonData["errcode"] = errCode
jsonData["message"] = errMsg
if len(data) > 0 && data[0] != nil {
jsonData["data"] = data[0]
}
returnJSON, err := json.Marshal(jsonData)
if err != nil {
logs.Error(err)
}
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8")
c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache, no-store")
_, err = io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
if err != nil {
logs.Error(err)
}
c.StopRun()
}
// 如果错误不为空,则响应错误信息到浏览器.
func (c *BaseController) CheckJsonError(code int, err error) {
if err == nil {
return
}
jsonData := make(map[string]interface{}, 3)
jsonData["errcode"] = code
jsonData["message"] = err.Error()
returnJSON, err := json.Marshal(jsonData)
if err != nil {
logs.Error(err)
}
c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8")
c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache, no-store")
_, err = io.WriteString(c.Ctx.ResponseWriter, string(returnJSON))
if err != nil {
logs.Error(err)
}
c.StopRun()
}
// ExecuteViewPathTemplate 执行指定的模板并返回执行结果.
func (c *BaseController) ExecuteViewPathTemplate(tplName string, data interface{}) (string, error) {
var buf bytes.Buffer
viewPath := c.ViewPath
if c.ViewPath == "" {
viewPath = web.BConfig.WebConfig.ViewsPath
}
if err := web.ExecuteViewPathTemplate(&buf, tplName, viewPath, data); err != nil {
return "", err
}
return buf.String(), nil
}
func (c *BaseController) BaseUrl() string {
baseUrl := web.AppConfig.DefaultString("baseurl", "")
if baseUrl != "" {
if strings.HasSuffix(baseUrl, "/") {
baseUrl = strings.TrimSuffix(baseUrl, "/")
}
} else {
baseUrl = c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host
}
return baseUrl
}
// 显示错误信息页面.
func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
c.TplName = "errors/error.tpl"
c.Data["ErrorMessage"] = errMsg
c.Data["ErrorCode"] = errCode
var buf bytes.Buffer
exeData := map[string]interface{}{"ErrorMessage": errMsg, "ErrorCode": errCode, "BaseUrl": conf.BaseUrl, "Lang": c.Lang}
if err := web.ExecuteViewPathTemplate(&buf, "errors/error.tpl", web.BConfig.WebConfig.ViewsPath, exeData); err != nil {
c.Abort("500")
}
if errCode >= 200 && errCode <= 510 {
c.CustomAbort(errCode, buf.String())
} else {
c.CustomAbort(500, buf.String())
}
}
func (c *BaseController) CheckErrorResult(code int, err error) {
if err != nil {
c.ShowErrorPage(code, err.Error())
}
}
func (c *BaseController) SetLang() {
hasCookie := false
lang := c.GetString("lang")
if len(lang) == 0 {
lang = c.Ctx.GetCookie("lang")
hasCookie = true
}
if len(lang) == 0 ||
!i18n.IsExist(lang) {
if c.Data["language"] != nil {
lang = c.Data["language"].(string)
} else {
lang, _ = web.AppConfig.String("default_lang")
}
}
if !hasCookie {
c.Ctx.SetCookie("lang", lang, 1<<31-1, "/")
}
c.Data["Lang"] = lang
c.Lang = lang
}
================================================
FILE: controllers/BlogController.go
================================================
package controllers
import (
"context"
"encoding/json"
"fmt"
"html/template"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"github.com/beego/i18n"
"github.com/mindoc-org/mindoc/conf"
"github.com/mindoc-org/mindoc/models"
"github.com/mindoc-org/mindoc/utils"
"github.com/mindoc-org/mindoc/utils/pagination"
)
type BlogController struct {
BaseController
}
func (c *BlogController) Prepare() {
c.BaseController.Prepare()
if !c.EnableAnonymous && c.Member == nil {
c.Redirect(conf.URLFor("AccountController.Login")+"?url="+url.PathEscape(conf.BaseUrl+c.Ctx.Request.URL.RequestURI()), 302)
}
}
// 文章阅读
func (c *BlogController) Index() {
c.Prepare()
c.TplName = "blog/index.tpl"
blogId, _ := strconv.Atoi(c.Ctx.Input.Param(":id"))
if blogId <= 0 {
c.ShowErrorPage(404, i18n.Tr(c.Lang, "message.page_not_existed"))
}
blogReadSession := fmt.Sprintf("blog:read:%d", blogId)
blog, err := models.NewBlog().FindFromCache(blogId)
if err != nil {
c.ShowErrorPage(404, i18n.Tr(c.Lang, "message.blog_not_existed"))
}
if c.Ctx.Input.IsPost() {
password := c.GetString("password")
if blog.BlogStatus == "password" && password != blog.Password {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.blog_pwd_incorrect"))
} else if blog.BlogStatus == "password" && password == blog.Password {
// Store the session value for the next GET request.
_ = c.CruSession.Set(context.TODO(), blogReadSession, blogId)
c.JsonResult(0, "OK")
} else {
c.JsonResult(0, "OK")
}
} else if blog.BlogStatus == "password" && c.CruSession.Get(context.TODO(), blogReadSession) == nil && // Read session doesn't exist
(c.Member == nil || (blog.MemberId != c.Member.MemberId && !c.Member.IsAdministrator())) { // User isn't author or administrator
//如果不存在已输入密码的标记
c.TplName = "blog/index_password.tpl"
}
if blog.BlogType != 1 {
//加载文章附件
_ = blog.LinkAttach()
}
c.Data["Model"] = blog
c.Data["Content"] = template.HTML(blog.BlogRelease)
if blog.BlogExcerpt == "" {
c.Data["Description"] = utils.AutoSummary(blog.BlogRelease, 120)
} else {
c.Data["Description"] = blog.BlogExcerpt
}
if nextBlog, err := models.NewBlog().QueryNext(blogId); err == nil {
c.Data["Next"] = nextBlog
}
if preBlog, err := models.NewBlog().QueryPrevious(blogId); err == nil {
c.Data["Previous"] = preBlog
}
}
// 文章列表
func (c *BlogController) List() {
c.Prepare()
c.TplName = "blog/list.tpl"
pageIndex, _ := c.GetInt("page", 1)
var blogList []*models.Blog
var totalCount int
var err error
blogList, totalCount, err = models.NewBlog().FindToPager(pageIndex, conf.PageSize, 0, "")
if err != nil && err != orm.ErrNoRows {
c.ShowErrorPage(500, err.Error())
}
if totalCount > 0 {
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
c.Data["PageHtml"] = pager.HtmlPages()
for _, blog := range blogList {
//如果没有添加文章摘要,则自动提取
if blog.BlogExcerpt == "" {
blog.BlogExcerpt = utils.AutoSummary(blog.BlogRelease, 120)
}
blog.Link()
}
} else {
c.Data["PageHtml"] = ""
}
c.Data["Lists"] = blogList
}
// 管理后台文章列表
func (c *BlogController) ManageList() {
c.Prepare()
c.TplName = "blog/manage_list.tpl"
pageIndex, _ := c.GetInt("page", 1)
blogList, totalCount, err := models.NewBlog().FindToPager(pageIndex, conf.PageSize, c.Member.MemberId, "all")
if err != nil {
c.ShowErrorPage(500, err.Error())
}
if totalCount > 0 {
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
c.Data["PageHtml"] = pager.HtmlPages()
} else {
c.Data["PageHtml"] = ""
}
c.Data["ModelList"] = blogList
}
// 文章设置
func (c *BlogController) ManageSetting() {
c.Prepare()
c.TplName = "blog/manage_setting.tpl"
//如果是post请求
if c.Ctx.Input.IsPost() {
blogId, _ := c.GetInt("id", 0)
blogTitle := c.GetString("title")
blogIdentify := c.GetString("identify")
orderIndex, _ := c.GetInt("order_index", 0)
blogType, _ := c.GetInt("blog_type", 0)
blogExcerpt := c.GetString("excerpt", "")
blogStatus := c.GetString("status", "publish")
blogPassword := c.GetString("password", "")
documentIdentify := strings.TrimSpace(c.GetString("documentIdentify"))
bookIdentify := strings.TrimSpace(c.GetString("bookIdentify"))
documentId := 0
if c.Member.Role == conf.MemberReaderRole {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.no_permission"))
}
if blogTitle == "" {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.blog_title_empty"))
}
if strings.Count(blogExcerpt, "") > 500 {
c.JsonResult(6008, i18n.Tr(c.Lang, "message.blog_digest_tips"))
}
if blogStatus != "private" && blogStatus != "public" && blogStatus != "password" && blogStatus != "draft" {
blogStatus = "public"
}
if blogStatus == "password" && blogPassword == "" {
c.JsonResult(6010, i18n.Tr(c.Lang, "message.set_pwd_pls"))
}
if blogType != 0 && blogType != 1 {
c.JsonResult(6005, i18n.Tr(c.Lang, "message.unknown_blog_type"))
}
if strings.Count(blogTitle, "") > 200 {
c.JsonResult(6002, i18n.Tr(c.Lang, "message.blog_title_tips"))
}
//如果是关联文章,需要同步关联的文档
if blogType == 1 {
book, err := models.NewBook().FindByIdentify(bookIdentify)
if err != nil {
c.JsonResult(6011, i18n.Tr(c.Lang, "message.ref_doc_not_exist_or_no_permit"))
}
doc, err := models.NewDocument().FindByIdentityFirst(documentIdentify, book.BookId)
if err != nil {
c.JsonResult(6003, i18n.Tr(c.Lang, "message.query_failed"))
}
documentId = doc.DocumentId
// 如果不是超级管理员,则校验权限
if !c.Member.IsAdministrator() {
bookResult, err := models.NewBookResult().FindByIdentify(book.Identify, c.Member.MemberId)
if err != nil || bookResult.RoleId == conf.BookObserver {
c.JsonResult(6002, i18n.Tr(c.Lang, "message.ref_doc_not_exist_or_no_permit"))
}
}
}
var blog *models.Blog
var err error
//如果文章ID存在,则从数据库中查询文章
if blogId > 0 {
if c.Member.IsAdministrator() {
blog, err = models.NewBlog().Find(blogId)
} else {
blog, err = models.NewBlog().FindByIdAndMemberId(blogId, c.Member.MemberId)
}
if err != nil {
c.JsonResult(6003, i18n.Tr(c.Lang, "message.blog_not_exist"))
}
//如果设置了文章标识
if blogIdentify != "" {
//如果查询到的文章标识存在并且不是当前文章的id
if b, err := models.NewBlog().FindByIdentify(blogIdentify); err == nil && b.BlogId != blogId {
c.JsonResult(6004, i18n.Tr(c.Lang, "message.blog_id_existed"))
}
}
blog.Modified = time.Now()
blog.ModifyAt = c.Member.MemberId
} else {
//如果设置了文章标识
if blogIdentify != "" {
if models.NewBlog().IsExist(blogIdentify) {
c.JsonResult(6004, i18n.Tr(c.Lang, "message.blog_id_existed"))
}
}
blog = models.NewBlog()
blog.MemberId = c.Member.MemberId
blog.Created = time.Now()
}
if blogIdentify == "" {
blog.BlogIdentify = fmt.Sprintf("%s-%d", "post", time.Now().UnixNano())
} else {
blog.BlogIdentify = blogIdentify
}
blog.BlogTitle = blogTitle
blog.OrderIndex = orderIndex
blog.BlogType = blogType
if blogType == 1 {
blog.DocumentId = documentId
}
blog.BlogExcerpt = blogExcerpt
blog.BlogStatus = blogStatus
blog.Password = blogPassword
if err := blog.Save(); err != nil {
logs.Error("保存文章失败 -> ", err)
c.JsonResult(6011, i18n.Tr(c.Lang, "message.failed"))
} else {
c.JsonResult(0, "ok", blog)
}
}
if c.Ctx.Input.Referer() == "" {
c.Data["Referer"] = "javascript:history.back();"
} else {
c.Data["Referer"] = c.Ctx.Input.Referer()
}
blogId, err := strconv.Atoi(c.Ctx.Input.Param(":id"))
c.Data["DocumentIdentify"] = ""
if err == nil {
blog, err := models.NewBlog().FindByIdAndMemberId(blogId, c.Member.MemberId)
if err != nil {
c.ShowErrorPage(500, err.Error())
}
c.Data["Model"] = blog
} else {
c.Data["Model"] = models.NewBlog()
}
}
// 文章创建或编辑
func (c *BlogController) ManageEdit() {
c.Prepare()
c.TplName = "blog/manage_edit.tpl"
if c.Member.Role == conf.MemberReaderRole {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.no_permission"))
}
if c.Ctx.Input.IsPost() {
blogId, _ := c.GetInt("blogId", 0)
if blogId <= 0 {
c.JsonResult(6001, i18n.Tr(c.Lang, "message.param_error"))
}
blogContent := c.GetString("content", "")
blogHtml := c.GetString("htmlContent", "")
version, _ := c.GetInt64("version", 0)
cover := c.GetString("cover")
var blog *models.Blog
var err error
if c.Member.IsAdministrator() {
blog, err = models.NewBlog().Find(blogId)
} else {
blog, err = models.NewBlog().FindByIdAndMemberId(blogId, c.Member.MemberId)
}
if err != nil {
logs.Error("查询文章失败 ->", err)
c.JsonResult(6002, i18n.Tr(c.Lang, "message.query_failed"))
}
if version > 0 && blog.Version != version && cover != "yes" {
c.JsonResult(6005, i18n.Tr(c.Lang, "message.blog_has_modified"))
}
//如果是关联文章,需要同步关联的文档
if blog.BlogType == 1 {
doc, err := models.NewDocument().Find(blog.DocumentId)
if err != nil {
logs.Error("查询关联项目文档时出错 ->", err)
c.JsonResult(6003, i18n.Tr(c.Lang, "message.query_failed"))
}
book, err := models.NewBook().Find(doc.BookId)
if err != nil {
c.JsonResult(6002, i18n.Tr(c.Lang, "message.item_not_exist_or_no_permit"))
}
// 如果不是超级管理员,则校验权限
if !c.Member.IsAdministrator() {
bookResult, err := models.NewBookResult().FindByIdentify(book.Identify, c.Member.MemberId)
if err != nil || bookResult.RoleId == conf.BookObserver {
logs.Error("FindByIdentify => ", err)
c.JsonResult(6002, i18n.Tr(c.Lang, "message.ref_doc_not_exist_or_no_permit"))
}
}
doc.Markdown = blogContent
doc.Release = blogHtml
doc.Content = blogHtml
doc.ModifyTime = time.Now()
doc.ModifyAt = c.Member.MemberId
if err := doc.InsertOrUpdate("markdown", "release", "content", "modify_time", "modify_at
gitextract_8kp_8qo8/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE.md
├── README.md
├── appveyor.yml
├── build_amd64.sh
├── build_musl_amd64.sh
├── cache/
│ ├── cache.go
│ └── cache_null.go
├── commands/
│ ├── command.go
│ ├── daemon/
│ │ └── daemon.go
│ ├── install.go
│ ├── migrate/
│ │ ├── migrate.go
│ │ └── migrate_v03.go
│ └── update.go
├── conf/
│ ├── app.conf.example
│ ├── enumerate.go
│ ├── lang/
│ │ ├── en-us.ini
│ │ ├── ru-ru.ini
│ │ └── zh-cn.ini
│ ├── mail.go
│ └── workweixin.go
├── controllers/
│ ├── AccountController.go
│ ├── BaseController.go
│ ├── BlogController.go
│ ├── BookController.go
│ ├── BookMemberController.go
│ ├── CommentController.go
│ ├── DocumentController.go
│ ├── ErrorController.go
│ ├── HomeController.go
│ ├── ItemsetsController.go
│ ├── LabelController.go
│ ├── ManagerController.go
│ ├── SearchController.go
│ ├── SettingController.go
│ ├── TemplateController.go
│ └── const.go
├── converter/
│ ├── converter.go
│ └── util.go
├── database/
│ └── clean.py
├── dev-win-build.cmd
├── docker-compose.yml
├── go.mod
├── go.sum
├── graphics/
│ ├── copy.go
│ └── file.go
├── lib/
│ └── time/
│ ├── README
│ └── update.bash
├── mail/
│ ├── smtp.go
│ ├── smtp_test.go
│ └── util.go
├── main.go
├── mcp/
│ ├── handler.go
│ ├── mcp.go
│ └── middleware.go
├── models/
│ ├── AttachmentModel.go
│ ├── AttachmentResult.go
│ ├── Auth2Account.go
│ ├── Base.go
│ ├── Blog.go
│ ├── BlogResult.go
│ ├── BookModel.go
│ ├── BookResult.go
│ ├── CommentModel.go
│ ├── ContentReverseIndex.go
│ ├── ConvertBookResult.go
│ ├── Dashboard.go
│ ├── DocumentHistory.go
│ ├── DocumentModel.go
│ ├── DocumentSearchResult.go
│ ├── DocumentTree.go
│ ├── Errors.go
│ ├── Itemsets.go
│ ├── LabelModel.go
│ ├── Logs.go
│ ├── Member.go
│ ├── MemberResult.go
│ ├── MemberToken.go
│ ├── Migrations.go
│ ├── Options.go
│ ├── Relationship.go
│ ├── Team.go
│ ├── TeamMember.go
│ ├── TeamRelationship.go
│ ├── Template.go
│ ├── comment_result.go
│ └── comment_vote.go
├── routers/
│ ├── filter.go
│ └── router.go
├── simsun.ttc
├── start.sh
├── static/
│ ├── bootstrap/
│ │ ├── css/
│ │ │ ├── bootstrap-theme.css
│ │ │ └── bootstrap.css
│ │ ├── js/
│ │ │ ├── bootstrap.js
│ │ │ └── npm.js
│ │ └── plugins/
│ │ ├── bootstrap-fileinput/
│ │ │ └── 4.4.7/
│ │ │ ├── css/
│ │ │ │ ├── fileinput-rtl.css
│ │ │ │ └── fileinput.css
│ │ │ ├── js/
│ │ │ │ ├── fileinput.js
│ │ │ │ ├── locales/
│ │ │ │ │ ├── LANG.js
│ │ │ │ │ ├── ar.js
│ │ │ │ │ ├── az.js
│ │ │ │ │ ├── bg.js
│ │ │ │ │ ├── ca.js
│ │ │ │ │ ├── cr.js
│ │ │ │ │ ├── cs.js
│ │ │ │ │ ├── da.js
│ │ │ │ │ ├── de.js
│ │ │ │ │ ├── el.js
│ │ │ │ │ ├── es.js
│ │ │ │ │ ├── et.js
│ │ │ │ │ ├── fa.js
│ │ │ │ │ ├── fi.js
│ │ │ │ │ ├── fr.js
│ │ │ │ │ ├── gl.js
│ │ │ │ │ ├── hu.js
│ │ │ │ │ ├── id.js
│ │ │ │ │ ├── it.js
│ │ │ │ │ ├── ja.js
│ │ │ │ │ ├── ka.js
│ │ │ │ │ ├── kr.js
│ │ │ │ │ ├── kz.js
│ │ │ │ │ ├── lt.js
│ │ │ │ │ ├── nl.js
│ │ │ │ │ ├── no.js
│ │ │ │ │ ├── pl.js
│ │ │ │ │ ├── pt-BR.js
│ │ │ │ │ ├── pt.js
│ │ │ │ │ ├── ro.js
│ │ │ │ │ ├── ru.js
│ │ │ │ │ ├── sk.js
│ │ │ │ │ ├── sl.js
│ │ │ │ │ ├── sv.js
│ │ │ │ │ ├── th.js
│ │ │ │ │ ├── tr.js
│ │ │ │ │ ├── uk.js
│ │ │ │ │ ├── vi.js
│ │ │ │ │ ├── zh-TW.js
│ │ │ │ │ └── zh.js
│ │ │ │ └── plugins/
│ │ │ │ ├── piexif.js
│ │ │ │ ├── purify.js
│ │ │ │ └── sortable.js
│ │ │ └── themes/
│ │ │ ├── explorer/
│ │ │ │ ├── theme.css
│ │ │ │ └── theme.js
│ │ │ ├── explorer-fa/
│ │ │ │ ├── theme.css
│ │ │ │ └── theme.js
│ │ │ ├── fa/
│ │ │ │ └── theme.js
│ │ │ └── gly/
│ │ │ └── theme.js
│ │ ├── bootstrap-switch/
│ │ │ ├── css/
│ │ │ │ ├── bootstrap2/
│ │ │ │ │ └── bootstrap-switch.css
│ │ │ │ └── bootstrap3/
│ │ │ │ └── bootstrap-switch.css
│ │ │ └── js/
│ │ │ └── bootstrap-switch.js
│ │ ├── bootstrap-wysiwyg/
│ │ │ ├── bootstrap-wysiwyg.js
│ │ │ └── external/
│ │ │ ├── google-code-prettify/
│ │ │ │ ├── lang-apollo.js
│ │ │ │ ├── lang-basic.js
│ │ │ │ ├── lang-clj.js
│ │ │ │ ├── lang-css.js
│ │ │ │ ├── lang-dart.js
│ │ │ │ ├── lang-erlang.js
│ │ │ │ ├── lang-go.js
│ │ │ │ ├── lang-hs.js
│ │ │ │ ├── lang-lisp.js
│ │ │ │ ├── lang-llvm.js
│ │ │ │ ├── lang-lua.js
│ │ │ │ ├── lang-matlab.js
│ │ │ │ ├── lang-ml.js
│ │ │ │ ├── lang-mumps.js
│ │ │ │ ├── lang-n.js
│ │ │ │ ├── lang-pascal.js
│ │ │ │ ├── lang-proto.js
│ │ │ │ ├── lang-r.js
│ │ │ │ ├── lang-rd.js
│ │ │ │ ├── lang-scala.js
│ │ │ │ ├── lang-sql.js
│ │ │ │ ├── lang-tcl.js
│ │ │ │ ├── lang-tex.js
│ │ │ │ ├── lang-vb.js
│ │ │ │ ├── lang-vhdl.js
│ │ │ │ ├── lang-wiki.js
│ │ │ │ ├── lang-xq.js
│ │ │ │ ├── lang-yaml.js
│ │ │ │ ├── prettify.css
│ │ │ │ ├── prettify.js
│ │ │ │ └── run_prettify.js
│ │ │ └── jquery.hotkeys.js
│ │ └── tagsinput/
│ │ ├── bootstrap-tagsinput.css
│ │ ├── bootstrap-tagsinput.js
│ │ └── bootstrap-tagsinput.less
│ ├── bootstrap-paginator/
│ │ └── bootstrap-paginator.js
│ ├── cherry/
│ │ ├── addons/
│ │ │ ├── cherry-code-block-mermaid-plugin.d.ts
│ │ │ ├── cherry-code-block-mermaid-plugin.js
│ │ │ ├── cherry-code-block-plantuml-plugin.d.ts
│ │ │ └── cherry-code-block-plantuml-plugin.js
│ │ ├── cherry-markdown.css
│ │ ├── cherry-markdown.js
│ │ ├── drawio-demo.js
│ │ ├── drawio_demo/
│ │ │ ├── Actions.js
│ │ │ ├── Dialogs.js
│ │ │ ├── Editor.js
│ │ │ ├── EditorUi.js
│ │ │ ├── Format.js
│ │ │ ├── Graph.js
│ │ │ ├── Init.js
│ │ │ ├── Menus.js
│ │ │ ├── Shapes.js
│ │ │ ├── Sidebar.js
│ │ │ ├── Toolbar.js
│ │ │ ├── atlas.css
│ │ │ ├── dark-default.xml
│ │ │ ├── dark.css
│ │ │ ├── default-old.xml
│ │ │ ├── default.xml
│ │ │ ├── drawio-demo.js
│ │ │ ├── font/
│ │ │ │ └── graph.iconfont.less
│ │ │ ├── grapheditor.css
│ │ │ ├── image/
│ │ │ │ └── stencils/
│ │ │ │ ├── arrows.xml
│ │ │ │ ├── basic.xml
│ │ │ │ ├── bpmn.xml
│ │ │ │ └── flowchart.xml
│ │ │ ├── jscolor/
│ │ │ │ └── jscolor.js
│ │ │ ├── lib/
│ │ │ │ └── base64.js
│ │ │ ├── resources/
│ │ │ │ ├── en.txt
│ │ │ │ └── zh.txt
│ │ │ └── src/
│ │ │ ├── css/
│ │ │ │ ├── common.css
│ │ │ │ └── explorer.css
│ │ │ ├── grapheditor.less
│ │ │ ├── js/
│ │ │ │ ├── editor/
│ │ │ │ │ ├── mxDefaultKeyHandler.js
│ │ │ │ │ ├── mxDefaultPopupMenu.js
│ │ │ │ │ ├── mxDefaultToolbar.js
│ │ │ │ │ └── mxEditor.js
│ │ │ │ ├── handler/
│ │ │ │ │ ├── mxCellHighlight.js
│ │ │ │ │ ├── mxCellMarker.js
│ │ │ │ │ ├── mxCellTracker.js
│ │ │ │ │ ├── mxConnectionHandler.js
│ │ │ │ │ ├── mxConstraintHandler.js
│ │ │ │ │ ├── mxEdgeHandler.js
│ │ │ │ │ ├── mxEdgeSegmentHandler.js
│ │ │ │ │ ├── mxElbowEdgeHandler.js
│ │ │ │ │ ├── mxGraphHandler.js
│ │ │ │ │ ├── mxHandle.js
│ │ │ │ │ ├── mxKeyHandler.js
│ │ │ │ │ ├── mxPanningHandler.js
│ │ │ │ │ ├── mxPopupMenuHandler.js
│ │ │ │ │ ├── mxRubberband.js
│ │ │ │ │ ├── mxSelectionCellsHandler.js
│ │ │ │ │ ├── mxTooltipHandler.js
│ │ │ │ │ └── mxVertexHandler.js
│ │ │ │ ├── index.txt
│ │ │ │ ├── io/
│ │ │ │ │ ├── mxCellCodec.js
│ │ │ │ │ ├── mxChildChangeCodec.js
│ │ │ │ │ ├── mxCodec.js
│ │ │ │ │ ├── mxCodecRegistry.js
│ │ │ │ │ ├── mxDefaultKeyHandlerCodec.js
│ │ │ │ │ ├── mxDefaultPopupMenuCodec.js
│ │ │ │ │ ├── mxDefaultToolbarCodec.js
│ │ │ │ │ ├── mxEditorCodec.js
│ │ │ │ │ ├── mxGenericChangeCodec.js
│ │ │ │ │ ├── mxGraphCodec.js
│ │ │ │ │ ├── mxGraphViewCodec.js
│ │ │ │ │ ├── mxModelCodec.js
│ │ │ │ │ ├── mxObjectCodec.js
│ │ │ │ │ ├── mxRootChangeCodec.js
│ │ │ │ │ ├── mxStylesheetCodec.js
│ │ │ │ │ └── mxTerminalChangeCodec.js
│ │ │ │ ├── layout/
│ │ │ │ │ ├── hierarchical/
│ │ │ │ │ │ ├── model/
│ │ │ │ │ │ │ ├── mxGraphAbstractHierarchyCell.js
│ │ │ │ │ │ │ ├── mxGraphHierarchyEdge.js
│ │ │ │ │ │ │ ├── mxGraphHierarchyModel.js
│ │ │ │ │ │ │ ├── mxGraphHierarchyNode.js
│ │ │ │ │ │ │ └── mxSwimlaneModel.js
│ │ │ │ │ │ ├── mxHierarchicalLayout.js
│ │ │ │ │ │ ├── mxSwimlaneLayout.js
│ │ │ │ │ │ └── stage/
│ │ │ │ │ │ ├── mxCoordinateAssignment.js
│ │ │ │ │ │ ├── mxHierarchicalLayoutStage.js
│ │ │ │ │ │ ├── mxMedianHybridCrossingReduction.js
│ │ │ │ │ │ ├── mxMinimumCycleRemover.js
│ │ │ │ │ │ └── mxSwimlaneOrdering.js
│ │ │ │ │ ├── mxCircleLayout.js
│ │ │ │ │ ├── mxCompactTreeLayout.js
│ │ │ │ │ ├── mxCompositeLayout.js
│ │ │ │ │ ├── mxEdgeLabelLayout.js
│ │ │ │ │ ├── mxFastOrganicLayout.js
│ │ │ │ │ ├── mxGraphLayout.js
│ │ │ │ │ ├── mxParallelEdgeLayout.js
│ │ │ │ │ ├── mxPartitionLayout.js
│ │ │ │ │ ├── mxRadialTreeLayout.js
│ │ │ │ │ └── mxStackLayout.js
│ │ │ │ ├── model/
│ │ │ │ │ ├── mxCell.js
│ │ │ │ │ ├── mxCellPath.js
│ │ │ │ │ ├── mxGeometry.js
│ │ │ │ │ └── mxGraphModel.js
│ │ │ │ ├── mxClient.js
│ │ │ │ ├── shape/
│ │ │ │ │ ├── mxActor.js
│ │ │ │ │ ├── mxArrow.js
│ │ │ │ │ ├── mxArrowConnector.js
│ │ │ │ │ ├── mxCloud.js
│ │ │ │ │ ├── mxConnector.js
│ │ │ │ │ ├── mxCylinder.js
│ │ │ │ │ ├── mxDoubleEllipse.js
│ │ │ │ │ ├── mxEllipse.js
│ │ │ │ │ ├── mxHexagon.js
│ │ │ │ │ ├── mxImageShape.js
│ │ │ │ │ ├── mxLabel.js
│ │ │ │ │ ├── mxLine.js
│ │ │ │ │ ├── mxMarker.js
│ │ │ │ │ ├── mxPolyline.js
│ │ │ │ │ ├── mxRectangleShape.js
│ │ │ │ │ ├── mxRhombus.js
│ │ │ │ │ ├── mxShape.js
│ │ │ │ │ ├── mxStencil.js
│ │ │ │ │ ├── mxStencilRegistry.js
│ │ │ │ │ ├── mxSwimlane.js
│ │ │ │ │ ├── mxText.js
│ │ │ │ │ └── mxTriangle.js
│ │ │ │ ├── util/
│ │ │ │ │ ├── mxAbstractCanvas2D.js
│ │ │ │ │ ├── mxAnimation.js
│ │ │ │ │ ├── mxAutoSaveManager.js
│ │ │ │ │ ├── mxClipboard.js
│ │ │ │ │ ├── mxConstants.js
│ │ │ │ │ ├── mxDictionary.js
│ │ │ │ │ ├── mxDivResizer.js
│ │ │ │ │ ├── mxDragSource.js
│ │ │ │ │ ├── mxEffects.js
│ │ │ │ │ ├── mxEvent.js
│ │ │ │ │ ├── mxEventObject.js
│ │ │ │ │ ├── mxEventSource.js
│ │ │ │ │ ├── mxForm.js
│ │ │ │ │ ├── mxGuide.js
│ │ │ │ │ ├── mxImage.js
│ │ │ │ │ ├── mxImageBundle.js
│ │ │ │ │ ├── mxImageExport.js
│ │ │ │ │ ├── mxLog.js
│ │ │ │ │ ├── mxMorphing.js
│ │ │ │ │ ├── mxMouseEvent.js
│ │ │ │ │ ├── mxObjectIdentity.js
│ │ │ │ │ ├── mxPanningManager.js
│ │ │ │ │ ├── mxPoint.js
│ │ │ │ │ ├── mxPopupMenu.js
│ │ │ │ │ ├── mxRectangle.js
│ │ │ │ │ ├── mxResources.js
│ │ │ │ │ ├── mxSvgCanvas2D.js
│ │ │ │ │ ├── mxToolbar.js
│ │ │ │ │ ├── mxUndoManager.js
│ │ │ │ │ ├── mxUndoableEdit.js
│ │ │ │ │ ├── mxUrlConverter.js
│ │ │ │ │ ├── mxUtils.js
│ │ │ │ │ ├── mxVmlCanvas2D.js
│ │ │ │ │ ├── mxWindow.js
│ │ │ │ │ ├── mxXmlCanvas2D.js
│ │ │ │ │ └── mxXmlRequest.js
│ │ │ │ └── view/
│ │ │ │ ├── mxCellEditor.js
│ │ │ │ ├── mxCellOverlay.js
│ │ │ │ ├── mxCellRenderer.js
│ │ │ │ ├── mxCellState.js
│ │ │ │ ├── mxCellStatePreview.js
│ │ │ │ ├── mxConnectionConstraint.js
│ │ │ │ ├── mxEdgeStyle.js
│ │ │ │ ├── mxGraph.js
│ │ │ │ ├── mxGraphSelectionModel.js
│ │ │ │ ├── mxGraphView.js
│ │ │ │ ├── mxLayoutManager.js
│ │ │ │ ├── mxMultiplicity.js
│ │ │ │ ├── mxOutline.js
│ │ │ │ ├── mxPerimeter.js
│ │ │ │ ├── mxPrintPreview.js
│ │ │ │ ├── mxStyleRegistry.js
│ │ │ │ ├── mxStylesheet.js
│ │ │ │ ├── mxSwimlaneManager.js
│ │ │ │ └── mxTemporaryCellStates.js
│ │ │ └── resources/
│ │ │ ├── editor.txt
│ │ │ ├── editor_de.txt
│ │ │ ├── editor_zh.txt
│ │ │ ├── graph.txt
│ │ │ ├── graph_de.txt
│ │ │ └── graph_zh.txt
│ │ ├── drawio_demo.html
│ │ ├── mxgraph/
│ │ │ ├── css/
│ │ │ │ ├── common.css
│ │ │ │ └── explorer.css
│ │ │ └── mxClient.js
│ │ └── pinyin/
│ │ ├── README.md
│ │ ├── hanziPinyin.js
│ │ ├── hanziPinyinWithoutYin.js
│ │ ├── pinyin.js
│ │ └── pinyin_dist.js
│ ├── cropper/
│ │ └── 2.3.4/
│ │ ├── cropper.css
│ │ └── cropper.js
│ ├── css/
│ │ ├── export.css
│ │ ├── jstree.css
│ │ ├── kancloud.css
│ │ ├── main.css
│ │ ├── markdown.css
│ │ ├── markdown.preview.css
│ │ └── print.css
│ ├── editor.md/
│ │ ├── css/
│ │ │ ├── editormd.css
│ │ │ ├── editormd.logo.css
│ │ │ └── editormd.preview.css
│ │ ├── editormd.amd.js
│ │ ├── editormd.js
│ │ ├── fonts/
│ │ │ └── FontAwesome.otf
│ │ ├── languages/
│ │ │ ├── en.js
│ │ │ └── zh-tw.js
│ │ ├── lib/
│ │ │ ├── codemirror/
│ │ │ │ ├── AUTHORS
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── addon/
│ │ │ │ │ ├── comment/
│ │ │ │ │ │ ├── comment.js
│ │ │ │ │ │ └── continuecomment.js
│ │ │ │ │ ├── dialog/
│ │ │ │ │ │ ├── dialog.css
│ │ │ │ │ │ └── dialog.js
│ │ │ │ │ ├── display/
│ │ │ │ │ │ ├── fullscreen.css
│ │ │ │ │ │ ├── fullscreen.js
│ │ │ │ │ │ ├── panel.js
│ │ │ │ │ │ ├── placeholder.js
│ │ │ │ │ │ └── rulers.js
│ │ │ │ │ ├── edit/
│ │ │ │ │ │ ├── closebrackets.js
│ │ │ │ │ │ ├── closetag.js
│ │ │ │ │ │ ├── continuelist.js
│ │ │ │ │ │ ├── matchbrackets.js
│ │ │ │ │ │ ├── matchtags.js
│ │ │ │ │ │ └── trailingspace.js
│ │ │ │ │ ├── fold/
│ │ │ │ │ │ ├── brace-fold.js
│ │ │ │ │ │ ├── comment-fold.js
│ │ │ │ │ │ ├── foldcode.js
│ │ │ │ │ │ ├── foldgutter.css
│ │ │ │ │ │ ├── foldgutter.js
│ │ │ │ │ │ ├── indent-fold.js
│ │ │ │ │ │ ├── markdown-fold.js
│ │ │ │ │ │ └── xml-fold.js
│ │ │ │ │ ├── hint/
│ │ │ │ │ │ ├── anyword-hint.js
│ │ │ │ │ │ ├── css-hint.js
│ │ │ │ │ │ ├── html-hint.js
│ │ │ │ │ │ ├── javascript-hint.js
│ │ │ │ │ │ ├── show-hint.css
│ │ │ │ │ │ ├── show-hint.js
│ │ │ │ │ │ ├── sql-hint.js
│ │ │ │ │ │ └── xml-hint.js
│ │ │ │ │ ├── lint/
│ │ │ │ │ │ ├── coffeescript-lint.js
│ │ │ │ │ │ ├── css-lint.js
│ │ │ │ │ │ ├── javascript-lint.js
│ │ │ │ │ │ ├── json-lint.js
│ │ │ │ │ │ ├── lint.css
│ │ │ │ │ │ ├── lint.js
│ │ │ │ │ │ └── yaml-lint.js
│ │ │ │ │ ├── merge/
│ │ │ │ │ │ ├── merge.css
│ │ │ │ │ │ └── merge.js
│ │ │ │ │ ├── mode/
│ │ │ │ │ │ ├── loadmode.js
│ │ │ │ │ │ ├── multiplex.js
│ │ │ │ │ │ ├── multiplex_test.js
│ │ │ │ │ │ ├── overlay.js
│ │ │ │ │ │ └── simple.js
│ │ │ │ │ ├── runmode/
│ │ │ │ │ │ ├── colorize.js
│ │ │ │ │ │ ├── runmode-standalone.js
│ │ │ │ │ │ ├── runmode.js
│ │ │ │ │ │ └── runmode.node.js
│ │ │ │ │ ├── scroll/
│ │ │ │ │ │ ├── annotatescrollbar.js
│ │ │ │ │ │ ├── scrollpastend.js
│ │ │ │ │ │ ├── simplescrollbars.css
│ │ │ │ │ │ └── simplescrollbars.js
│ │ │ │ │ ├── search/
│ │ │ │ │ │ ├── match-highlighter.js
│ │ │ │ │ │ ├── matchesonscrollbar.css
│ │ │ │ │ │ ├── matchesonscrollbar.js
│ │ │ │ │ │ ├── search.js
│ │ │ │ │ │ └── searchcursor.js
│ │ │ │ │ ├── selection/
│ │ │ │ │ │ ├── active-line.js
│ │ │ │ │ │ ├── mark-selection.js
│ │ │ │ │ │ └── selection-pointer.js
│ │ │ │ │ ├── tern/
│ │ │ │ │ │ ├── tern.css
│ │ │ │ │ │ ├── tern.js
│ │ │ │ │ │ └── worker.js
│ │ │ │ │ └── wrap/
│ │ │ │ │ └── hardwrap.js
│ │ │ │ ├── bower.json
│ │ │ │ ├── lib/
│ │ │ │ │ ├── codemirror.css
│ │ │ │ │ └── codemirror.js
│ │ │ │ ├── mode/
│ │ │ │ │ ├── apl/
│ │ │ │ │ │ ├── apl.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── asterisk/
│ │ │ │ │ │ ├── asterisk.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── clike/
│ │ │ │ │ │ ├── clike.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── scala.html
│ │ │ │ │ ├── clojure/
│ │ │ │ │ │ ├── clojure.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── cobol/
│ │ │ │ │ │ ├── cobol.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── coffeescript/
│ │ │ │ │ │ ├── coffeescript.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── commonlisp/
│ │ │ │ │ │ ├── commonlisp.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── css/
│ │ │ │ │ │ ├── css.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── less.html
│ │ │ │ │ │ ├── less_test.js
│ │ │ │ │ │ ├── scss.html
│ │ │ │ │ │ ├── scss_test.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── cypher/
│ │ │ │ │ │ ├── cypher.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── d/
│ │ │ │ │ │ ├── d.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dart/
│ │ │ │ │ │ ├── dart.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── diff/
│ │ │ │ │ │ ├── diff.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── django/
│ │ │ │ │ │ ├── django.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dockerfile/
│ │ │ │ │ │ ├── dockerfile.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dtd/
│ │ │ │ │ │ ├── dtd.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── dylan/
│ │ │ │ │ │ ├── dylan.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── ebnf/
│ │ │ │ │ │ ├── ebnf.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── ecl/
│ │ │ │ │ │ ├── ecl.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── eiffel/
│ │ │ │ │ │ ├── eiffel.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── erlang/
│ │ │ │ │ │ ├── erlang.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── forth/
│ │ │ │ │ │ ├── forth.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── fortran/
│ │ │ │ │ │ ├── fortran.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── gas/
│ │ │ │ │ │ ├── gas.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── gfm/
│ │ │ │ │ │ ├── gfm.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── gherkin/
│ │ │ │ │ │ ├── gherkin.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── go/
│ │ │ │ │ │ ├── go.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── groovy/
│ │ │ │ │ │ ├── groovy.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── haml/
│ │ │ │ │ │ ├── haml.js
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── haskell/
│ │ │ │ │ │ ├── haskell.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── haxe/
│ │ │ │ │ │ ├── haxe.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── htmlembedded/
│ │ │ │ │ │ ├── htmlembedded.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── htmlmixed/
│ │ │ │ │ │ ├── htmlmixed.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── http/
│ │ │ │ │ │ ├── http.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── idl/
│ │ │ │ │ │ ├── idl.js
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── jade/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── jade.js
│ │ │ │ │ ├── javascript/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── javascript.js
│ │ │ │ │ │ ├── json-ld.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── typescript.html
│ │ │ │ │ ├── jinja2/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── jinja2.js
│ │ │ │ │ ├── julia/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── julia.js
│ │ │ │ │ ├── kotlin/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── kotlin.js
│ │ │ │ │ ├── livescript/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── livescript.js
│ │ │ │ │ ├── lua/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── lua.js
│ │ │ │ │ ├── markdown/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── markdown.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── meta.js
│ │ │ │ │ ├── mirc/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── mirc.js
│ │ │ │ │ ├── mllike/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── mllike.js
│ │ │ │ │ ├── modelica/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── modelica.js
│ │ │ │ │ ├── nginx/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── nginx.js
│ │ │ │ │ ├── ntriples/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── ntriples.js
│ │ │ │ │ ├── octave/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── octave.js
│ │ │ │ │ ├── pascal/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── pascal.js
│ │ │ │ │ ├── pegjs/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── pegjs.js
│ │ │ │ │ ├── perl/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── perl.js
│ │ │ │ │ ├── php/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── php.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── pig/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── pig.js
│ │ │ │ │ ├── properties/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── properties.js
│ │ │ │ │ ├── puppet/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── puppet.js
│ │ │ │ │ ├── python/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── python.js
│ │ │ │ │ ├── q/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── q.js
│ │ │ │ │ ├── r/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── r.js
│ │ │ │ │ ├── rpm/
│ │ │ │ │ │ ├── changes/
│ │ │ │ │ │ │ └── index.html
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── rpm.js
│ │ │ │ │ ├── rst/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── rst.js
│ │ │ │ │ ├── ruby/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── ruby.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── rust/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── rust.js
│ │ │ │ │ ├── sass/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sass.js
│ │ │ │ │ ├── scheme/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── scheme.js
│ │ │ │ │ ├── shell/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── shell.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── sieve/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sieve.js
│ │ │ │ │ ├── slim/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── slim.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── smalltalk/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── smalltalk.js
│ │ │ │ │ ├── smarty/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── smarty.js
│ │ │ │ │ ├── smartymixed/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── smartymixed.js
│ │ │ │ │ ├── solr/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── solr.js
│ │ │ │ │ ├── soy/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── soy.js
│ │ │ │ │ ├── sparql/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sparql.js
│ │ │ │ │ ├── spreadsheet/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── spreadsheet.js
│ │ │ │ │ ├── sql/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── sql.js
│ │ │ │ │ ├── stex/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── stex.js
│ │ │ │ │ │ └── test.js
│ │ │ │ │ ├── stylus/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── stylus.js
│ │ │ │ │ ├── tcl/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── tcl.js
│ │ │ │ │ ├── textile/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── textile.js
│ │ │ │ │ ├── tiddlywiki/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── tiddlywiki.css
│ │ │ │ │ │ └── tiddlywiki.js
│ │ │ │ │ ├── tiki/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── tiki.css
│ │ │ │ │ │ └── tiki.js
│ │ │ │ │ ├── toml/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── toml.js
│ │ │ │ │ ├── tornado/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── tornado.js
│ │ │ │ │ ├── turtle/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── turtle.js
│ │ │ │ │ ├── vb/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── vb.js
│ │ │ │ │ ├── vbscript/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── vbscript.js
│ │ │ │ │ ├── velocity/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── velocity.js
│ │ │ │ │ ├── verilog/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── verilog.js
│ │ │ │ │ ├── xml/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── xml.js
│ │ │ │ │ ├── xquery/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ ├── test.js
│ │ │ │ │ │ └── xquery.js
│ │ │ │ │ ├── yaml/
│ │ │ │ │ │ ├── index.html
│ │ │ │ │ │ └── yaml.js
│ │ │ │ │ └── z80/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── z80.js
│ │ │ │ ├── package.json
│ │ │ │ └── theme/
│ │ │ │ ├── 3024-day.css
│ │ │ │ ├── 3024-night.css
│ │ │ │ ├── ambiance-mobile.css
│ │ │ │ ├── ambiance.css
│ │ │ │ ├── base16-dark.css
│ │ │ │ ├── base16-light.css
│ │ │ │ ├── blackboard.css
│ │ │ │ ├── cobalt.css
│ │ │ │ ├── colorforth.css
│ │ │ │ ├── eclipse.css
│ │ │ │ ├── elegant.css
│ │ │ │ ├── erlang-dark.css
│ │ │ │ ├── lesser-dark.css
│ │ │ │ ├── mbo.css
│ │ │ │ ├── mdn-like.css
│ │ │ │ ├── midnight.css
│ │ │ │ ├── monokai.css
│ │ │ │ ├── neat.css
│ │ │ │ ├── neo.css
│ │ │ │ ├── night.css
│ │ │ │ ├── paraiso-dark.css
│ │ │ │ ├── paraiso-light.css
│ │ │ │ ├── pastel-on-dark.css
│ │ │ │ ├── rubyblue.css
│ │ │ │ ├── solarized.css
│ │ │ │ ├── the-matrix.css
│ │ │ │ ├── tomorrow-night-bright.css
│ │ │ │ ├── tomorrow-night-eighties.css
│ │ │ │ ├── twilight.css
│ │ │ │ ├── vibrant-ink.css
│ │ │ │ ├── xq-dark.css
│ │ │ │ ├── xq-light.css
│ │ │ │ └── zenburn.css
│ │ │ ├── highlight/
│ │ │ │ ├── highlight.js
│ │ │ │ ├── languages/
│ │ │ │ │ ├── 1c.js
│ │ │ │ │ ├── abnf.js
│ │ │ │ │ ├── accesslog.js
│ │ │ │ │ ├── actionscript.js
│ │ │ │ │ ├── ada.js
│ │ │ │ │ ├── apache.js
│ │ │ │ │ ├── applescript.js
│ │ │ │ │ ├── arduino.js
│ │ │ │ │ ├── armasm.js
│ │ │ │ │ ├── asciidoc.js
│ │ │ │ │ ├── aspectj.js
│ │ │ │ │ ├── autohotkey.js
│ │ │ │ │ ├── autoit.js
│ │ │ │ │ ├── avrasm.js
│ │ │ │ │ ├── awk.js
│ │ │ │ │ ├── axapta.js
│ │ │ │ │ ├── bash.js
│ │ │ │ │ ├── basic.js
│ │ │ │ │ ├── bnf.js
│ │ │ │ │ ├── brainfuck.js
│ │ │ │ │ ├── cal.js
│ │ │ │ │ ├── capnproto.js
│ │ │ │ │ ├── ceylon.js
│ │ │ │ │ ├── clean.js
│ │ │ │ │ ├── clojure-repl.js
│ │ │ │ │ ├── clojure.js
│ │ │ │ │ ├── cmake.js
│ │ │ │ │ ├── coffeescript.js
│ │ │ │ │ ├── coq.js
│ │ │ │ │ ├── cos.js
│ │ │ │ │ ├── cpp.js
│ │ │ │ │ ├── crmsh.js
│ │ │ │ │ ├── crystal.js
│ │ │ │ │ ├── cs.js
│ │ │ │ │ ├── csp.js
│ │ │ │ │ ├── css.js
│ │ │ │ │ ├── d.js
│ │ │ │ │ ├── dart.js
│ │ │ │ │ ├── delphi.js
│ │ │ │ │ ├── diff.js
│ │ │ │ │ ├── django.js
│ │ │ │ │ ├── dns.js
│ │ │ │ │ ├── dockerfile.js
│ │ │ │ │ ├── dos.js
│ │ │ │ │ ├── dsconfig.js
│ │ │ │ │ ├── dts.js
│ │ │ │ │ ├── dust.js
│ │ │ │ │ ├── ebnf.js
│ │ │ │ │ ├── elixir.js
│ │ │ │ │ ├── elm.js
│ │ │ │ │ ├── erb.js
│ │ │ │ │ ├── erlang-repl.js
│ │ │ │ │ ├── erlang.js
│ │ │ │ │ ├── excel.js
│ │ │ │ │ ├── fix.js
│ │ │ │ │ ├── flix.js
│ │ │ │ │ ├── fortran.js
│ │ │ │ │ ├── fsharp.js
│ │ │ │ │ ├── gams.js
│ │ │ │ │ ├── gauss.js
│ │ │ │ │ ├── gcode.js
│ │ │ │ │ ├── gherkin.js
│ │ │ │ │ ├── glsl.js
│ │ │ │ │ ├── go.js
│ │ │ │ │ ├── golo.js
│ │ │ │ │ ├── gradle.js
│ │ │ │ │ ├── groovy.js
│ │ │ │ │ ├── haml.js
│ │ │ │ │ ├── handlebars.js
│ │ │ │ │ ├── haskell.js
│ │ │ │ │ ├── haxe.js
│ │ │ │ │ ├── hsp.js
│ │ │ │ │ ├── htmlbars.js
│ │ │ │ │ ├── http.js
│ │ │ │ │ ├── inform7.js
│ │ │ │ │ ├── ini.js
│ │ │ │ │ ├── irpf90.js
│ │ │ │ │ ├── java.js
│ │ │ │ │ ├── javascript.js
│ │ │ │ │ ├── json.js
│ │ │ │ │ ├── julia.js
│ │ │ │ │ ├── kotlin.js
│ │ │ │ │ ├── lasso.js
│ │ │ │ │ ├── ldif.js
│ │ │ │ │ ├── less.js
│ │ │ │ │ ├── lisp.js
│ │ │ │ │ ├── livecodeserver.js
│ │ │ │ │ ├── livescript.js
│ │ │ │ │ ├── lsl.js
│ │ │ │ │ ├── lua.js
│ │ │ │ │ ├── makefile.js
│ │ │ │ │ ├── markdown.js
│ │ │ │ │ ├── mathematica.js
│ │ │ │ │ ├── matlab.js
│ │ │ │ │ ├── maxima.js
│ │ │ │ │ ├── mel.js
│ │ │ │ │ ├── mercury.js
│ │ │ │ │ ├── mipsasm.js
│ │ │ │ │ ├── mizar.js
│ │ │ │ │ ├── mojolicious.js
│ │ │ │ │ ├── monkey.js
│ │ │ │ │ ├── moonscript.js
│ │ │ │ │ ├── nginx.js
│ │ │ │ │ ├── nimrod.js
│ │ │ │ │ ├── nix.js
│ │ │ │ │ ├── nsis.js
│ │ │ │ │ ├── objectivec.js
│ │ │ │ │ ├── ocaml.js
│ │ │ │ │ ├── openscad.js
│ │ │ │ │ ├── oxygene.js
│ │ │ │ │ ├── parser3.js
│ │ │ │ │ ├── perl.js
│ │ │ │ │ ├── pf.js
│ │ │ │ │ ├── php.js
│ │ │ │ │ ├── pony.js
│ │ │ │ │ ├── powershell.js
│ │ │ │ │ ├── processing.js
│ │ │ │ │ ├── profile.js
│ │ │ │ │ ├── prolog.js
│ │ │ │ │ ├── protobuf.js
│ │ │ │ │ ├── puppet.js
│ │ │ │ │ ├── purebasic.js
│ │ │ │ │ ├── python.js
│ │ │ │ │ ├── q.js
│ │ │ │ │ ├── qml.js
│ │ │ │ │ ├── r.js
│ │ │ │ │ ├── rib.js
│ │ │ │ │ ├── roboconf.js
│ │ │ │ │ ├── rsl.js
│ │ │ │ │ ├── ruby.js
│ │ │ │ │ ├── ruleslanguage.js
│ │ │ │ │ ├── rust.js
│ │ │ │ │ ├── scala.js
│ │ │ │ │ ├── scheme.js
│ │ │ │ │ ├── scilab.js
│ │ │ │ │ ├── scss.js
│ │ │ │ │ ├── smali.js
│ │ │ │ │ ├── smalltalk.js
│ │ │ │ │ ├── sml.js
│ │ │ │ │ ├── sqf.js
│ │ │ │ │ ├── sql.js
│ │ │ │ │ ├── stan.js
│ │ │ │ │ ├── stata.js
│ │ │ │ │ ├── step21.js
│ │ │ │ │ ├── stylus.js
│ │ │ │ │ ├── subunit.js
│ │ │ │ │ ├── swift.js
│ │ │ │ │ ├── taggerscript.js
│ │ │ │ │ ├── tap.js
│ │ │ │ │ ├── tcl.js
│ │ │ │ │ ├── tex.js
│ │ │ │ │ ├── thrift.js
│ │ │ │ │ ├── tp.js
│ │ │ │ │ ├── twig.js
│ │ │ │ │ ├── typescript.js
│ │ │ │ │ ├── vala.js
│ │ │ │ │ ├── vbnet.js
│ │ │ │ │ ├── vbscript-html.js
│ │ │ │ │ ├── vbscript.js
│ │ │ │ │ ├── verilog.js
│ │ │ │ │ ├── vhdl.js
│ │ │ │ │ ├── vim.js
│ │ │ │ │ ├── x86asm.js
│ │ │ │ │ ├── xl.js
│ │ │ │ │ ├── xml.js
│ │ │ │ │ ├── xquery.js
│ │ │ │ │ ├── yaml.js
│ │ │ │ │ └── zephir.js
│ │ │ │ └── styles/
│ │ │ │ ├── agate.css
│ │ │ │ ├── androidstudio.css
│ │ │ │ ├── arduino-light.css
│ │ │ │ ├── arta.css
│ │ │ │ ├── ascetic.css
│ │ │ │ ├── atelier-cave-dark.css
│ │ │ │ ├── atelier-cave-light.css
│ │ │ │ ├── atelier-dune-dark.css
│ │ │ │ ├── atelier-dune-light.css
│ │ │ │ ├── atelier-estuary-dark.css
│ │ │ │ ├── atelier-estuary-light.css
│ │ │ │ ├── atelier-forest-dark.css
│ │ │ │ ├── atelier-forest-light.css
│ │ │ │ ├── atelier-heath-dark.css
│ │ │ │ ├── atelier-heath-light.css
│ │ │ │ ├── atelier-lakeside-dark.css
│ │ │ │ ├── atelier-lakeside-light.css
│ │ │ │ ├── atelier-plateau-dark.css
│ │ │ │ ├── atelier-plateau-light.css
│ │ │ │ ├── atelier-savanna-dark.css
│ │ │ │ ├── atelier-savanna-light.css
│ │ │ │ ├── atelier-seaside-dark.css
│ │ │ │ ├── atelier-seaside-light.css
│ │ │ │ ├── atelier-sulphurpool-dark.css
│ │ │ │ ├── atelier-sulphurpool-light.css
│ │ │ │ ├── atom-one-dark.css
│ │ │ │ ├── atom-one-light.css
│ │ │ │ ├── brown-paper.css
│ │ │ │ ├── codepen-embed.css
│ │ │ │ ├── color-brewer.css
│ │ │ │ ├── darcula.css
│ │ │ │ ├── dark.css
│ │ │ │ ├── darkula.css
│ │ │ │ ├── default.css
│ │ │ │ ├── docco.css
│ │ │ │ ├── dracula.css
│ │ │ │ ├── far.css
│ │ │ │ ├── foundation.css
│ │ │ │ ├── github-gist.css
│ │ │ │ ├── github.css
│ │ │ │ ├── googlecode.css
│ │ │ │ ├── grayscale.css
│ │ │ │ ├── gruvbox-dark.css
│ │ │ │ ├── gruvbox-light.css
│ │ │ │ ├── hopscotch.css
│ │ │ │ ├── hybrid.css
│ │ │ │ ├── idea.css
│ │ │ │ ├── ir-black.css
│ │ │ │ ├── kimbie.dark.css
│ │ │ │ ├── kimbie.light.css
│ │ │ │ ├── magula.css
│ │ │ │ ├── mono-blue.css
│ │ │ │ ├── monokai-sublime.css
│ │ │ │ ├── monokai.css
│ │ │ │ ├── obsidian.css
│ │ │ │ ├── ocean.css
│ │ │ │ ├── paraiso-dark.css
│ │ │ │ ├── paraiso-light.css
│ │ │ │ ├── pojoaque.css
│ │ │ │ ├── purebasic.css
│ │ │ │ ├── qtcreator_dark.css
│ │ │ │ ├── qtcreator_light.css
│ │ │ │ ├── railscasts.css
│ │ │ │ ├── rainbow.css
│ │ │ │ ├── school-book.css
│ │ │ │ ├── solarized-dark.css
│ │ │ │ ├── solarized-light.css
│ │ │ │ ├── sunburst.css
│ │ │ │ ├── tomorrow-night-blue.css
│ │ │ │ ├── tomorrow-night-bright.css
│ │ │ │ ├── tomorrow-night-eighties.css
│ │ │ │ ├── tomorrow-night.css
│ │ │ │ ├── tomorrow.css
│ │ │ │ ├── vs.css
│ │ │ │ ├── xcode.css
│ │ │ │ ├── xt256.css
│ │ │ │ └── zenburn.css
│ │ │ ├── marked.js
│ │ │ ├── mermaid/
│ │ │ │ └── mermaid.js
│ │ │ ├── mindmap/
│ │ │ │ ├── d3@5.js
│ │ │ │ ├── transform.js
│ │ │ │ └── view.js
│ │ │ └── sequence/
│ │ │ ├── sequence-diagram-min.css
│ │ │ ├── sequence-diagram-min.js
│ │ │ ├── sequence-diagram-raphael-min.js
│ │ │ ├── sequence-diagram-raphael.js
│ │ │ ├── sequence-diagram-snap-min.js
│ │ │ ├── snap.svg-min.js
│ │ │ ├── underscore-min.js
│ │ │ └── webfont.js
│ │ └── plugins/
│ │ ├── code-block-dialog/
│ │ │ └── code-block-dialog.js
│ │ ├── emoji-dialog/
│ │ │ ├── emoji-dialog.js
│ │ │ └── emoji.json
│ │ ├── file-dialog/
│ │ │ └── file-dialog.js
│ │ ├── goto-line-dialog/
│ │ │ └── goto-line-dialog.js
│ │ ├── help-dialog/
│ │ │ ├── help-dialog.js
│ │ │ └── help.md
│ │ ├── html-entities-dialog/
│ │ │ ├── html-entities-dialog.js
│ │ │ └── html-entities.json
│ │ ├── image-dialog/
│ │ │ └── image-dialog.js
│ │ ├── link-dialog/
│ │ │ └── link-dialog.js
│ │ ├── plugin-template.js
│ │ ├── preformatted-text-dialog/
│ │ │ └── preformatted-text-dialog.js
│ │ ├── reference-link-dialog/
│ │ │ └── reference-link-dialog.js
│ │ ├── table-dialog/
│ │ │ └── table-dialog.js
│ │ └── test-plugin/
│ │ └── test-plugin.js
│ ├── font-awesome/
│ │ ├── css/
│ │ │ └── font-awesome.css
│ │ └── fonts/
│ │ └── FontAwesome.otf
│ ├── fonts/
│ │ ├── lato-100.css
│ │ └── notosans.css
│ ├── jquery/
│ │ └── 1.12.4/
│ │ └── jquery.js
│ ├── js/
│ │ ├── array.js
│ │ ├── blog.js
│ │ ├── cherry_markdown.js
│ │ ├── class2browser.js
│ │ ├── dingtalk-ddlogin.js
│ │ ├── dingtalk-jsapi.js
│ │ ├── editor.js
│ │ ├── froala-editor.js
│ │ ├── html-editor.js
│ │ ├── html-to-markdown.js
│ │ ├── jquery.form.js
│ │ ├── jquery.highlight.js
│ │ ├── kancloud.js
│ │ ├── main.js
│ │ ├── markdown.js
│ │ ├── quill.js
│ │ ├── sort.js
│ │ ├── splitbar.js
│ │ ├── wangEditor-plugins/
│ │ │ ├── attach-menu.js
│ │ │ ├── history-menu.js
│ │ │ ├── release-menu.js
│ │ │ └── save-menu.js
│ │ ├── word-to-html.js
│ │ └── x-frame-bypass-1.0.2.js
│ ├── jstree/
│ │ └── 3.3.4/
│ │ ├── jstree.js
│ │ └── themes/
│ │ ├── default/
│ │ │ └── style.css
│ │ └── default-dark/
│ │ └── style.css
│ ├── katex/
│ │ ├── README.md
│ │ ├── katex.css
│ │ └── katex.js
│ ├── layer/
│ │ ├── layer.js
│ │ ├── mobile/
│ │ │ ├── layer.js
│ │ │ └── need/
│ │ │ └── layer.css
│ │ └── skin/
│ │ └── default/
│ │ └── layer.css
│ ├── mammoth/
│ │ └── mammoth.browser.js
│ ├── mergely/
│ │ ├── editor/
│ │ │ ├── editor.css
│ │ │ ├── editor.js
│ │ │ ├── editor.php
│ │ │ └── lib/
│ │ │ ├── farbtastic/
│ │ │ │ ├── LICENSE.txt
│ │ │ │ ├── farbtastic.css
│ │ │ │ ├── farbtastic.js
│ │ │ │ └── index.html
│ │ │ ├── gatag.js
│ │ │ ├── tipsy/
│ │ │ │ ├── jquery.tipsy.js
│ │ │ │ └── tipsy.css
│ │ │ ├── wicked-ui.css
│ │ │ └── wicked-ui.js
│ │ └── lib/
│ │ ├── codemirror.css
│ │ ├── codemirror.js
│ │ ├── mergely.css
│ │ ├── mergely.js
│ │ └── searchcursor.js
│ ├── nprogress/
│ │ ├── nprogress.css
│ │ └── nprogress.js
│ ├── prettify/
│ │ └── themes/
│ │ └── prettify.css
│ ├── prismjs/
│ │ ├── prismjs.css
│ │ └── prismjs.js
│ ├── quill/
│ │ ├── quill.bubble.css
│ │ ├── quill.core.css
│ │ ├── quill.core.js
│ │ ├── quill.icons.js
│ │ ├── quill.js
│ │ └── quill.snow.css
│ ├── table-editor/
│ │ ├── .gitignore
│ │ ├── dist/
│ │ │ └── index.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── main.js
│ │ └── webpack.config.js
│ ├── to-markdown/
│ │ ├── dist/
│ │ │ └── to-markdown.js
│ │ └── lib/
│ │ ├── gfm-converters.js
│ │ ├── html-parser.js
│ │ └── md-converters.js
│ ├── turndown/
│ │ └── turndown.js
│ ├── vuejs/
│ │ ├── vue.common.js
│ │ ├── vue.esm.js
│ │ ├── vue.js
│ │ ├── vue.runtime.common.js
│ │ ├── vue.runtime.esm.js
│ │ └── vue.runtime.js
│ ├── wangEditor/
│ │ ├── wangEditor.d.ts
│ │ └── wangEditor.js
│ └── webuploader/
│ ├── README.md
│ ├── Uploader.swf
│ ├── webuploader.css
│ ├── webuploader.custom.js
│ ├── webuploader.fis.js
│ ├── webuploader.flashonly.js
│ ├── webuploader.html5nodepend.js
│ ├── webuploader.html5only.js
│ ├── webuploader.js
│ ├── webuploader.noimage.js
│ ├── webuploader.nolog.js
│ └── webuploader.withoutimage.js
├── uploads/
│ └── .gitkeep
├── utils/
│ ├── auth2/
│ │ ├── auth2.go
│ │ ├── dingtalk/
│ │ │ └── dingtalk.go
│ │ └── wecom/
│ │ └── wecom.go
│ ├── cryptil/
│ │ └── cryptil.go
│ ├── dingtalk/
│ │ └── dingtalk.go
│ ├── docx2md.go
│ ├── filetil/
│ │ └── filetil.go
│ ├── gob.go
│ ├── gopool/
│ │ └── gopool.go
│ ├── html.go
│ ├── krand.go
│ ├── ldap.go
│ ├── pagination/
│ │ └── pagination.go
│ ├── password.go
│ ├── requests/
│ │ └── requests.go
│ ├── segmenter/
│ │ └── segmenter.go
│ ├── sqltil/
│ │ └── sql.go
│ ├── template_fun.go
│ ├── url.go
│ ├── wkhtmltopdf/
│ │ ├── options.go
│ │ └── wkhtmltopdf.go
│ ├── workweixin/
│ │ └── workweixin.go
│ └── ziptil/
│ └── ziptil.go
└── views/
├── account/
│ ├── auth2_callback.tpl
│ ├── find_password_setp1.tpl
│ ├── find_password_setp2.tpl
│ ├── login.tpl
│ ├── mail_template.tpl
│ └── register.tpl
├── blog/
│ ├── index.tpl
│ ├── index_password.tpl
│ ├── list.tpl
│ ├── manage_edit.tpl
│ ├── manage_list.tpl
│ └── manage_setting.tpl
├── book/
│ ├── dashboard.tpl
│ ├── index.tpl
│ ├── setting.tpl
│ ├── team.tpl
│ └── users.tpl
├── comment/
│ └── index.tpl
├── document/
│ ├── cherry_markdown_edit_template.tpl
│ ├── cherry_read.tpl
│ ├── compare.tpl
│ ├── default_read.tpl
│ ├── document_password.tpl
│ ├── export.tpl
│ ├── froala_edit_template.tpl
│ ├── history.tpl
│ ├── html_edit_template.tpl
│ ├── index.tpl
│ ├── kancloud_read_template.tpl
│ ├── markdown_edit_template.tpl
│ ├── new_html_edit_template.tpl
│ ├── template_api-en.tpl
│ ├── template_api.tpl
│ ├── template_code-en.tpl
│ ├── template_code.tpl
│ ├── template_normal-en.tpl
│ └── template_normal.tpl
├── errors/
│ ├── 403.tpl
│ ├── 404.tpl
│ └── error.tpl
├── home/
│ └── index.tpl
├── items/
│ ├── index.tpl
│ └── list.tpl
├── label/
│ ├── index.tpl
│ └── list.tpl
├── manager/
│ ├── attach_detailed.tpl
│ ├── attach_list.tpl
│ ├── books.tpl
│ ├── comments.tpl
│ ├── config.tpl
│ ├── edit_book.tpl
│ ├── edit_users.tpl
│ ├── index.tpl
│ ├── itemsets.tpl
│ ├── label_list.tpl
│ ├── setting.tpl
│ ├── team.tpl
│ ├── team_book_list.tpl
│ ├── team_member_list.tpl
│ ├── users.tpl
│ └── widgets.tpl
├── search/
│ └── index.tpl
├── setting/
│ ├── index.tpl
│ └── password.tpl
├── template/
│ └── list.tpl
├── template.tpl
└── widgets/
├── footer.tpl
├── header.tpl
└── ie.tpl
Showing preview only (1,269K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (15702 symbols across 452 files)
FILE: cache/cache.go
function Get (line 18) | func Get(key string, e interface{}) error {
function Put (line 56) | func Put(key string, val interface{}, timeout time.Duration) error {
function Delete (line 71) | func Delete(key string) error {
function Incr (line 74) | func Incr(key string) error {
function Decr (line 77) | func Decr(key string) error {
function IsExist (line 80) | func IsExist(key string) (bool, error) {
function ClearAll (line 83) | func ClearAll() error {
function StartAndGC (line 87) | func StartAndGC(config string) error {
function Init (line 92) | func Init(c cache.Cache) {
FILE: cache/cache_null.go
type NullCache (line 8) | type NullCache struct
method Get (line 13) | func (bm *NullCache) Get(ctx context.Context, key string) (interface{}...
method GetMulti (line 17) | func (bm *NullCache)GetMulti(ctx context.Context, keys []string) ([]in...
method Put (line 21) | func (bm *NullCache)Put(ctx context.Context,key string, val interface{...
method Delete (line 24) | func (bm *NullCache)Delete(ctx context.Context,key string) error {
method Incr (line 27) | func (bm *NullCache)Incr(ctx context.Context,key string) error {
method Decr (line 30) | func (bm *NullCache)Decr(ctx context.Context,key string) error {
method IsExist (line 33) | func (bm *NullCache)IsExist(ctx context.Context,key string) (bool, err...
method ClearAll (line 36) | func (bm *NullCache)ClearAll(ctx context.Context) error{
method StartAndGC (line 40) | func (bm *NullCache)StartAndGC(config string) error {
FILE: commands/command.go
function RegisterDataBase (line 36) | func RegisterDataBase() {
function RegisterModel (line 118) | func RegisterModel() {
function RegisterLogger (line 154) | func RegisterLogger(log string) {
function RegisterCommand (line 229) | func RegisterCommand() {
function RegisterFunction (line 245) | func RegisterFunction() {
function ResolveCommand (line 362) | func ResolveCommand(args []string) {
function RegisterCache (line 434) | func RegisterCache() {
function RegisterAutoLoadConfig (line 534) | func RegisterAutoLoadConfig() {
function RegisterError (line 575) | func RegisterError() {
function init (line 604) | func init() {
FILE: commands/daemon/daemon.go
type Daemon (line 17) | type Daemon struct
method Config (line 38) | func (d *Daemon) Config() *service.Config {
method Start (line 41) | func (d *Daemon) Start(s service.Service) error {
method Run (line 47) | func (d *Daemon) Run() {
method Stop (line 70) | func (d *Daemon) Stop(s service.Service) error {
function NewDaemon (line 22) | func NewDaemon() *Daemon {
function Install (line 77) | func Install() {
function Uninstall (line 98) | func Uninstall() {
function Restart (line 116) | func Restart() {
FILE: commands/install.go
function Install (line 21) | func Install() {
function Version (line 36) | func Version() {
function ModifyPassword (line 44) | func ModifyPassword() {
function initialization (line 98) | func initialization() {
FILE: commands/migrate/migrate.go
type MigrationDatabase (line 33) | type MigrationDatabase interface
type migrationCache (line 54) | type migrationCache struct
function RunMigration (line 58) | func RunMigration() {
function ExportDatabaseTable (line 116) | func ExportDatabaseTable() ([]string, error) {
function RegisterMigration (line 161) | func RegisterMigration() {
FILE: commands/migrate/migrate_v03.go
type MigrationVersion03 (line 13) | type MigrationVersion03 struct
method Version (line 22) | func (m *MigrationVersion03) Version() int64 {
method ValidUpdate (line 26) | func (m *MigrationVersion03) ValidUpdate(version int64) error {
method ValidForBackupTableSchema (line 35) | func (m *MigrationVersion03) ValidForBackupTableSchema() error {
method ValidForUpdateTableSchema (line 45) | func (m *MigrationVersion03) ValidForUpdateTableSchema() error {
method MigrationOldTableData (line 61) | func (m *MigrationVersion03) MigrationOldTableData() error {
method MigrationNewTableData (line 68) | func (m *MigrationVersion03) MigrationNewTableData() error {
method AddMigrationRecord (line 85) | func (m *MigrationVersion03) AddMigrationRecord(version int64) error {
method MigrationCleanup (line 104) | func (m *MigrationVersion03) MigrationCleanup() error {
method RollbackMigration (line 109) | func (m *MigrationVersion03) RollbackMigration() error {
function NewMigrationVersion03 (line 18) | func NewMigrationVersion03() *MigrationVersion03 {
FILE: commands/update.go
function CheckUpdate (line 17) | func CheckUpdate() {
function Update (line 53) | func Update() {
function UpdateInitialization (line 66) | func UpdateInitialization() {
FILE: conf/enumerate.go
constant LoginSessionName (line 16) | LoginSessionName = "LoginSessionName"
constant CaptchaSessionName (line 18) | CaptchaSessionName = "__captcha__"
constant RegexpEmail (line 20) | RegexpEmail = "^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z...
constant RegexpAccount (line 23) | RegexpAccount = `^[a-zA-Z0-9][a-zA-Z0-9\.-]{2,50}$`
constant PageSize (line 26) | PageSize = 10
constant MemberSuperRole (line 31) | MemberSuperRole SystemRole = iota
constant MemberAdminRole (line 33) | MemberAdminRole
constant MemberGeneralRole (line 35) | MemberGeneralRole
constant MemberReaderRole (line 37) | MemberReaderRole
type SystemRole (line 41) | type SystemRole
constant BookFounder (line 45) | BookFounder BookRole = iota
constant BookAdmin (line 47) | BookAdmin
constant BookEditor (line 49) | BookEditor
constant BookObserver (line 51) | BookObserver
constant BookRoleNoSpecific (line 53) | BookRoleNoSpecific
type BookRole (line 57) | type BookRole
constant LoggerOperate (line 60) | LoggerOperate = "operate"
constant LoggerSystem (line 61) | LoggerSystem = "system"
constant LoggerException (line 62) | LoggerException = "exception"
constant LoggerDocument (line 63) | LoggerDocument = "document"
constant AuthMethodLocal (line 67) | AuthMethodLocal = "local"
constant AuthMethodLDAP (line 69) | AuthMethodLDAP = "ldap"
function GetAppKey (line 87) | func GetAppKey() string {
function GetDatabasePrefix (line 91) | func GetDatabasePrefix() string {
function GetDefaultAvatar (line 96) | func GetDefaultAvatar() string {
function GetTokenSize (line 101) | func GetTokenSize() int {
function GetDefaultCover (line 106) | func GetDefaultCover() string {
function GetUploadFileExt (line 112) | func GetUploadFileExt() []string {
function GetUploadFileSize (line 130) | func GetUploadFileSize() int64 {
function GetEnableExport (line 160) | func GetEnableExport() bool {
function GetEnableIframe (line 165) | func GetEnableIframe() bool {
function GetExportProcessNum (line 170) | func GetExportProcessNum() int {
function GetExportLimitNum (line 180) | func GetExportLimitNum() int {
function GetExportQueueLimitNum (line 190) | func GetExportQueueLimitNum() int {
function GetExportOutputPath (line 200) | func GetExportOutputPath() string {
function IsAllowUploadFileExt (line 207) | func IsAllowUploadFileExt(ext string) bool {
function CONF (line 226) | func CONF(key string, value ...string) string {
function URLFor (line 235) | func URLFor(endpoint string, values ...interface{}) string {
function URLForNotHost (line 254) | func URLForNotHost(endpoint string, values ...interface{}) string {
function URLForWithCdnImage (line 273) | func URLForWithCdnImage(p string) string {
function URLForWithCdnCss (line 299) | func URLForWithCdnCss(p string, v ...string) string {
function URLForWithCdnJs (line 330) | func URLForWithCdnJs(p string, v ...string) string {
function WorkingDir (line 363) | func WorkingDir(elem ...string) string {
function init (line 370) | func init() {
FILE: conf/mail.go
type SmtpConf (line 9) | type SmtpConf struct
function GetMailConfig (line 21) | func GetMailConfig() *SmtpConf {
FILE: conf/workweixin.go
type WorkWeixinConf (line 7) | type WorkWeixinConf struct
function GetWorkWeixinConfig (line 14) | func GetWorkWeixinConfig() *WorkWeixinConf {
FILE: controllers/AccountController.go
constant SessionUserInfoKey (line 31) | SessionUserInfoKey = "session-user-info-key"
constant AccessTokenCacheKey (line 32) | AccessTokenCacheKey = "access-token-cache-key"
type AccountController (line 38) | type AccountController struct
method referer (line 42) | func (c *AccountController) referer() string {
method IsInWorkWeixin (line 50) | func (c *AccountController) IsInWorkWeixin() bool {
method Prepare (line 57) | func (c *AccountController) Prepare() {
method Login (line 95) | func (c *AccountController) Login() {
method getAuth2Client (line 201) | func (c *AccountController) getAuth2Client() (auth2.Client, error) {
method parseAuth2CallbackParam (line 255) | func (c *AccountController) parseAuth2CallbackParam() (code, state str...
method getAuth2Account (line 270) | func (c *AccountController) getAuth2Account() (models.Auth2Account, er...
method Auth2Redirect (line 283) | func (c *AccountController) Auth2Redirect() {
method Auth2Callback (line 319) | func (c *AccountController) Auth2Callback() {
method Auth2BindAccount (line 442) | func (c *AccountController) Auth2BindAccount() {
method Auth2AutoAccount (line 527) | func (c *AccountController) Auth2AutoAccount() {
method LoggedIn (line 1138) | func (c *AccountController) LoggedIn(isPost bool) interface{} {
method Register (line 1155) | func (c *AccountController) Register() {
method FindPassword (line 1216) | func (c *AccountController) FindPassword() {
method ValidEmail (line 1360) | func (c *AccountController) ValidEmail() {
method Logout (line 1425) | func (c *AccountController) Logout() {
method Captcha (line 1433) | func (c *AccountController) Captcha() {
FILE: controllers/BaseController.go
type BaseController (line 22) | type BaseController struct
method Prepare (line 38) | func (c *BaseController) Prepare() {
method isUserLoggedIn (line 87) | func (c *BaseController) isUserLoggedIn() bool {
method SetMember (line 92) | func (c *BaseController) SetMember(member models.Member) {
method JsonResult (line 105) | func (c *BaseController) JsonResult(errCode int, errMsg string, data ....
method CheckJsonError (line 131) | func (c *BaseController) CheckJsonError(code int, err error) {
method ExecuteViewPathTemplate (line 157) | func (c *BaseController) ExecuteViewPathTemplate(tplName string, data ...
method BaseUrl (line 173) | func (c *BaseController) BaseUrl() string {
method ShowErrorPage (line 186) | func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
method CheckErrorResult (line 205) | func (c *BaseController) CheckErrorResult(code int, err error) {
method SetLang (line 211) | func (c *BaseController) SetLang() {
type CookieRemember (line 31) | type CookieRemember struct
FILE: controllers/BlogController.go
type BlogController (line 26) | type BlogController struct
method Prepare (line 30) | func (c *BlogController) Prepare() {
method Index (line 38) | func (c *BlogController) Index() {
method List (line 93) | func (c *BlogController) List() {
method ManageList (line 125) | func (c *BlogController) ManageList() {
method ManageSetting (line 148) | func (c *BlogController) ManageSetting() {
method ManageEdit (line 288) | func (c *BlogController) ManageEdit() {
method ManageDelete (line 405) | func (c *BlogController) ManageDelete() {
method Upload (line 433) | func (c *BlogController) Upload() {
method RemoveAttachment (line 577) | func (c *BlogController) RemoveAttachment() {
method Download (line 626) | func (c *BlogController) Download() {
FILE: controllers/BookController.go
type BookController (line 31) | type BookController struct
method Index (line 35) | func (c *BookController) Index() {
method Dashboard (line 73) | func (c *BookController) Dashboard() {
method Setting (line 97) | func (c *BookController) Setting() {
method SaveBook (line 131) | func (c *BookController) SaveBook() {
method PrivatelyOwned (line 234) | func (c *BookController) PrivatelyOwned() {
method Transfer (line 278) | func (c *BookController) Transfer() {
method UploadCover (line 314) | func (c *BookController) UploadCover() {
method Users (line 415) | func (c *BookController) Users() {
method Create (line 458) | func (c *BookController) Create() {
method Copy (line 566) | func (c *BookController) Copy() {
method Import (line 594) | func (c *BookController) Import() {
method Delete (line 726) | func (c *BookController) Delete() {
method Release (line 753) | func (c *BookController) Release() {
method UpdateBookOrder (line 792) | func (c *BookController) UpdateBookOrder() {
method SaveSort (line 825) | func (c *BookController) SaveSort() {
method Team (line 905) | func (c *BookController) Team() {
method TeamAdd (line 947) | func (c *BookController) TeamAdd() {
method TeamDelete (line 986) | func (c *BookController) TeamDelete() {
method TeamSearch (line 1017) | func (c *BookController) TeamSearch() {
method ItemsetsSearch (line 1038) | func (c *BookController) ItemsetsSearch() {
method IsPermission (line 1053) | func (c *BookController) IsPermission() (*models.BookResult, error) {
FILE: controllers/BookMemberController.go
type BookMemberController (line 13) | type BookMemberController struct
method AddMember (line 18) | func (c *BookMemberController) AddMember() {
method ChangeRole (line 67) | func (c *BookMemberController) ChangeRole() {
method RemoveMember (line 123) | func (c *BookMemberController) RemoveMember() {
method IsPermission (line 156) | func (c *BookMemberController) IsPermission() (*models.BookResult, err...
FILE: controllers/CommentController.go
type CommentController (line 12) | type CommentController struct
method Lists (line 16) | func (c *CommentController) Lists() {
method Create (line 35) | func (c *CommentController) Create() {
method Index (line 69) | func (c *CommentController) Index() {
method Delete (line 74) | func (c *CommentController) Delete() {
FILE: controllers/DocumentController.go
type DocumentController (line 37) | type DocumentController struct
method Index (line 52) | func (c *DocumentController) Index() {
method CheckPassword (line 117) | func (c *DocumentController) CheckPassword() {
method Read (line 149) | func (c *DocumentController) Read() {
method Edit (line 328) | func (c *DocumentController) Edit() {
method Create (line 402) | func (c *DocumentController) Create() {
method Upload (line 485) | func (c *DocumentController) Upload() {
method DownloadAttachment (line 682) | func (c *DocumentController) DownloadAttachment() {
method RemoveAttachment (line 746) | func (c *DocumentController) RemoveAttachment() {
method Delete (line 792) | func (c *DocumentController) Delete() {
method Content (line 847) | func (c *DocumentController) Content() {
method Export (line 976) | func (c *DocumentController) Export() {
method QrCode (line 1071) | func (c *DocumentController) QrCode() {
method Search (line 1106) | func (c *DocumentController) Search() {
method History (line 1145) | func (c *DocumentController) History() {
method DeleteHistory (line 1214) | func (c *DocumentController) DeleteHistory() {
method RestoreHistory (line 1273) | func (c *DocumentController) RestoreHistory() {
method Compare (line 1330) | func (c *DocumentController) Compare() {
method isReadable (line 1395) | func (c *DocumentController) isReadable(identify, token string) *model...
type DocumentTreeFlatten (line 42) | type DocumentTreeFlatten struct
function getTreeRecursive (line 300) | func getTreeRecursive(list []*models.DocumentTree, parentId int) (res []...
function Flatten (line 312) | func Flatten(list []*models.DocumentTree, flattened *[]DocumentTreeFlatt...
function promptUserToLogIn (line 1469) | func promptUserToLogIn(c *DocumentController) {
FILE: controllers/ErrorController.go
type ErrorController (line 3) | type ErrorController struct
method Error404 (line 7) | func (c *ErrorController) Error404() {
method Error403 (line 11) | func (c *ErrorController) Error403() {
method Error500 (line 15) | func (c *ErrorController) Error500() {
FILE: controllers/HomeController.go
type HomeController (line 13) | type HomeController struct
method Prepare (line 17) | func (c *HomeController) Prepare() {
method Index (line 25) | func (c *HomeController) Index() {
FILE: controllers/ItemsetsController.go
type ItemsetsController (line 13) | type ItemsetsController struct
method Prepare (line 17) | func (c *ItemsetsController) Prepare() {
method Index (line 26) | func (c *ItemsetsController) Index() {
method List (line 54) | func (c *ItemsetsController) List() {
FILE: controllers/LabelController.go
type LabelController (line 13) | type LabelController struct
method Prepare (line 17) | func (c *LabelController) Prepare() {
method Index (line 28) | func (c *LabelController) Index() {
method List (line 68) | func (c *LabelController) List() {
FILE: controllers/ManagerController.go
type ManagerController (line 28) | type ManagerController struct
method Prepare (line 32) | func (c *ManagerController) Prepare() {
method Index (line 40) | func (c *ManagerController) Index() {
method Users (line 48) | func (c *ManagerController) Users() {
method CreateMember (line 81) | func (c *ManagerController) CreateMember() {
method UpdateMemberStatus (line 137) | func (c *ManagerController) UpdateMemberStatus() {
method ChangeMemberRole (line 170) | func (c *ManagerController) ChangeMemberRole() {
method EditMember (line 203) | func (c *ManagerController) EditMember() {
method DeleteMember (line 255) | func (c *ManagerController) DeleteMember() {
method Books (line 287) | func (c *ManagerController) Books() {
method EditBook (line 317) | func (c *ManagerController) EditBook() {
method DeleteBook (line 407) | func (c *ManagerController) DeleteBook() {
method CreateToken (line 430) | func (c *ManagerController) CreateToken() {
method Setting (line 464) | func (c *ManagerController) Setting() {
method Transfer (line 502) | func (c *ManagerController) Transfer() {
method Comments (line 548) | func (c *ManagerController) Comments() {
method DeleteComment (line 558) | func (c *ManagerController) DeleteComment() {
method PrivatelyOwned (line 582) | func (c *ManagerController) PrivatelyOwned() {
method AttachList (line 620) | func (c *ManagerController) AttachList() {
method AttachClean (line 651) | func (c *ManagerController) AttachClean() {
method AttachDetailed (line 686) | func (c *ManagerController) AttachDetailed() {
method AttachDelete (line 715) | func (c *ManagerController) AttachDelete() {
method LabelList (line 738) | func (c *ManagerController) LabelList() {
method LabelDelete (line 760) | func (c *ManagerController) LabelDelete() {
method Config (line 782) | func (c *ManagerController) Config() {
method Team (line 820) | func (c *ManagerController) Team() {
method TeamCreate (line 851) | func (c *ManagerController) TeamCreate() {
method TeamEdit (line 872) | func (c *ManagerController) TeamEdit() {
method TeamDelete (line 896) | func (c *ManagerController) TeamDelete() {
method TeamMemberList (line 909) | func (c *ManagerController) TeamMemberList() {
method TeamSearchMember (line 953) | func (c *ManagerController) TeamSearchMember() {
method TeamMemberAdd (line 971) | func (c *ManagerController) TeamMemberAdd() {
method TeamMemberDelete (line 995) | func (c *ManagerController) TeamMemberDelete() {
method TeamChangeMemberRole (line 1012) | func (c *ManagerController) TeamChangeMemberRole() {
method TeamBookList (line 1031) | func (c *ManagerController) TeamBookList() {
method TeamBookAdd (line 1078) | func (c *ManagerController) TeamBookAdd() {
method TeamSearchBook (line 1102) | func (c *ManagerController) TeamSearchBook() {
method TeamBookDelete (line 1122) | func (c *ManagerController) TeamBookDelete() {
method Itemsets (line 1139) | func (c *ManagerController) Itemsets() {
method ItemsetsEdit (line 1167) | func (c *ManagerController) ItemsetsEdit() {
method ItemsetsDelete (line 1202) | func (c *ManagerController) ItemsetsDelete() {
FILE: controllers/SearchController.go
type SearchV2Result (line 18) | type SearchV2Result struct
type SearchV2RawResult (line 33) | type SearchV2RawResult struct
function PerformSearchV2Raw (line 57) | func PerformSearchV2Raw(keyword string, pageIndex, pageSize int, memberI...
type SearchController (line 225) | type SearchController struct
method performSearchV2 (line 181) | func (c *SearchController) performSearchV2(keyword string, pageIndex, ...
method Index (line 230) | func (c *SearchController) Index() {
method User (line 295) | func (c *SearchController) User() {
method IndexV2 (line 334) | func (c *SearchController) IndexV2() {
method SearchV2 (line 378) | func (c *SearchController) SearchV2() {
FILE: controllers/SettingController.go
type SettingController (line 19) | type SettingController struct
method Index (line 23) | func (c *SettingController) Index() {
method Password (line 47) | func (c *SettingController) Password() {
method Upload (line 93) | func (c *SettingController) Upload() {
FILE: controllers/TemplateController.go
type TemplateController (line 13) | type TemplateController struct
method isPermission (line 18) | func (c *TemplateController) isPermission() error {
method Get (line 50) | func (c *TemplateController) Get() {
method List (line 68) | func (c *TemplateController) List() {
method Add (line 90) | func (c *TemplateController) Add() {
method Delete (line 150) | func (c *TemplateController) Delete() {
FILE: controllers/const.go
constant Markdown (line 4) | Markdown = "markdown"
constant EditorMarkdown (line 5) | EditorMarkdown = "markdown"
constant EditorCherryMarkdown (line 6) | EditorCherryMarkdown = "cherry_markdown"
constant EditorHtml (line 7) | EditorHtml = "html"
constant EditorNewHtml (line 8) | EditorNewHtml = "new_html"
constant EditorFroala (line 9) | EditorFroala = "froala"
FILE: converter/converter.go
type Converter (line 25) | type Converter struct
method Convert (line 118) | func (convert *Converter) Convert() (err error) {
method converterDefer (line 234) | func (this *Converter) converterDefer() {
method generateMetaInfo (line 246) | func (this *Converter) generateMetaInfo() (err error) {
method generateMimeType (line 261) | func (this *Converter) generateMimeType() (err error) {
method generateTitlePage (line 266) | func (this *Converter) generateTitlePage() (err error) {
method generateTocNcx (line 296) | func (this *Converter) generateTocNcx() (err error) {
method generateSummary (line 317) | func (this *Converter) generateSummary() (err error) {
method tocToXml (line 339) | func (this *Converter) tocToXml(pid, idx int) (codes []string, next_id...
method tocToSummary (line 363) | func (this *Converter) tocToSummary(pid int) (summarys []string) {
method getNavPoint (line 385) | func (this *Converter) getNavPoint(toc Toc, idx int) (navpoint string,...
method generateContentOpf (line 400) | func (this *Converter) generateContentOpf() (err error) {
method convertToEpub (line 493) | func (this *Converter) convertToEpub() (err error) {
method convertToMobi (line 510) | func (this *Converter) convertToMobi() (err error) {
method convertToPdf (line 524) | func (this *Converter) convertToPdf() (err error) {
method convertToDocx (line 575) | func (this *Converter) convertToDocx() (err error) {
type Toc (line 37) | type Toc struct
type Config (line 45) | type Config struct
function CheckConvertCommand (line 76) | func CheckConvertCommand() error {
function NewConverter (line 85) | func NewConverter(configFile string, debug ...bool) (converter *Converte...
FILE: converter/util.go
function GetMediaType (line 33) | func GetMediaType(ext string) string {
function parseConfig (line 41) | func parseConfig(configFile string) (cfg Config, err error) {
FILE: graphics/copy.go
function ImageCopy (line 11) | func ImageCopy(src image.Image, x, y, w, h int) (image.Image, error) {
function ImageCopyFromFile (line 31) | func ImageCopyFromFile(p string, x, y, w, h int) (image.Image, error) {
function ImageResize (line 44) | func ImageResize(src image.Image, w, h int) image.Image {
function ImageResizeSaveFile (line 47) | func ImageResizeSaveFile(src image.Image, width, height int, p string) e...
FILE: graphics/file.go
function SaveImage (line 14) | func SaveImage(p string, src image.Image) error {
FILE: mail/smtp.go
type Mail (line 30) | type Mail struct
method AddTo (line 299) | func (m *Mail) AddTo(email string) error {
method SetTos (line 310) | func (m *Mail) SetTos(emails []string) {
method AddToName (line 315) | func (m *Mail) AddToName(name string) {
method AddRecipient (line 320) | func (m *Mail) AddRecipient(receipient *mail.Address) {
method AddSubject (line 328) | func (m *Mail) AddSubject(s string) {
method AddHTML (line 333) | func (m *Mail) AddHTML(html string) {
method AddText (line 338) | func (m *Mail) AddText(text string) {
method AddFrom (line 343) | func (m *Mail) AddFrom(from string) error {
method AddBCC (line 355) | func (m *Mail) AddBCC(email string) error {
method AddRecipientBCC (line 365) | func (m *Mail) AddRecipientBCC(email *mail.Address) {
method AddFromName (line 370) | func (m *Mail) AddFromName(name string) {
method AddReplyTo (line 375) | func (m *Mail) AddReplyTo(reply string) {
method AddDate (line 380) | func (m *Mail) AddDate(date string) {
method AddAttachment (line 385) | func (m *Mail) AddAttachment(filePath string) error {
method ReadAttachment (line 399) | func (m *Mail) ReadAttachment(filePath string) (string, error) {
method AddHeaders (line 417) | func (m *Mail) AddHeaders(headers string) {
function NewMail (line 49) | func NewMail() Mail {
type SMTPClient (line 54) | type SMTPClient struct
method NewMail (line 107) | func (c *SMTPClient) NewMail() Mail {
method Send (line 112) | func (c *SMTPClient) Send(m Mail) error {
method SendTLS (line 214) | func (c *SMTPClient) SendTLS(m Mail, message bytes.Buffer) error {
type SMTPConfig (line 63) | type SMTPConfig struct
method Address (line 72) | func (s *SMTPConfig) Address() string {
method Auth (line 79) | func (s *SMTPConfig) Auth() smtp.Auth {
function NewSMTPClient (line 96) | func NewSMTPClient(conf *SMTPConfig) SMTPClient {
type unencryptedAuth (line 425) | type unencryptedAuth struct
method Start (line 429) | func (a unencryptedAuth) Start(server *smtp.ServerInfo) (string, []byt...
type loginAuth (line 439) | type loginAuth struct
method Start (line 448) | func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, er...
method Next (line 455) | func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
function LoginAuth (line 444) | func LoginAuth(username, password string) smtp.Auth {
FILE: mail/smtp_test.go
function TestSend (line 8) | func TestSend(t *testing.T) {
FILE: mail/util.go
function MailAddr (line 7) | func MailAddr(name string, address string) *mail.Address {
type Attachments (line 14) | type Attachments struct
function SendMail (line 20) | func SendMail(subject string, content string, receiver, sender string,
FILE: main.go
function isViaDaemonUnix (line 22) | func isViaDaemonUnix() bool {
function main (line 37) | func main() {
FILE: mcp/handler.go
function GetGlobalSearchMcpTool (line 13) | func GetGlobalSearchMcpTool() mcp.Tool {
function GlobalSearchMcpHandler (line 29) | func GlobalSearchMcpHandler(ctx context.Context, request mcp.CallToolReq...
function globalSearchFunction (line 59) | func globalSearchFunction(keyword string, pageIndex int) (int, []*contro...
FILE: mcp/mcp.go
type MCPServer (line 8) | type MCPServer struct
method ServeHTTP (line 28) | func (s *MCPServer) ServeHTTP() *server.StreamableHTTPServer {
function NewMCPServer (line 13) | func NewMCPServer() *MCPServer {
FILE: mcp/middleware.go
function AuthMiddleware (line 12) | func AuthMiddleware(ctx *beegoContext.Context) {
FILE: models/AttachmentModel.go
type Attachment (line 25) | type Attachment struct
method TableName (line 40) | func (m *Attachment) TableName() string {
method TableEngine (line 45) | func (m *Attachment) TableEngine() string {
method TableNameWithPrefix (line 48) | func (m *Attachment) TableNameWithPrefix() string {
method Insert (line 56) | func (m *Attachment) Insert() error {
method Update (line 63) | func (m *Attachment) Update() error {
method Delete (line 69) | func (m *Attachment) Delete() error {
method Find (line 83) | func (m *Attachment) Find(id int) (*Attachment, error) {
method FindListByDocumentId (line 95) | func (m *Attachment) FindListByDocumentId(docId int) (attaches []*Atta...
method FindToPager (line 103) | func (m *Attachment) FindToPager(pageIndex, pageSize int) (attachList ...
function NewAttachment (line 52) | func NewAttachment() *Attachment {
FILE: models/AttachmentResult.go
type AttachmentResult (line 10) | type AttachmentResult struct
method Find (line 24) | func (m *AttachmentResult) Find(id int) (*AttachmentResult, error) {
function NewAttachmentResult (line 20) | func NewAttachmentResult() *AttachmentResult {
FILE: models/Auth2Account.go
type Auth2Account (line 19) | type Auth2Account interface
function NewWorkWeixinAccount (line 24) | func NewWorkWeixinAccount() *WorkWeixinAccount {
type WorkWeixinAccount (line 28) | type WorkWeixinAccount struct
method TableName (line 43) | func (m *WorkWeixinAccount) TableName() string {
method TableEngine (line 48) | func (m *WorkWeixinAccount) TableEngine() string {
method TableNameWithPrefix (line 52) | func (m *WorkWeixinAccount) TableNameWithPrefix() string {
method ExistedMember (line 56) | func (m *WorkWeixinAccount) ExistedMember(workweixin_user_id string) (...
method AddBind (line 79) | func (m *WorkWeixinAccount) AddBind(o orm.Ormer, userInfo auth2.UserIn...
function NewDingTalkAccount (line 108) | func NewDingTalkAccount() *DingTalkAccount {
type DingTalkAccount (line 112) | type DingTalkAccount struct
method TableName (line 122) | func (m *DingTalkAccount) TableName() string {
method TableEngine (line 127) | func (m *DingTalkAccount) TableEngine() string {
method TableNameWithPrefix (line 131) | func (m *DingTalkAccount) TableNameWithPrefix() string {
method ExistedMember (line 135) | func (m *DingTalkAccount) ExistedMember(userid string) (*Member, error) {
method AddBind (line 158) | func (m *DingTalkAccount) AddBind(o orm.Ormer, userInfo auth2.UserInfo...
FILE: models/Base.go
type Model (line 3) | type Model struct
FILE: models/Blog.go
type Blog (line 19) | type Blog struct
method TableUnique (line 66) | func (b *Blog) TableUnique() [][]string {
method TableName (line 73) | func (b *Blog) TableName() string {
method TableEngine (line 78) | func (b *Blog) TableEngine() string {
method TableNameWithPrefix (line 82) | func (b *Blog) TableNameWithPrefix() string {
method Find (line 93) | func (b *Blog) Find(blogId int) (*Blog, error) {
method FindFromCache (line 106) | func (b *Blog) FindFromCache(blogId int) (blog *Blog, err error) {
method FindByIdAndMemberId (line 130) | func (b *Blog) FindByIdAndMemberId(blogId, memberId int) (*Blog, error) {
method FindByIdentify (line 143) | func (b *Blog) FindByIdentify(identify string) (*Blog, error) {
method Link (line 155) | func (b *Blog) Link() (*Blog, error) {
method IsExist (line 215) | func (b *Blog) IsExist(identify string) bool {
method Save (line 222) | func (b *Blog) Save(cols ...string) error {
method Processor (line 268) | func (b *Blog) Processor() *Blog {
method FindToPager (line 303) | func (b *Blog) FindToPager(pageIndex, pageSize int, memberId int, stat...
method Delete (line 348) | func (b *Blog) Delete(blogId int) error {
method QueryNext (line 366) | func (b *Blog) QueryNext(blogId int) (*Blog, error) {
method QueryPrevious (line 384) | func (b *Blog) QueryPrevious(blogId int) (*Blog, error) {
method LinkAttach (line 402) | func (b *Blog) LinkAttach() (err error) {
function NewBlog (line 86) | func NewBlog() *Blog {
FILE: models/BlogResult.go
type BlogResult (line 4) | type BlogResult struct
FILE: models/BookModel.go
type Book (line 36) | type Book struct
method String (line 89) | func (book *Book) String() string {
method TableName (line 99) | func (book *Book) TableName() string {
method TableEngine (line 104) | func (book *Book) TableEngine() string {
method TableNameWithPrefix (line 107) | func (book *Book) TableNameWithPrefix() string {
method QueryTable (line 111) | func (book *Book) QueryTable() orm.QuerySeter {
method Insert (line 120) | func (book *Book) Insert(lang string) error {
method Find (line 160) | func (book *Book) Find(id int, cols ...string) (*Book, error) {
method Update (line 172) | func (book *Book) Update(cols ...string) error {
method Copy (line 193) | func (book *Book) Copy(identify string) error {
method FindByField (line 338) | func (book *Book) FindByField(field string, value interface{}, cols .....
method FindByFieldFirst (line 348) | func (book *Book) FindByFieldFirst(field string, value interface{}) (*...
method FindByIdentify (line 358) | func (book *Book) FindByIdentify(identify string, cols ...string) (*Bo...
method FindToPager (line 367) | func (book *Book) FindToPager(pageIndex, pageSize, memberId int, lang ...
method ThoroughDeleteBook (line 449) | func (book *Book) ThoroughDeleteBook(id int) error {
method FindForHomeToPager (line 550) | func (book *Book) FindForHomeToPager(pageIndex, pageSize, memberId int...
method FindForLabelToPager (line 603) | func (book *Book) FindForLabelToPager(keyword string, pageIndex, pageS...
method ReleaseContent (line 660) | func (book *Book) ReleaseContent(bookId int, lang string) {
method ResetDocumentNumber (line 694) | func (book *Book) ResetDocumentNumber(bookId int) {
method ImportBook (line 709) | func (book *Book) ImportBook(zipPath string, lang string) error {
method ImportWordBook (line 1009) | func (book *Book) ImportWordBook(docxPath string, lang string) (err er...
method FindForRoleId (line 1078) | func (book *Book) FindForRoleId(bookId, memberId int) (conf.BookRole, ...
function NewBook (line 115) | func NewBook() *Book {
function recursiveInsertDocument (line 295) | func recursiveInsertDocument(docs []*Document, o orm.TxOrmer, bookId int...
FILE: models/BookResult.go
type BookResult (line 35) | type BookResult struct
method String (line 82) | func (m *BookResult) String() string {
method SetLang (line 91) | func (m *BookResult) SetLang(lang string) *BookResult {
method FindByIdentify (line 97) | func (m *BookResult) FindByIdentify(identify string, memberId int) (*B...
method FindToPager (line 165) | func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*Bo...
method ToBookResult (line 190) | func (m *BookResult) ToBookResult(book Book) *BookResult {
method Converter (line 282) | func (m *BookResult) Converter(sessionId string) (ConvertBookResult, e...
method ExportMarkdown (line 533) | func (m *BookResult) ExportMarkdown(sessionId string) (string, error) {
method FindFirstDocumentByBookId (line 721) | func (m *BookResult) FindFirstDocumentByBookId(bookId int) (*Document,...
function NewBookResult (line 78) | func NewBookResult() *BookResult {
function BackgroundConvert (line 262) | func BackgroundConvert(sessionId string, bookResult *BookResult) error {
function exportMarkdown (line 558) | func exportMarkdown(p string, parentId int, bookId int, baseDir string, ...
function recursiveJoinDocumentIdentify (line 697) | func recursiveJoinDocumentIdentify(parentDocId int, identify string) str...
FILE: models/CommentModel.go
type Comment (line 12) | type Comment struct
method TableName (line 42) | func (m *Comment) TableName() string {
method TableEngine (line 47) | func (m *Comment) TableEngine() string {
method TableNameWithPrefix (line 51) | func (m *Comment) TableNameWithPrefix() string {
method CanDelete (line 60) | func (m *Comment) CanDelete(user_memberid int, user_bookrole conf.Book...
method QueryCommentByDocumentId (line 65) | func (m *Comment) QueryCommentByDocumentId(doc_id, page, pagesize int,...
method Update (line 100) | func (m *Comment) Update(cols ...string) error {
method Insert (line 109) | func (m *Comment) Insert() error {
method Delete (line 175) | func (m *Comment) Delete() error {
method Find (line 181) | func (m *Comment) Find(id int, cols ...string) (*Comment, error) {
function NewComment (line 55) | func NewComment() *Comment {
FILE: models/ContentReverseIndex.go
function init (line 17) | func init() {
type ContentReverseIndex (line 22) | type ContentReverseIndex struct
method TableName (line 35) | func (c *ContentReverseIndex) TableName() string {
method TableEngine (line 40) | func (c *ContentReverseIndex) TableEngine() string {
method TableNameWithPrefix (line 44) | func (c *ContentReverseIndex) TableNameWithPrefix() string {
method Insert (line 53) | func (c *ContentReverseIndex) Insert() error {
method DeleteByContentTypeAndContentId (line 73) | func (c *ContentReverseIndex) DeleteByContentTypeAndContentId(contentT...
method BatchInsert (line 87) | func (c *ContentReverseIndex) BatchInsert(indices []*ContentReverseInd...
method FindByWordsWithPagination (line 109) | func (c *ContentReverseIndex) FindByWordsWithPagination(words []string...
function NewContentReverseIndex (line 48) | func NewContentReverseIndex() *ContentReverseIndex {
type ContentReverseIndexResult (line 98) | type ContentReverseIndexResult struct
function sortResultsByScore (line 240) | func sortResultsByScore(results []*ContentReverseIndexResult) {
function generateIndexId (line 250) | func generateIndexId(contentType, contentId int, word string) string {
function BuildIndexForDocument (line 258) | func BuildIndexForDocument(documentId int, content string) error {
function BuildIndexForBlog (line 307) | func BuildIndexForBlog(blogId int, content string) error {
function CheckDocumentIndexed (line 357) | func CheckDocumentIndexed(documentId int) bool {
function CheckBlogIndexed (line 367) | func CheckBlogIndexed(blogId int) bool {
function GetUnindexedDocuments (line 377) | func GetUnindexedDocuments(limit int) ([]*Document, error) {
function GetUnindexedBlogs (line 398) | func GetUnindexedBlogs(limit int) ([]*Blog, error) {
function InitializeMissingIndexes (line 420) | func InitializeMissingIndexes() {
function InitializeMissingDocumentIndexes (line 429) | func InitializeMissingDocumentIndexes() {
function InitializeMissingBlogIndexes (line 464) | func InitializeMissingBlogIndexes() {
FILE: models/ConvertBookResult.go
type ConvertBookResult (line 4) | type ConvertBookResult struct
FILE: models/Dashboard.go
type Dashboard (line 5) | type Dashboard struct
method Query (line 17) | func (m *Dashboard) Query() *Dashboard {
function NewDashboard (line 13) | func NewDashboard() *Dashboard {
FILE: models/DocumentHistory.go
type DocumentHistory (line 11) | type DocumentHistory struct
method TableName (line 39) | func (m *DocumentHistory) TableName() string {
method TableEngine (line 44) | func (m *DocumentHistory) TableEngine() string {
method TableNameWithPrefix (line 48) | func (m *DocumentHistory) TableNameWithPrefix() string {
method Find (line 55) | func (m *DocumentHistory) Find(id int) (*DocumentHistory, error) {
method Clear (line 63) | func (m *DocumentHistory) Clear(docId int) error {
method Delete (line 72) | func (m *DocumentHistory) Delete(historyId, docId int) error {
method Restore (line 81) | func (m *DocumentHistory) Restore(historyId, docId, uid int) error {
method InsertOrUpdate (line 121) | func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory, ...
method FindToPager (line 156) | func (m *DocumentHistory) FindToPager(docId, pageIndex, pageSize int) ...
type DocumentHistorySimpleResult (line 27) | type DocumentHistorySimpleResult struct
function NewDocumentHistory (line 52) | func NewDocumentHistory() *DocumentHistory {
FILE: models/DocumentModel.go
type Document (line 26) | type Document struct
method TableUnique (line 50) | func (item *Document) TableUnique() [][]string {
method TableName (line 55) | func (item *Document) TableName() string {
method TableEngine (line 60) | func (item *Document) TableEngine() string {
method TableNameWithPrefix (line 64) | func (item *Document) TableNameWithPrefix() string {
method Find (line 75) | func (item *Document) Find(id int) (*Document, error) {
method InsertOrUpdate (line 92) | func (item *Document) InsertOrUpdate(cols ...string) error {
method FindByIdentityFirst (line 124) | func (item *Document) FindByIdentityFirst(identify string, bookId int)...
method RecursiveDocument (line 133) | func (item *Document) RecursiveDocument(docId int) error {
method PutToCache (line 169) | func (item *Document) PutToCache() {
method RemoveCache (line 187) | func (item *Document) RemoveCache() {
method FromCacheById (line 198) | func (item *Document) FromCacheById(id int) (*Document, error) {
method FromCacheByIdentify (line 217) | func (item *Document) FromCacheByIdentify(identify string, bookId int)...
method FindListByBookId (line 235) | func (item *Document) FindListByBookId(bookId int) (docs []*Document, ...
method IsExist (line 244) | func (item *Document) IsExist(documentId int) bool {
method ReleaseContent (line 251) | func (item *Document) ReleaseContent() error {
method Processor (line 287) | func (item *Document) Processor() *Document {
method IncrViewCount (line 418) | func (item *Document) IncrViewCount(id int) {
function NewDocument (line 68) | func NewDocument() *Document {
FILE: models/DocumentSearchResult.go
type DocumentSearchResult (line 14) | type DocumentSearchResult struct
method FindToPager (line 54) | func (m *DocumentSearchResult) FindToPager(keyword string, pageIndex, ...
method SearchDocument (line 304) | func (m *DocumentSearchResult) SearchDocument(keyword string, bookId i...
method SearchAllDocument (line 323) | func (m *DocumentSearchResult) SearchAllDocument(keyword string) (docs...
function need_escape (line 32) | func need_escape(keyword string) bool {
function escape_name (line 40) | func escape_name(name string) string {
function NewDocumentSearchResult (line 49) | func NewDocumentSearchResult() *DocumentSearchResult {
FILE: models/DocumentTree.go
type DocumentTree (line 15) | type DocumentTree struct
type DocumentSelected (line 35) | type DocumentSelected struct
method FindDocumentTree (line 42) | func (item *Document) FindDocumentTree(bookId int) ([]*DocumentTree, err...
method FindDocumentTree2 (line 95) | func (item *Document) FindDocumentTree2(bookId int) ([]*DocumentTree, er...
method CreateDocumentTreeForHtml (line 147) | func (item *Document) CreateDocumentTreeForHtml(bookId, selectedId int) ...
function getSelectedNode (line 163) | func getSelectedNode(array []*DocumentTree, parent_id int) int {
function getDocumentTree (line 175) | func getDocumentTree(array []*DocumentTree, parentId int, selectedId int...
FILE: models/Errors.go
type Error (line 45) | type Error struct
method Error (line 50) | func (e Error) Error() string {
method Code (line 54) | func (e Error) Code() int {
function NewError (line 58) | func NewError(code int, message string) Error {
FILE: models/Itemsets.go
type Itemsets (line 16) | type Itemsets struct
method TableName (line 32) | func (item *Itemsets) TableName() string {
method TableEngine (line 37) | func (item *Itemsets) TableEngine() string {
method TableNameWithPrefix (line 40) | func (item *Itemsets) TableNameWithPrefix() string {
method QueryTable (line 44) | func (item *Itemsets) QueryTable() orm.QuerySeter {
method First (line 52) | func (item *Itemsets) First(itemId int) (*Itemsets, error) {
method FindFirst (line 65) | func (item *Itemsets) FindFirst(itemKey string) (*Itemsets, error) {
method Exist (line 75) | func (item *Itemsets) Exist(itemId int) bool {
method Save (line 80) | func (item *Itemsets) Save() (err error) {
method Delete (line 105) | func (item *Itemsets) Delete(itemId int) (err error) {
method Include (line 135) | func (item *Itemsets) Include() (*Itemsets, error) {
method FindToPager (line 159) | func (item *Itemsets) FindToPager(pageIndex, pageSize int) (list []*It...
method FindItemsetsByName (line 182) | func (item *Itemsets) FindItemsetsByName(name string, limit int) (*Sel...
method FindItemsetsByItemKey (line 212) | func (item *Itemsets) FindItemsetsByItemKey(key string, pageIndex, pag...
function NewItemsets (line 48) | func NewItemsets() *Itemsets {
FILE: models/LabelModel.go
type Label (line 11) | type Label struct
method TableName (line 18) | func (m *Label) TableName() string {
method TableEngine (line 23) | func (m *Label) TableEngine() string {
method TableNameWithPrefix (line 27) | func (m *Label) TableNameWithPrefix() string {
method FindFirst (line 35) | func (m *Label) FindFirst(field string, value interface{}) (*Label, er...
method InsertOrUpdate (line 44) | func (m *Label) InsertOrUpdate(labelName string) error {
method InsertOrUpdateMulti (line 66) | func (m *Label) InsertOrUpdateMulti(labels string) {
method Delete (line 79) | func (m *Label) Delete() error {
method FindToPager (line 90) | func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label,...
function NewLabel (line 31) | func NewLabel() *Label {
FILE: models/Logs.go
type logQueue (line 14) | type logQueue struct
type Logger (line 20) | type Logger struct
method TableName (line 34) | func (m *Logger) TableName() string {
method TableEngine (line 39) | func (m *Logger) TableEngine() string {
method TableNameWithPrefix (line 42) | func (m *Logger) TableNameWithPrefix() string {
method Add (line 50) | func (m *Logger) Add() error {
function NewLogger (line 46) | func NewLogger() *Logger {
function addLoggerAsync (line 68) | func addLoggerAsync() {
FILE: models/Member.go
type Member (line 34) | type Member struct
method TableName (line 57) | func (m *Member) TableName() string {
method TableEngine (line 62) | func (m *Member) TableEngine() string {
method TableNameWithPrefix (line 66) | func (m *Member) TableNameWithPrefix() string {
method Login (line 75) | func (m *Member) Login(account string, password string) (*Member, erro...
method ldapLogin (line 126) | func (m *Member) ldapLogin(account string, password string) (*Member, ...
method httpLogin (line 239) | func (m *Member) httpLogin(account, password string) (*Member, error) {
method Add (line 316) | func (m *Member) Add() error {
method Update (line 359) | func (m *Member) Update(cols ...string) error {
method Find (line 375) | func (m *Member) Find(id int, cols ...string) (*Member, error) {
method ResolveRoleName (line 385) | func (m *Member) ResolveRoleName() {
method FindByAccount (line 398) | func (m *Member) FindByAccount(account string) (*Member, error) {
method FindByAccountList (line 410) | func (m *Member) FindByAccountList(accounts ...string) ([]*Member, err...
method FindToPager (line 425) | func (m *Member) FindToPager(pageIndex, pageSize int) ([]*Member, int,...
method IsAdministrator (line 451) | func (m *Member) IsAdministrator() bool {
method FindByFieldFirst (line 459) | func (m *Member) FindByFieldFirst(field string, value interface{}) (*M...
method Valid (line 468) | func (m *Member) Valid(is_hash_password bool) error {
method Delete (line 524) | func (m *Member) Delete(oldId int, newId int) error {
function NewMember (line 70) | func NewMember() *Member {
FILE: models/MemberResult.go
type MemberRelationshipResult (line 11) | type MemberRelationshipResult struct
method FromMember (line 42) | func (m *MemberRelationshipResult) FromMember(member *Member) *MemberR...
method ResolveRoleName (line 58) | func (m *MemberRelationshipResult) ResolveRoleName(lang string) *Membe...
method FindForUsersByBookId (line 70) | func (m *MemberRelationshipResult) FindForUsersByBookId(lang string, b...
method FindNotJoinUsersByAccount (line 102) | func (m *MemberRelationshipResult) FindNotJoinUsersByAccount(bookId, l...
method FindNotJoinUsersByAccountOrRealName (line 115) | func (m *MemberRelationshipResult) FindNotJoinUsersByAccountOrRealName...
type SelectMemberResult (line 30) | type SelectMemberResult struct
type KeyValueItem (line 33) | type KeyValueItem struct
function NewMemberRelationshipResult (line 38) | func NewMemberRelationshipResult() *MemberRelationshipResult {
FILE: models/MemberToken.go
type MemberToken (line 10) | type MemberToken struct
method TableName (line 21) | func (m *MemberToken) TableName() string {
method TableEngine (line 26) | func (m *MemberToken) TableEngine() string {
method TableNameWithPrefix (line 30) | func (m *MemberToken) TableNameWithPrefix() string {
method InsertOrUpdate (line 38) | func (m *MemberToken) InsertOrUpdate() (*MemberToken, error) {
method FindByFieldFirst (line 50) | func (m *MemberToken) FindByFieldFirst(field string, value interface{}...
method FindSendCount (line 58) | func (m *MemberToken) FindSendCount(mail string, start_time time.Time,...
function NewMemberToken (line 34) | func NewMemberToken() *MemberToken {
FILE: models/Migrations.go
type Migration (line 10) | type Migration struct
method TableName (line 20) | func (m *Migration) TableName() string {
method TableEngine (line 25) | func (m *Migration) TableEngine() string {
method TableNameWithPrefix (line 29) | func (m *Migration) TableNameWithPrefix() string {
method FindFirst (line 37) | func (m *Migration) FindFirst() (*Migration, error) {
function NewMigration (line 33) | func NewMigration() *Migration {
FILE: models/Options.go
type Option (line 9) | type Option struct
method TableName (line 18) | func (m *Option) TableName() string {
method TableEngine (line 23) | func (m *Option) TableEngine() string {
method TableNameWithPrefix (line 27) | func (m *Option) TableNameWithPrefix() string {
method Find (line 35) | func (p *Option) Find(id int) (*Option, error) {
method FindByKey (line 46) | func (p *Option) FindByKey(key string) (*Option, error) {
method InsertOrUpdate (line 64) | func (p *Option) InsertOrUpdate() error {
method InsertMulti (line 78) | func (p *Option) InsertMulti(option ...Option) error {
method All (line 86) | func (p *Option) All() ([]*Option, error) {
method Init (line 98) | func (m *Option) Init() error {
method Update (line 180) | func (m *Option) Update() error {
function NewOption (line 31) | func NewOption() *Option {
function GetOptionValue (line 56) | func GetOptionValue(key, def string) string {
FILE: models/Relationship.go
type Relationship (line 11) | type Relationship struct
method TableName (line 20) | func (m *Relationship) TableName() string {
method TableNameWithPrefix (line 23) | func (m *Relationship) TableNameWithPrefix() string {
method TableEngine (line 28) | func (m *Relationship) TableEngine() string {
method TableUnique (line 33) | func (m *Relationship) TableUnique() [][]string {
method QueryTable (line 39) | func (m *Relationship) QueryTable() orm.QuerySeter {
method Find (line 46) | func (m *Relationship) Find(id int) (*Relationship, error) {
method FindFounder (line 54) | func (m *Relationship) FindFounder(book_id int) (*Relationship, error) {
method UpdateRoleId (line 62) | func (m *Relationship) UpdateRoleId(bookId, memberId int, roleId conf....
method FindForRoleId (line 95) | func (m *Relationship) FindForRoleId(bookId, memberId int) (conf.BookR...
method FindByBookIdAndMemberId (line 108) | func (m *Relationship) FindByBookIdAndMemberId(book_id, member_id int)...
method Insert (line 116) | func (m *Relationship) Insert() error {
method Update (line 124) | func (m *Relationship) Update(txOrm orm.TxOrmer) error {
method DeleteByBookIdAndMemberId (line 132) | func (m *Relationship) DeleteByBookIdAndMemberId(book_id, member_id in...
method Transfer (line 153) | func (m *Relationship) Transfer(book_id, founder_id, receive_id int) e...
function NewRelationship (line 42) | func NewRelationship() *Relationship {
FILE: models/Team.go
type Team (line 13) | type Team struct
method TableName (line 25) | func (t *Team) TableName() string {
method TableEngine (line 30) | func (t *Team) TableEngine() string {
method TableNameWithPrefix (line 34) | func (t *Team) TableNameWithPrefix() string {
method First (line 43) | func (t *Team) First(id int, cols ...string) (*Team, error) {
method Delete (line 58) | func (t *Team) Delete(id int) (err error) {
method FindToPager (line 99) | func (t *Team) FindToPager(pageIndex, pageSize int) (list []*Team, tot...
method Include (line 122) | func (t *Team) Include() {
method Save (line 142) | func (t *Team) Save(cols ...string) (err error) {
function NewTeam (line 38) | func NewTeam() *Team {
FILE: models/TeamMember.go
type TeamMember (line 12) | type TeamMember struct
method TableName (line 26) | func (m *TeamMember) TableName() string {
method TableNameWithPrefix (line 29) | func (m *TeamMember) TableNameWithPrefix() string {
method TableEngine (line 34) | func (m *TeamMember) TableEngine() string {
method TableUnique (line 39) | func (m *TeamMember) TableUnique() [][]string {
method QueryTable (line 43) | func (m *TeamMember) QueryTable() orm.QuerySeter {
method SetLang (line 51) | func (m *TeamMember) SetLang(lang string) *TeamMember {
method First (line 56) | func (m *TeamMember) First(id int, cols ...string) (*TeamMember, error) {
method ChangeRoleId (line 71) | func (m *TeamMember) ChangeRoleId(teamId int, memberId int, roleId con...
method FindFirst (line 95) | func (m *TeamMember) FindFirst(teamId, memberId int) (*TeamMember, err...
method Save (line 110) | func (m *TeamMember) Save(cols ...string) (err error) {
method Delete (line 143) | func (m *TeamMember) Delete(id int) (err error) {
method FindToPager (line 157) | func (m *TeamMember) FindToPager(teamId, pageIndex, pageSize int) (lis...
method Include (line 190) | func (m *TeamMember) Include() *TeamMember {
method FindNotJoinMemberByAccount (line 210) | func (m *TeamMember) FindNotJoinMemberByAccount(teamId int, account st...
method FindByBookIdAndMemberId (line 246) | func (m *TeamMember) FindByBookIdAndMemberId(bookId, memberId int) (*T...
function NewTeamMember (line 47) | func NewTeamMember() *TeamMember {
FILE: models/TeamRelationship.go
type TeamRelationship (line 12) | type TeamRelationship struct
method TableName (line 25) | func (m *TeamRelationship) TableName() string {
method TableNameWithPrefix (line 28) | func (m *TeamRelationship) TableNameWithPrefix() string {
method TableEngine (line 33) | func (m *TeamRelationship) TableEngine() string {
method TableUnique (line 38) | func (m *TeamRelationship) TableUnique() [][]string {
method QueryTable (line 41) | func (m *TeamRelationship) QueryTable() orm.QuerySeter {
method First (line 49) | func (m *TeamRelationship) First(teamId int, cols ...string) (*TeamRel...
method FindByBookId (line 61) | func (m *TeamRelationship) FindByBookId(bookId int, teamId int) (*Team...
method DeleteByBookId (line 73) | func (m *TeamRelationship) DeleteByBookId(bookId int, teamId int) error {
method Save (line 84) | func (m *TeamRelationship) Save(cols ...string) (err error) {
method Delete (line 103) | func (m *TeamRelationship) Delete(teamRelId int) (err error) {
method FindToPager (line 116) | func (m *TeamRelationship) FindToPager(teamId, pageIndex, pageSize int...
method Include (line 145) | func (m *TeamRelationship) Include() (*TeamRelationship, error) {
method FindNotJoinBookByName (line 176) | func (m *TeamRelationship) FindNotJoinBookByName(teamId int, bookName ...
method FindNotJoinBookByBookIdentify (line 211) | func (m *TeamRelationship) FindNotJoinBookByBookIdentify(bookId int, t...
method FindByBookToPager (line 246) | func (m *TeamRelationship) FindByBookToPager(bookId, pageIndex, pageSi...
function NewTeamRelationship (line 45) | func NewTeamRelationship() *TeamRelationship {
FILE: models/Template.go
type Template (line 12) | type Template struct
method TableName (line 30) | func (m *Template) TableName() string {
method TableEngine (line 35) | func (m *Template) TableEngine() string {
method TableNameWithPrefix (line 39) | func (m *Template) TableNameWithPrefix() string {
method Find (line 48) | func (t *Template) Find(templateId int) (*Template, error) {
method FindByBookId (line 64) | func (t *Template) FindByBookId(bookId int) ([]*Template, error) {
method FindAllByBookId (line 81) | func (t *Template) FindAllByBookId(bookId int) ([]*Template, error) {
method Delete (line 104) | func (t *Template) Delete(templateId int, memberId int) error {
method Save (line 125) | func (t *Template) Save(cols ...string) (err error) {
method Preload (line 152) | func (t *Template) Preload() *Template {
function NewTemplate (line 43) | func NewTemplate() *Template {
FILE: models/comment_result.go
type CommentResult (line 5) | type CommentResult struct
method FindForDocumentToPager (line 11) | func (m *CommentResult) FindForDocumentToPager(doc_id, page_index, pag...
FILE: models/comment_vote.go
type CommentVote (line 10) | type CommentVote struct
method TableName (line 20) | func (m *CommentVote) TableName() string {
method TableEngine (line 25) | func (m *CommentVote) TableEngine() string {
method TableNameWithPrefix (line 29) | func (m *CommentVote) TableNameWithPrefix() string {
method TableUnique (line 32) | func (u *CommentVote) TableUnique() [][]string {
method InsertOrUpdate (line 40) | func (m *CommentVote) InsertOrUpdate() (*CommentVote, error) {
function NewCommentVote (line 37) | func NewCommentVote() *CommentVote {
FILE: routers/filter.go
function init (line 16) | func init() {
FILE: routers/router.go
type CorsTransport (line 20) | type CorsTransport struct
method RoundTrip (line 24) | func (t *CorsTransport) RoundTrip(req *http.Request) (resp *http.Respo...
function singleJoiningSlash (line 68) | func singleJoiningSlash(a, b string) string {
function init (line 80) | func init() {
FILE: static/bootstrap/js/bootstrap.js
function transitionEnd (line 34) | function transitionEnd() {
function removeElement (line 126) | function removeElement() {
function Plugin (line 142) | function Plugin(option) {
function Plugin (line 251) | function Plugin(option) {
function Plugin (line 475) | function Plugin(option) {
function getTargetFromTrigger (line 695) | function getTargetFromTrigger($trigger) {
function Plugin (line 707) | function Plugin(option) {
function getParent (line 774) | function getParent($this) {
function clearMenus (line 787) | function clearMenus(e) {
function Plugin (line 880) | function Plugin(option) {
function Plugin (line 1208) | function Plugin(option, _relatedTarget) {
function complete (line 1574) | function complete() {
function Plugin (line 1750) | function Plugin(option) {
function Plugin (line 1859) | function Plugin(option) {
function ScrollSpy (line 1902) | function ScrollSpy(element, options) {
function Plugin (line 2022) | function Plugin(option) {
function next (line 2131) | function next() {
function Plugin (line 2177) | function Plugin(option) {
function Plugin (line 2334) | function Plugin(option) {
FILE: static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/plugins/piexif.js
function copy (line 308) | function copy(obj) {
function _get_thumbnail (line 313) | function _get_thumbnail(jpeg) {
function _pack_byte (line 322) | function _pack_byte(array) {
function _pack_short (line 327) | function _pack_short(array) {
function _pack_long (line 332) | function _pack_long(array) {
function _value_to_bytes (line 337) | function _value_to_bytes(raw_value, value_type, offset) {
function _dict_to_bytes (line 431) | function _dict_to_bytes(ifd_dict, ifd, ifd_offset) {
function ExifReader (line 480) | function ExifReader(data) {
function getImageSize (line 711) | function getImageSize(imageArray) {
function pack (line 730) | function pack(mark, array) {
function unpack (line 801) | function unpack(mark, str) {
function nStr (line 879) | function nStr(ch, num) {
function splitIntoSegments (line 887) | function splitIntoSegments(data) {
function getExifSeg (line 913) | function getExifSeg(segments) {
function mergeSegments (line 926) | function mergeSegments(segments, exif) {
function toHex (line 960) | function toHex(str) {
FILE: static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/plugins/sortable.js
function toFn (line 185) | function toFn(value, pull) {
function KvSortable (line 242) | function KvSortable(el, options) {
function _cloneHide (line 1188) | function _cloneHide(kvsortable, state) {
function _closest (line 1212) | function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElemen...
function _getParentOrHost (line 1228) | function _getParentOrHost(el) {
function _globalDragOver (line 1235) | function _globalDragOver(/**Event*/evt) {
function _on (line 1243) | function _on(el, event, fn) {
function _off (line 1248) | function _off(el, event, fn) {
function _toggleClass (line 1253) | function _toggleClass(el, name, state) {
function _css (line 1266) | function _css(el, prop, val) {
function _find (line 1291) | function _find(ctx, tagName, iterator) {
function _dispatchEvent (line 1309) | function _dispatchEvent(kvsortable, rootEl, name, targetEl, toEl, fromEl...
function _onMove (line 1334) | function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, o...
function _disableDraggable (line 1361) | function _disableDraggable(el) {
function _unsilent (line 1366) | function _unsilent() {
function _ghostIsLast (line 1372) | function _ghostIsLast(el, evt) {
function _generateId (line 1389) | function _generateId(el) {
function _index (line 1408) | function _index(el, selector) {
function _matches (line 1424) | function _matches(/**HTMLElement*/el, /**String*/selector) {
function _throttle (line 1440) | function _throttle(callback, ms) {
function _extend (line 1461) | function _extend(dst, src) {
function _clone (line 1473) | function _clone(el) {
function _saveInputCheckedState (line 1485) | function _saveInputCheckedState(root) {
function _nextTick (line 1495) | function _nextTick(fn) {
function _cancelNextTick (line 1499) | function _cancelNextTick(id) {
FILE: static/bootstrap/plugins/bootstrap-switch/js/bootstrap-switch.js
function _interopRequireDefault (line 27) | function _interopRequireDefault(obj) {
function _classCallCheck (line 47) | function _classCallCheck(instance, Constructor) {
function defineProperties (line 54) | function defineProperties(target, props) {
function BootstrapSwitch (line 74) | function BootstrapSwitch(element) {
function reducer (line 748) | function reducer(ret, next) {
FILE: static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/prettify.js
function S (line 2) | function S(a){function d(e){var b=e.charCodeAt(0);if(b!==92)return b;var...
function T (line 6) | function T(a,d){function g(a){var c=a.nodeType;if(c==1){if(!b.test(a.cla...
function H (line 7) | function H(a,d,g,b){d&&(a={a:d,e:a},g(a),b.push.apply(b,a.g))}
function U (line 7) | function U(a){for(var d=void 0,g=a.firstChild;g;g=g.nextSibling)var b=g....
function C (line 7) | function C(a,d){function g(a){for(var j=a.e,k=[j,"pln"],c=0,i=a.a.match(...
function v (line 9) | function v(a){var d=[],g=[];a.tripleQuotedStrings?d.push(["str",/^(?:'''...
function J (line 13) | function J(a,d,g){function b(a){var c=a.nodeType;if(c==1&&!x.test(a.clas...
function p (line 15) | function p(a,d){for(var g=d.length;--g>=0;){var b=d[g];F.hasOwnProperty(...
function I (line 15) | function I(a,d){if(!a||!F.hasOwnProperty(a))a=/^\s*</.test(d)?"default-m...
function K (line 15) | function K(a){var d=a.h;try{var g=T(a.c,a.i),b=g.a;
function g (line 27) | function g(){for(var b=D.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity...
FILE: static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/run_prettify.js
function X (line 2) | function X(e){function j(){try{J.doScroll("left")}catch(e){P(j,50);retur...
function Q (line 3) | function Q(){S&&X(function(){var e=K.length;$(e?function(){for(var j=0;j...
function j (line 5) | function j(m){if(m!==w){var n=x.createElement("link");n.rel="stylesheet"...
function j (line 6) | function j(a){function d(f){var b=f.charCodeAt(0);if(b!==92)return b;var...
function m (line 10) | function m(a,d){function h(a){var c=a.nodeType;if(c==1){if(!b.test(a.cla...
function n (line 11) | function n(a,d,h,b){d&&(a={a:d,e:a},h(a),b.push.apply(b,a.g))}
function x (line 11) | function x(a){for(var d=void 0,h=a.firstChild;h;h=h.nextSibling)var b=h....
function C (line 11) | function C(a,d){function h(a){for(var l=a.e,j=[l,"pln"],c=
function t (line 13) | function t(a){var d=[],h=[];a.tripleQuotedStrings?d.push(["str",/^(?:'''...
function z (line 17) | function z(a,d,h){function b(a){var c=a.nodeType;if(c==1&&!j.test(a.clas...
function i (line 19) | function i(a,d){for(var h=d.length;--h>=0;){var b=d[h];U.hasOwnProperty(...
function A (line 19) | function A(a,d){if(!a||!U.hasOwnProperty(a))a=/^\s*</.test(d)?"default-m...
function D (line 19) | function D(a){var d=
function e (line 31) | function e(){for(var b=V.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity...
FILE: static/bootstrap/plugins/bootstrap-wysiwyg/external/jquery.hotkeys.js
function keyHandler (line 35) | function keyHandler( handleObj ) {
FILE: static/bootstrap/plugins/tagsinput/bootstrap-tagsinput.js
function TagsInput (line 35) | function TagsInput(element, options) {
function processItems (line 280) | function processItems(items) {
function makeOptionItemFunction (line 569) | function makeOptionItemFunction(options, key) {
function makeOptionFunction (line 575) | function makeOptionFunction(options, key) {
function htmlEncode (line 585) | function htmlEncode(value) {
function doGetCaretPosition (line 597) | function doGetCaretPosition(oField) {
function keyCombinationInList (line 617) | function keyCombinationInList(keyPressEvent, lookupList) {
FILE: static/cherry/addons/cherry-code-block-mermaid-plugin.d.ts
class MermaidCodeEngine (line 1) | class MermaidCodeEngine {
FILE: static/cherry/addons/cherry-code-block-mermaid-plugin.js
function r (line 1) | function r(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.ca...
function e (line 1) | function e(t,r){return t(r={exports:{}},r.exports),r.exports}
function t (line 1) | function t(){}
function t (line 1) | function t(){}
function r (line 1) | function r(e,n){return t.exports=r=No||function(t,r){return t.__proto__=...
function r (line 1) | function r(e,n,o){return Uo()?(t.exports=r=Ro,t.exports.__esModule=!0,t....
function r (line 1) | function r(t,r){for(var e=0;e<r.length;e++){var n=r[e];n.enumerable=n.en...
function si (line 1) | function si(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){va...
function ta (line 1) | function ta(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){va...
function fa (line 1) | function fa(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){va...
function pa (line 1) | function pa(t){var r=this.__data__=new li(t);this.size=r.size}
function t (line 1) | function t(){}
function xu (line 1) | function xu(t,r){var e=pr(t);if(mn){var n=mn(t);r&&(n=xn(n).call(n,(func...
function Au (line 1) | function Au(t){for(var r=1;r<arguments.length;r++){var e,n,o=null!=argum...
function t (line 1) | function t(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0...
FILE: static/cherry/addons/cherry-code-block-plantuml-plugin.d.ts
class PlantUMLCodeEngine (line 1) | class PlantUMLCodeEngine {
FILE: static/cherry/addons/cherry-code-block-plantuml-plugin.js
function r (line 1) | function r(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.ca...
function e (line 1) | function e(t,r){return t(r={exports:{}},r.exports),r.exports}
function t (line 1) | function t(){}
function r (line 1) | function r(t,r){for(var e=0;e<r.length;e++){var n=r[e];n.enumerable=n.en...
function Uo (line 1) | function Uo(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){va...
function Fi (line 1) | function Fi(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){va...
function Gi (line 1) | function Gi(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r<e;){va...
function $i (line 1) | function $i(t){var r=this.__data__=new Bo(t);this.size=r.size}
function t (line 1) | function t(){}
function nt (line 1) | function nt(){this.fc=0,this.dl=0}
function ot (line 1) | function ot(){this.dyn_tree=null,this.static_tree=null,this.extra_bits=n...
function it (line 1) | function it(t,r,e,n){this.good_length=t,this.max_lazy=r,this.nice_length...
function at (line 1) | function at(){this.next=null,this.len=0,this.ptr=new Array(8192),this.of...
function pt (line 1) | function pt(r){r.next=t,t=r}
function vt (line 1) | function vt(t){return l[32768+t]}
function yt (line 1) | function yt(t,r){return l[32768+t]=r}
function dt (line 1) | function dt(n){et[i+o++]=n,i+o==8192&&function(){if(0!=o){var n,a;for(nu...
function ht (line 1) | function ht(t){t&=65535,i+o<8190?(et[i+o++]=255&t,et[i+o++]=t>>>8):(dt(2...
function bt (line 1) | function bt(){y=8191&(y<<rt^255&u[_+3-1]),d=vt(y),l[32767&_]=d,yt(y,_)}
function gt (line 1) | function gt(t,r){zt(r[t].fc,r[t].dl)}
function mt (line 1) | function mt(t){return 255&(t<256?B[t]:B[256+(t>>7)])}
function _t (line 1) | function _t(t,r,e){return t[r].fc<t[e].fc||t[r].fc==t[e].fc&&G[r]<=G[e]}
function wt (line 1) | function wt(t,r,e){var n;for(n=0;n<e&&tt<Z.length;n++)t[r+n]=255&Z.charC...
function Ot (line 1) | function Ot(t){var r,e,n=S,o=_,i=m,a=_>32506?_-32506:0,c=_+258,f=u[o+i-1...
function jt (line 1) | function jt(){var t,r,e=65536-j-_;if(-1==e)e--;else if(_>=65274){for(t=0...
function St (line 1) | function St(){O||(s=0,p=0,function(){var t,r,e,n,o;if(0!=F[0].dl)return;...
function xt (line 1) | function xt(t,e,o){var i;return n||(St(),n=!0,0!=j)?(i=At(t,e,o))==o?o:a...
function At (line 1) | function At(t,e,n){var a,u,c;for(a=0;null!=r&&a<n;){for((u=n-a)>r.len&&(...
function Pt (line 1) | function Pt(){var t;for(t=0;t<286;t++)T[t].fc=0;for(t=0;t<30;t++)E[t].fc...
function Tt (line 1) | function Tt(t,r){for(var e=D[r],n=r<<1;n<=R&&(n<R&&_t(t,D[n+1],D[n])&&n+...
function Et (line 1) | function Et(t,r){var e,n,o=new Array(16),i=0;for(e=1;e<=15;e++)i=i+z[e-1...
function Ct (line 1) | function Ct(t){var r,e,n=t.dyn_tree,o=t.static_tree,i=t.elems,a=-1,u=i;f...
function Ft (line 1) | function Ft(t,r){var e,n,o=-1,i=t[0].dl,a=0,u=7,c=4;for(0==i&&(u=138,c=3...
function Lt (line 1) | function Lt(t,r){var e,n,o=-1,i=t[0].dl,a=0,u=7,c=4;for(0==i&&(u=138,c=3...
function kt (line 1) | function kt(t){var r,e,n,o,i;if(o=_-v,W[Y]=J,Ct(k),Ct(M),n=function(){va...
function Mt (line 1) | function Mt(t,r){if(f[q++]=r,0==t?T[r].fc++:(t--,T[U[r]+256+1].fc++,E[mt...
function It (line 1) | function It(t,r){var e,n,o,i,a=0,u=0,l=0,s=0;if(0!=q)do{0==(7&a)&&(s=W[l...
function zt (line 1) | function zt(t,r){p>16-r?(ht(s|=t<<p),s=t>>16-p,p+=r-16):(s|=t<<p,p+=r)}
function Dt (line 1) | function Dt(t,r){var e=0;do{e|=1&t,t>>=1,e<<=1}while(--r>0);return e>>1}
function Rt (line 1) | function Rt(){p>8?ht(s):p>0&&dt(s),s=0,p=0}
function gu (line 1) | function gu(t,r){var e=pr(t);if(gn){var n=gn(t);r&&(n=An(n).call(n,(func...
function mu (line 1) | function mu(t){for(var r=1;r<arguments.length;r++){var e,n,o=null!=argum...
function _u (line 1) | function _u(t,r,e){var n=(3&t)<<4|r>>4,o=(15&r)<<2|e>>6,i=63&e,a="";retu...
function wu (line 1) | function wu(t){var r=t;return r<10?String.fromCharCode(48+r):(r-=10)<26?...
function Ou (line 1) | function Ou(t,r){var e,n=unescape(encodeURIComponent(t));return Lo(e=""....
function t (line 1) | function t(){var r,e=arguments.length>0&&void 0!==arguments[0]?arguments...
FILE: static/cherry/cherry-markdown.js
function unwrapExports (line 9) | function unwrapExports (x) {
function createCommonjsModule (line 13) | function createCommonjsModule(fn, module) {
function getCjsExportFromNamespace (line 17) | function getCjsExportFromNamespace (n) {
function F (line 949) | function F() { /* empty */ }
function F (line 1724) | function F() { /* empty */ }
function _classCallCheck (line 2125) | function _classCallCheck(instance, Constructor) {
function _defineProperties (line 2145) | function _defineProperties(target, props) {
function _createClass (line 2156) | function _createClass(Constructor, protoProps, staticProps) {
function _assertThisInitialized (line 2173) | function _assertThisInitialized(self) {
function _setPrototypeOf (line 2232) | function _setPrototypeOf(o, p) {
function _inherits (line 2246) | function _inherits(subClass, superClass) {
function _typeof (line 2509) | function _typeof(obj) {
function _possibleConstructorReturn (line 2529) | function _possibleConstructorReturn(self, call) {
function _getPrototypeOf (line 2567) | function _getPrototypeOf(o) {
function _defineProperty (line 2580) | function _defineProperty(obj, key, value) {
function listCacheClear (line 2695) | function listCacheClear() {
function eq (line 2734) | function eq(value, other) {
function assocIndexOf (line 2748) | function assocIndexOf(array, key) {
function listCacheDelete (line 2775) | function listCacheDelete(key) {
function listCacheGet (line 2803) | function listCacheGet(key) {
function listCacheHas (line 2821) | function listCacheHas(key) {
function listCacheSet (line 2837) | function listCacheSet(key, value) {
function ListCache (line 2859) | function ListCache(entries) {
function stackClear (line 2886) | function stackClear() {
function stackDelete (line 2902) | function stackDelete(key) {
function stackGet (line 2921) | function stackGet(key) {
function stackHas (line 2936) | function stackHas(key) {
function getRawTag (line 2983) | function getRawTag(value) {
function objectToString$1 (line 3022) | function objectToString$1(value) {
function baseGetTag (line 3042) | function baseGetTag(value) {
function isObject$1 (line 3078) | function isObject$1(value) {
function isFunction (line 3108) | function isFunction(value) {
function isMasked (line 3138) | function isMasked(func) {
function toSource (line 3157) | function toSource(func) {
function baseIsNative (line 3204) | function baseIsNative(value) {
function getValue (line 3222) | function getValue(object, key) {
function getNative (line 3236) | function getNative(object, key) {
function hashClear (line 3260) | function hashClear() {
function hashDelete (line 3277) | function hashDelete(key) {
function hashGet (line 3303) | function hashGet(key) {
function hashHas (line 3329) | function hashHas(key) {
function hashSet (line 3349) | function hashSet(key, value) {
function Hash (line 3365) | function Hash(entries) {
function mapCacheClear (line 3392) | function mapCacheClear() {
function isKeyable (line 3410) | function isKeyable(value) {
function getMapData (line 3427) | function getMapData(map, key) {
function mapCacheDelete (line 3445) | function mapCacheDelete(key) {
function mapCacheGet (line 3462) | function mapCacheGet(key) {
function mapCacheHas (line 3477) | function mapCacheHas(key) {
function mapCacheSet (line 3493) | function mapCacheSet(key, value) {
function MapCache (line 3511) | function MapCache(entries) {
function stackSet (line 3544) | function stackSet(key, value) {
function Stack (line 3569) | function Stack(entries) {
function baseAssignValue (line 3602) | function baseAssignValue(object, key, value) {
function assignMergeValue (line 3626) | function assignMergeValue(object, key, value) {
function createBaseFor (line 3642) | function createBaseFor(fromRight) {
function cloneBuffer (line 3698) | function cloneBuffer(buffer, isDeep) {
function cloneArrayBuffer (line 3724) | function cloneArrayBuffer(arrayBuffer) {
function cloneTypedArray (line 3740) | function cloneTypedArray(typedArray, isDeep) {
function copyArray (line 3755) | function copyArray(source, array) {
function object (line 3780) | function object() {}
function overArg (line 3805) | function overArg(func, transform) {
function isPrototype (line 3828) | function isPrototype(value) {
function initCloneObject (line 3844) | function initCloneObject(object) {
function isObjectLike (line 3876) | function isObjectLike(value) {
function baseIsArguments (line 3892) | function baseIsArguments(value) {
function isLength (line 3988) | function isLength(value) {
function isArrayLike (line 4020) | function isArrayLike(value) {
function isArrayLikeObject (line 4051) | function isArrayLikeObject(value) {
function stubFalse (line 4070) | function stubFalse() {
function isPlainObject (line 4158) | function isPlainObject(value) {
function baseIsTypedArray (line 4223) | function baseIsTypedArray(value) {
function baseUnary (line 4237) | function baseUnary(func) {
function safeGet (line 4308) | function safeGet(object, key) {
function assignValue (line 4338) | function assignValue(object, key, value) {
function copyObject (line 4358) | function copyObject(source, props, object, customizer) {
function baseTimes (line 4395) | function baseTimes(n, iteratee) {
function isIndex (line 4421) | function isIndex(value, length) {
function arrayLikeKeys (line 4447) | function arrayLikeKeys(value, inherited) {
function nativeKeysIn (line 4485) | function nativeKeysIn(object) {
function baseKeysIn (line 4510) | function baseKeysIn(object) {
function keysIn (line 4550) | function keysIn(object) {
function toPlainObject (line 4580) | function toPlainObject(value) {
function baseMergeDeep (line 4601) | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customi...
function baseMerge (line 4676) | function baseMerge(object, source, srcIndex, customizer, stack) {
function identity (line 4716) | function identity(value) {
function apply$1 (line 4732) | function apply$1(func, thisArg, args) {
function overRest (line 4756) | function overRest(func, start, transform) {
function constant (line 4798) | function constant(value) {
function shortOut (line 4841) | function shortOut(func) {
function baseRest (line 4883) | function baseRest(func, start) {
function isIterateeCall (line 4899) | function isIterateeCall(value, index, object) {
function createAssigner (line 4922) | function createAssigner(assigner) {
function _objectWithoutPropertiesLoose (line 5046) | function _objectWithoutPropertiesLoose(source, excluded) {
function _objectWithoutProperties (line 5069) | function _objectWithoutProperties(source, excluded) {
function classTest (line 5510) | function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)...
function removeChildren (line 5521) | function removeChildren(e) {
function removeChildrenAndAdd (line 5527) | function removeChildrenAndAdd(parent, e) {
function elt (line 5531) | function elt(tag, content, className, style) {
function eltP (line 5540) | function eltP(tag, content, className, style) {
function contains (line 5563) | function contains(parent, child) {
function activeElt (line 5574) | function activeElt() {
function addClass (line 5589) | function addClass(node, cls) {
function joinClasses (line 5593) | function joinClasses(a, b) {
function bind (line 5606) | function bind(f) {
function copyObj (line 5611) | function copyObj(obj, target, overwrite) {
function countColumn (line 5621) | function countColumn(string, end, tabSize, startIndex, startValue) {
function indexOf (line 5660) | function indexOf(array, elt) {
function findColumn (line 5678) | function findColumn(string, goal, tabSize) {
function spaceStr (line 5693) | function spaceStr(n) {
function lst (line 5699) | function lst(arr) { return arr[arr.length-1] }
function map (line 5701) | function map(array, f) {
function insertSorted (line 5707) | function insertSorted(array, value, score) {
function nothing (line 5713) | function nothing() {}
function createObj (line 5715) | function createObj(base, props) {
function isWordCharBasic (line 5728) | function isWordCharBasic(ch) {
function isWordChar (line 5732) | function isWordChar(ch, helper) {
function isEmpty (line 5738) | function isEmpty(obj) {
function isExtendingChar (line 5749) | function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendi...
function skipExtendingChars (line 5752) | function skipExtendingChars(str, pos, dir) {
function findFirst (line 5760) | function findFirst(pred, from, to) {
function iterateBidiSections (line 5775) | function iterateBidiSections(order, from, to, f) {
function getBidiPartAt (line 5789) | function getBidiPartAt(order, ch, sticky) {
function charType (line 5835) | function charType(code) {
function BidiSpan (line 5848) | function BidiSpan(level, from, to) {
function getOrder (line 5981) | function getOrder(line, direction) {
function getHandlers (line 6005) | function getHandlers(emitter, type) {
function off (line 6009) | function off(emitter, type, f) {
function signal (line 6024) | function signal(emitter, type /*, values...*/) {
function signalDOMEvent (line 6034) | function signalDOMEvent(cm, e, override) {
function signalCursorActivity (line 6041) | function signalCursorActivity(cm) {
function hasHandler (line 6049) | function hasHandler(emitter, type) {
function eventMixin (line 6055) | function eventMixin(ctor) {
function e_preventDefault (line 6063) | function e_preventDefault(e) {
function e_stopPropagation (line 6067) | function e_stopPropagation(e) {
function e_defaultPrevented (line 6071) | function e_defaultPrevented(e) {
function e_stop (line 6074) | function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
function e_target (line 6076) | function e_target(e) {return e.target || e.srcElement}
function e_button (line 6077) | function e_button(e) {
function zeroWidthElement (line 6098) | function zeroWidthElement(measure) {
function hasBadBidiRects (line 6113) | function hasBadBidiRects(measure) {
function hasBadZoomedRects (line 6162) | function hasBadZoomedRects(measure) {
function defineMode (line 6176) | function defineMode(name, mode) {
function defineMIME (line 6182) | function defineMIME(mime, spec) {
function resolveMode (line 6188) | function resolveMode(spec) {
function getMode (line 6207) | function getMode(options, spec) {
function extendMode (line 6231) | function extendMode(mode, properties) {
function copyState (line 6236) | function copyState(mode, state) {
function innerMode (line 6250) | function innerMode(mode, state) {
function startState (line 6261) | function startState(mode, a1, a2) {
function getLine (line 6351) | function getLine(doc, n) {
function getBetween (line 6367) | function getBetween(doc, start, end) {
function getLines (line 6379) | function getLines(doc, from, to) {
function updateLineHeight (line 6387) | function updateLineHeight(line, height) {
function lineNo (line 6394) | function lineNo(line) {
function lineAtHeight (line 6408) | function lineAtHeight(chunk, h) {
function isLine (line 6428) | function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
function lineNumberFor (line 6430) | function lineNumberFor(options, i) {
function Pos (line 6435) | function Pos(line, ch, sticky) {
function cmp (line 6446) | function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
function equalCursorPos (line 6448) | function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b)...
function copyPos (line 6450) | function copyPos(x) {return Pos(x.line, x.ch)}
function maxPos (line 6451) | function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
function minPos (line 6452) | function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
function clipLine (line 6456) | function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.fi...
function clipPos (line 6457) | function clipPos(doc, pos) {
function clipToLen (line 6463) | function clipToLen(pos, linelen) {
function clipPosArray (line 6469) | function clipPosArray(doc, array) {
function highlightLine (line 6526) | function highlightLine(cm, line, context, forceToEnd) {
function getLineStyles (line 6571) | function getLineStyles(cm, line, updateFrontier) {
function getContextBefore (line 6587) | function getContextBefore(cm, n, precise) {
function processLine (line 6607) | function processLine(cm, text, context, startAt) {
function callBlankLine (line 6618) | function callBlankLine(mode, state) {
function readToken (line 6625) | function readToken(mode, stream, state, inner) {
function takeToken (line 6642) | function takeToken(cm, pos, precise, asArray) {
function extractLineClasses (line 6656) | function extractLineClasses(type, output) {
function runMode (line 6671) | function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
function findStartLine (line 6715) | function findStartLine(cm, n, precise) {
function retreatFrontier (line 6732) | function retreatFrontier(doc, n) {
function seeReadOnlySpans (line 6752) | function seeReadOnlySpans() {
function seeCollapsedSpans (line 6756) | function seeCollapsedSpans() {
function MarkedSpan (line 6762) | function MarkedSpan(marker, from, to) {
function getMarkedSpanFor (line 6768) | function getMarkedSpanFor(spans, marker) {
function removeMarkedSpan (line 6776) | function removeMarkedSpan(spans, span) {
function addMarkedSpan (line 6783) | function addMarkedSpan(line, span) {
function markedSpansBefore (line 6792) | function markedSpansBefore(old, startCh, isInsert) {
function markedSpansAfter (line 6804) | function markedSpansAfter(old, endCh, isInsert) {
function stretchSpansOverChange (line 6824) | function stretchSpansOverChange(doc, change) {
function clearEmptySpans (line 6886) | function clearEmptySpans(spans) {
function removeReadOnlyRanges (line 6897) | function removeReadOnlyRanges(doc, from, to) {
function detachMarkedSpans (line 6926) | function detachMarkedSpans(line) {
function attachMarkedSpans (line 6933) | function attachMarkedSpans(line, spans) {
function extraLeft (line 6942) | function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
function extraRight (line 6943) | function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
function compareCollapsedMarkers (line 6948) | function compareCollapsedMarkers(a, b) {
function collapsedSpanAtSide (line 6961) | function collapsedSpanAtSide(line, start) {
function collapsedSpanAtStart (line 6971) | function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, t...
function collapsedSpanAtEnd (line 6972) | function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, fal...
function collapsedSpanAround (line 6974) | function collapsedSpanAround(line, ch) {
function conflictingCollapsedRange (line 6987) | function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
function visualLine (line 7007) | function visualLine(line) {
function visualLineEnd (line 7014) | function visualLineEnd(line) {
function visualLineContinued (line 7023) | function visualLineContinued(line) {
function visualLineNo (line 7034) | function visualLineNo(doc, lineN) {
function visualLineEndNo (line 7042) | function visualLineEndNo(doc, lineN) {
function lineIsHidden (line 7054) | function lineIsHidden(doc, line) {
function lineIsHiddenInner (line 7065) | function lineIsHiddenInner(doc, line, span) {
function heightAtLine (line 7082) | function heightAtLine(lineObj) {
function lineLength (line 7104) | function lineLength(line) {
function findMaxLine (line 7123) | function findMaxLine(cm) {
function updateLine (line 7153) | function updateLine(line, text, markedSpans, estimateHeight) {
function cleanUpLine (line 7165) | function cleanUpLine(line) {
function interpretTokenStyle (line 7174) | function interpretTokenStyle(style, options) {
function buildLineContent (line 7186) | function buildLineContent(cm, lineView) {
function defaultSpecialCharPlaceholder (line 7244) | function defaultSpecialCharPlaceholder(ch) {
function buildToken (line 7253) | function buildToken(builder, text, style, startStyle, endStyle, css, att...
function splitSpaces (line 7320) | function splitSpaces(text, trailingBefore) {
function buildTokenBadBidi (line 7335) | function buildTokenBadBidi(inner, order) {
function buildCollapsedSpan (line 7355) | function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
function insertLineContent (line 7373) | function insertLineContent(line, builder, styles) {
function LineView (line 7452) | function LineView(doc, line, lineN) {
function buildViewArray (line 7464) | function buildViewArray(cm, from, to) {
function pushOperation (line 7476) | function pushOperation(op) {
function fireCallbacksForOps (line 7487) | function fireCallbacksForOps(group) {
function finishOperation (line 7503) | function finishOperation(op, endCb) {
function signalLater (line 7523) | function signalLater(emitter, type /*, values...*/) {
function fireOrphanDelayed (line 7543) | function fireOrphanDelayed() {
function updateLineForChanges (line 7552) | function updateLineForChanges(cm, lineView, lineN, dims) {
function ensureLineWrapped (line 7565) | function ensureLineWrapped(lineView) {
function updateLineBackground (line 7576) | function updateLineBackground(cm, lineView) {
function getLineContent (line 7591) | function getLineContent(cm, lineView) {
function updateLineText (line 7604) | function updateLineText(cm, lineView) {
function updateLineClasses (line 7619) | function updateLineClasses(cm, lineView) {
function updateLineGutter (line 7629) | function updateLineGutter(cm, lineView, lineN, dims) {
function updateLineWidgets (line 7667) | function updateLineWidgets(cm, lineView, dims) {
function buildLineElement (line 7678) | function buildLineElement(cm, lineView, lineN, dims) {
function insertLineWidgets (line 7692) | function insertLineWidgets(cm, lineView, dims) {
function insertLineWidgetsFor (line 7698) | function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
function positionLineWidget (line 7714) | function positionLineWidget(widget, node, lineView, dims) {
function widgetHeight (line 7732) | function widgetHeight(widget) {
function eventInWidget (line 7748) | function eventInWidget(display, e) {
function paddingTop (line 7758) | function paddingTop(display) {return display.lineSpace.offsetTop}
function paddingVert (line 7759) | function paddingVert(display) {return display.mover.offsetHeight - displ...
function paddingH (line 7760) | function paddingH(display) {
function scrollGap (line 7769) | function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
function displayWidth (line 7770) | function displayWidth(cm) {
function displayHeight (line 7773) | function displayHeight(cm) {
function ensureLineHeights (line 7781) | function ensureLineHeights(cm, lineView, rect) {
function mapFromLineView (line 7802) | function mapFromLineView(lineView, line, lineN) {
function updateExternalMeasurement (line 7815) | function updateExternalMeasurement(cm, line) {
function measureChar (line 7828) | function measureChar(cm, line, ch, bias) {
function findViewForLine (line 7833) | function findViewForLine(cm, lineN) {
function prepareMeasureForLine (line 7846) | function prepareMeasureForLine(cm, line) {
function measureCharPrepared (line 7868) | function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
function nodeAndOffsetInLineMap (line 7890) | function nodeAndOffsetInLineMap(map, ch, bias) {
function getUsefulRect (line 7928) | function getUsefulRect(rects, bias) {
function measureCharInner (line 7938) | function measureCharInner(cm, prepared, ch, bias) {
function maybeUpdateRectForZooming (line 7991) | function maybeUpdateRectForZooming(measure, rect) {
function clearLineMeasurementCacheFor (line 8001) | function clearLineMeasurementCacheFor(lineView) {
function clearLineMeasurementCache (line 8010) | function clearLineMeasurementCache(cm) {
function clearCaches (line 8017) | function clearCaches(cm) {
function pageScrollX (line 8024) | function pageScrollX() {
function pageScrollY (line 8031) | function pageScrollY() {
function widgetTopHeight (line 8036) | function widgetTopHeight(lineObj) {
function intoCoordSystem (line 8047) | function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
function fromCoordSystem (line 8069) | function fromCoordSystem(cm, coords, context) {
function charCoords (line 8086) | function charCoords(cm, pos, context, lineObj, bias) {
function cursorCoords (line 8107) | function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHei...
function estimateCoords (line 8138) | function estimateCoords(cm, pos) {
function PosWithInfo (line 8153) | function PosWithInfo(line, ch, sticky, outside, xRel) {
function coordsChar (line 8162) | function coordsChar(cm, x, y) {
function wrappedLineExtent (line 8182) | function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
function wrappedLineExtentChar (line 8190) | function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
function boxIsAfter (line 8198) | function boxIsAfter(box, x, y, left) {
function coordsCharInner (line 8202) | function coordsCharInner(cm, lineObj, lineNo, x, y) {
function coordsBidiPart (line 8269) | function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, ...
function coordsBidiPartWrapped (line 8293) | function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, or...
function textHeight (line 8328) | function textHeight(display) {
function charWidth (line 8348) | function charWidth(display) {
function getDimensions (line 8360) | function getDimensions(cm) {
function compensateForHScroll (line 8378) | function compensateForHScroll(display) {
function estimateHeight (line 8385) | function estimateHeight(cm) {
function estimateLineHeights (line 8403) | function estimateLineHeights(cm) {
function posFromMouse (line 8416) | function posFromMouse(cm, e, liberal, forRect) {
function findViewIndex (line 8434) | function findViewIndex(cm, n) {
function regChange (line 8451) | function regChange(cm, from, to, lendiff) {
function regLineChange (line 8516) | function regLineChange(cm, line, type) {
function resetView (line 8530) | function resetView(cm) {
function viewCuttingPoint (line 8536) | function viewCuttingPoint(cm, oldN, newN, dir) {
function adjustView (line 8563) | function adjustView(cm, from, to) {
function countDirtyView (line 8584) | function countDirtyView(cm) {
function updateSelection (line 8593) | function updateSelection(cm) {
function prepareSelection (line 8597) | function prepareSelection(cm, primary) {
function drawSelectionCursor (line 8618) | function drawSelectionCursor(cm, head, output) {
function cmpCoords (line 8636) | function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
function drawSelectionRange (line 8639) | function drawSelectionRange(cm, range, output) {
function restartBlink (line 8732) | function restartBlink(cm) {
function ensureFocus (line 8747) | function ensureFocus(cm) {
function delayBlurEvent (line 8751) | function delayBlurEvent(cm) {
function onFocus (line 8759) | function onFocus(cm, e) {
function onBlur (line 8778) | function onBlur(cm, e) {
function updateHeightsInViewport (line 8792) | function updateHeightsInViewport(cm) {
function updateWidgetHeight (line 8831) | function updateWidgetHeight(line) {
function visibleLines (line 8841) | function visibleLines(display, doc, viewport) {
function maybeScrollWindow (line 8866) | function maybeScrollWindow(cm, rect) {
function scrollPosIntoView (line 8883) | function scrollPosIntoView(cm, pos, end, margin) {
function scrollIntoView (line 8917) | function scrollIntoView(cm, rect) {
function calculateScrollPos (line 8927) | function calculateScrollPos(cm, rect) {
function addToScrollTop (line 8958) | function addToScrollTop(cm, top) {
function ensureCursorVisible (line 8966) | function ensureCursorVisible(cm) {
function scrollToCoords (line 8972) | function scrollToCoords(cm, x, y) {
function scrollToRange (line 8978) | function scrollToRange(cm, range) {
function resolveScrollToPos (line 8987) | function resolveScrollToPos(cm) {
function scrollToCoordsRange (line 8996) | function scrollToCoordsRange(cm, from, to, margin) {
function updateScrollTop (line 9008) | function updateScrollTop(cm, val) {
function setScrollTop (line 9016) | function setScrollTop(cm, val, forceScroll) {
function setScrollLeft (line 9026) | function setScrollLeft(cm, val, isScroller, forceScroll) {
function measureForScrollbars (line 9039) | function measureForScrollbars(cm) {
function maybeDisable (line 9131) | function maybeDisable() {
function updateScrollbars (line 9160) | function updateScrollbars(cm, measure) {
function updateScrollbarsInner (line 9174) | function updateScrollbarsInner(cm, measure) {
function initScrollbars (line 9196) | function initScrollbars(cm) {
function startOperation (line 9226) | function startOperation(cm) {
function endOperation (line 9248) | function endOperation(cm) {
function endOperations (line 9259) | function endOperations(group) {
function endOperation_R1 (line 9273) | function endOperation_R1(op) {
function endOperation_W1 (line 9286) | function endOperation_W1(op) {
function endOperation_R2 (line 9290) | function endOperation_R2(op) {
function endOperation_W2 (line 9311) | function endOperation_W2(op) {
function endOperation_finish (line 9336) | function endOperation_finish(op) {
function runInOp (line 9375) | function runInOp(cm, f) {
function operation (line 9382) | function operation(cm, f) {
function methodOp (line 9392) | function methodOp(f) {
function docMethodOp (line 9400) | function docMethodOp(f) {
function startWorker (line 9412) | function startWorker(cm, time) {
function highlightWorker (line 9417) | function highlightWorker(cm) {
function maybeClipScrollbars (line 9485) | function maybeClipScrollbars(cm) {
function selectionSnapshot (line 9496) | function selectionSnapshot(cm) {
function restoreSelection (line 9513) | function restoreSelection(snapshot) {
function updateDisplayIfNeeded (line 9530) | function updateDisplayIfNeeded(cm, update) {
function postUpdateDisplay (line 9602) | function postUpdateDisplay(cm, update) {
function updateDisplaySimple (line 9634) | function updateDisplaySimple(cm, viewport) {
function patchDisplay (line 9651) | function patchDisplay(cm, updateNumbersFrom, dims) {
function updateGutterSpace (line 9692) | function updateGutterSpace(display) {
function setDocumentHeight (line 9697) | function setDocumentHeight(cm, measure) {
function alignHorizontally (line 9705) | function alignHorizontally(cm) {
function maybeUpdateLineNumberWidth (line 9728) | function maybeUpdateLineNumberWidth(cm) {
function getGutters (line 9746) | function getGutters(gutters, lineNumbers) {
function renderGutters (line 9763) | function renderGutters(display) {
function updateGutters (line 9782) | function updateGutters(cm) {
function Display (line 9792) | function Display(place, doc, input, options) {
function wheelEventDelta (line 9915) | function wheelEventDelta(e) {
function wheelEventPixels (line 9922) | function wheelEventPixels(e) {
function onScrollWheel (line 9929) | function onScrollWheel(cm, e) {
function normalizeSelection (line 10060) | function normalizeSelection(cm, ranges, primIndex) {
function simpleSelection (line 10078) | function simpleSelection(anchor, head) {
function changeEnd (line 10084) | function changeEnd(change) {
function adjustForChange (line 10092) | function adjustForChange(pos, change) {
function computeSelAfterChange (line 10101) | function computeSelAfterChange(doc, change) {
function offsetPos (line 10111) | function offsetPos(pos, old, nw) {
function computeReplacedSel (line 10120) | function computeReplacedSel(doc, changes, hint) {
function loadMode (line 10141) | function loadMode(cm) {
function resetModeState (line 10146) | function resetModeState(cm) {
function isWholeLineUpdate (line 10162) | function isWholeLineUpdate(doc, change) {
function updateDoc (line 10168) | function updateDoc(doc, change, markedSpans, estimateHeight) {
function linkedDocs (line 10220) | function linkedDocs(doc, f, sharedHistOnly) {
function attachDoc (line 10235) | function attachDoc(cm, doc) {
function setDirectionClass (line 10247) | function setDirectionClass(cm) {
function directionChanged (line 10251) | function directionChanged(cm) {
function History (line 10258) | function History(startGen) {
function historyChangeFromChange (line 10275) | function historyChangeFromChange(doc, change) {
function clearSelectionEvents (line 10284) | function clearSelectionEvents(array) {
function lastChangeEvent (line 10294) | function lastChangeEvent(hist, force) {
function addChangeToHistory (line 10309) | function addChangeToHistory(doc, change, selAfter, opId) {
function selectionEventCanBeMerged (line 10352) | function selectionEventCanBeMerged(doc, origin, prev, sel) {
function addSelectionToHistory (line 10365) | function addSelectionToHistory(doc, sel, opId, options) {
function pushSelectionToHistory (line 10387) | function pushSelectionToHistory(sel, dest) {
function attachLocalSpans (line 10394) | function attachLocalSpans(doc, change, from, to) {
function removeClearedSpans (line 10405) | function removeClearedSpans(spans) {
function getOldSpans (line 10416) | function getOldSpans(doc, change) {
function mergeOldSpans (line 10429) | function mergeOldSpans(doc, change) {
function copyHistoryArray (line 10453) | function copyHistoryArray(events, newGroup, instantiateSel) {
function extendRange (line 10485) | function extendRange(range, head, other, extend) {
function extendSelection (line 10504) | function extendSelection(doc, head, other, options, extend) {
function extendSelections (line 10511) | function extendSelections(doc, heads, options) {
function replaceOneSelection (line 10521) | function replaceOneSelection(doc, i, range, options) {
function setSimpleSelection (line 10528) | function setSimpleSelection(doc, anchor, head, options) {
function filterSelectionChange (line 10534) | function filterSelectionChange(doc, sel, options) {
function setSelectionReplaceHistory (line 10551) | function setSelectionReplaceHistory(doc, sel, options) {
function setSelection (line 10562) | function setSelection(doc, sel, options) {
function setSelectionNoUndo (line 10567) | function setSelectionNoUndo(doc, sel, options) {
function setSelectionInner (line 10579) | function setSelectionInner(doc, sel) {
function reCheckSelection (line 10594) | function reCheckSelection(doc) {
function skipAtomicInSelection (line 10600) | function skipAtomicInSelection(doc, sel, bias, mayClear) {
function skipAtomicInner (line 10615) | function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
function skipAtomic (line 10655) | function skipAtomic(doc, pos, oldPos, bias, mayClear) {
function movePos (line 10668) | function movePos(doc, pos, dir, line) {
function selectAll (line 10680) | function selectAll(cm) {
function filterChange (line 10687) | function filterChange(doc, change, update) {
function makeChange (line 10714) | function makeChange(doc, change, ignoreReadOnly) {
function makeChangeInner (line 10736) | function makeChangeInner(doc, change) {
function makeChangeFromHistory (line 10754) | function makeChangeFromHistory(doc, type, allowSelectionOnly) {
function shiftDoc (line 10830) | function shiftDoc(doc, distance) {
function makeChangeSingleDoc (line 10846) | function makeChangeSingleDoc(doc, change, selAfter, spans) {
function makeChangeSingleDocInEditor (line 10882) | function makeChangeSingleDocInEditor(cm, change, spans) {
function replaceRange (line 10940) | function replaceRange(doc, code, from, to, origin) {
function rebaseHistSelSingle (line 10951) | function rebaseHistSelSingle(pos, from, to, diff) {
function rebaseHistArray (line 10967) | function rebaseHistArray(array, from, to, diff) {
function rebaseHist (line 10995) | function rebaseHist(hist, change) {
function changeLine (line 11004) | function changeLine(doc, handle, changeType, op) {
function LeafChunk (line 11026) | function LeafChunk(lines) {
function BranchChunk (line 11071) | function BranchChunk(children) {
function adjustScrollWhenAboveVisible (line 11220) | function adjustScrollWhenAboveVisible(cm, line, diff) {
function addLineWidget (line 11225) | function addLineWidget(doc, handle, node, options) {
function markText (line 11381) | function markText(doc, from, to, options, type) {
function markTextShared (line 11476) | function markTextShared(doc, from, to, options, type) {
function findSharedMarkers (line 11491) | function findSharedMarkers(doc) {
function copySharedMarkers (line 11495) | function copySharedMarkers(doc, markers) {
function detachSharedMarkers (line 11507) | function detachSharedMarkers(markers) {
function onDrop (line 11944) | function onDrop(e) {
function onDragStart (line 12015) | function onDragStart(cm, e) {
function onDragOver (line 12038) | function onDragOver(cm, e) {
function clearDragCursor (line 12050) | function clearDragCursor(cm) {
function forEachCodeMirror (line 12061) | function forEachCodeMirror(f) {
function ensureGlobalHandlers (line 12074) | function ensureGlobalHandlers() {
function registerGlobalHandlers (line 12079) | function registerGlobalHandlers() {
function onResize (line 12092) | function onResize(cm) {
function normalizeKeyName (line 12163) | function normalizeKeyName(name) {
function normalizeKeyMap (line 12187) | function normalizeKeyMap(keymap) {
function lookupKey (line 12214) | function lookupKey(key, map, handle, context) {
function isModifierKey (line 12233) | function isModifierKey(value) {
function addModifierNames (line 12238) | function addModifierNames(name, event, noShift) {
function keyName (line 12248) | function keyName(event, noShift) {
function getKeyMap (line 12258) | function getKeyMap(val) {
function deleteNearSelection (line 12264) | function deleteNearSelection(cm, compute) {
function moveCharLogically (line 12287) | function moveCharLogically(line, ch, dir) {
function moveLogically (line 12292) | function moveLogically(line, start, dir) {
function endOfLine (line 12297) | function endOfLine(visually, cm, lineObj, lineNo, dir) {
function moveVisually (line 12325) | function moveVisually(cm, line, start, dir) {
function lineStart (line 12537) | function lineStart(cm, lineN) {
function lineEnd (line 12543) | function lineEnd(cm, lineN) {
function lineStartSmart (line 12549) | function lineStartSmart(cm, pos) {
function doHandleBinding (line 12562) | function doHandleBinding(cm, bound, dropShift) {
function lookupKeyForEditor (line 12582) | function lookupKeyForEditor(cm, name, handle) {
function dispatchKey (line 12596) | function dispatchKey(cm, name, e, handle) {
function dispatchKeyInner (line 12614) | function dispatchKeyInner(cm, name, e, handle) {
function handleKeyBinding (line 12631) | function handleKeyBinding(cm, e) {
function handleCharBinding (line 12650) | function handleCharBinding(cm, e, ch) {
function onKeyDown (line 12655) | function onKeyDown(e) {
function showCrossHair (line 12679) | function showCrossHair(cm) {
function onKeyUp (line 12694) | function onKeyUp(e) {
function onKeyPress (line 12699) | function onKeyPress(e) {
function clickRepeat (line 12727) | function clickRepeat(pos, button) {
function onMouseDown (line 12748) | function onMouseDown(e) {
function handleMappedButton (line 12785) | function handleMappedButton(cm, button, pos, repeat, event) {
function configureMouse (line 12805) | function configureMouse(cm, repeat, event) {
function leftButtonDown (line 12818) | function leftButtonDown(cm, pos, repeat, event) {
function leftButtonStartDrag (line 12836) | function leftButtonStartDrag(cm, event, pos, behavior) {
function rangeForUnit (line 12875) | function rangeForUnit(cm, pos, unit) {
function leftButtonSelect (line 12884) | function leftButtonSelect(cm, event, start, behavior) {
function bidiSimplify (line 13021) | function bidiSimplify(cm, range) {
function gutterEvent (line 13056) | function gutterEvent(cm, e, type, prevent) {
function clickInGutter (line 13085) | function clickInGutter(cm, e) {
function onContextMenu (line 13094) | function onContextMenu(cm, e) {
function contextMenuInGutter (line 13100) | function contextMenuInGutter(cm, e) {
function themeChanged (line 13105) | function themeChanged(cm) {
function defineOptions (line 13116) | function defineOptions(CodeMirror) {
function dragDropChanged (line 13260) | function dragDropChanged(cm, value, old) {
function wrappingChanged (line 13273) | function wrappingChanged(cm) {
function CodeMirror (line 13291) | function CodeMirror(place, options) {
function registerEventHandlers (line 13368) | function registerEventHandlers(cm) {
function indentLine (line 13486) | function indentLine(cm, n, how, aggressive) {
function setLastCopied (line 13550) | function setLastCopied(newLastCopied) {
function applyTextInput (line 13554) | function applyTextInput(cm, inserted, deleted, sel, origin) {
function handlePaste (line 13602) | function handlePaste(e, cm) {
function triggerElectric (line 13612) | function triggerElectric(cm, inserted) {
function copyableRanges (line 13636) | function copyableRanges(cm) {
function disableBrowserMagic (line 13647) | function disableBrowserMagic(field, spellcheck, autocorrect, autocapital...
function hiddenTextarea (line 13653) | function hiddenTextarea() {
function addEditorMethods (line 13676) | function addEditorMethods(CodeMirror) {
function findPosH (line 14116) | function findPosH(doc, pos, dir, unit, visually) {
function findPosV (line 14182) | function findPosV(cm, pos, dir, unit) {
function belongsToInput (line 14220) | function belongsToInput(e) {
function onCopyCut (line 14253) | function onCopyCut(e) {
function poll (line 14420) | function poll() {
function posToDOM (line 14586) | function posToDOM(cm, pos) {
function isInGutter (line 14602) | function isInGutter(node) {
function badPos (line 14608) | function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
function domTextBetween (line 14610) | function domTextBetween(cm, from, to, fromLine, toLine) {
function domToPos (line 14663) | function domToPos(cm, node, offset) {
function locateNodeInLineView (line 14682) | function locateNodeInLineView(lineView, node, offset) {
function prepareCopyCut (line 14779) | function prepareCopyCut(e) {
function p (line 14936) | function p() {
function prepareSelectAllHack (line 15040) | function prepareSelectAllHack() {
function rehide (line 15053) | function rehide() {
function fromTextArea (line 15101) | function fromTextArea(textarea, options) {
function addLegacyProps (line 15158) | function addLegacyProps(CodeMirror) {
function inText (line 15315) | function inText(stream, state) {
function inTag (line 15363) | function inTag(stream, state) {
function inAttribute (line 15388) | function inAttribute(quote) {
function inBlock (line 15402) | function inBlock(style, terminator) {
function doctype (line 15415) | function doctype(depth) {
function Context (line 15436) | function Context(state, tagName, startOfLine) {
function popContext (line 15444) | function popContext(state) {
function maybePopContext (line 15447) | function maybePopContext(state, nextTagName) {
function baseState (line 15462) | function baseState(type, stream, state) {
function tagNameState (line 15472) | function tagNameState(type, stream, state) {
function closeTagNameState (line 15485) | function closeTagNameState(type, stream, state) {
function closeState (line 15507) | function closeState(type, _stream, state) {
function closeStateErr (line 15515) | function closeStateErr(type, stream, state) {
function attrState (line 15520) | function attrState(type, _stream, state) {
function attrEqState (line 15539) | function attrEqState(type, stream, state) {
function attrValueState (line 15544) | function attrValueState(type, stream, state) {
function attrContinuedState (line 15550) | function attrContinuedState(type, stream, state) {
function getMode (line 15893) | function getMode(name) {
function switchInline (line 15974) | function switchInline(stream, state, f) {
function switchBlock (line 15979) | function switchBlock(stream, state, f) {
function lineIsEmpty (line 15984) | function lineIsEmpty(line) {
function blankLine (line 15990) | function blankLine(state) {
function blockNormal (line 16027) | function blockNormal(stream, state) {
function htmlBlock (line 16158) | function htmlBlock(stream, state) {
function local (line 16173) | function local(stream, state) {
function getType (line 16198) | function getType(state) {
function handleText (line 16281) | function handleText(stream, state) {
function inlineNormal (line 16288) | function inlineNormal(stream, state) {
function linkInline (line 16518) | function linkInline(stream, state) {
function linkHref (line 16538) | function linkHref(stream, state) {
function getLinkHrefInside (line 16558) | function getLinkHrefInside(endChar) {
function footnoteLink (line 16576) | function footnoteLink(stream, state) {
function footnoteLinkInside (line 16587) | function footnoteLinkInside(stream, state) {
function footnoteUrl (line 16601) | function footnoteUrl(stream, state) {
function blankLine (line 16862) | function blankLine(state) {
function incrementRemainingMarkdownListNumbers (line 17037) | function incrementRemainingMarkdownListNumbers(cm, pos) {
function cmp (line 17083) | function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }
function Iter (line 17089) | function Iter(cm, line, ch, range) {
function tagAt (line 17096) | function tagAt(iter, ch) {
function nextLine (line 17101) | function nextLine(iter) {
function prevLine (line 17107) | function prevLine(iter) {
function toTagEnd (line 17114) | function toTagEnd(iter) {
function toTagStart (line 17125) | function toTagStart(iter) {
function toNextTag (line 17137) | function toNextTag(iter) {
function toPrevTag (line 17147) | function toPrevTag(iter) {
function findMatchingClose (line 17159) | function findMatchingClose(iter, tag) {
function findMatchingOpen (line 17180) | function findMatchingOpen(iter, tag) {
function autoCloseGT (line 17305) | function autoCloseGT(cm) {
function autoCloseCurrent (line 17358) | function autoCloseCurrent(cm, typingSlash) {
function autoCloseSlash (line 17397) | function autoCloseSlash(cm) {
function indexOf (line 17404) | function indexOf(collection, elt) {
function closingTagExists (line 17413) | function closingTagExists(cm, context, tagName, pos, newTag) {
function clear (line 17459) | function clear(cm) {
function doMatchTags (line 17465) | function doMatchTags(cm) {
function maybeUpdateMatch (line 17486) | function maybeUpdateMatch(cm) {
function regexpFlags (line 17509) | function regexpFlags(regexp) {
function ensureFlags (line 17516) | function ensureFlags(regexp, flags) {
function maybeMultiline (line 17523) | function maybeMultiline(regexp) {
function searchRegexpForward (line 17527) | function searchRegexpForward(doc, regexp, start) {
function searchRegexpForwardMultiline (line 17539) | function searchRegexpForwardMultiline(doc, regexp, start) {
function lastMatchIn (line 17569) | function lastMatchIn(string, regexp, endMargin) {
function searchRegexpBackward (line 17584) | function searchRegexpBackward(doc, regexp, start) {
function searchRegexpBackwardMultiline (line 17596) | function searchRegexpBackwardMultiline(doc, regexp, start) {
function adjustPos (line 17630) | function adjustPos(orig, folded, pos, foldFunc) {
function searchStringForward (line 17642) | function searchStringForward(doc, query, start, caseFold) {
function searchStringBackward (line 17670) | function searchStringBackward(doc, query, start, caseFold) {
function SearchCursor (line 17697) | function SearchCursor(doc, query, pos, options) {
function clearPlaceholder (line 17821) | function clearPlaceholder(cm) {
function setPlaceholder (line 17827) | function setPlaceholder(cm) {
function onComposition (line 17839) | function onComposition(cm) {
function onBlur (line 17851) | function onBlur(cm) {
function onChange (line 17854) | function onChange(cm) {
function isEmpty (line 17862) | function isEmpty(cm) {
function bracketRegex (line 17882) | function bracketRegex(config) {
function findMatchingBracket (line 17886) | function findMatchingBracket(cm, where, config) {
function scanForBracket (line 17917) | function scanForBracket(cm, where, dir, style, config) {
function matchBrackets (line 17944) | function matchBrackets(cm, autoclear, config) {
function doMatchBrackets (line 17973) | function doMatchBrackets(cm) {
function clear (line 17984) | function clear(cm) {
function findPosSubword (line 18039) | function findPosSubword(doc, start, dir) {
function moveSubword (line 18065) | function moveSubword(cm, dir) {
function insertLine (line 18123) | function insertLine(cm, above) {
function wordAt (line 18145) | function wordAt(cm, pos) {
function addCursorToSelection (line 18187) | function addCursorToSelection(cm, dir) {
function isSelectedRange (line 18208) | function isSelectedRange(ranges, from, to) {
function selectBetweenBrackets (line 18216) | function selectBetweenBrackets(cm) {
function puncType (line 18249) | function puncType(type) {
function sortLines (line 18360) | function sortLines(cm, caseSensitive) {
function modifyWordOrSelection (line 18462) | function modifyWordOrSelection(cm, mod) {
function getTarget (line 18560) | function getTarget(cm) {
function findAndGoTo (line 18571) | function findAndGoTo(cm, forward) {
function SearchBox (line 18773) | function SearchBox(cm) {
function setCssClass (line 19475) | function setCssClass(el, className, condition) {
function delayedCall (line 19481) | function delayedCall(fcn, defaultTimeout) {
function key (line 19515) | function key(str, event) {
function keyCheck (line 19601) | function keyCheck(str, event) {
function Annotation (line 19624) | function Annotation(cm, options) {
function getY (line 19679) | function getY(pos, top) {
function SearchAnnotation (line 19748) | function SearchAnnotation(cm, query, caseFold, options) {
function offsetLine (line 19788) | function offsetLine(line, changeStart, sizeChange) {
function _arrayWithHoles (line 19847) | function _arrayWithHoles(arr) {
function _iterableToArrayLimit (line 19869) | function _iterableToArrayLimit(arr, i) {
function _arrayLikeToArray (line 19969) | function _arrayLikeToArray(arr, len) {
function _unsupportedIterableToArray (line 19985) | function _unsupportedIterableToArray(o, minLen) {
function _nonIterableRest (line 20004) | function _nonIterableRest() {
function _slicedToArray (line 20014) | function _slicedToArray(arr, i) {
function _extends (line 21152) | function _extends() {
function mergeMarginBottom (line 21220) | function mergeMarginBottom(bottom, top) {
function mergeMarginTop (line 21238) | function mergeMarginTop(bottom, top) {
function getBlockTopAndHeightWithMargin (line 21262) | function getBlockTopAndHeightWithMargin(element) {
function elementsFromPoint (line 21318) | function elementsFromPoint(x, y) {
function getHTML (line 21360) | function getHTML(who, deep) {
function createElement (line 21387) | function createElement(tagName) {
function addEvent (line 21679) | function addEvent(elm, evType, fn, useCapture) {
function removeEvent (line 21694) | function removeEvent(elm, evType, fn, useCapture) {
function mitt (line 21735) | function mitt(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t...
function Event (line 21742) | function Event() {
function handleUpload (line 21811) | function handleUpload(editor) {
function handelParams (line 21886) | function handelParams(params) {
function compileRegExp (line 21931) | function compileRegExp(obj, flags, allowExtendedFlags) {
function isLookbehindSupported (line 21941) | function isLookbehindSupported() {
function getTableRule (line 21988) | function getTableRule() {
function getCodeBlockRule (line 22035) | function getCodeBlockRule() {
function getListFromStr (line 22060) | function getListFromStr(selection, type) {
function getPanelRule (line 22101) | function getPanelRule() {
function getDetailRule (line 22124) | function getDetailRule() {
function handleNewlineIndentList (line 22163) | function handleNewlineIndentList(cm) {
function handleCherryList (line 22168) | function handleCherryList(cm) {
function Editor (line 22218) | function Editor(options) {
function SyntaxBase (line 23070) | function SyntaxBase(editorConfig) {
function prependLineFeedForParagraph (line 23308) | function prependLineFeedForParagraph(match, processedContent) {
function calculateLinesOfParagraph (line 23335) | function calculateLinesOfParagraph(preLinesMatch, contentLines) {
function customizer (line 23370) | function customizer(objValue, srcValue) {
function testKeyInLocal (line 23380) | function testKeyInLocal(key) {
function saveIsClassicBrToLocal (line 23392) | function saveIsClassicBrToLocal(isClassicBr) {
function getIsClassicBrFromLocal (line 23401) | function getIsClassicBrFromLocal() {
function saveThemeToLocal (line 23415) | function saveThemeToLocal(theme) {
function getThemeFromLocal (line 23426) | function getThemeFromLocal() {
function changeTheme (line 23446) | function changeTheme($cherry) {
function ownKeys$1 (line 23491) | function ownKeys$1(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread (line 23493) | function _objectSpread(target) { for (var i = 1; i < arguments.length; i...
function escapeHTMLEntitiesWithoutSemicolon (line 23809) | function escapeHTMLEntitiesWithoutSemicolon(content) {
function escapeHTMLSpecialChar (line 23862) | function escapeHTMLSpecialChar(content, enableQuote) {
function unescapeHTMLSpecialChar (line 23877) | function unescapeHTMLSpecialChar(content) {
function escapeHTMLSpecialCharOnce (line 23886) | function escapeHTMLSpecialCharOnce(content, enableQuote) {
function convertHTMLNumberToName (line 23895) | function convertHTMLNumberToName(html) {
function unescapeHTMLNumberEntities (line 23901) | function unescapeHTMLNumberEntities(html) {
function unescapeHTMLHexEntities (line 23913) | function unescapeHTMLHexEntities(html) {
function isValidScheme (line 23927) | function isValidScheme(url) {
function encodeURIOnce (line 23949) | function encodeURIOnce(str) {
function _createSuper (line 23955) | function _createSuper(Derived) { var hasNativeReflectConstruct = _isNati...
function _isNativeReflectConstruct (line 23957) | function _isNativeReflectConstruct() { if (typeof Reflect === "undefined...
function ParagraphBase (line 23967) | function ParagraphBase() {
function _isNativeFunction (line 25195) | function _isNativeFunction(fn) {
function _isNativeReflectConstruct (line 25223) | function _isNativeReflectConstruct() {
function _construct (line 25242) | function _construct(Parent, args, Class) {
function _wrapNativeSuper (line 25267) | function _wrapNativeSuper(Class) {
function _createSuper$1 (line 25305) | function _createSuper$1(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$1 (line 25307) | function _isNativeReflectConstruct$1() { if (typeof Reflect === "undefin...
function NestedError (line 25358) | function NestedError(message, nested) {
function processWarning (line 25402) | function processWarning(type, objClass, index) {
function isHookValid (line 25420) | function isHookValid(HookClass) {
function isProtoOfSyntaxBase (line 25430) | function isProtoOfSyntaxBase(value) {
function isProtoOfParagraphBase (line 25440) | function isProtoOfParagraphBase(value) {
function isCustomSyntaxConfig (line 25450) | function isCustomSyntaxConfig(value) {
function isRegisteredCustomSyntaxClass (line 25465) | function isRegisteredCustomSyntaxClass(value) {
function HookCenter (line 25481) | function HookCenter(hooksConfig, editorConfig, cherry) {
function _arrayWithoutHoles (line 25726) | function _arrayWithoutHoles(arr) {
function _iterableToArray (line 25736) | function _iterableToArray(iter) {
function _nonIterableSpread (line 25746) | function _nonIterableSpread() {
function _toConsumableArray (line 25756) | function _toConsumableArray(arr) {
function _toArray (line 25766) | function _toArray(arr) {
function ownKeys$2 (line 25775) | function ownKeys$2(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread$1 (line 25777) | function _objectSpread$1(target) { for (var i = 1; i < arguments.length;...
function replaceStringByBuffer (line 25800) | function replaceStringByBuffer(str, buffer) {
function replaceLookbehind (line 25830) | function replaceLookbehind(str, regex, replacer) {
function _createSuper$2 (line 25880) | function _createSuper$2(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$2 (line 25882) | function _isNativeReflectConstruct$2() { if (typeof Reflect === "undefin...
function Color (line 25889) | function Color() {
function _createSuper$3 (line 25932) | function _createSuper$3(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$3 (line 25934) | function _isNativeReflectConstruct$3() { if (typeof Reflect === "undefin...
function BackgroundColor (line 25941) | function BackgroundColor() {
function _createSuper$4 (line 25984) | function _createSuper$4(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$4 (line 25986) | function _isNativeReflectConstruct$4() { if (typeof Reflect === "undefin...
function Size (line 25993) | function Size() {
function _createSuper$5 (line 26040) | function _createSuper$5(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$5 (line 26042) | function _isNativeReflectConstruct$5() { if (typeof Reflect === "undefin...
function Strikethrough (line 26052) | function Strikethrough() {
function _createSuper$6 (line 26124) | function _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$6 (line 26126) | function _isNativeReflectConstruct$6() { if (typeof Reflect === "undefin...
function Sup (line 26133) | function Sup() {
function _createSuper$7 (line 26176) | function _createSuper$7(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$7 (line 26178) | function _isNativeReflectConstruct$7() { if (typeof Reflect === "undefin...
function Sub (line 26185) | function Sub() {
function insertHighlightedCode (line 26813) | function insertHighlightedCode(highlightedCode) {
function Token (line 27011) | function Token(type, content, alias, matchedStr) {
function matchPattern (line 27118) | function matchPattern(pattern, pos, text, lookbehind) {
function matchGrammar (line 27144) | function matchGrammar(text, tokenList, grammar, startNode, startPos, rem...
function LinkedList (line 27304) | function LinkedList() {
function addAfter (line 27327) | function addAfter(list, node, value) {
function removeRange (line 27346) | function removeRange(list, node, count) {
function toArray (line 27360) | function toArray(list) {
function highlightAutomaticallyCallback (line 27406) | function highlightAutomaticallyCallback() {
function replace (line 27619) | function replace(pattern, replacements) {
function re (line 27630) | function re(pattern, replacements, flags) {
function nested (line 27641) | function nested(pattern, depthLog2) {
function keywordsToPattern (line 27662) | function keywordsToPattern(words) {
function createInterpolationInside (line 27924) | function createInterpolationInside(interpolation, interpolationRound) {
function re (line 28496) | function re(source, flags) {
function createValuePattern (line 28717) | function createValuePattern(value, flags) {
function createInline (line 28793) | function createInline(pattern) {
function walkTokens (line 29043) | function walkTokens(tokens) {
function textContent (line 29159) | function textContent(html) {
function getToken (line 29279) | function getToken(offset) {
function isTokenType (line 29290) | function isTokenType(types, offset) {
function findClosingBracket (line 29312) | function findClosingBracket(open, close) {
function addAlias (line 29342) | function addAlias(token, alias) {
function getPlaceholder (line 29883) | function getPlaceholder(language, index) {
function walkTokens (line 29947) | function walkTokens(tokens) {
function re (line 31492) | function re(source, flags) {
function ownKeys$3 (line 32181) | function ownKeys$3(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread$2 (line 32183) | function _objectSpread$2(target) { for (var i = 1; i < arguments.length;...
function _createSuper$8 (line 32185) | function _createSuper$8(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$8 (line 32187) | function _isNativeReflectConstruct$8() { if (typeof Reflect === "undefin...
function CodeBlock (line 32198) | function CodeBlock(_ref) {
function addBlockQuoteSignToResult (line 32514) | function addBlockQuoteSignToResult(result) {
function _createSuper$9 (line 32687) | function _createSuper$9(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$9 (line 32689) | function _isNativeReflectConstruct$9() { if (typeof Reflect === "undefin...
function InlineCode (line 32696) | function InlineCode() {
function isBuffer (line 32888) | function isBuffer (obj) {
function isSlowBuffer (line 32893) | function isSlowBuffer (obj) {
function urlProcessorProxy (line 33062) | function urlProcessorProxy(urlProcessor) {
function UrlCache (line 33074) | function UrlCache() {
function _createSuper$a (line 33174) | function _createSuper$a(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$a (line 33176) | function _isNativeReflectConstruct$a() { if (typeof Reflect === "undefin...
function Link (line 33183) | function Link(_ref) {
function _createSuper$b (line 33396) | function _createSuper$b(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$b (line 33398) | function _isNativeReflectConstruct$b() { if (typeof Reflect === "undefin...
function Emphasis (line 33405) | function Emphasis() {
function _createSuper$c (line 33536) | function _createSuper$c(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$c (line 33538) | function _isNativeReflectConstruct$c() { if (typeof Reflect === "undefin...
function Paragraph (line 33557) | function Paragraph(options) {
function get$1 (line 33654) | function get$1(target, propertyKey /* , receiver */) {
function _superPropBase (line 33690) | function _superPropBase(object, property) {
function _get (line 33705) | function _get() {
function _createSuper$d (line 33731) | function _createSuper$d(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$d (line 33733) | function _isNativeReflectConstruct$d() { if (typeof Reflect === "undefin...
function Header (line 33745) | function Header() {
function _createSuper$e (line 34017) | function _createSuper$e(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$e (line 34019) | function _isNativeReflectConstruct$e() { if (typeof Reflect === "undefin...
function Transfer (line 34026) | function Transfer() {
function ownKeys$4 (line 34137) | function ownKeys$4(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread$3 (line 34139) | function _objectSpread$3(target) { for (var i = 1; i < arguments.length;...
function _createSuper$f (line 34141) | function _createSuper$f(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$f (line 34143) | function _isNativeReflectConstruct$f() { if (typeof Reflect === "undefin...
function Table (line 34152) | function Table(_ref) {
function isBrowser (line 34503) | function isBrowser() {
function _createSuper$g (line 34507) | function _createSuper$g(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$g (line 34509) | function _isNativeReflectConstruct$g() { if (typeof Reflect === "undefin...
function Br (line 34516) | function Br(options) {
function _createSuper$h (line 34611) | function _createSuper$h(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$h (line 34613) | function _isNativeReflectConstruct$h() { if (typeof Reflect === "undefin...
function Hr (line 34623) | function Hr() {
function ownKeys$5 (line 34793) | function ownKeys$5(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread$4 (line 34795) | function _objectSpread$4(target) { for (var i = 1; i < arguments.length;...
function _createSuper$i (line 34797) | function _createSuper$i(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$i (line 34799) | function _isNativeReflectConstruct$i() { if (typeof Reflect === "undefin...
function Image (line 34849) | function Image(_ref) {
function ownKeys$6 (line 35013) | function ownKeys$6(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread$5 (line 35015) | function _objectSpread$5(target) { for (var i = 1; i < arguments.length;...
function _createSuper$j (line 35017) | function _createSuper$j(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$j (line 35019) | function _isNativeReflectConstruct$j() { if (typeof Reflect === "undefin...
function attrsToAttributeString (line 35024) | function attrsToAttributeString(object) {
function makeChecklist (line 35042) | function makeChecklist(text) {
function handleIndent (line 35051) | function handleIndent(str, node) {
function getListStyle (line 35064) | function getListStyle(m2) {
function handleMark (line 35089) | function handleMark(str, node) {
function List (line 35124) | function List(_ref) {
function _createSuper$k (line 35334) | function _createSuper$k(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$k (line 35336) | function _isNativeReflectConstruct$k() { if (typeof Reflect === "undefin...
function computeLeadingSpaces (line 35338) | function computeLeadingSpaces(leadingChars) {
function Blockquote (line 35356) | function Blockquote() {
function _createSuper$l (line 35469) | function _createSuper$l(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$l (line 35471) | function _isNativeReflectConstruct$l() { if (typeof Reflect === "undefin...
function AutoLink (line 35478) | function AutoLink(_ref) {
function LoadMathModule (line 35728) | function LoadMathModule() {
function _createSuper$m (line 35791) | function _createSuper$m(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$m (line 35793) | function _isNativeReflectConstruct$m() { if (typeof Reflect === "undefin...
function MathBlock (line 35806) | function MathBlock(_ref) {
function _createSuper$n (line 35921) | function _createSuper$n(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$n (line 35923) | function _isNativeReflectConstruct$n() { if (typeof Reflect === "undefin...
function InlineMath (line 35936) | function InlineMath(_ref) {
function _createSuper$o (line 36096) | function _createSuper$o(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$o (line 36098) | function _isNativeReflectConstruct$o() { if (typeof Reflect === "undefin...
function defaultLinkProcessor (line 36100) | function defaultLinkProcessor(link) {
function Toc (line 36124) | function Toc(_ref) {
function _createSuper$p (line 36470) | function _createSuper$p(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$p (line 36472) | function _isNativeReflectConstruct$p() { if (typeof Reflect === "undefin...
function Footnote (line 36479) | function Footnote(_ref) {
function _createSuper$q (line 36629) | function _createSuper$q(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$q (line 36631) | function _isNativeReflectConstruct$q() { if (typeof Reflect === "undefin...
function CommentReference (line 36648) | function CommentReference(_ref) {
function _typeof (line 36787) | function _typeof(obj) {
function _setPrototypeOf (line 36797) | function _setPrototypeOf(o, p) {
function _isNativeReflectConstruct (line 36806) | function _isNativeReflectConstruct() {
function _construct (line 36819) | function _construct(Parent, args, Class) {
function _toConsumableArray (line 36836) | function _toConsumableArray(arr) {
function _arrayWithoutHoles (line 36840) | function _arrayWithoutHoles(arr) {
function _iterableToArray (line 36844) | function _iterableToArray(iter) {
function _unsupportedIterableToArray (line 36848) | function _unsupportedIterableToArray(o, minLen) {
function _arrayLikeToArray (line 36857) | function _arrayLikeToArray(arr, len) {
function _nonIterableSpread (line 36865) | function _nonIterableSpread() {
function unapply (line 36916) | function unapply(func) {
function unconstruct (line 36925) | function unconstruct(func) {
function addToSet (line 36936) | function addToSet(set, array, transformCaseFunc) {
function clone (line 36971) | function clone(object) {
function lookupGetter (line 36988) | function lookupGetter(object, prop) {
function createDOMPurify (line 37095) | function createDOMPurify() {
function _createSuper$r (line 38462) | function _createSuper$r(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$r (line 38464) | function _isNativeReflectConstruct$r() { if (typeof Reflect === "undefin...
function HtmlBlock (line 38471) | function HtmlBlock() {
function ownKeys$7 (line 40399) | function ownKeys$7(object, enumerableOnly) { var keys = keys$3(object); ...
function _objectSpread$6 (line 40401) | function _objectSpread$6(target) { for (var i = 1; i < arguments.length;...
function _createSuper$s (line 40403) | function _createSuper$s(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$s (line 40405) | function _isNativeReflectConstruct$s() { if (typeof Reflect === "undefin...
function fromCodePoint$3 (line 40407) | function fromCodePoint$3() {
function Emoji (line 40447) | function Emoji() {
function _createSuper$t (line 40556) | function _createSuper$t(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$t (line 40558) | function _isNativeReflectConstruct$t() { if (typeof Reflect === "undefin...
function Underline (line 40565) | function Underline() {
function _createSuper$u (line 40601) | function _createSuper$u(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$u (line 40603) | function _isNativeReflectConstruct$u() { if (typeof Reflect === "undefin...
function HighLight (line 40610) | function HighLight() {
function arrayMap (line 40714) | function arrayMap(array, iteratee) {
function isSymbol$1 (line 40747) | function isSymbol$1(value) {
function baseToString (line 40769) | function baseToString(value) {
function toString$2 (line 40808) | function toString$2(value) {
function escapeRegExp (line 40836) | function escapeRegExp(string) {
function _createSuper$v (line 40853) | function _createSuper$v(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$v (line 40855) | function _isNativeReflectConstruct$v() { if (typeof Reflect === "undefin...
function Suggester (line 40885) | function Suggester(_ref) {
function SuggesterPanel (line 41144) | function SuggesterPanel() {
function isChildNode (line 41271) | function isChildNode(parent, node) {
function _createSuper$w (line 41643) | function _createSuper$w(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$w (line 41645) | function _isNativeReflectConstruct$w() { if (typeof Reflect === "undefin...
function Ruby (line 41652) | function Ruby() {
function _createSuper$x (line 41685) | function _createSuper$x(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$x (line 41687) | function _isNativeReflectConstruct$x() { if (typeof Reflect === "undefin...
function Panel (line 41707) | function Panel(options) {
function _createSuper$y (line 41868) | function _createSuper$y(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$y (line 41870) | function _isNativeReflectConstruct$y() { if (typeof Reflect === "undefin...
function Detail (line 41887) | function Detail() {
function Engine (line 42035) | function Engine(markdownParams, cherry) {
function isArray$9 (line 42267) | function isArray$9(obj) {
function isVirtualNode (line 42275) | function isVirtualNode(x) {
function isWidget (line 42281) | function isWidget(w) {
function isThunk (line 42287) | function isThunk(t) {
function isHook (line 42293) | function isHook(hook) {
function VirtualNode (line 42304) | function VirtualNode(tagName, properties, children, key, namespace) {
function VirtualText (line 42368) | function VirtualText(text) {
function isVirtualText (line 42377) | function isVirtualText(x) {
function parseTag (line 42493) | function parseTag(tag, props) {
function SoftSetHook (line 42541) | function SoftSetHook(value) {
function Individual (line 42563) | function Individual(key, value) {
function OneVersion (line 42575) | function OneVersion(moduleName, version, defaultValue) {
function EvStore (line 42599) | function EvStore(elem) {
function EvHook (line 42611) | function EvHook(value) {
function h (line 42635) | function h(tagName, properties, children) {
function addChild (line 42679) | function addChild(c, childNodes, tag, props) {
function transformProperties (line 42703) | function transformProperties(props) {
function isChild (line 42720) | function isChild(x) {
function isChildren (line 42724) | function isChildren(x) {
function UnexpectedVirtualElement (line 42728) | function UnexpectedVirtualElement(data) {
function errorString (line 42745) | function errorString(obj) {
function VirtualPatch (line 42767) | function VirtualPatch(type, vNode, patch) {
function handleThunk (line 42778) | function handleThunk(a, b) {
function renderThunk (line 42796) | function renderThunk(thunk, previous) {
function diffProps (line 42818) | function diffProps(a, b) {
function getPrototype$1 (line 42862) | function getPrototype$1(value) {
function diff (line 42874) | function diff(a, b) {
function walk (line 42880) | function walk(a, b, patch, index) {
function diffChildren (line 42944) | function diffChildren(a, b, patch, apply, index) {
function clearState (line 42985) | function clearState(vNode, patch, index) {
function destroyWidgets (line 42993) | function destroyWidgets(vNode, patch, index) {
function thunks (line 43020) | function thunks(a, b, patch, index) {
function hasPatches (line 43028) | function hasPatches(patch) {
function unhook (line 43039) | function unhook(vNode, patch, index) {
function undefinedKeys (line 43071) | function undefinedKeys(obj) {
function reorder (line 43082) | function reorder(aChildren, bChildren) {
function remove (line 43245) | function remove(arr, index, key) {
function keyIndex (line 43254) | function keyIndex(children) {
function appendPatch (line 43275) | function appendPatch(apply, patch) {
function applyProperties (line 43320) | function applyProperties(node, props, previous) {
function removeProperty (line 43343) | function removeProperty(node, propName, propValue, previous) {
function patchObject (line 43367) | function patchObject(node, props, previous, propName, propValue) {
function getPrototype$2 (line 43403) | function getPrototype$2(value) {
function createElement$1 (line 43415) | function createElement$1(vnode, opts) {
function domIndex (line 43461) | function domIndex(rootNode, tree, indices, nodes) {
function recurse (line 43470) | function recurse(rootNode, tree, indices, nodes, rootIndex) {
function indexInRange (line 43505) | function indexInRange(indices, left, right) {
function ascending (line 43533) | function ascending(a, b) {
function updateWidget (line 43539) | function updateWidget(a, b) {
function applyPatch (line 43553) | function applyPatch(vpatch$1, domNode, renderOptions) {
function removeNode (line 43583) | function removeNode(domNode, vNode) {
function insertNode (line 43595) | function insertNode(parentNode, vNode, renderOptions) {
function stringPatch (line 43605) | function stringPatch(domNode, leftVNode, vText, renderOptions) {
function widgetPatch (line 43623) | function widgetPatch(domNode, leftVNode, widget, renderOptions) {
function vNodePatch (line 43646) | function vNodePatch(domNode, leftVNode, vNode, renderOptions) {
function destroyWidget (line 43657) | function destroyWidget(domNode, w) {
function reorderChildren (line 43663) | function reorderChildren(domNode, moves) {
function replaceRoot (line 43688) | function replaceRoot(oldRoot, newRoot) {
function patch (line 43698) | function patch(rootNode, patches, renderOptions) {
function patchRecursive (line 43708) | function patchRecursive(rootNode, patches, renderOptions) {
function applyPatch$1 (line 43733) | function applyPatch$1(rootNode, domNode, patchList, renderOptions) {
function patchIndices (line 43759) | function patchIndices(patches) {
function MyersDiff (line 43774) | function MyersDiff(newObj, oldObj, getElement) {
function __extends (line 45739) | function __extends(d, b) {
function __awaiter (line 45758) | function __awaiter(thisArg, _arguments, P, generator) {
function __generator (line 45768) | function __generator(thisArg, body) {
function __spreadArray (line 45796) | function __spreadArray(to, from, pack) {
function Bounds (line 45807) | function Bounds(left, top, width, height) {
function Trie (line 46042) | function Trie(initialValue, errorValue, highStart, highValueIndex, index...
function Break (line 46510) | function Break(codePoints, lineBreak, start, end) {
function Tokenizer (line 46732) | function Tokenizer() {
method constructor (line 76037) | constructor(options, handler) {
method _err (line 76063) | _err(code) {
method getCurrentLocation (line 76068) | getCurrentLocation(offset) {
method _runParsingLoop (line 76081) | _runParsingLoop() {
method pause (line 76095) | pause() {
method resume (line 76098) | resume(writeCallback) {
method write (line 76111) | write(chunk, isLastChunk, writeCallback) {
method insertHtmlAtCurrentPos (line 76119) | insertHtmlAtCurrentPos(chunk) {
method _ensureHibernation (line 76125) | _ensureHibernation() {
method _consume (line 76134) | _consume() {
method _unconsume (line 76138) | _unconsume(count) {
method _reconsumeInState (line 76142) | _reconsumeInState(state) {
method _advanceBy (line 76146) | _advanceBy(count) {
method _consumeSequenceIfMatch (line 76152) | _consumeSequenceIfMatch(pattern, caseSensitive) {
method _createStartTagToken (line 76161) | _createStartTagToken() {
method _createEndTagToken (line 76172) | _createEndTagToken() {
method _createCommentToken (line 76183) | _createCommentToken(offset) {
method _createDoctypeToken (line 76190) | _createDoctypeToken(initialName) {
method _createCharacterToken (line 76200) | _createCharacterToken(type, chars) {
method _createAttr (line 76208) | _createAttr(attrNameFirstCh) {
method _leaveAttrName (line 76215) | _leaveAttrName() {
method _leaveAttrValue (line 76232) | _leaveAttrValue() {
method prepareToken (line 76240) | prepareToken(ct) {
method emitCurrentTagToken (line 76250) | emitCurrentTagToken() {
method emitCurrentComment (line 76269) | emitCurrentComment(ct) {
method emitCurrentDoctype (line 76274) | emitCurrentDoctype(ct) {
method _emitCurrentCharacterToken (line 76279) | _emitCurrentCharacterToken(nextLocation) {
method _emitEOFToken (line 76305) | _emitEOFToken() {
method _appendCharToCurrentCharacterToken (line 76325) | _appendCharToCurrentCharacterToken(type, ch) {
method _emitCodePoint (line 76339) | _emitCodePoint(cp) {
method _emitChars (line 76351) | _emitChars(ch) {
method _matchNamedCharacterReference (line 76355) | _matchNamedCharacterReference(cp) {
method _isCharacterReferenceInAttribute (line 76409) | _isCharacterReferenceInAttribute() {
method _flushCodePointConsumedAsCharacterReference (line 76414) | _flushCodePointConsumedAsCharacterReference(cp) {
method _callState (line 76423) | _callState(cp) {
method _stateData (line 76753) | _stateData(cp) {
method _stateRcdata (line 76780) | _stateRcdata(cp) {
method _stateRawtext (line 76807) | _stateRawtext(cp) {
method _stateScriptData (line 76829) | _stateScriptData(cp) {
method _statePlaintext (line 76851) | _statePlaintext(cp) {
method _stateTagOpen (line 76869) | _stateTagOpen(cp) {
method _stateEndTagOpen (line 76908) | _stateEndTagOpen(cp) {
method _stateTagName (line 76937) | _stateTagName(cp) {
method _stateRcdataLessThanSign (line 76973) | _stateRcdataLessThanSign(cp) {
method _stateRcdataEndTagOpen (line 76985) | _stateRcdataEndTagOpen(cp) {
method handleSpecialEndTag (line 76996) | handleSpecialEndTag(_cp) {
method _stateRcdataEndTagName (line 77031) | _stateRcdataEndTagName(cp) {
method _stateRawtextLessThanSign (line 77040) | _stateRawtextLessThanSign(cp) {
method _stateRawtextEndTagOpen (line 77052) | _stateRawtextEndTagOpen(cp) {
method _stateRawtextEndTagName (line 77065) | _stateRawtextEndTagName(cp) {
method _stateScriptDataLessThanSign (line 77074) | _stateScriptDataLessThanSign(cp) {
method _stateScriptDataEndTagOpen (line 77094) | _stateScriptDataEndTagOpen(cp) {
method _stateScriptDataEndTagName (line 77107) | _stateScriptDataEndTagName(cp) {
method _stateScriptDataEscapeStart (line 77116) | _stateScriptDataEscapeStart(cp) {
method _stateScriptDataEscapeStartDash (line 77128) | _stateScriptDataEscapeStartDash(cp) {
method _stateScriptDataEscaped (line 77140) | _stateScriptDataEscaped(cp) {
method _stateScriptDataEscapedDash (line 77168) | _stateScriptDataEscapedDash(cp) {
method _stateScriptDataEscapedDashDash (line 77198) | _stateScriptDataEscapedDashDash(cp) {
method _stateScriptDataEscapedLessThanSign (line 77232) | _stateScriptDataEscapedLessThanSign(cp) {
method _stateScriptDataEscapedEndTagOpen (line 77249) | _stateScriptDataEscapedEndTagOpen(cp) {
method _stateScriptDataEscapedEndTagName (line 77262) | _stateScriptDataEscapedEndTagName(cp) {
method _stateScriptDataDoubleEscapeStart (line 77271) | _stateScriptDataDoubleEscapeStart(cp) {
method _stateScriptDataDoubleEscaped (line 77287) | _stateScriptDataDoubleEscaped(cp) {
method _stateScriptDataDoubleEscapedDash (line 77316) | _stateScriptDataDoubleEscapedDash(cp) {
method _stateScriptDataDoubleEscapedDashDash (line 77347) | _stateScriptDataDoubleEscapedDashDash(cp) {
method _stateScriptDataDoubleEscapedLessThanSign (line 77382) | _stateScriptDataDoubleEscapedLessThanSign(cp) {
method _stateScriptDataDoubleEscapeEnd (line 77394) | _stateScriptDataDoubleEscapeEnd(cp) {
method _stateBeforeAttributeName (line 77410) | _stateBeforeAttributeName(cp) {
method _stateAttributeName (line 77441) | _stateAttributeName(cp) {
method _stateAfterAttributeName (line 77479) | _stateAfterAttributeName(cp) {
method _stateBeforeAttributeValue (line 77515) | _stateBeforeAttributeValue(cp) {
method _stateAttributeValueDoubleQuoted (line 77546) | _stateAttributeValueDoubleQuoted(cp) {
method _stateAttributeValueSingleQuoted (line 77574) | _stateAttributeValueSingleQuoted(cp) {
method _stateAttributeValueUnquoted (line 77602) | _stateAttributeValueUnquoted(cp) {
method _stateAfterAttributeValueQuoted (line 77649) | _stateAfterAttributeValueQuoted(cp) {
method _stateSelfClosingStartTag (line 77684) | _stateSelfClosingStartTag(cp) {
method _stateBogusComment (line 77707) | _stateBogusComment(cp) {
method _stateMarkupDeclarationOpen (line 77732) | _stateMarkupDeclarationOpen(cp) {
method _stateCommentStart (line 77764) | _stateCommentStart(cp) {
method _stateCommentStartDash (line 77785) | _stateCommentStartDash(cp) {
method _stateComment (line 77813) | _stateComment(cp) {
method _stateCommentLessThanSign (line 77843) | _stateCommentLessThanSign(cp) {
method _stateCommentLessThanSignBang (line 77863) | _stateCommentLessThanSignBang(cp) {
method _stateCommentLessThanSignBangDash (line 77874) | _stateCommentLessThanSignBangDash(cp) {
method _stateCommentLessThanSignBangDashDash (line 77885) | _stateCommentLessThanSignBangDashDash(cp) {
method _stateCommentEndDash (line 77894) | _stateCommentEndDash(cp) {
method _stateCommentEnd (line 77916) | _stateCommentEnd(cp) {
method _stateCommentEndBang (line 77947) | _stateCommentEndBang(cp) {
method _stateDoctype (line 77976) | _stateDoctype(cp) {
method _stateBeforeDoctypeName (line 78008) | _stateBeforeDoctypeName(cp) {
method _stateDoctypeName (line 78054) | _stateDoctypeName(cp) {
method _stateAfterDoctypeName (line 78088) | _stateAfterDoctypeName(cp) {
method _stateAfterDoctypePublicKeyword (line 78129) | _stateAfterDoctypePublicKeyword(cp) {
method _stateBeforeDoctypePublicIdentifier (line 78175) | _stateBeforeDoctypePublicIdentifier(cp) {
method _stateDoctypePublicIdentifierDoubleQuoted (line 78219) | _stateDoctypePublicIdentifierDoubleQuoted(cp) {
method _stateDoctypePublicIdentifierSingleQuoted (line 78252) | _stateDoctypePublicIdentifierSingleQuoted(cp) {
method _stateAfterDoctypePublicIdentifier (line 78285) | _stateAfterDoctypePublicIdentifier(cp) {
method _stateBetweenDoctypePublicAndSystemIdentifiers (line 78329) | _stateBetweenDoctypePublicAndSystemIdentifiers(cp) {
method _stateAfterDoctypeSystemKeyword (line 78371) | _stateAfterDoctypeSystemKeyword(cp) {
method _stateBeforeDoctypeSystemIdentifier (line 78417) | _stateBeforeDoctypeSystemIdentifier(cp) {
method _stateDoctypeSystemIdentifierDoubleQuoted (line 78461) | _stateDoctypeSystemIdentifierDoubleQuoted(cp) {
method _stateDoctypeSystemIdentifierSingleQuoted (line 78494) | _stateDoctypeSystemIdentifierSingleQuoted(cp) {
method _stateAfterDoctypeSystemIdentifier (line 78527) | _stateAfterDoctypeSystemIdentifier(cp) {
method _stateBogusDoctype (line 78558) | _stateBogusDoctype(cp) {
method _stateCdataSection (line 78580) | _stateCdataSection(cp) {
method _stateCdataSectionBracket (line 78598) | _stateCdataSectionBracket(cp) {
method _stateCdataSectionEnd (line 78610) | _stateCdataSectionEnd(cp) {
method _stateCharacterReference (line 78629) | _stateCharacterReference(cp) {
method _stateNamedCharacterReference (line 78644) | _stateNamedCharacterReference(cp) {
method _stateAmbiguousAmpersand (line 78662) | _stateAmbiguousAmpersand(cp) {
method _stateNumericCharacterReference (line 78675) | _stateNumericCharacterReference(cp) {
method _stateHexademicalCharacterReferenceStart (line 78687) | _stateHexademicalCharacterReferenceStart(cp) {
method _stateDecimalCharacterReferenceStart (line 78702) | _stateDecimalCharacterReferenceStart(cp) {
method _stateHexademicalCharacterReference (line 78716) | _stateHexademicalCharacterReference(cp) {
method _stateDecimalCharacterReference (line 78737) | _stateDecimalCharacterReference(cp) {
method _stateNumericCharacterReferenceEnd (line 78752) | _stateNumericCharacterReferenceEnd() {
function Parser (line 47172) | function Parser(tokens) {
method constructor (line 79770) | constructor(options, document, fragmentContext = null, scriptHandler =...
method parse (line 79809) | static parse(html, options) {
method getFragmentParser (line 79814) | static getFragmentParser(fragmentContext, options) {
method getFragment (line 79836) | getFragment() {
method _err (line 79843) | _err(token, code, beforeToken) {
method onItemPush (line 79860) | onItemPush(node, tid, isTop) {
method onItemPop (line 79866) | onItemPop(node, isTop) {
method _setContextModes (line 79885) | _setContextModes(current, tid) {
method _switchToTextParsing (line 79890) | _switchToTextParsing(currentToken, nextTokenizerState) {
method switchToPlaintextParsing (line 79896) | switchToPlaintextParsing() {
method _getAdjustedCurrentElement (line 79902) | _getAdjustedCurrentElement() {
method _findFormInFragmentContext (line 79907) | _findFormInFragmentContext() {
method _initTokenizerForFragmentParsing (line 79917) | _initTokenizerForFragmentParsing() {
method _setDocumentType (line 79948) | _setDocumentType(token) {
method _attachElementToTree (line 79961) | _attachElementToTree(element, location) {
method _appendElement (line 79977) | _appendElement(token, namespaceURI) {
method _insertElement (line 79981) | _insertElement(token, namespaceURI) {
method _insertFakeElement (line 79986) | _insertFakeElement(tagName, tagID) {
method _insertTemplate (line 79991) | _insertTemplate(token) {
method _insertFakeRootElement (line 80000) | _insertFakeRootElement() {
method _appendCommentNode (line 80007) | _appendCommentNode(token, parent) {
method _insertCharacters (line 80014) | _insertCharacters(token) {
method _adoptNodes (line 80045) | _adoptNodes(donor, recipient) {
method _setEndLocation (line 80051) | _setEndLocation(element, closingToken) {
method shouldProcessStartTagTokenInForeignContent (line 80074) | shouldProcessStartTagTokenInForeignContent(token) {
method _processToken (line 80100) | _processToken(token) {
method _isIntegrationPoint (line 80137) | _isIntegrationPoint(tid, element, foreignNS) {
method _reconstructActiveFormattingElements (line 80143) | _reconstructActiveFormattingElements() {
method _closeTableCell (line 80156) | _closeTableCell() {
method _closePElement (line 80162) | _closePElement() {
method _resetInsertionMode (line 80167) | _resetInsertionMode() {
method _resetInsertionModeForSelect (line 80220) | _resetInsertionModeForSelect(selectIdx) {
method _isElementCausesFosterParenting (line 80236) | _isElementCausesFosterParenting(tn) {
method _shouldFosterParentOnInsertion (line 80239) | _shouldFosterParentOnInsertion() {
method _findFosterParentingLocation (line 80242) | _findFosterParentingLocation() {
method _fosterParentElement (line 80263) | _fosterParentElement(element) {
method _isSpecialElement (line 80273) | _isSpecialElement(element, id) {
method onCharacter (line 80277) | onCharacter(token) {
method onNullCharacter (line 80333) | onNullCharacter(token) {
method onComment (line 80378) | onComment(token) {
method onDoctype (line 80418) | onDoctype(token) {
method onStartTag (line 80436) | onStartTag(token) {
method _processStartTag (line 80454) | _processStartTag(token) {
method _startTagOutsideForeignContent (line 80462) | _startTagOutsideForeignContent(token) {
method onEndTag (line 80533) | onEndTag(token) {
method _endTagOutsideForeignContent (line 80543) | _endTagOutsideForeignContent(token) {
method onEof (line 80614) | onEof(token) {
method onWhitespaceCharacter (line 80664) | onWhitespaceCharacter(token) {
function hue2rgb (line 47504) | function hue2rgb(t1, t2, hue) {
function isSupportedImage (line 48167) | function isSupportedImage(value) {
function CSSParsedDeclaration (line 49321) | function CSSParsedDeclaration(context, declaration) {
function CSSParsedPseudoDeclaration (line 49420) | function CSSParsedPseudoDeclaration(context, declaration) {
function CSSParsedCounterDeclaration (line 49427) | function CSSParsedCounterDeclaration(context, declaration) {
function ElementContainer (line 49492) | function ElementContainer(context, element) {
function Trie (line 49660) | function Trie(initialValue, errorValue, highStart, highValueIndex, index...
method SUPPORT_RANGE_BOUNDS (line 50034) | get SUPPORT_RANGE_BOUNDS() {
method SUPPORT_WORD_BREAKING (line 50039) | get SUPPORT_WORD_BREAKING() {
method SUPPORT_SVG_DRAWING (line 50044) | get SUPPORT_SVG_DRAWING() {
method SUPPORT_FOREIGNOBJECT_DRAWING (line 50049) | get SUPPORT_FOREIGNOBJECT_DRAWING() {
method SUPPORT_CORS_IMAGES (line 50056) | get SUPPORT_CORS_IMAGES() {
method SUPPORT_RESPONSE_TYPE (line 50061) | get SUPPORT_RESPONSE_TYPE() {
method SUPPORT_CORS_XHR (line 50066) | get SUPPORT_CORS_XHR() {
method SUPPORT_NATIVE_TEXT_SEGMENTATION (line 50071) | get SUPPORT_NATIVE_TEXT_SEGMENTATION() {
function TextBounds (line 50080) | function TextBounds(text, bounds) {
function TextContainer (line 50207) | function TextContainer(context, node, styles) {
function ImageElementContainer (line 50235) | function ImageElementContainer(context, img) {
function CanvasElementContainer (line 50248) | function CanvasElementContainer(context, canvas) {
function SVGElementContainer (line 50260) | function SVGElementContainer(context, img) {
function LIElementContainer (line 50277) | function LIElementContainer(context, element) {
function OLElementContainer (line 50287) | function OLElementContainer(context, element) {
function InputElementContainer (line 50330) | function InputElementContainer(context, input) {
function SelectElementContainer (line 50379) | function SelectElementContainer(context, element) {
function TextareaElementContainer (line 50390) | function TextareaElementContainer(context, element) {
function IFrameElementContainer (line 50400) | function IFrameElementContainer(context, iframe) {
function CounterState (line 50539) | function CounterState() {
function DocumentCloner (line 50907) | function DocumentCloner(context, element, options) {
function CacheStorage (line 51385) | function CacheStorage() {
function Cache (line 51407) | function Cache(context, _options) {
function Vector (line 51541) | function Vector(x, y) {
function BezierCurve (line 51556) | function BezierCurve(start, startControl, endControl, end) {
function BoundCurves (line 51583) | function BoundCurves(element) {
function TransformEffect (line 51763) | function TransformEffect(offsetX, offsetY, matrix) {
function ClipEffect (line 51773) | function ClipEffect(path, target) {
function OpacityEffect (line 51781) | function OpacityEffect(opacity) {
function StackingContext (line 51817) | function StackingContext(container) {
function ElementPaint (line 51830) | function ElementPaint(container, parent) {
function FontMetrics (line 52263) | function FontMetrics(document) {
function Renderer (line 52312) | function Renderer(context, options) {
function CanvasRenderer (line 52322) | function CanvasRenderer(context, options) {
function ForeignObjectRenderer (line 53269) | function ForeignObjectRenderer(context, options) {
function Logger (line 53317) | function Logger(_a) {
function Context (line 53396) | function Context(options, windowBounds) {
function exportPDF (line 53627) | function exportPDF(previeweDom, fileName) {
function exportScreenShot (line 53646) | function exportScreenShot(previeweDom, fileName) {
function exportMarkdownFile (line 53672) | function exportMarkdownFile(markdownText, fileName) {
function exportHTMLFile (line 53690) | function exportHTMLFile(HTMLText, fileName) {
function TableHandler (line 54240) | function TableHandler(trigger, target, container, previewerDom, codeMirr...
function drawioDialog (line 54989) | function drawioDialog() {
function copyToClip (line 55024) | function copyToClip(str) {
function trimmedEndIndex (line 55069) | function trimmedEndIndex(string) {
function baseTrim (line 55088) | function baseTrim(string) {
function toNumber (line 55134) | function toNumber(value) {
function debounce (line 55218) | function debounce(func, wait, options) {
function PreviewerBubble (line 55354) | function PreviewerBubble(previewer) {
function LazyLoadImg (line 56068) | function LazyLoadImg(options, previewer) {
function Previewer (line 56542) | function Previewer(options) {
function getPosition (line 57714) | function getPosition(targetDom) {
function MenuBase (line 57759) | function MenuBase($cherry) {
function _createSuper$z (line 58178) | function _createSuper$z(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$z (line 58180) | function _isNativeReflectConstruct$z() { if (typeof Reflect === "undefin...
function Bold (line 58190) | function Bold($cherry) {
function _createSuper$A (line 58264) | function _createSuper$A(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$A (line 58266) | function _isNativeReflectConstruct$A() { if (typeof Reflect === "undefin...
function Italic (line 58276) | function Italic($cherry) {
function _createSuper$B (line 58350) | function _createSuper$B(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$B (line 58352) | function _isNativeReflectConstruct$B() { if (typeof Reflect === "undefin...
function Split (line 58363) | function Split($cherry) {
function getSelection (line 58417) | function getSelection(cm, selection) {
function _createSuper$C (line 58468) | function _createSuper$C(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$C (line 58470) | function _isNativeReflectConstruct$C() { if (typeof Reflect === "undefin...
function Strikethrough (line 58480) | function Strikethrough($cherry) {
function _createSuper$D (line 58552) | function _createSuper$D(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$D (line 58554) | function _isNativeReflectConstruct$D() { if (typeof Reflect === "undefin...
function Sub (line 58564) | function Sub($cherry) {
function _createSuper$E (line 58622) | function _createSuper$E(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$E (line 58624) | function _isNativeReflectConstruct$E() { if (typeof Reflect === "undefin...
function Sup (line 58634) | function Sup($cherry) {
function _createSuper$F (line 58692) | function _createSuper$F(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$F (line 58694) | function _isNativeReflectConstruct$F() { if (typeof Reflect === "undefin...
function Color (line 58704) | function Color($cherry) {
function BubbleColor (line 58838) | function BubbleColor($cherry) {
function _createSuper$G (line 58970) | function _createSuper$G(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$G (line 58972) | function _isNativeReflectConstruct$G() { if (typeof Reflect === "undefin...
function Header (line 58982) | function Header($cherry) {
function BubbleTableMenu (line 59145) | function BubbleTableMenu(_ref, className) {
function _createSuper$H (line 59307) | function _createSuper$H(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$H (line 59309) | function _isNativeReflectConstruct$H() { if (typeof Reflect === "undefin...
function Insert (line 59320) | function Insert($cherry) {
function _createSuper$I (line 59551) | function _createSuper$I(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$I (line 59553) | function _isNativeReflectConstruct$I() { if (typeof Reflect === "undefin...
function List (line 59563) | function List($cherry) {
function _createSuper$J (line 59631) | function _createSuper$J(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$J (line 59633) | function _isNativeReflectConstruct$J() { if (typeof Reflect === "undefin...
function Ol (line 59643) | function Ol($cherry) {
function _createSuper$K (line 59683) | function _createSuper$K(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$K (line 59685) | function _isNativeReflectConstruct$K() { if (typeof Reflect === "undefin...
function Ul (line 59695) | function Ul($cherry) {
function _createSuper$L (line 59735) | function _createSuper$L(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$L (line 59737) | function _isNativeReflectConstruct$L() { if (typeof Reflect === "undefin...
function Checklist (line 59747) | function Checklist($cherry) {
function _createSuper$M (line 59787) | function _createSuper$M(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$M (line 59789) | function _isNativeReflectConstruct$M() { if (typeof Reflect === "undefin...
function generateExample (line 59791) | function generateExample(title, mermaidCode) {
function Graph (line 59814) | function Graph($cherry) {
function _createSuper$N (line 59912) | function _createSuper$N(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$N (line 59914) | function _isNativeReflectConstruct$N() { if (typeof Reflect === "undefin...
function Size (line 59921) | function Size($cherry) {
function _createSuper$O (line 60047) | function _createSuper$O(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$O (line 60049) | function _isNativeReflectConstruct$O() { if (typeof Reflect === "undefin...
function H1 (line 60059) | function H1($cherry) {
function _createSuper$P (line 60135) | function _createSuper$P(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$P (line 60137) | function _isNativeReflectConstruct$P() { if (typeof Reflect === "undefin...
function H2 (line 60147) | function H2($cherry) {
function _createSuper$Q (line 60223) | function _createSuper$Q(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$Q (line 60225) | function _isNativeReflectConstruct$Q() { if (typeof Reflect === "undefin...
function H3 (line 60235) | function H3($cherry) {
function _createSuper$R (line 60311) | function _createSuper$R(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$R (line 60313) | function _isNativeReflectConstruct$R() { if (typeof Reflect === "undefin...
function Quote (line 60323) | function Quote($cherry) {
function _createSuper$S (line 60369) | function _createSuper$S(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$S (line 60371) | function _isNativeReflectConstruct$S() { if (typeof Reflect === "undefin...
function QuickTable (line 60383) | function QuickTable($cherry) {
function _createSuper$T (line 60413) | function _createSuper$T(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$T (line 60415) | function _isNativeReflectConstruct$T() { if (typeof Reflect === "undefin...
function TogglePreview (line 60426) | function TogglePreview($cherry) {
function _createSuper$U (line 60506) | function _createSuper$U(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$U (line 60508) | function _isNativeReflectConstruct$U() { if (typeof Reflect === "undefin...
function FullScreen (line 60518) | function FullScreen($cherry) {
function _createSuper$V (line 60563) | function _createSuper$V(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$V (line 60565) | function _isNativeReflectConstruct$V() { if (typeof Reflect === "undefin...
function Undo (line 60576) | function Undo($cherry) {
function _createSuper$W (line 60598) | function _createSuper$W(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$W (line 60600) | function _isNativeReflectConstruct$W() { if (typeof Reflect === "undefin...
function Redo (line 60611) | function Redo($cherry) {
function _createSuper$X (line 60637) | function _createSuper$X(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$X (line 60639) | function _isNativeReflectConstruct$X() { if (typeof Reflect === "undefin...
function Code (line 60649) | function Code($cherry) {
function _createSuper$Y (line 60692) | function _createSuper$Y(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$Y (line 60694) | function _isNativeReflectConstruct$Y() { if (typeof Reflect === "undefin...
function CodeTheme (line 60705) | function CodeTheme($cherry) {
function _createSuper$Z (line 60772) | function _createSuper$Z(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$Z (line 60774) | function _isNativeReflectConstruct$Z() { if (typeof Reflect === "undefin...
function Export (line 60781) | function Export($cherry) {
function _createSuper$_ (line 60844) | function _createSuper$_(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$_ (line 60846) | function _isNativeReflectConstruct$_() { if (typeof Reflect === "undefin...
function Settings (line 60859) | function Settings($cherry) {
function _createSuper$$ (line 61094) | function _createSuper$$(Derived) { var hasNativeReflectConstruct = _isNa...
function _isNativeReflectConstruct$$ (line 61096) | function _isNativeReflectConstruct$$() { if (typeof Reflect === "undefin...
function Underline (line 61106) | function Underline($cherry) {
function _createSuper$10 (line 61174) | function _createSuper$10(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$10 (line 61176) | function _isNativeReflectConstruct$10() { if (typeof Reflect === "undefi...
function SwitchModel (line 61188) | function SwitchModel($cherry) {
function _createSuper$11 (line 61242) | function _createSuper$11(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$11 (line 61244) | function _isNativeReflectConstruct$11() { if (typeof Reflect === "undefi...
function Image (line 61254) | function Image($cherry) {
function _createSuper$12 (line 61326) | function _createSuper$12(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$12 (line 61328) | function _isNativeReflectConstruct$12() { if (typeof Reflect === "undefi...
function Audio (line 61338) | function Audio($cherry) {
function _createSuper$13 (line 61401) | function _createSuper$13(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$13 (line 61403) | function _isNativeReflectConstruct$13() { if (typeof Reflect === "undefi...
function Video (line 61413) | function Video($cherry) {
function _createSuper$14 (line 61476) | function _createSuper$14(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$14 (line 61478) | function _isNativeReflectConstruct$14() { if (typeof Reflect === "undefi...
function Br (line 61488) | function Br($cherry) {
function _createSuper$15 (line 61516) | function _createSuper$15(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$15 (line 61518) | function _isNativeReflectConstruct$15() { if (typeof Reflect === "undefi...
function Hr (line 61528) | function Hr($cherry) {
function _createSuper$16 (line 61557) | function _createSuper$16(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$16 (line 61559) | function _isNativeReflectConstruct$16() { if (typeof Reflect === "undefi...
function Formula (line 61569) | function Formula($cherry) {
function _createSuper$17 (line 61614) | function _createSuper$17(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$17 (line 61616) | function _isNativeReflectConstruct$17() { if (typeof Reflect === "undefi...
function Link (line 61626) | function Link($cherry) {
function _createSuper$18 (line 61672) | function _createSuper$18(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$18 (line 61674) | function _isNativeReflectConstruct$18() { if (typeof Reflect === "undefi...
function Table (line 61684) | function Table($cherry) {
function _createSuper$19 (line 61745) | function _createSuper$19(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$19 (line 61747) | function _isNativeReflectConstruct$19() { if (typeof Reflect === "undefi...
function Toc (line 61757) | function Toc($cherry) {
function _createSuper$1a (line 61786) | function _createSuper$1a(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1a (line 61788) | function _isNativeReflectConstruct$1a() { if (typeof Reflect === "undefi...
function LineTable (line 61798) | function LineTable($cherry) {
function _createSuper$1b (line 61828) | function _createSuper$1b(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1b (line 61830) | function _isNativeReflectConstruct$1b() { if (typeof Reflect === "undefi...
function BrTable (line 61840) | function BrTable($cherry) {
function _createSuper$1c (line 61870) | function _createSuper$1c(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1c (line 61872) | function _isNativeReflectConstruct$1c() { if (typeof Reflect === "undefi...
function Pdf (line 61882) | function Pdf($cherry) {
function _createSuper$1d (line 61945) | function _createSuper$1d(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1d (line 61947) | function _isNativeReflectConstruct$1d() { if (typeof Reflect === "undefi...
function File (line 61957) | function File($cherry) {
function _createSuper$1e (line 62020) | function _createSuper$1e(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1e (line 62022) | function _isNativeReflectConstruct$1e() { if (typeof Reflect === "undefi...
function Word (line 62032) | function Word($cherry) {
function _createSuper$1f (line 62095) | function _createSuper$1f(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1f (line 62097) | function _isNativeReflectConstruct$1f() { if (typeof Reflect === "undefi...
function Ruby (line 62107) | function Ruby($cherry) {
function _createSuper$1g (line 62169) | function _createSuper$1g(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1g (line 62171) | function _isNativeReflectConstruct$1g() { if (typeof Reflect === "undefi...
function Theme (line 62181) | function Theme($cherry) {
function isArray$a (line 62249) | function isArray$a(val) {
function isUndefined (line 62259) | function isUndefined(val) {
function isBuffer$1 (line 62269) | function isBuffer$1(val) {
function isArrayBuffer (line 62280) | function isArrayBuffer(val) {
function isFormData (line 62290) | function isFormData(val) {
function isArrayBufferView (line 62300) | function isArrayBufferView(val) {
function isString (line 62316) | function isString(val) {
function isNumber (line 62326) | function isNumber(val) {
function isObject$3 (line 62336) | function isObject$3(val) {
function isPlainObject$1 (line 62346) | function isPlainObject$1(val) {
function isDate (line 62361) | function isDate(val) {
function isFile (line 62371) | function isFile(val) {
function isBlob (line 62381) | function isBlob(val) {
function isFunction$1 (line 62391) | function isFunction$1(val) {
function isStream (line 62401) | function isStream(val) {
function isURLSearchParams (line 62411) | function isURLSearchParams(val) {
function trim$6 (line 62421) | function trim$6(str) {
function isStandardBrowserEnv (line 62440) | function isStandardBrowserEnv() {
function forEach$5 (line 62464) | function forEach$5(obj, fn) {
function merge$1 (line 62508) | function merge$1(/* obj1, obj2, obj3, ... */) {
function extend (line 62536) | function extend(a, b, thisArg) {
function stripBOM (line 62553) | function stripBOM(content) {
function encode$1 (line 62585) | function encode$1(val) {
function InterceptorManager (line 62652) | function InterceptorManager() {
function resolveURL (line 62955) | function resolveURL(url) {
function Cancel (line 63010) | function Cancel(message) {
function done (line 63028) | function done() {
function onloadend (line 63057) | function onloadend() {
function setContentTypeIfUnset (line 63226) | function setContentTypeIfUnset(headers, value) {
function getDefaultAdapter (line 63232) | function getDefaultAdapter() {
function stringifySafely (line 63244) | function stringifySafely(rawValue, parser, encoder) {
function throwIfCancellationRequested (line 63372) | function throwIfCancellationRequested(config) {
function getMergedValue (line 63462) | function getMergedValue(target, source) {
function mergeDeepProperties (line 63474) | function mergeDeepProperties(prop) {
function valueFromConfig2 (line 63483) | function valueFromConfig2(prop) {
function defaultToConfig2 (line 63490) | function defaultToConfig2(prop) {
function mergeDirectKeys (line 63499) | function mergeDirectKeys(prop) {
function formatMessage (line 63570) | function formatMessage(opt, desc) {
function assertOptions (line 63602) | function assertOptions(options, schema, allowUnknown) {
function Axios (line 63636) | function Axios(instanceConfig) {
function CancelToken (line 63776) | function CancelToken(executor) {
function createInstance (line 63928) | function createInstance(defaultConfig) {
class BaseAPI (line 64008) | class BaseAPI {
method constructor (line 64009) | constructor(configuration, basePath = exports.BASE_PATH, axios = axios...
class RequiredError (line 64025) | class RequiredError extends Error {
method constructor (line 64026) | constructor(field, msg) {
function adopt (line 64056) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 64058) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 64059) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 64060) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function setFlattenedQueryParams (line 64133) | function setFlattenedQueryParams(urlSearchParams, parameter, key = "") {
function adopt (line 64221) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 64223) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 64224) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 64225) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
method cancelFineTune (line 65212) | cancelFineTune(fineTuneId, options) {
method createAnswer (line 65226) | createAnswer(createAnswerRequest, options) {
method createChatCompletion (line 65239) | createChatCompletion(createChatCompletionRequest, options) {
method createClassification (line 65253) | createClassification(createClassificationRequest, options) {
method createCompletion (line 65266) | createCompletion(createCompletionRequest, options) {
method createEdit (line 65279) | createEdit(createEditRequest, options) {
method createEmbedding (line 65292) | createEmbedding(createEmbeddingRequest, options) {
method createFile (line 65306) | createFile(file, purpose, options) {
method createFineTune (line 65319) | createFineTune(createFineTuneRequest, options) {
method createImage (line 65332) | createImage(createImageRequest, options) {
method createImageEdit (line 65351) | createImageEdit(image, prompt, mask, n, size, responseFormat, user, opti...
method createImageVariation (line 65368) | createImageVariation(image, n, size, responseFormat, user, options) {
method createModeration (line 65381) | createModeration(createModerationRequest, options) {
method createSearch (line 65396) | createSearch(engineId, createSearchRequest, options) {
method createTranscription (line 65414) | createTranscription(file, model, prompt, responseFormat, temperature, la...
method createTranslation (line 65431) | createTranslation(file, model, prompt, responseFormat, temperature, opti...
method deleteFile (line 65444) | deleteFile(fileId, options) {
method deleteModel (line 65457) | deleteModel(model, options) {
method downloadFile (line 65470) | downloadFile(fileId, options) {
method listEngines (line 65483) | listEngines(options) {
method listFiles (line 65495) | listFiles(options) {
method listFineTuneEvents (line 65509) | listFineTuneEvents(fineTuneId, stream, options) {
method listFineTunes (line 65521) | listFineTunes(options) {
method listModels (line 65533) | listModels(options) {
method retrieveEngine (line 65547) | retrieveEngine(engineId, options) {
method retrieveFile (line 65560) | retrieveFile(fileId, options) {
method retrieveFineTune (line 65573) | retrieveFineTune(fineTuneId, options) {
method retrieveModel (line 65586) | retrieveModel(model, options) {
method cancelFineTune (line 65608) | cancelFineTune(fineTuneId, options) {
method createAnswer (line 65619) | createAnswer(createAnswerRequest, options) {
method createChatCompletion (line 65629) | createChatCompletion(createChatCompletionRequest, options) {
method createClassification (line 65640) | createClassification(createClassificationRequest, options) {
method createCompletion (line 65650) | createCompletion(createCompletionRequest, options) {
method createEdit (line 65660) | createEdit(createEditRequest, options) {
method createEmbedding (line 65670) | createEmbedding(createEmbeddingRequest, options) {
method createFile (line 65681) | createFile(file, purpose, options) {
method createFineTune (line 65691) | createFineTune(createFineTuneRequest, options) {
method createImage (line 65701) | createImage(createImageRequest, options) {
method createImageEdit (line 65717) | createImageEdit(image, prompt, mask, n, size, responseFormat, user, opti...
method createImageVariation (line 65731) | createImageVariation(image, n, size, responseFormat, user, options) {
method createModeration (line 65741) | createModeration(createModerationRequest, options) {
method createSearch (line 65753) | createSearch(engineId, createSearchRequest, options) {
method createTranscription (line 65768) | createTranscription(file, model, prompt, responseFormat, temperature, la...
method createTranslation (line 65782) | createTranslation(file, model, prompt, responseFormat, temperature, opti...
method deleteFile (line 65792) | deleteFile(fileId, options) {
method deleteModel (line 65802) | deleteModel(model, options) {
method downloadFile (line 65812) | downloadFile(fileId, options) {
method listEngines (line 65822) | listEngines(options) {
method listFiles (line 65831) | listFiles(options) {
method listFineTuneEvents (line 65842) | listFineTuneEvents(fineTuneId, stream, options) {
method listFineTunes (line 65851) | listFineTunes(options) {
method listModels (line 65860) | listModels(options) {
method retrieveEngine (line 65871) | retrieveEngine(engineId, options) {
method retrieveFile (line 65881) | retrieveFile(fileId, options) {
method retrieveFineTune (line 65891) | retrieveFineTune(fineTuneId, options) {
method retrieveModel (line 65901) | retrieveModel(model, options) {
class OpenAIApi (line 65912) | class OpenAIApi extends base$1.BaseAPI {
method cancelFineTune (line 65921) | cancelFineTune(fineTuneId, options) {
method createAnswer (line 65933) | createAnswer(createAnswerRequest, options) {
method createChatCompletion (line 65944) | createChatCompletion(createChatCompletionRequest, options) {
method createClassification (line 65956) | createClassification(createClassificationRequest, options) {
method createCompletion (line 65967) | createCompletion(createCompletionRequest, options) {
method createEdit (line 65978) | createEdit(createEditRequest, options) {
method createEmbedding (line 65989) | createEmbedding(createEmbeddingRequest, options) {
method createFile (line 66001) | createFile(file, purpose, options) {
method createFineTune (line 66012) | createFineTune(createFineTuneRequest, options) {
method createImage (line 66023) | createImage(createImageRequest, options) {
method createImageEdit (line 66040) | createImageEdit(image, prompt, mask, n, size, responseFormat, user, op...
method createImageVariation (line 66055) | createImageVariation(image, n, size, responseFormat, user, options) {
method createModeration (line 66066) | createModeration(createModerationRequest, options) {
method createSearch (line 66079) | createSearch(engineId, createSearchRequest, options) {
method createTranscription (line 66095) | createTranscription(file, model, prompt, responseFormat, temperature, ...
method createTranslation (line 66110) | createTranslation(file, model, prompt, responseFormat, temperature, op...
method deleteFile (line 66121) | deleteFile(fileId, options) {
method deleteModel (line 66132) | deleteModel(model, options) {
method downloadFile (line 66143) | downloadFile(fileId, options) {
method listEngines (line 66154) | listEngines(options) {
method listFiles (line 66164) | listFiles(options) {
method listFineTuneEvents (line 66176) | listFineTuneEvents(fineTuneId, stream, options) {
method listFineTunes (line 66186) | listFineTunes(options) {
method listModels (line 66196) | listModels(options) {
method retrieveEngine (line 66208) | retrieveEngine(engineId, options) {
method retrieveFile (line 66219) | retrieveFile(fileId, options) {
method retrieveFineTune (line 66230) | retrieveFineTune(fineTuneId, options) {
method retrieveModel (line 66241) | retrieveModel(model, options) {
class Configuration (line 66341) | class Configuration {
method constructor (line 66342) | constructor(param = {}) {
method isJsonMime (line 66372) | isJsonMime(mime) {
function _createSuper$1h (line 66416) | function _createSuper$1h(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1h (line 66418) | function _isNativeReflectConstruct$1h() { if (typeof Reflect === "undefi...
function ChatGpt (line 66433) | function ChatGpt($cherry) {
function queryCompletion (line 66603) | function queryCompletion(type, input) {
function _createSuper$1i (line 66623) | function _createSuper$1i(Derived) { var hasNativeReflectConstruct = _isN...
function _isNativeReflectConstruct$1i (line 66625) | function _isNativeReflectConstruct$1i() { if (typeof Reflect === "undefi...
function MobilePreview (line 66635) | function MobilePreview($cherry) {
function asyncGeneratorStep (line 67541) | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, ar...
function _asyncToGenerator (line 67557) | function _asyncToGenerator(fn) {
function _regeneratorRuntime (line 67645) | function _regeneratorRuntime() {
function flatten (line 68026) | function flatten(options) {
function isTag (line 68061) | function isTag(elem) {
class Node$2 (line 68090) | class Node$2 {
method constructor (line 68091) | constructor() {
method parentNode (line 68108) | get parentNode() {
method parentNode (line 68111) | set parentNode(parent) {
method previousSibling (line 68118) | get previousSibling() {
method previousSibling (line 68121) | set previousSibling(prev) {
method nextSibling (line 68128) | get nextSibling() {
method nextSibling (line 68131) | set nextSibling(next) {
method cloneNode (line 68140) | cloneNode(recursive = false) {
class DataNode (line 68147) | class DataNode extends Node$2 {
method constructor (line 68151) | constructor(data) {
method nodeValue (line 68159) | get nodeValue() {
method nodeValue (line 68162) | set nodeValue(data) {
class Text$1 (line 68169) | class Text$1 extends DataNode {
method constructor (line 68170) | constructor() {
method nodeType (line 68174) | get nodeType() {
class Comment$1 (line 68181) | class Comment$1 extends DataNode {
method constructor (line 68182) | constructor() {
method nodeType (line 68186) | get nodeType() {
class ProcessingInstruction (line 68193) | class ProcessingInstruction extends DataNode {
method constructor (line 68194) | constructor(name, data) {
method nodeType (line 68199) | get nodeType() {
class NodeWithChildren (line 68206) | class NodeWithChildren extends Node$2 {
method constructor (line 68210) | constructor(children) {
method firstChild (line 68216) | get firstChild() {
method lastChild (line 68221) | get lastChild() {
method childNodes (line 68230) | get childNodes() {
method childNodes (line 68233) | set childNodes(children) {
class CDATA$1 (line 68237) | class CDATA$1 extends NodeWithChildren {
method constructor (line 68238) | constructor() {
method nodeType (line 68242) | get nodeType() {
class Document (line 68249) | class Document extends NodeWithChildren {
method constructor (line 68250) | constructor() {
method nodeType (line 68254) | get nodeType() {
class Element (line 68261) | class Element extends NodeWithChildren {
method constructor (line 68267) | constructor(name, attribs, children = [], type = name === "script"
method nodeType (line 68277) | get nodeType() {
method tagName (line 68285) | get tagName() {
method tagName (line 68288) | set tagName(name) {
method attributes (line 68291) | get attributes() {
function isTag$1 (line 68307) | function isTag$1(node) {
function isCDATA (line 68314) | function isCDATA(node) {
function isText (line 68321) | function isText(node) {
function isComment (line 68328) | function isComment(node) {
function isDirective (line 68335) | function isDirective(node) {
function isDocument (line 68342) | function isDocument(node) {
function hasChildren (line 68349) | function hasChildren(node) {
function cloneNode (line 68358) | function cloneNode(node, recursive = false) {
function cloneChildren (line 68415) | function cloneChildren(childs) {
class DomHandler (line 68430) | class DomHandler {
method constructor (line 68436) | constructor(callback, options, elementCB) {
method onparserinit (line 68462) | onparserinit(parser) {
method onreset (line 68466) | onreset() {
method onend (line 68475) | onend() {
method onerror (line 68482) | onerror(error) {
method onclosetag (line 68485) | onclosetag() {
method onopentag (line 68494) | onopentag(name, attribs) {
method ontext (line 68500) | ontext(data) {
method oncomment (line 68514) | oncomment(data) {
method oncommentend (line 68523) | oncommentend() {
method oncdatastart (line 68526) | oncdatastart() {
method oncdataend (line 68533) | oncdataend() {
method onprocessinginstruction (line 68536) | onprocessinginstruction(name, data) {
method handleCallback (line 68540) | handleCallback(error) {
method addNode (line 68548) | addNode(node) {
function encodeXML (line 68594) | function encodeXML(str) {
function getEscaper (line 68614) | function getEscaper(regex, map) {
function replaceQuotes (line 68769) | function replaceQuotes(value) {
function formatAttributes (line 68775) | function formatAttributes(attributes, opts) {
function render (line 68831) | function render(node, options = {}) {
function renderNode (line 68839) | function renderNode(node, options) {
function renderTag (line 68871) | function renderTag(elem, opts) {
function renderDirective (line 68912) | function renderDirective(elem) {
function renderText (line 68915) | function renderText(elem, opts) {
function renderCdat
Copy disabled (too large)
Download .json
Condensed preview — 1184 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (32,745K chars).
[
{
"path": ".gitattributes",
"chars": 52,
"preview": "*.js linguist-language=Go\n*.css linguist-language=Go"
},
{
"path": ".github/ISSUE_TEMPLATE",
"chars": 139,
"preview": "请按照一下格式提交issue,谢谢!\n\n1. 你当前使用的是哪个版本的 MinDoc(`godoc_linux_amd64 version`)?\n\n\n2. 你当前使用的是什么操作系统?\n\n\n3. 你是如何操作的?\n\n\n4. 你期望得到什么结"
},
{
"path": ".github/workflows/build.yml",
"chars": 1136,
"preview": "name: Go\n\non:\n push:\n branches: [ \"master\" ]\n pull_request:\n branches: [ \"master\" ]\n\njobs:\n build:\n name: ${"
},
{
"path": ".gitignore",
"chars": 443,
"preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n.DS_Store\n# Folders\n_obj\n_test\n\n# Archite"
},
{
"path": ".travis.yml",
"chars": 1232,
"preview": "os: linux\ndist: focal\n\nlanguage: go\ngo:\n - \"1.18.1\"\n\narch:\n- amd64\n\nenv:\n- GO111MODULE=on CGO_ENABLED=1\n\ninstall:\n - g"
},
{
"path": "Dockerfile",
"chars": 4344,
"preview": "FROM golang:bookworm AS build\n\nARG TAG=0.0.1\n\n# 编译-环境变量\nENV GO111MODULE=on\nENV GOPROXY=https://goproxy.cn,direct\nENV CGO"
},
{
"path": "LICENSE.md",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 11464,
"preview": "# MinDoc 简介\n\n[](https://travis-ci.com/mindoc-o"
},
{
"path": "appveyor.yml",
"chars": 1648,
"preview": "version: 1.0.{build}\nbranches:\n only:\n - master\nimage: Visual Studio 2022\nclone_folder: c:\\gopath\\src\\github.com\\mindo"
},
{
"path": "build_amd64.sh",
"chars": 982,
"preview": "rm mindoc_linux_amd64 mindoc_linux_musl_amd64\nrm -rf ../mindoc_linux_amd64/\n\nexport GOARCH=amd64\nexport GOOS=linux\nexpor"
},
{
"path": "build_musl_amd64.sh",
"chars": 1043,
"preview": "rm mindoc_linux_musl_amd64 mindoc_linux_amd64\nrm -rf ../mindoc_linux_musl_amd64/\n\nexport GOARCH=amd64\nexport GOOS=linux\n"
},
{
"path": "cache/cache.go",
"chars": 1627,
"preview": "package cache\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/gob\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/cache\""
},
{
"path": "cache/cache_null.go",
"chars": 880,
"preview": "package cache\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\ntype NullCache struct {\n\n}\n\n\nfunc (bm *NullCache) Get(ctx context.Context,"
},
{
"path": "commands/command.go",
"chars": 16924,
"preview": "package commands\n\nimport (\n\t\"encoding/gob\"\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\""
},
{
"path": "commands/daemon/daemon.go",
"chars": 2425,
"preview": "package daemon\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"github.com/beego/beego/"
},
{
"path": "commands/install.go",
"chars": 3617,
"preview": "package commands\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"flag\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com"
},
{
"path": "commands/migrate/migrate.go",
"chars": 3851,
"preview": "// Copyright 2013 bee authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"): you may\n// not use t"
},
{
"path": "commands/migrate/migrate_v03.go",
"chars": 2906,
"preview": "package migrate\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mind"
},
{
"path": "commands/update.go",
"chars": 1242,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/mindoc-org/mindoc/models\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"os\""
},
{
"path": "conf/app.conf.example",
"chars": 6886,
"preview": "appname = mindoc\n\n#默认监听的网卡,为空则监听所有\nhttpaddr=\"${MINDOC_ADDR}\"\nhttpport = \"${MINDOC_PORT||8181}\"\nrunmode = \"${MINDOC_RUN_M"
},
{
"path": "conf/enumerate.go",
"chars": 8560,
"preview": "// package conf 为配置相关.\npackage conf\n\nimport (\n\t\"strings\"\n\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\n\t\"github.com/beego/b"
},
{
"path": "conf/lang/en-us.ini",
"chars": 19887,
"preview": "[common]\ntitle = mindoc\nhome = Home\nblog = Blog\nproject_space = Project Space\nperson_center = Personal Center\nmy_project"
},
{
"path": "conf/lang/ru-ru.ini",
"chars": 22184,
"preview": "[common]\ntitle = MinDoc\nhome = Домашняя\nblog = Блог\nproject_space = Проекты\nperson_center = Профиль\nmy_project = Мои про"
},
{
"path": "conf/lang/zh-cn.ini",
"chars": 12434,
"preview": "[common]\ntitle = 文档在线管理系统\nhome = 首页\nblog = 文章\nproject_space = 项目空间\nperson_center = 个人中心\nmy_project = 我的项目\nmy_blog = 我的文章"
},
{
"path": "conf/mail.go",
"chars": 1129,
"preview": "package conf\n\nimport (\n\t\"strings\"\n\n\t\"github.com/beego/beego/v2/server/web\"\n)\n\ntype SmtpConf struct {\n\tEnableMail bool\n"
},
{
"path": "conf/workweixin.go",
"chars": 627,
"preview": "package conf\n\nimport (\n\t\"github.com/beego/beego/v2/server/web\"\n)\n\ntype WorkWeixinConf struct {\n\tCorpId string // 企业ID\n\t"
},
{
"path": "controllers/AccountController.go",
"chars": 41638,
"preview": "package controllers\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"github.com/mindoc-org/mindoc/cache\"\n\t\"github.com/m"
},
{
"path": "controllers/BaseController.go",
"chars": 5793,
"preview": "package controllers\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"html/template\"\n\t\"io/ioutil\"\n\t\"path/f"
},
{
"path": "controllers/BlogController.go",
"chars": 18841,
"preview": "package controllers\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/fi"
},
{
"path": "controllers/BookController.go",
"chars": 27600,
"preview": "package controllers\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reg"
},
{
"path": "controllers/BookMemberController.go",
"chars": 5290,
"preview": "package controllers\n\nimport (\n\t\"errors\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n"
},
{
"path": "controllers/CommentController.go",
"chars": 2101,
"preview": "package controllers\n\nimport (\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/mindoc-org/mindoc/conf\"\n\t\"github.com/mindoc-org/mindoc/mo"
},
{
"path": "controllers/DocumentController.go",
"chars": 40701,
"preview": "package controllers\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"image/png\"\n\t\"io\"\n\t\"mime/multipart\"\n\t"
},
{
"path": "controllers/ErrorController.go",
"chars": 287,
"preview": "package controllers\n\ntype ErrorController struct {\n\tBaseController\n}\n\nfunc (c *ErrorController) Error404() {\n\tc.TplName "
},
{
"path": "controllers/HomeController.go",
"chars": 1175,
"preview": "package controllers\n\nimport (\n\t\"math\"\n\t\"net/url\"\n\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"github.com/mindoc-org/mindoc/"
},
{
"path": "controllers/ItemsetsController.go",
"chars": 2191,
"preview": "package controllers\n\nimport (\n\t\"math\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\""
},
{
"path": "controllers/LabelController.go",
"chars": 2056,
"preview": "package controllers\n\nimport (\n\t\"math\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\""
},
{
"path": "controllers/ManagerController.go",
"chars": 29541,
"preview": "package controllers\n\nimport (\n\t\"encoding/json\"\n\t\"html/template\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"math\"\n\t\"path/filepath\"\n\t\"strconv"
},
{
"path": "controllers/SearchController.go",
"chars": 12929,
"preview": "package controllers\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"github.com/beego/i18n\"\n\t\"g"
},
{
"path": "controllers/SettingController.go",
"chars": 4498,
"preview": "package controllers\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/c"
},
{
"path": "controllers/TemplateController.go",
"chars": 4393,
"preview": "package controllers\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/i18n\"\n\t\"g"
},
{
"path": "controllers/const.go",
"chars": 242,
"preview": "package controllers\n\nconst (\n\tMarkdown = \"markdown\"\n\tEditorMarkdown = \"markdown\"\n\tEditorCherryMarkdown"
},
{
"path": "converter/converter.go",
"chars": 18236,
"preview": "//Author:TruthHun\n//Email:TruthHun@QQ.COM\n//Date:2018-01-21\npackage converter\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path"
},
{
"path": "converter/util.go",
"chars": 985,
"preview": "//Author:TruthHun\n//Email:TruthHun@QQ.COM\n//Date:2018-01-21\npackage converter\n\nimport (\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\""
},
{
"path": "database/clean.py",
"chars": 953,
"preview": "import sqlite3\nimport os, glob\n\nconn = sqlite3.connect(\"mindoc.db\")\ncur = conn.cursor() #通过建立数据库游标对象,准备读写操作\n\n\ncm"
},
{
"path": "dev-win-build.cmd",
"chars": 102,
"preview": "go build -v -ldflags \"-linkmode external -extldflags '-static' -w\" -o mindoc_windows_amd64.exe main.go"
},
{
"path": "docker-compose.yml",
"chars": 873,
"preview": "version: \"3\"\nservices:\n mindoc:\n image: registry.cn-hangzhou.aliyuncs.com/mindoc-org/mindoc:v2.1\n container_name:"
},
{
"path": "go.mod",
"chars": 2542,
"preview": "module github.com/mindoc-org/mindoc\n\ngo 1.23.0\n\nrequire (\n\tgithub.com/PuerkitoBio/goquery v1.10.2\n\tgithub.com/beego/beeg"
},
{
"path": "go.sum",
"chars": 21651,
"preview": "filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=\nfilippo.io/edwards25519 v1.1.0/go.mod h1:"
},
{
"path": "graphics/copy.go",
"chars": 1355,
"preview": "package graphics\n\nimport (\n\t\"errors\"\n\t\"image\"\n\t\"os\"\n\n\t\"github.com/nfnt/resize\"\n)\n\nfunc ImageCopy(src image.Image, x, y, "
},
{
"path": "graphics/file.go",
"chars": 676,
"preview": "package graphics\n\nimport (\n\t\"image\"\n\t\"image/gif\"\n\t\"image/jpeg\"\n\t\"image/png\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// 将图片保"
},
{
"path": "lib/time/README",
"chars": 377,
"preview": "The zoneinfo.zip archive contains time zone files compiled using\nthe code and data maintained as part of the IANA Time Z"
},
{
"path": "lib/time/update.bash",
"chars": 1361,
"preview": "#!/bin/bash\n# Copyright 2012 The Go Authors. All rights reserved.\n# Use of this source code is governed by a BSD-style\n#"
},
{
"path": "mail/smtp.go",
"chars": 11604,
"preview": "package mail\n\nimport (\n\t\"bytes\"\n\t\"crypto/md5\"\n\t\"crypto/tls\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/iou"
},
{
"path": "mail/smtp_test.go",
"chars": 544,
"preview": "package mail\n\nimport (\n\t// \"os\"\n\t\"testing\"\n)\n\nfunc TestSend(t *testing.T) {\n\t/*\n\tconf := &SMTPConfig{\n\t\tUsername: \"swh@a"
},
{
"path": "mail/util.go",
"chars": 953,
"preview": "package mail\n\nimport (\n\t\"net/mail\"\n)\n\nfunc MailAddr(name string, address string) *mail.Address {\n\treturn &mail.Address{\n"
},
{
"path": "main.go",
"chars": 1436,
"preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\n\t_ \"github.com/beego/bee"
},
{
"path": "mcp/handler.go",
"chars": 1952,
"preview": "package mcp\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\t\"github.com/mindoc-org/mindoc/con"
},
{
"path": "mcp/mcp.go",
"chars": 592,
"preview": "package mcp\n\nimport (\n\t\"github.com/mark3labs/mcp-go/server\"\n)\n\n// MCPServer MinDoc MCP Server\ntype MCPServer struct {\n\ts"
},
{
"path": "mcp/middleware.go",
"chars": 677,
"preview": "package mcp\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\n\t\"github.com/beego/beego/v2/server/web\"\n\tbeegoContext \"github.com/beego/be"
},
{
"path": "models/AttachmentModel.go",
"chars": 4470,
"preview": "// 数据库模型.\npackage models\n\nimport (\n\t\"time\"\n\n\t\"os\"\n\n\t\"strings\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beeg"
},
{
"path": "models/AttachmentResult.go",
"chars": 1741,
"preview": "package models\n\nimport (\n\t\"strings\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-org/mindoc/utils/fileti"
},
{
"path": "models/Auth2Account.go",
"chars": 5486,
"preview": "// Package models .\npackage models\n\nimport (\n\t\"errors\"\n\t\"github.com/mindoc-org/mindoc/utils/auth2\"\n\t\"time\"\n\n\t\"github.com"
},
{
"path": "models/Base.go",
"chars": 38,
"preview": "package models\n\ntype Model struct {\n}\n"
},
{
"path": "models/Blog.go",
"chars": 11638,
"preview": "package models\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n\t\"github.com/beego/beego/"
},
{
"path": "models/BlogResult.go",
"chars": 43,
"preview": "package models\n\n\ntype BlogResult struct{\n\n}"
},
{
"path": "models/BookModel.go",
"chars": 35777,
"preview": "package models\n\nimport (\n\t\"context\"\n\t\"crypto/md5\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t"
},
{
"path": "models/BookResult.go",
"chars": 23185,
"preview": "package models\n\nimport (\n\t\"bytes\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"encoding/json\"\n\t\""
},
{
"path": "models/CommentModel.go",
"chars": 4869,
"preview": "package models\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-org/mindoc/conf\""
},
{
"path": "models/ContentReverseIndex.go",
"chars": 12421,
"preview": "package models\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\n\t\"github.com/beego/beego/v2/client/orm\""
},
{
"path": "models/ConvertBookResult.go",
"chars": 126,
"preview": "package models\n\n// 转换结果\ntype ConvertBookResult struct {\n\tPDFPath string\n\tEpubPath string\n\tMobiPath string\n\tWordPath str"
},
{
"path": "models/Dashboard.go",
"chars": 1018,
"preview": "package models\n\nimport \"github.com/beego/beego/v2/client/orm\"\n\ntype Dashboard struct {\n\tBookNumber int64 `json:\"bo"
},
{
"path": "models/DocumentHistory.go",
"chars": 5570,
"preview": "package models\n\nimport (\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"githu"
},
{
"path": "models/DocumentModel.go",
"chars": 13370,
"preview": "package models\n\nimport (\n\t\"time\"\n\n\t\"github.com/beego/i18n\"\n\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings"
},
{
"path": "models/DocumentSearchResult.go",
"chars": 12049,
"preview": "package models\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego"
},
{
"path": "models/DocumentTree.go",
"chars": 6221,
"preview": "package models\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"math\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/"
},
{
"path": "models/Errors.go",
"chars": 1780,
"preview": "// Package models 为项目所需的模型对象定义.\npackage models\n\nimport \"errors\"\n\nvar (\n\t// ErrMemberNoExist 用户不存在.\n\tErrMemberNoExist "
},
{
"path": "models/Itemsets.go",
"chars": 7979,
"preview": "package models\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/"
},
{
"path": "models/LabelModel.go",
"chars": 2423,
"preview": "package models\n\nimport (\n\t\"strings\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"gi"
},
{
"path": "models/Logs.go",
"chars": 1957,
"preview": "package models\n\nimport (\n\t\"errors\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-o"
},
{
"path": "models/Member.go",
"chars": 17924,
"preview": "// Package models .\npackage models\n\nimport (\n\t\"crypto/md5\"\n\t\"crypto/tls\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fm"
},
{
"path": "models/MemberResult.go",
"chars": 3975,
"preview": "package models\n\nimport (\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/i18n\"\n\t\"github.com/mindoc-o"
},
{
"path": "models/MemberToken.go",
"chars": 1801,
"preview": "package models\n\nimport (\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-org/mindoc/conf\"\n)\n\ntype M"
},
{
"path": "models/Migrations.go",
"chars": 1143,
"preview": "package models\n\nimport (\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-org/mindoc/conf\"\n)\n\ntype M"
},
{
"path": "models/Options.go",
"chars": 4767,
"preview": "package models\n\nimport (\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-org/mindoc/conf\"\n)\n\n// Option struc"
},
{
"path": "models/Relationship.go",
"chars": 4699,
"preview": "package models\n\nimport (\n\t\"errors\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"git"
},
{
"path": "models/Team.go",
"chars": 3631,
"preview": "package models\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/log"
},
{
"path": "models/TeamMember.go",
"chars": 6751,
"preview": "package models\n\nimport (\n\t\"errors\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/logs\"\n\t\"git"
},
{
"path": "models/TeamRelationship.go",
"chars": 7129,
"preview": "package models\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/log"
},
{
"path": "models/Template.go",
"chars": 4422,
"preview": "package models\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/beego/beego/v2/core/log"
},
{
"path": "models/comment_result.go",
"chars": 1029,
"preview": "package models\n\nimport \"github.com/beego/beego/v2/client/orm\"\n\ntype CommentResult struct {\n\tComment\n\tAuthor string"
},
{
"path": "models/comment_vote.go",
"chars": 1372,
"preview": "package models\n\nimport (\n\t\"time\"\n\n\t\"github.com/beego/beego/v2/client/orm\"\n\t\"github.com/mindoc-org/mindoc/conf\"\n)\n\ntype C"
},
{
"path": "routers/filter.go",
"chars": 2106,
"preview": "package routers\n\nimport (\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"regexp\"\n\n\t\"github.com/beego/beego/v2/server/web\"\n\t\"github.com/be"
},
{
"path": "routers/router.go",
"chars": 13802,
"preview": "package routers\n\nimport (\n\t// \"crypto/tls\"\n\t// \"log\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.co"
},
{
"path": "start.sh",
"chars": 966,
"preview": "#!/bin/bash\nset -eux\n\n# 默认资源\nif [ ! -d \"/mindoc/conf\" ]; then mkdir -p \"/mindoc/conf\" ; fi\nif [[ -z \"$(ls -A -- \"/mindoc"
},
{
"path": "static/bootstrap/css/bootstrap-theme.css",
"chars": 26132,
"preview": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://gi"
},
{
"path": "static/bootstrap/css/bootstrap.css",
"chars": 146010,
"preview": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://gi"
},
{
"path": "static/bootstrap/js/bootstrap.js",
"chars": 69707,
"preview": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under the MIT license"
},
{
"path": "static/bootstrap/js/npm.js",
"chars": 484,
"preview": "// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequ"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/css/fileinput-rtl.css",
"chars": 2061,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Krajee RTL (Right To Left) default styli"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/css/fileinput.css",
"chars": 11003,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Krajee default styling for bootstrap-fil"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/fileinput.js",
"chars": 201594,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Author: Kartik Visweswaran\n * Copyright:"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/LANG.js",
"chars": 4764,
"preview": "/*!\n * FileInput <_LANG_> Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/ar.js",
"chars": 4671,
"preview": "/*!\n * FileInput Arabic Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/az.js",
"chars": 4969,
"preview": "/*!\n * FileInput Azerbaijan Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', o"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/bg.js",
"chars": 4839,
"preview": "/*!\n * FileInput Bulgarian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/ca.js",
"chars": 4996,
"preview": "/*!\n * FileInput Català Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/cr.js",
"chars": 5021,
"preview": "/*!\n * FileInput Croatian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/cs.js",
"chars": 4904,
"preview": "/*!\n * FileInput Czech Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n * "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/da.js",
"chars": 4820,
"preview": "/*!\n * FileInput Danish Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/de.js",
"chars": 5126,
"preview": "/*!\n * FileInput German Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/el.js",
"chars": 5200,
"preview": "/*!\n * FileInput Greek Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n * "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/es.js",
"chars": 5182,
"preview": "/*!\n * FileInput Spanish Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/et.js",
"chars": 4675,
"preview": "/*!\n * FileInput Estonian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/fa.js",
"chars": 4827,
"preview": "/*!\n * FileInput Persian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/fi.js",
"chars": 4428,
"preview": "/*!\n * FileInput Finnish Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/fr.js",
"chars": 5221,
"preview": "/*!\n * FileInput French Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/gl.js",
"chars": 5152,
"preview": "/*!\n * FileInput Galician Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/hu.js",
"chars": 5003,
"preview": "/*!\n * FileInput Hungarian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/id.js",
"chars": 4908,
"preview": "/*!\n * FileInput Indonesian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', o"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/it.js",
"chars": 5112,
"preview": "/*!\n * FileInput Italian Translation\n * \n * Author: Lorenzo Milesi <maxxer@yetopen.it>\n *\n * This file must be loaded af"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/ja.js",
"chars": 4702,
"preview": "/*!\n * FileInput Japanese Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/ka.js",
"chars": 5070,
"preview": "/*!\n * FileInput Georgian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/kr.js",
"chars": 4333,
"preview": "/*!\n * FileInput Korean Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/kz.js",
"chars": 4281,
"preview": "/*!\n * FileInput Kazakh Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/lt.js",
"chars": 4958,
"preview": "/*!\n * FileInput <_LANG_> Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/nl.js",
"chars": 4991,
"preview": "/*!\n * FileInput Dutch Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n * "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/no.js",
"chars": 4699,
"preview": "/*!\n * FileInput Norwegian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/pl.js",
"chars": 4821,
"preview": "/*!\n * FileInput Polish Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n *"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/pt-BR.js",
"chars": 5162,
"preview": "/*!\n * FileInput Brazillian Portuguese Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in bra"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/pt.js",
"chars": 4963,
"preview": "/*!\n * FileInput Portuguese Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', o"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/ro.js",
"chars": 5035,
"preview": "/*!\n * FileInput Romanian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/ru.js",
"chars": 5009,
"preview": "/*!\n * FileInput Russian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/sk.js",
"chars": 4916,
"preview": "/*!\n * FileInput Slovakian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/sl.js",
"chars": 4720,
"preview": "/*!\n * FileInput Slovenian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/sv.js",
"chars": 4797,
"preview": "/*!\n * FileInput <_LANG_> Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/th.js",
"chars": 4724,
"preview": "/*!\n * FileInput Thai Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n * a"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/tr.js",
"chars": 5019,
"preview": "/*!\n * FileInput Turkish Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/uk.js",
"chars": 4860,
"preview": "/*!\n * FileInput Ukrainian Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/vi.js",
"chars": 4778,
"preview": "/*!\n * FileInput Vietnamese Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', o"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/zh-TW.js",
"chars": 4161,
"preview": "/*!\n * FileInput Chinese Traditional Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in brace"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/zh.js",
"chars": 3771,
"preview": "/*!\n * FileInput Chinese Translations\n *\n * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or\n "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/plugins/piexif.js",
"chars": 75990,
"preview": "/* piexifjs\n\nThe MIT License (MIT)\n\nCopyright (c) 2014, 2015 hMatoba(https://github.com/hMatoba)\n\nPermission is hereby g"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/plugins/purify.js",
"chars": 30605,
"preview": ";(function(factory) {\n 'use strict';\n /* global window: false, define: false, module: false */\n var root = type"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/plugins/sortable.js",
"chars": 38565,
"preview": "/**!\n * KvSortable\n * @author\tRubaXa <trash@rubaxa.org>\n * @license MIT\n *\n * Changed kvsortable plugin naming to prev"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/explorer/theme.css",
"chars": 3525,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Krajee Explorer theme style for bootstra"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/explorer/theme.js",
"chars": 2631,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Krajee Explorer theme configuration for "
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/explorer-fa/theme.css",
"chars": 3630,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Krajee Explorer Font Awesome theme style"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/explorer-fa/theme.js",
"chars": 4179,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Krajee Explorer Font Awesome theme confi"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/fa/theme.js",
"chars": 1971,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Font Awesome icon theme configuration fo"
},
{
"path": "static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/gly/theme.js",
"chars": 2160,
"preview": "/*!\n * bootstrap-fileinput v4.4.7\n * http://plugins.krajee.com/file-input\n *\n * Glyphicon (default) theme configuration "
},
{
"path": "static/bootstrap/plugins/bootstrap-switch/css/bootstrap2/bootstrap-switch.css",
"chars": 23705,
"preview": "/**\n * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.\n *\n * @version v3.3.4\n * @homepage"
},
{
"path": "static/bootstrap/plugins/bootstrap-switch/css/bootstrap3/bootstrap-switch.css",
"chars": 6352,
"preview": "/**\n * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.\n *\n * @version v3.3.4\n * @homepage"
},
{
"path": "static/bootstrap/plugins/bootstrap-switch/js/bootstrap-switch.js",
"chars": 26277,
"preview": "/**\n * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.\n *\n * @version v3.3.4\n * @homepage"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/bootstrap-wysiwyg.js",
"chars": 9587,
"preview": "/* http://github.com/mindmup/bootstrap-wysiwyg */\n/*global jQuery, $, FileReader*/\n/*jslint browser:true*/\n(function ($)"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-apollo.js",
"chars": 988,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"com\",/^#[^\\n\\r]*/,null,\"#\"],[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\""
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-basic.js",
"chars": 516,
"preview": "var a=null;\nPR.registerLangHandler(PR.createSimpleLexer([[\"str\",/^\"(?:[^\\n\\r\"\\\\]|\\\\.)*(?:\"|$)/,a,'\"'],[\"pln\",/^\\s+/,a,\" "
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-clj.js",
"chars": 1446,
"preview": "/*\n Copyright (C) 2011 Google Inc.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use th"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-css.js",
"chars": 868,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\f\\r ]+/,null,\" \\t\\r\\n\\u000c\"]],[[\"str\",/^\"(?:[^\\n\\f\\r\"\\\\]|\\\\"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-dart.js",
"chars": 947,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"]],[[\"com\",/^#!.*/],[\"kwd\",/^\\"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-erlang.js",
"chars": 583,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t-\\r ]+/,null,\"\\t\\n\\u000b\\u000c\\r \"],[\"str\",/^\"(?:[^\\n\\f\\r\"\\\\]|\\"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-go.js",
"chars": 283,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"pln\",/^(?:\"(?:[^\"\\\\]|\\\\[\\S"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-hs.js",
"chars": 579,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t-\\r ]+/,null,\"\\t\\n\\u000b\\u000c\\r \"],[\"str\",/^\"(?:[^\\n\\f\\r\"\\\\]|\\"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-lisp.js",
"chars": 774,
"preview": "var a=null;\nPR.registerLangHandler(PR.createSimpleLexer([[\"opn\",/^\\(+/,a,\"(\"],[\"clo\",/^\\)+/,a,\")\"],[\"com\",/^;[^\\n\\r]*/,a"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-llvm.js",
"chars": 358,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"str\",/^!?\"(?:[^\"\\\\]|\\\\[\\S\\"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-lua.js",
"chars": 553,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"str\",/^(?:\"(?:[^\"\\\\]|\\\\[\\S"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-matlab.js",
"chars": 19700,
"preview": "var a=null,b=window.PR,c=[[b.PR_PLAIN,/^[\\t-\\r \\xa0]+/,a,\" \\t\\r\\n\\u000b\\u000c\\u00a0\"],[b.PR_COMMENT,/^%{[^%]*%+(?:[^%}]["
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-ml.js",
"chars": 1106,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"com\",/^#(?:if[\\t\\n\\r \\xa0]"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-mumps.js",
"chars": 887,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"str\",/^\"(?:[^\"]|\\\\.)*\"/,nu"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-n.js",
"chars": 1402,
"preview": "var a=null;\nPR.registerLangHandler(PR.createSimpleLexer([[\"str\",/^(?:'(?:[^\\n\\r'\\\\]|\\\\.)*'|\"(?:[^\\n\\r\"\\\\]|\\\\.)*(?:\"|$))/"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-pascal.js",
"chars": 713,
"preview": "var a=null;\nPR.registerLangHandler(PR.createSimpleLexer([[\"str\",/^'(?:[^\\n\\r'\\\\]|\\\\.)*(?:'|$)/,a,\"'\"],[\"pln\",/^\\s+/,a,\" "
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-proto.js",
"chars": 302,
"preview": "PR.registerLangHandler(PR.sourceDecorator({keywords:\"bytes,default,double,enum,extend,extensions,false,group,import,max,"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-r.js",
"chars": 696,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"str\",/^\"(?:[^\"\\\\]|\\\\[\\S\\s]"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-rd.js",
"chars": 268,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"com\",/^%[^\\n\\r]*/,null,\"%\""
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-scala.js",
"chars": 916,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"str\",/^\"(?:\"\"(?:\"\"?(?!\")|["
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-sql.js",
"chars": 1802,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"str\",/^(?:\"(?:[^\"\\\\]|\\\\.)*"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-tcl.js",
"chars": 635,
"preview": "var a=null;\nPR.registerLangHandler(PR.createSimpleLexer([[\"opn\",/^{+/,a,\"{\"],[\"clo\",/^}+/,a,\"}\"],[\"com\",/^#[^\\n\\r]*/,a,\""
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-tex.js",
"chars": 286,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"],[\"com\",/^%[^\\n\\r]*/,null,\"%\""
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-vb.js",
"chars": 1791,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0\\u2028\\u2029]+/,null,\"\\t\\n\\r \\u00a0\\u2028\\u2029\"],[\"st"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-vhdl.js",
"chars": 1450,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \\u00a0\"]],[[\"str\",/^(?:[box]?\"(?:[^\"]"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-wiki.js",
"chars": 544,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\d\\t a-gi-z\\xa0]+/,null,\"\\t \\u00a0abcdefgijklmnopqrstuvwxyz012345"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-xq.js",
"chars": 23242,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"var pln\",/^\\$[\\w-]+/,null,\"$\"]],[[\"pln\",/^[\\s=][<>][\\s=]/],[\"lit\",/^@[\\w-"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/lang-yaml.js",
"chars": 412,
"preview": "var a=null;\nPR.registerLangHandler(PR.createSimpleLexer([[\"pun\",/^[:>?|]+/,a,\":|>?\"],[\"dec\",/^%(?:YAML|TAG)[^\\n\\r#]+/,a,"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/prettify.css",
"chars": 675,
"preview": ".pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/prettify.js",
"chars": 14551,
"preview": "!function(){var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;\n(function(){function S(a){function d(e){var b=e.charCodeAt("
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/google-code-prettify/run_prettify.js",
"chars": 16682,
"preview": "!function(){var r=null;\n(function(){function X(e){function j(){try{J.doScroll(\"left\")}catch(e){P(j,50);return}w(\"poll\")}"
},
{
"path": "static/bootstrap/plugins/bootstrap-wysiwyg/external/jquery.hotkeys.js",
"chars": 3283,
"preview": "/*\n * jQuery Hotkeys Plugin\n * Copyright 2010, John Resig\n * Dual licensed under the MIT or GPL Version 2 licenses.\n *\n "
},
{
"path": "static/bootstrap/plugins/tagsinput/bootstrap-tagsinput.css",
"chars": 1317,
"preview": ".bootstrap-tagsinput {\n background-color: #fff;\n border: 1px solid #ccc;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0"
},
{
"path": "static/bootstrap/plugins/tagsinput/bootstrap-tagsinput.js",
"chars": 21104,
"preview": "(function ($) {\n \"use strict\";\n\n var defaultOptions = {\n tagClass: function(item) {\n return 'label label-info'"
},
{
"path": "static/bootstrap/plugins/tagsinput/bootstrap-tagsinput.less",
"chars": 978,
"preview": ".bootstrap-tagsinput {\n background-color: #fff;\n border: 1px solid #ccc;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0"
},
{
"path": "static/bootstrap-paginator/bootstrap-paginator.js",
"chars": 20829,
"preview": "/**\n * bootstrap-paginator.js v0.5\n * --\n * Copyright 2013 Yun Lai <lyonlai1984@gmail.com>\n * --\n * Licensed under the A"
},
{
"path": "static/cherry/addons/cherry-code-block-mermaid-plugin.d.ts",
"chars": 849,
"preview": "export default class MermaidCodeEngine {\n static TYPE: string;\n static install(cherryOptions: any, ...args: any[])"
},
{
"path": "static/cherry/addons/cherry-code-block-mermaid-plugin.js",
"chars": 38907,
"preview": "!function(t,r){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=r():\"function\"==typeof define&&define"
},
{
"path": "static/cherry/addons/cherry-code-block-plantuml-plugin.d.ts",
"chars": 199,
"preview": "export default class PlantUMLCodeEngine {\n static install(cherryOptions: any, args: any): void;\n constructor(plant"
},
{
"path": "static/cherry/addons/cherry-code-block-plantuml-plugin.js",
"chars": 43906,
"preview": "!function(t,r){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=r():\"function\"==typeof define&&define"
},
{
"path": "static/cherry/cherry-markdown.css",
"chars": 154580,
"preview": "@charset \"UTF-8\";\n\n.cherry *::-webkit-scrollbar {\n height: 7px;\n width: 7px;\n background: transparent;\n}\n\n.cherry *::"
},
{
"path": "static/cherry/cherry-markdown.js",
"chars": 4653843,
"preview": "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof"
},
{
"path": "static/cherry/drawio-demo.js",
"chars": 2622,
"preview": "// Extends EditorUi to update I/O action states based on availability of backend\n(function () {\n var editorUiInit = Edi"
},
{
"path": "static/cherry/drawio_demo/Actions.js",
"chars": 53003,
"preview": "/**\n * Copyright (c) 2006-2020, JGraph Ltd\n * Copyright (c) 2006-2020, draw.io AG\n *\n * Constructs the actions object fo"
},
{
"path": "static/cherry/drawio_demo/Dialogs.js",
"chars": 67078,
"preview": "/**\n * Copyright (c) 2006-2012, JGraph Ltd\n */\n/**\n * Constructs a new open dialog.\n */\nvar OpenDialog = function()\n{\n\tv"
}
]
// ... and 984 more files (download for full content)
About this extraction
This page contains the full source code of the mindoc-org/mindoc GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1184 files (46.9 MB), approximately 7.8M tokens, and a symbol index with 15702 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.