├── src
├── assets
│ ├── sass
│ │ ├── pages
│ │ │ └── _home.scss
│ │ ├── abstracts
│ │ │ ├── _colorDefinitions.scss
│ │ │ ├── _functions.scss
│ │ │ ├── _dark_roboto.scss
│ │ │ ├── _light_roboto.scss
│ │ │ ├── _dark.scss
│ │ │ ├── _light.scss
│ │ │ └── _variables.scss
│ │ ├── layout
│ │ │ └── _sidebar.scss
│ │ ├── base
│ │ │ ├── _base.scss
│ │ │ └── _typography.scss
│ │ ├── main.scss
│ │ ├── _colors.scss
│ │ └── components
│ │ │ └── _topbar-dropdown.scss
│ ├── images
│ │ ├── druppel.png
│ │ ├── trash-solid.svg
│ │ ├── arrowRight.svg
│ │ ├── arrowLeft.svg
│ │ ├── arrowDown.svg
│ │ ├── arrowUp.svg
│ │ ├── arrowPrevious.svg
│ │ ├── plus.svg
│ │ ├── closing_cross.svg
│ │ ├── commentButton.svg
│ │ ├── arrowNext.svg
│ │ ├── arrowDoubleRight.svg
│ │ ├── tooltipClose.svg
│ │ ├── tooltipExpand.svg
│ │ ├── textButton.svg
│ │ ├── newfile.svg
│ │ ├── WaterproofIconWhite.svg
│ │ ├── settingsGear.svg
│ │ ├── looking_glass_blue.svg
│ │ ├── looking_glass_grey.svg
│ │ ├── tick.svg
│ │ ├── symbolButton.svg
│ │ ├── tickInCircle.svg
│ │ ├── tutorial.svg
│ │ ├── lock_locked.svg
│ │ ├── lock_unlocked.svg
│ │ ├── cross.svg
│ │ ├── cross-blue.svg
│ │ ├── crossInCircle.svg
│ │ ├── spinner.svg
│ │ ├── tutorialButton.svg
│ │ ├── bulbOffWhite.svg
│ │ ├── bulbOff.svg
│ │ ├── tacticButton.svg
│ │ ├── arrowToCursor.svg
│ │ ├── openfile.svg
│ │ ├── insertAtCursor.svg
│ │ ├── copy.svg
│ │ ├── codeButton.svg
│ │ ├── bulbNo.svg
│ │ ├── commandButton.svg
│ │ └── findButton.svg
│ └── fonts
│ │ ├── CenturyGothic
│ │ ├── CenturyGothic.woff2
│ │ ├── CenturyGothic-Bold.woff2
│ │ ├── CenturyGothic-Italic.woff2
│ │ └── CenturyGothic-BoldItalic.woff2
│ │ ├── LetterGothicStd
│ │ ├── LetterGothicStd.woff2
│ │ ├── LetterGothicStd-Bold.woff2
│ │ ├── LetterGothicStd-Slanted.woff2
│ │ └── LetterGothicStd-BoldSlanted.woff2
│ │ ├── roboto-v20-latin
│ │ ├── roboto-v20-latin-700.woff2
│ │ ├── roboto-v20-latin-italic.woff2
│ │ ├── roboto-v20-latin-regular.woff2
│ │ └── roboto-v20-latin-700italic.woff2
│ │ └── roboto-mono-v13-latin
│ │ ├── roboto-mono-v13-latin-700.woff2
│ │ ├── roboto-mono-v13-latin-italic.woff2
│ │ ├── roboto-mono-v13-latin-regular.woff2
│ │ └── roboto-mono-v13-latin-700italic.woff2
├── App.vue
├── editpage
│ └── components
│ │ ├── blocks
│ │ ├── code
│ │ │ └── Inlineable.vue
│ │ ├── FoldBlock.vue
│ │ ├── TextBlock.vue
│ │ ├── InputBlock.vue
│ │ └── BlockContextMenuButton.vue
│ │ ├── mixins
│ │ └── CodeExecution.vue
│ │ ├── assistance
│ │ ├── symbols
│ │ │ ├── MathsSymbol.vue
│ │ │ └── SymbolCategory.vue
│ │ ├── AssistanceButton.vue
│ │ ├── search
│ │ │ ├── SearchResult.vue
│ │ │ └── SearchBar.vue
│ │ ├── AssistanceItem.vue
│ │ ├── tactics
│ │ │ └── Tactic.vue
│ │ └── commands
│ │ │ └── Command.vue
│ │ ├── response
│ │ ├── ResponseWindow.vue
│ │ └── GoalsWindow.vue
│ │ ├── Gutter.vue
│ │ └── menubars
│ │ ├── TopbarButton.vue
│ │ ├── ShortcutButton.vue
│ │ └── SidebarButton.vue
├── router.js
├── activity-log.js
├── coq
│ ├── serapi
│ │ ├── util
│ │ │ └── SerapiCallbacks.js
│ │ ├── workers
│ │ │ ├── SerapiWorker.js
│ │ │ ├── SerapiWorkerJs.js
│ │ │ └── SerapiWorkerTCP.js
│ │ ├── flatten-expr.js
│ │ └── processors
│ │ │ └── SerapiASTProcessor.js
│ ├── CoqInterface.js
│ └── EditorInterface.js
├── io
│ ├── pathHelper.js
│ ├── recents.js
│ └── readfile.js
├── main.js
├── pageless
│ └── Loader.vue
└── index
│ └── components
│ └── RecentFile.vue
├── .gitconfig
├── wrapper
├── wplib
│ ├── compileList.json
│ ├── Tactics
│ │ ├── Waterprove.wpn
│ │ ├── SetTheoryTactics.wpn
│ │ └── TacticsContra.wpn
│ ├── Definitions
│ │ └── SetDefinitions.wpn
│ ├── Notations
│ │ └── SetNotations.wpn
│ ├── Lib
│ │ └── sequential_accumulation_points.wpn
│ ├── Notebooks
│ │ └── Intro_to_bounded_functions.wpn
│ └── Exercise_sheets
│ │ ├── Lec_05_Ex_4.wpe
│ │ └── Lec_02_Ex_2.wpe
├── win
│ └── wpwrapper.exe
├── mac
│ └── wpwrapper_mac.mac
├── lin
│ └── wpwrapper_ubuntu.ubuntu
├── windows-installer.nsh
└── assistance
│ └── commands.json
├── public
├── icon.png
├── katex
│ └── fonts
│ │ ├── KaTeX_AMS-Regular.ttf
│ │ ├── KaTeX_Main-Bold.ttf
│ │ ├── KaTeX_Main-Bold.woff
│ │ ├── KaTeX_Main-Bold.woff2
│ │ ├── KaTeX_Main-Italic.ttf
│ │ ├── KaTeX_Math-Italic.ttf
│ │ ├── KaTeX_AMS-Regular.woff
│ │ ├── KaTeX_AMS-Regular.woff2
│ │ ├── KaTeX_Fraktur-Bold.ttf
│ │ ├── KaTeX_Fraktur-Bold.woff
│ │ ├── KaTeX_Main-Italic.woff
│ │ ├── KaTeX_Main-Italic.woff2
│ │ ├── KaTeX_Main-Regular.ttf
│ │ ├── KaTeX_Main-Regular.woff
│ │ ├── KaTeX_Math-Italic.woff
│ │ ├── KaTeX_Math-Italic.woff2
│ │ ├── KaTeX_Size1-Regular.ttf
│ │ ├── KaTeX_Size2-Regular.ttf
│ │ ├── KaTeX_Size3-Regular.ttf
│ │ ├── KaTeX_Size4-Regular.ttf
│ │ ├── KaTeX_Caligraphic-Bold.ttf
│ │ ├── KaTeX_Fraktur-Bold.woff2
│ │ ├── KaTeX_Fraktur-Regular.ttf
│ │ ├── KaTeX_Fraktur-Regular.woff
│ │ ├── KaTeX_Main-BoldItalic.ttf
│ │ ├── KaTeX_Main-BoldItalic.woff
│ │ ├── KaTeX_Main-Regular.woff2
│ │ ├── KaTeX_Math-BoldItalic.ttf
│ │ ├── KaTeX_Math-BoldItalic.woff
│ │ ├── KaTeX_SansSerif-Bold.ttf
│ │ ├── KaTeX_SansSerif-Bold.woff
│ │ ├── KaTeX_SansSerif-Bold.woff2
│ │ ├── KaTeX_SansSerif-Italic.ttf
│ │ ├── KaTeX_Script-Regular.ttf
│ │ ├── KaTeX_Script-Regular.woff
│ │ ├── KaTeX_Script-Regular.woff2
│ │ ├── KaTeX_Size1-Regular.woff
│ │ ├── KaTeX_Size1-Regular.woff2
│ │ ├── KaTeX_Size2-Regular.woff
│ │ ├── KaTeX_Size2-Regular.woff2
│ │ ├── KaTeX_Size3-Regular.woff
│ │ ├── KaTeX_Size3-Regular.woff2
│ │ ├── KaTeX_Size4-Regular.woff
│ │ ├── KaTeX_Size4-Regular.woff2
│ │ ├── KaTeX_Caligraphic-Bold.woff
│ │ ├── KaTeX_Caligraphic-Bold.woff2
│ │ ├── KaTeX_Fraktur-Regular.woff2
│ │ ├── KaTeX_Main-BoldItalic.woff2
│ │ ├── KaTeX_Math-BoldItalic.woff2
│ │ ├── KaTeX_SansSerif-Italic.woff
│ │ ├── KaTeX_SansSerif-Italic.woff2
│ │ ├── KaTeX_SansSerif-Regular.ttf
│ │ ├── KaTeX_SansSerif-Regular.woff
│ │ ├── KaTeX_Typewriter-Regular.ttf
│ │ ├── KaTeX_Caligraphic-Regular.ttf
│ │ ├── KaTeX_Caligraphic-Regular.woff
│ │ ├── KaTeX_Caligraphic-Regular.woff2
│ │ ├── KaTeX_SansSerif-Regular.woff2
│ │ ├── KaTeX_Typewriter-Regular.woff
│ │ └── KaTeX_Typewriter-Regular.woff2
└── index.html
├── WaterproofScreenshot.png
├── tests
├── .eslintrc.js
├── unit
│ ├── io
│ │ ├── test-notebooks
│ │ │ ├── text-block.wpn
│ │ │ ├── hint-block.wpn
│ │ │ ├── code-block.wpn
│ │ │ ├── exercise-sheet.wpn
│ │ │ ├── input-area.wpn
│ │ │ ├── non-exercise-sheet-input.wpn
│ │ │ └── exercise-sheet-input.wpe
│ │ ├── compileToVO.spec.js
│ │ ├── blocks
│ │ │ ├── notebook-filepath.spec.js
│ │ │ ├── notebook-parse-to-text.spec.js
│ │ │ └── notebook-input-blocks.spec.js
│ │ └── shortkey.spec.js
│ ├── serapi
│ │ ├── processors
│ │ │ └── responses
│ │ │ │ ├── checkQuestionMarkResult.json
│ │ │ │ ├── readyResponse.json
│ │ │ │ └── searchPlusResponse.json
│ │ ├── flatten-expr.spec.js
│ │ ├── util
│ │ │ └── ExpectingSerapiWorker.js
│ │ └── stringIndex.spec.js
│ └── vue
│ │ └── tabs.spec.js
└── e2e
│ └── electron.e2e.js
├── stylelint.config.js
├── scripts
├── checked-timeout
├── unix_installer.sh
├── Dockerfile
├── unit_test_parser.py
├── actions
│ └── match-glob.js
└── sloc
├── test-notebooks
├── acceptance-test
│ ├── filler1.wpn
│ ├── filler2.wpn
│ ├── filler3.wpn
│ ├── coq-version.wpn
│ ├── libraries.wpn
│ ├── invalid-code.wpn
│ ├── goals.wpn
│ ├── tactics.wpn
│ ├── notations.wpn
│ ├── definitions.wpn
│ ├── exercise.wpe
│ └── exercise.wpn
├── test4.wpn
├── error_test.wpn
├── test1.wpe
├── test3.wpn
├── exerciseTest.wpe
├── exerciseTest.wpn
└── test2.wpn
├── nyc.config.js
├── babel.config.js
├── e2e.mocha.json
├── unit.mocha.json
├── .eslintrc.json
├── .editorconfig
├── advanced-installation.md
├── .gitignore
├── .github
└── workflows
│ └── lint-and-test.yml
├── documentation
└── Cloning-the-repository.md
└── vue.config.js
/src/assets/sass/pages/_home.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitconfig:
--------------------------------------------------------------------------------
1 | [core]
2 | autocrlf true
3 |
--------------------------------------------------------------------------------
/wrapper/wplib/compileList.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/icon.png
--------------------------------------------------------------------------------
/WaterproofScreenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/WaterproofScreenshot.png
--------------------------------------------------------------------------------
/wrapper/win/wpwrapper.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/wrapper/win/wpwrapper.exe
--------------------------------------------------------------------------------
/src/assets/images/druppel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/images/druppel.png
--------------------------------------------------------------------------------
/wrapper/mac/wpwrapper_mac.mac:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/wrapper/mac/wpwrapper_mac.mac
--------------------------------------------------------------------------------
/wrapper/lin/wpwrapper_ubuntu.ubuntu:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/wrapper/lin/wpwrapper_ubuntu.ubuntu
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_AMS-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_AMS-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Bold.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Bold.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Bold.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Italic.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Math-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Math-Italic.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_AMS-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_AMS-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_AMS-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_AMS-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Fraktur-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Fraktur-Bold.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Fraktur-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Fraktur-Bold.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Italic.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Italic.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Math-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Math-Italic.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Math-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Math-Italic.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size1-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size1-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size2-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size2-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size3-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size3-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size4-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size4-Regular.ttf
--------------------------------------------------------------------------------
/tests/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | mocha: true,
4 | },
5 | rules: {
6 | 'require-jsdoc': 0,
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Caligraphic-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Caligraphic-Bold.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Fraktur-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Fraktur-Bold.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Fraktur-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Fraktur-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Fraktur-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Fraktur-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-BoldItalic.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-BoldItalic.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Math-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Math-BoldItalic.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Math-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Math-BoldItalic.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Bold.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Bold.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Bold.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Italic.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Script-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Script-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Script-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Script-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Script-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Script-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size1-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size1-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size1-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size1-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size2-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size2-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size2-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size2-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size3-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size3-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size3-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size3-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size4-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size4-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Size4-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Size4-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Caligraphic-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Caligraphic-Bold.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Caligraphic-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Caligraphic-Bold.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Fraktur-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Fraktur-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Main-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Main-BoldItalic.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Math-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Math-BoldItalic.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Italic.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Italic.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Typewriter-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Typewriter-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Caligraphic-Regular.ttf
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Caligraphic-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Caligraphic-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Caligraphic-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_SansSerif-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_SansSerif-Regular.woff2
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Typewriter-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Typewriter-Regular.woff
--------------------------------------------------------------------------------
/public/katex/fonts/KaTeX_Typewriter-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/public/katex/fonts/KaTeX_Typewriter-Regular.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/CenturyGothic/CenturyGothic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/CenturyGothic/CenturyGothic.woff2
--------------------------------------------------------------------------------
/stylelint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'stylelint-config-standard-scss',
3 | rules: {
4 | 'color-hex-length': 'long',
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/src/assets/fonts/CenturyGothic/CenturyGothic-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/CenturyGothic/CenturyGothic-Bold.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/LetterGothicStd/LetterGothicStd.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/LetterGothicStd/LetterGothicStd.woff2
--------------------------------------------------------------------------------
/scripts/checked-timeout:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | timeout "$@"
4 | ret=$?
5 |
6 | if [[ ${ret} -eq 124 ]]
7 | then
8 | exit 0
9 | fi
10 |
11 | exit ${ret}
12 |
--------------------------------------------------------------------------------
/src/assets/fonts/CenturyGothic/CenturyGothic-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/CenturyGothic/CenturyGothic-Italic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/LetterGothicStd/LetterGothicStd-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/LetterGothicStd/LetterGothicStd-Bold.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-700.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/CenturyGothic/CenturyGothic-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/CenturyGothic/CenturyGothic-BoldItalic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/LetterGothicStd/LetterGothicStd-Slanted.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/LetterGothicStd/LetterGothicStd-Slanted.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-italic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-regular.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/LetterGothicStd/LetterGothicStd-BoldSlanted.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/LetterGothicStd/LetterGothicStd-BoldSlanted.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-700italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-v20-latin/roboto-v20-latin-700italic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-700.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-italic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-regular.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-700italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/impermeable/waterproof/HEAD/src/assets/fonts/roboto-mono-v13-latin/roboto-mono-v13-latin-700italic.woff2
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/text-block.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "This is some sample text."
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/filler1.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof filler notebook 1"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/filler2.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof filler notebook 2"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/filler3.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof filler notebook 3"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/hint-block.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "hint",
6 | "text": "It's really not that hard."
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/code-block.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "code",
6 | "text": "Lemma a: forall n: nat, n + 0 = n."
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/nyc.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | perFile: true,
3 | include: ['src/**/*.{js,vue}'],
4 | reportDir: 'out/coverage',
5 | reporter: ['text', 'text-summary', 'html'],
6 | instrument: false,
7 | sourceMap: false,
8 | };
9 |
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_colorDefinitions.scss:
--------------------------------------------------------------------------------
1 | $colors: (
2 | // Could specify colors here in the form:
3 | // name: #value,
4 | tronLightBlue: #a1fefe,
5 | tronDarkBlue: #004242,
6 | white: #FFFFFF,
7 | black: #000000
8 | );
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | if (process.env.NODE_ENV === 'coverage') {
2 | module.exports = {
3 | presets: ['@vue/app'],
4 | plugins: ['istanbul'],
5 | };
6 | } else {
7 | module.exports = {
8 | presets: ['@vue/app'],
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/exercise-sheet.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "commandBlacklist": [],
4 | "blocks": [
5 | {
6 | "type": "code",
7 | "text": "Lemma a: forall n: nat, n + 0 = n."
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/e2e.mocha.json:
--------------------------------------------------------------------------------
1 | {
2 | "reporterEnabled": "mochawesome,mocha-junit-reporter",
3 | "mochawesomeReporterOptions": {
4 | "reportFilename": "index",
5 | "reportDir": "out/test-e2e"
6 | },
7 | "mochaJunitReporterReporterOptions": {
8 | "mochaFile": "out/test-e2e.xml"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/unit.mocha.json:
--------------------------------------------------------------------------------
1 | {
2 | "reporterEnabled": "mochawesome,mocha-junit-reporter",
3 | "mochawesomeReporterOptions": {
4 | "reportFilename": "index",
5 | "reportDir": "out/test-unit"
6 | },
7 | "mochaJunitReporterReporterOptions": {
8 | "mochaFile": "out/test-unit.xml"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/input-area.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "input",
6 | "start": true,
7 | "id": "in1"
8 | },
9 | {
10 | "type": "input",
11 | "start": false,
12 | "id": "in1"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/coq-version.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: Coq version"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Lia.\nAbout Lia."
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
15 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/libraries.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: libraries"
7 | },
8 | {
9 | "type": "code",
10 | "text": "From Coq Require Import Reals.\nOpen Scope R_scope."
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/wrapper/windows-installer.nsh:
--------------------------------------------------------------------------------
1 | !macro customInstall
2 | File '/oname=$PLUGINSDIR\Coq-Waterproof-installer.exe' '${PROJECT_DIR}\Coq-Waterproof-installer.exe'
3 | ExecWait '"$PLUGINSDIR\Coq-Waterproof-installer.exe"' $0
4 | DetailPrint "installer result: $0"
5 | Delete "$PLUGINSDIR\coq-platform-installer.exe"
6 | !macroend
7 |
8 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/invalid-code.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: definitions"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Lemma a1 n: n + 0 = n.\nProof.\n now induction k.\nQed.\n"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/src/editpage/components/blocks/code/Inlineable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
18 |
--------------------------------------------------------------------------------
/src/assets/images/trash-solid.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import Index from './index/Index';
2 | import Edit from './editpage/Edit';
3 |
4 | export default {
5 | routes: [
6 | {
7 | path: '/',
8 | name: 'home',
9 | component: Index,
10 | },
11 | {
12 | path: '/edit',
13 | name: 'edit',
14 | component: Edit,
15 | },
16 | {
17 | path: '*',
18 | redirect: '/',
19 | },
20 | ],
21 | };
22 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/goals.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: goals and hypotheses"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Lemma a: forall m n: nat, m >= 0 -> n >= 0 -> m = m /\\ n = n.\nProof.\n intro m.\n intro n.\n split.\n reflexivity.\n reflexivity.\nQed."
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/test-notebooks/test4.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "## Gaussian integral\n\nIn ```1809```, mathematician *Karl Friedrich Gauss* proved that the following holds:\n$$ \\int_{-\\infty}^{\\infty}e^{-ax^2} \\text{d}x = \\sqrt{\\frac{\\pi}{a}} $$\nThis is a **very interesting** mathematical result. It can be proven using a polar coordinate substitution."
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/scripts/unix_installer.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Run as root
3 | if [ "$EUID" -ne 0 ]; then
4 | echo "Please run as root"
5 | exit
6 | fi
7 |
8 | if [[ "$OSTYPE" == "linux-gnu" ]]; then
9 | echo "Detected Linux"
10 | tar -C /opt -zxf waterproof-ubuntu.tar.gz
11 | if [[ "$OSTYPE" == "darwin" ]]; then
12 | echo "Detected Linux"
13 | tar -C /opt -zxf waterproof-macos.tar.gz
14 | else
15 | echo "This operating system is not supported!"
16 | fi
--------------------------------------------------------------------------------
/src/activity-log.js:
--------------------------------------------------------------------------------
1 | const ipcRenderer = (() => {
2 | if (process.env.NODE_ENV === 'test') {
3 | return {
4 | send(channel, activity) {
5 | console.log('Would have written', activity, 'to', channel);
6 | },
7 | };
8 | } else {
9 | return require('electron').ipcRenderer;
10 | }
11 | })();
12 |
13 | export function writeActivity(type, details = {}) {
14 | ipcRenderer.send('activity', Object.assign({type}, details));
15 | }
16 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es6": true,
4 | "node": true
5 | },
6 | "extends": ["eslint:recommended", "plugin:vue/essential", "google"],
7 | "globals": {
8 | "Atomics": "readonly",
9 | "SharedArrayBuffer": "readonly"
10 | },
11 | "parserOptions": {
12 | "ecmaVersion": 2018,
13 | "sourceType": "module"
14 | },
15 | "rules": {
16 | "linebreak-style": 0,
17 | "no-console": 0,
18 | "require-jsdoc": "warn"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/coq/serapi/util/SerapiCallbacks.js:
--------------------------------------------------------------------------------
1 | /**
2 | * A general interface for receiving messages and feedbacks from serapi
3 | * @interface
4 | */
5 | class SerapiCallbacks {
6 | /**
7 | * Called when a message is received from serapi
8 | * @param {*} data the already parsed response from serapi
9 | * @param {String} extraTag the extra identifying tag
10 | */
11 | handleSerapiMessage(data, extraTag) {
12 | }
13 | }
14 |
15 | export default SerapiCallbacks;
16 |
--------------------------------------------------------------------------------
/scripts/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:lts
2 |
3 | RUN apt-get update && apt-get install -y \
4 | cloc \
5 | dc \
6 | jq \
7 | libasound2 \
8 | # libdbus-1-3 \
9 | libgconf-2-4 \
10 | libgtk-3-0 \
11 | libnss3 \
12 | libx11-xcb1 \
13 | libxss1 \
14 | libxtst6 \
15 | rsync \
16 | sudo \
17 | xvfb
18 |
19 | RUN echo "node ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/node && \
20 | chmod 0440 /etc/sudoers.d/node
21 |
22 | USER node
23 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | insert_final_newline = true
5 | trim_trailing_whitespace = true
6 | charset = utf-8
7 |
8 | # Google style guide requires 2-space indent.
9 | [e2e/**.js]
10 | indent_style = space
11 | indent_size = 2
12 | continuation_indent_size = 4
13 |
14 | [src/**.js]
15 | indent_style = space
16 | indent_size = 2
17 | continuation_indent_size = 4
18 |
19 | [test/**.js]
20 | indent_style = space
21 | indent_size = 2
22 | continuation_indent_size = 4
23 |
--------------------------------------------------------------------------------
/src/coq/serapi/workers/SerapiWorker.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Class that connects to serapi
5 | */
6 | class SerapiWorker {
7 | /**
8 | * Interface (non implementation) of SerapiWorker
9 | */
10 | constructor() {
11 | }
12 |
13 | /**
14 | * Send message
15 | * @param {String} message the message
16 | */
17 | postMessage(message) {
18 | }
19 |
20 | /**
21 | * Stop this worker
22 | */
23 | terminate() {
24 | }
25 | }
26 |
27 | export default SerapiWorker;
28 |
--------------------------------------------------------------------------------
/src/assets/sass/layout/_sidebar.scss:
--------------------------------------------------------------------------------
1 | @import '../colors.scss';
2 |
3 | .sidebar-button {
4 | display: flex;
5 | color: white;
6 | padding: 5px 0 5px 0;
7 | white-space: nowrap;
8 | block-size: 35px;
9 | user-select: none;
10 | transition: 0.3s;
11 |
12 | @include respond-to(sm-lower) {
13 | block-size: 25px;
14 | }
15 |
16 | &:hover:not(.disabled) {
17 | @include theme(background-color, color-primary-light);
18 | }
19 |
20 | .button-tooltip {
21 | margin: auto 0;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/tactics.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: tactics"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Definition def1 n := 0 + n = n.\nLtac tac1 var :=\n intros var;\n unfold def1.\n\nLtac tac2 var :=\n tac1 var;\n rewrite plus_O_n;\n reflexivity.\n\nLemma l : forall n : nat, def1 n.\nProof.\n tac2 n.\nQed.\n\nPrint def1.\nPrint tac1.\nPrint tac2.\nCheck l."
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/src/assets/images/arrowRight.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/wrapper/assistance/commands.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "Check",
4 | "description": "Check gives you the type of a Coq object.",
5 | "example": "Check plus."
6 | },
7 | {
8 | "name": "Print",
9 | "description": "Print gives a more detailed description of a Coq object.",
10 | "example": "Print nat."
11 | },
12 | {
13 | "name": "About",
14 | "description": "About gives an overview of a Coq object.",
15 | "example": "About plus."
16 | }
17 | ]
--------------------------------------------------------------------------------
/src/assets/images/arrowLeft.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/notations.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: notations"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Fixpoint power (x n : nat) {struct n} : nat :=\n match n with\n | 0 => 1\n | S m => x * power x m\n end.\n\nNotation \"x ^ n\" := (power x n).\nLemma a: forall n : nat, n ^ 1 = n * 1.\nProof.\n intro n.\n unfold power.\n reflexivity.\nQed.\nPrint power.\nCheck a."
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/tests/unit/io/compileToVO.spec.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | //TODO write tests for vo compiler
3 | const fs = require('fs');
4 | const path = require('path');
5 | const sinon = require('sinon');
6 | const chai = require('chai');
7 | const sandbox = sinon.createSandbox();
8 | const expect = chai.expect;
9 |
10 |
11 | import {VOCompiler}
12 | from '../../../src/io/compileToVO.js';
13 |
14 |
15 | describe('Compiling wpn files', () => {
16 | beforeEach(() => {
17 |
18 | });
19 |
20 | afterEach(() => {
21 | sandbox.restore();
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/src/assets/images/arrowDown.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/assets/images/arrowUp.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test-notebooks/error_test.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Example code\n\nFirst, we will show some mathematics: $\\forall n \\in \\mathbb{N}: n + 0 = n$. We prove this in Coq."
7 | },
8 | {
9 | "type": "code",
10 | "text": "Lemma a: forall n: nat, n + 0 = n.\nProof. intro n.\nQed."
11 | },
12 | {
13 | "type": "text",
14 | "text": "This proof does not work, because we don't successfully prove that $n + 0 = n$ for the $n \\in \\mathbb{N}$ we introduced."
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/src/assets/images/arrowPrevious.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/sass/base/_base.scss:
--------------------------------------------------------------------------------
1 | /** Standard styles for common HTML elements. */
2 |
3 | /**
4 | * Easier to size elements
5 | * See https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
6 | */
7 | html {
8 | box-sizing: border-box;
9 | }
10 |
11 | /**
12 | * We let all other elements inherit (from html). This will make it easier to
13 | * change this setting for e.g. plugins or components in the future.
14 | */
15 | *,
16 | *::before,
17 | *::after {
18 | box-sizing: inherit;
19 | }
20 |
21 | /**
22 | * Don't underline links.
23 | */
24 | a {
25 | text-decoration: none;
26 | }
27 |
--------------------------------------------------------------------------------
/src/editpage/components/blocks/FoldBlock.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 | +
7 |
8 |
9 |
10 |
18 |
19 |
25 |
--------------------------------------------------------------------------------
/src/assets/images/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/images/closing_cross.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/images/commentButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/wrapper/wplib/Tactics/Waterprove.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "* Waterprove: Tactic automation for Waterproof"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Reals."
11 | },
12 | {
13 | "type": "code",
14 | "text": "Ltac waterprove t s :=\n timeout 60 (first [ solve [auto using s with *]\n | solve [eauto using s with *]\n | solve [intuition (auto using s with * )]\n | solve [intuition (eauto using s with * )]\n | idtac \"Waterproof could not find a proof of \" t])."
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_functions.scss:
--------------------------------------------------------------------------------
1 | @import './_colorDefinitions';
2 |
3 | //gets a color value from color map, defined in colorDefinitions
4 | @function color($colorName) {
5 | @return map-get($colors, $colorName);
6 | }
7 |
8 | //helper function for checking if theme exists in theme colors
9 | @function themeExists($key, $theme) {
10 | @if map-has-key($themeValues, $key) {
11 | @return map-has-key(map-get($themeValues, $key), $theme);
12 | }
13 | @return null;
14 | }
15 |
16 | //helper function for getting a theme color
17 | @function getThemeValue($key, $theme) {
18 | @return map-get(map-get($themeValues, $key), $theme);
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/non-exercise-sheet-input.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "This is sample text"
7 | },
8 | {
9 | "type": "input",
10 | "start": true,
11 | "id": "in1"
12 | },
13 | {
14 | "type": "code",
15 | "text": "Lemma a n: n + 0 = n."
16 | },
17 | {
18 | "type": "text",
19 | "text": "This is sample text"
20 | },
21 | {
22 | "type": "input",
23 | "start": false,
24 | "id": "in1"
25 | },
26 | {
27 | "type": "code",
28 | "text": "Proof."
29 | }
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/src/assets/images/arrowNext.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/unit/io/test-notebooks/exercise-sheet-input.wpe:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "commandBlacklist": [],
4 | "blocks": [
5 | {
6 | "type": "text",
7 | "text": "This is sample text"
8 | },
9 | {
10 | "type": "input",
11 | "start": true,
12 | "id": "in1"
13 | },
14 | {
15 | "type": "code",
16 | "text": "Lemma a n: n + 0 = n."
17 | },
18 | {
19 | "type": "text",
20 | "text": "This is sample text"
21 | },
22 | {
23 | "type": "input",
24 | "start": false,
25 | "id": "in1"
26 | },
27 | {
28 | "type": "code",
29 | "text": "Proof."
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/src/assets/images/arrowDoubleRight.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/editpage/components/mixins/CodeExecution.vue:
--------------------------------------------------------------------------------
1 |
29 |
--------------------------------------------------------------------------------
/advanced-installation.md:
--------------------------------------------------------------------------------
1 | # Advanced installation on Windows (e.g. for developers)
2 |
3 | 1. Follow the steps under "Compiling from sources with Cygwin as build host" in the Windows install instructions on https://github.com/coq/platform
4 | 2. Convert the files to unix line endings with ```find . -type f -print0 | xargs -0 dos2unix``` from cygwin
5 | 3. In particular, make sure you have activated the right opam switch as described in the build instructions
6 | 4. In the installed cygwin, execute ```opam install coq-serapi```
7 | 5. Clone the repository https://github.com/impermeable/coq-waterproof
8 | 6. With the installed cygwin, navigate to the folder in which coq-waterproof is located, execute ```make``` and then ```make install```.
9 |
--------------------------------------------------------------------------------
/src/assets/images/tooltipClose.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/images/tooltipExpand.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/scripts/unit_test_parser.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | def tex_escape(text):
4 | return text.replace("&", "\\&").replace("$", "\\$").replace("_", "\\_")
5 |
6 | def append_test(file, suites):
7 | for suite in suites:
8 | for test in suite["tests"]:
9 | text = "\\item " + tex_escape(test["fullTitle"]) + "\n"
10 | file.write(text)
11 | append_test(file, suite["suites"])
12 |
13 | def main():
14 | tex_file = open("unit_tests.tex", "w", encoding="utf8")
15 |
16 | with open("../out/test-unit/index.json", "r", encoding="utf8") as json_file:
17 | data = json.load(json_file)
18 | append_test(tex_file, data["results"])
19 |
20 | print("Done!")
21 | tex_file.close()
22 |
23 | if __name__ == '__main__':
24 | main()
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | doc/
2 | node_modules/
3 | out/
4 | .DS_Store
5 | dist/
6 |
7 | tests/e2e/reports/
8 | selenium-debug.log
9 |
10 | # local env files
11 | .env.local
12 | .env.*.local
13 |
14 | # Log files
15 | npm-debug.log*
16 | yarn-debug.log*
17 | yarn-error.log*
18 |
19 | # Editor directories and files
20 | .idea
21 | .vscode
22 | *.suo
23 | *.ntvs*
24 | *.njsproj
25 | *.sln
26 | *.sw?
27 |
28 | #Electron-builder output
29 | /dist_electron
30 | .nyc_output
31 |
32 | # Recent files list
33 | src/io/recentFileList.json
34 | recentFileList.json
35 |
36 | # Shortcuts
37 | shortKeys.json
38 |
39 | build/icons/*
40 | scripts/unit_tests.tex
41 |
42 | # wpwrapper logs
43 | /wpwrapper.*
44 |
45 | # compiled Coq libraries
46 | *.vo
47 |
48 | wrapper/**/*.v
49 |
--------------------------------------------------------------------------------
/src/assets/sass/base/_typography.scss:
--------------------------------------------------------------------------------
1 | /** Basic typography styles */
2 | @import '../_colors.scss';
3 |
4 | body {
5 | @include theme(color, color-on-surface);
6 | @include theme(font, font-stack-body, normal 125% / 1.4);
7 | }
8 |
9 | h1 {
10 | font-size: 2.5rem;
11 | }
12 |
13 | h2 {
14 | font-size: 2rem;
15 | }
16 |
17 | h3 {
18 | font-size: 1.75rem;
19 | }
20 |
21 | h4 {
22 | font-size: 1.5rem;
23 | }
24 |
25 | h5 {
26 | font-size: 1.25rem;
27 | }
28 |
29 | h6 {
30 | font-size: 1rem;
31 | }
32 |
33 | h1, h2, h3, h4, h5, h6 {
34 | margin-top: 0;
35 | margin-bottom: 0.5rem;
36 | //@include theme(font-family, font-stack-headers); // Not quite sure why this does not work...
37 | }
38 |
39 | p {
40 | margin-bottom: 1rem;
41 | }
42 |
--------------------------------------------------------------------------------
/src/assets/sass/main.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /** Contains all imports */
4 | @import 'colors.scss';
5 |
6 | @import 'abstracts/colorDefinitions';
7 | @import 'abstracts/functions';
8 | @import 'abstracts/light';
9 | @import 'abstracts/dark';
10 | @import 'abstracts/light_roboto';
11 | @import 'abstracts/dark_roboto';
12 | @import 'abstracts/variables';
13 | @import 'abstracts/mixins';
14 |
15 | @import 'base/base';
16 | @import 'base/reset';
17 | @import 'base/typography';
18 | @import 'base/fonts';
19 |
20 | @import 'components/topbar-dropdown';
21 |
22 | @import 'layout/_topbar';
23 | @import 'layout/_sidebar';
24 | @import 'layout/_tablist';
25 | @import 'layout/_response-window';
26 |
27 | @import '~vue-context/dist/css/vue-context.css';
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/definitions.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: definitions"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Lemma a1 n: n + 0 = n.\nProof.\n now induction n.\nQed.\n"
11 | },
12 | {
13 | "type": "code",
14 | "text": "Definition plus_0 n := n + 0.\nDefinition is_self n := plus_0 n = n.\n"
15 | },
16 | {
17 | "type": "code",
18 | "text": "Lemma a2: forall n: nat, is_self n.\nProof.\n intro n.\n unfold is_self.\n unfold plus_0.\n apply a1.\nQed.\n"
19 | },
20 | {
21 | "type": "code",
22 | "text": "Check a1.\nPrint plus_0.\nPrint is_self.\nCheck a2."
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Waterproof
11 |
12 |
13 |
14 | We're sorry but electron-vue doesn't work properly without JavaScript enabled. Please enable it to continue.
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/editpage/components/blocks/TextBlock.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
27 |
28 |
30 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/symbols/MathsSymbol.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{item.symbol}}
4 |
5 |
6 |
7 |
16 |
17 |
33 |
--------------------------------------------------------------------------------
/tests/unit/io/blocks/notebook-filepath.spec.js:
--------------------------------------------------------------------------------
1 | import Notebook from '../../../../src/io/notebook';
2 |
3 | const chai = require('chai');
4 | const expect = chai.expect;
5 |
6 |
7 | describe('Notebook file path', () => {
8 | let notebook;
9 |
10 | beforeEach(() => {
11 | notebook = new Notebook;
12 | });
13 |
14 | it('should not have file path at the start', (done) => {
15 | expect(notebook.filePath).to.equal('');
16 | expect(notebook.getName()).to.equal('untitled');
17 | done();
18 | });
19 |
20 | it('should update the filepath and name when set', (done) => {
21 | const filePath = '/test/a/real/path/notebook.wpn';
22 | notebook.setFilePath(filePath);
23 | expect(notebook.filePath).to.equal(filePath);
24 | expect(notebook.getName()).to.equal('notebook.wpn');
25 | done();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/assets/images/textButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/assets/images/newfile.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
11 |
12 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/assets/images/WaterproofIconWhite.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/images/settingsGear.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/assets/images/looking_glass_blue.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/images/looking_glass_grey.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/images/tick.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/src/editpage/components/response/ResponseWindow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
36 |
37 |
39 |
--------------------------------------------------------------------------------
/tests/unit/serapi/processors/responses/checkQuestionMarkResult.json:
--------------------------------------------------------------------------------
1 | [
2 | "Ack",
3 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents Processed)))",
4 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents(Message Notice()(Pp_glue((Pp_box(Pp_hovbox 0)(Pp_tag constr.evar(Pp_glue((Pp_string ?y)))))Pp_force_newline(Pp_string\" : \")(Pp_box(Pp_hovbox 0)(Pp_tag constr.evar(Pp_glue((Pp_string ?T)))))Pp_force_newline(Pp_string where)Pp_force_newline(Pp_box(Pp_hovbox 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_string\"?T : \")(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_string\"[\")(Pp_box(Pp_hvbox 0)Pp_empty)(Pp_print_break 1 0)(Pp_string\"|- \")(Pp_tag constr.type(Pp_string Type))(Pp_string\"]\"))))))))Pp_force_newline(Pp_box(Pp_hovbox 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_string\"?y : \")(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_string\"[\")(Pp_box(Pp_hvbox 0)Pp_empty)(Pp_print_break 1 0)(Pp_string\"|- \")(Pp_box(Pp_hovbox 0)(Pp_tag constr.evar(Pp_glue((Pp_string ?T)))))(Pp_string\"]\"))))))))))))))",
5 | "(ObjList())",
6 | "Completed"
7 | ]
8 |
--------------------------------------------------------------------------------
/src/assets/images/symbolButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/images/tickInCircle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/tests/unit/serapi/flatten-expr.spec.js:
--------------------------------------------------------------------------------
1 | const parse = require('s-expression');
2 | const {flatten} = require('../../../src/coq/serapi/flatten-expr');
3 |
4 | const chai = require('chai');
5 | const expect = chai.expect;
6 |
7 | describe('s-expression flattener', () => {
8 | it('should parse an s-expression correctly', (done) => {
9 | // Give a sample string, that contains key-value pairs, nested key-value
10 | // pairs, and entries that are not key-value pairs
11 | const expression = '(((key1 val1)(key2 ((subkey1 subval1)(subkey2 ' +
12 | 'subval2)))(key3 val3))(not_a_key))';
13 | const parsed = parse(expression);
14 | const flattened = flatten(parsed);
15 | const expected = [
16 | {
17 | 'key1': 'val1',
18 | 'key2': {
19 | 'subkey1': 'subval1',
20 | 'subkey2': 'subval2',
21 | },
22 | 'key3': 'val3',
23 | },
24 | [
25 | 'not_a_key',
26 | ],
27 | ];
28 | expect(flattened).to.deep.equal(expected);
29 | done();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/src/editpage/components/Gutter.vue:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
8 |
10 |
12 |
14 |
15 |
16 |
17 |
31 |
--------------------------------------------------------------------------------
/.github/workflows/lint-and-test.yml:
--------------------------------------------------------------------------------
1 | name: run-test-lint
2 | on: [push, pull_request]
3 |
4 | jobs:
5 | lint-test-run:
6 | runs-on: ubuntu-latest
7 | name: Lint the sources and run unit tests
8 | steps:
9 | - uses: actions/checkout@v3
10 | - name: Cache node modules
11 | uses: actions/cache@v3
12 | with:
13 | path: ~/.npm
14 | key: small-npm-deps-${{ hashFiles('**/package-lock.json') }}-ubuntu-latest
15 | restore-keys: small-npm-deps-
16 | - name: Use Node.js
17 | uses: actions/setup-node@v2
18 | with:
19 | node-version: '12.x'
20 | - run: npm ci
21 | - name: Lint sources
22 | run: npm run lint
23 | - name: Run unit tests
24 | run: npm run test:unit
25 | - name: Can serve/start application
26 | run: |
27 | echo "::group::Building application"
28 | scripts/checked-timeout 30 xvfb-run npm run electron:testserve
29 | echo "::endgroup::"
30 | echo "Application started succesfully!"
31 |
--------------------------------------------------------------------------------
/src/assets/images/tutorial.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/assets/sass/_colors.scss:
--------------------------------------------------------------------------------
1 | @import '/abstracts/_mixins.scss';
2 |
3 | /** this section generates a theme map for each theme **/
4 | $themes: ();
5 | $themeValues: ();
6 |
7 | @import '/abstracts/_light.scss';
8 | @include generateThemeMappings(light, $light);
9 |
10 | @import '/abstracts/_dark.scss';
11 | @include generateThemeMappings(dark, $dark);
12 |
13 | @import '/abstracts/_light_roboto.scss';
14 | @include generateThemeMappings(light_roboto, $light_roboto);
15 |
16 | @import '/abstracts/_dark_roboto.scss';
17 | @include generateThemeMappings(dark_roboto, $dark_roboto);
18 | /** end theme generation **/
19 |
20 | /** To add another theme:
21 | - Create file like light.scss in src/sass/abstracts
22 | - Add reference in src/sass/main
23 | - Add reference and generateThemeMapping in this file
24 | - Go to SettingsModal.vue and add map name to styles list
25 | (For simplicity, we only check in SettingsModal whether the map exists)
26 |
27 | NOTE: The default theme is light, and to change this:
28 | - Go to src/store/store.js and change default
29 | - Change class of element
30 | */
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/exercise.wpe:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: definitions"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Lemma a1 n: n + 0 = n.\nProof.\n now induction n.\nQed.\n"
11 | },
12 | {
13 | "type": "code",
14 | "text": "Definition plus_0 n := n + 0.\nDefinition is_self n := plus_0 n = n.\n"
15 | },
16 | {
17 | "type": "code",
18 | "text": "Lemma a2: forall n: nat, is_self n.\nProof.\n intro n.\n unfold is_self.\n unfold plus_0.\n apply a1.\nQed.\n"
19 | },
20 | {
21 | "type": "code",
22 | "text": "Check a1.\nPrint plus_0.\nPrint is_self.\nCheck a2."
23 | },
24 | {
25 | "type": "hint",
26 | "text": "This is the hint title.\n\nThis is the hint description."
27 | },
28 | {
29 | "type": "input",
30 | "start": true,
31 | "id": "input-0"
32 | },
33 | {
34 | "type": "input",
35 | "start": false,
36 | "id": "input-0"
37 | }
38 | ]
39 | }
--------------------------------------------------------------------------------
/test-notebooks/acceptance-test/exercise.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Waterproof test: definitions"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Lemma a1 n: n + 0 = n.\nProof.\n now induction n.\nQed.\n"
11 | },
12 | {
13 | "type": "code",
14 | "text": "Definition plus_0 n := n + 0.\nDefinition is_self n := plus_0 n = n.\n"
15 | },
16 | {
17 | "type": "code",
18 | "text": "Lemma a2: forall n: nat, is_self n.\nProof.\n intro n.\n unfold is_self.\n unfold plus_0.\n apply a1.\nQed.\n"
19 | },
20 | {
21 | "type": "code",
22 | "text": "Check a1.\nPrint plus_0.\nPrint is_self.\nCheck a2."
23 | },
24 | {
25 | "type": "hint",
26 | "text": "This is the hint title.\n\nThis is the hint description."
27 | },
28 | {
29 | "type": "input",
30 | "start": true,
31 | "id": "input-0"
32 | },
33 | {
34 | "type": "input",
35 | "start": false,
36 | "id": "input-0"
37 | }
38 | ]
39 | }
--------------------------------------------------------------------------------
/src/editpage/components/blocks/InputBlock.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
17 |
18 |
38 |
--------------------------------------------------------------------------------
/scripts/actions/match-glob.js:
--------------------------------------------------------------------------------
1 | const glob = require('@actions/glob');
2 | const core = require('@actions/core');
3 | const path = require('path');
4 |
5 | // eslint-disable-next-line require-jsdoc
6 | async function main() {
7 | console.log(process.argv);
8 | const globs = process.argv.slice(2).join('\n');
9 | if (globs === '') {
10 | throw new Error('Must specify some globs!');
11 | }
12 | core.info('Reading globs ', globs);
13 | const globber = await glob.create(globs, {
14 | followSymbolicLinks: false,
15 | });
16 | const files = await globber.glob();
17 |
18 | const file = files.length > 0 ? files[0] : '';
19 |
20 | core.info('Found ' + files.length + ' files');
21 |
22 | core.setOutput('any', files.length > 0);
23 | core.setOutput('match', file);
24 | core.setOutput('name', path.basename(file));
25 | core.setOutput('matchCount', files.length);
26 |
27 | return files.length > 0;
28 | }
29 |
30 | main().then((any) => {
31 | if (!any) {
32 | core.setFailed(`No files matched!`);
33 | } else {
34 | process.exit(0);
35 | }
36 | }).catch((err) => {
37 | core.setFailed(`Action failed with error ${err}`);
38 | });
39 |
40 |
--------------------------------------------------------------------------------
/wrapper/wplib/Definitions/SetDefinitions.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "* Definitions for sets"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Reals.\nOpen Scope R_scope."
11 | },
12 | {
13 | "type": "text",
14 | "text": "The following line automatically generates induction schemes for Records."
15 | },
16 | {
17 | "type": "code",
18 | "text": "Set Nonrecursive Elimination Schemes."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Record elements_R_satisfying (pred : R -> Prop)\n := mk_element_R {\n element :> R;\n witness : pred element;\n}."
23 | },
24 | {
25 | "type": "code",
26 | "text": "Record subsets_R :=\n mk_subset_R {\n is_in : R -> Prop;\n elements := elements_R_satisfying is_in;\n}."
27 | },
28 | {
29 | "type": "code",
30 | "text": "Coercion subsets_R_to_elements :=\n (fun A : subsets_R => elements A).\n"
31 | },
32 | {
33 | "type": "code",
34 | "text": ""
35 | },
36 | {
37 | "type": "code",
38 | "text": ""
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/src/assets/images/lock_locked.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/src/coq/serapi/workers/SerapiWorkerJs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import SerapiWorker from './SerapiWorker';
4 |
5 | /**
6 | * Class that connects to serapi
7 | */
8 | class SerapiWorkerJs extends SerapiWorker {
9 | /**
10 | * Interface (non implementation) of SerapiWorker
11 | * @param {String} workerLocation
12 | */
13 | constructor(workerLocation='../../jscoq-builds/sertop_js.js') {
14 | super();
15 | this.worker = new Worker(workerLocation);
16 | this.worker.onmessage = (m) => this.handleMessage(m);
17 | this.worker.onerror =(error) => {
18 | console.log('js worker error:');
19 | console.log(error);
20 | };
21 | }
22 |
23 | /**
24 | * Send message
25 | * @param {String} message the message
26 | */
27 | postMessage(message) {
28 | this.worker.postMessage(message);
29 | }
30 |
31 | /**
32 | * Receives the messages from the worker
33 | * @param {String} message the message
34 | */
35 | handleMessage(message) {
36 | this.onMessage(message.data);
37 | }
38 |
39 | /**
40 | * Stop this worker
41 | */
42 | terminate() {
43 | this.worker.terminate();
44 | }
45 | }
46 |
47 | export default SerapiWorkerJs;
48 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/AssistanceButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | {{name}}
8 |
9 |
10 |
11 |
17 |
18 |
50 |
--------------------------------------------------------------------------------
/src/assets/images/lock_unlocked.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/src/io/pathHelper.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | /**
4 | * Get a path to the resources folder.
5 | * @return {string} the path to the resources folder
6 | */
7 | function getResourcesPath() {
8 | let resourcesPath;
9 | if (process.env.NODE_ENV === 'production') {
10 | resourcesPath = path.join(__dirname, '../../wrapper/');
11 | } else {
12 | resourcesPath = path.join('./wrapper/');
13 | }
14 | return path.resolve(resourcesPath);
15 | }
16 |
17 | /**
18 | * Get a path where we can (should be able to) store files
19 | * @return {string} the path
20 | */
21 | function getAppdataPath() {
22 | if (process.env.NODE_ENV === 'test') {
23 | return 'C:\\Users\\Sertop\\AppData\\Roaming\\waterproof\\';
24 | }
25 | const electron = require('electron');
26 | // userdata just gives the appdata with a folder with waterproof
27 | return (electron.app || electron.remote.app).getPath('userData');
28 | }
29 |
30 | /**
31 | * Get the path to the log files directory
32 | * @return {string} the path to the log files directory
33 | */
34 | function getLogfilesPath() {
35 | const basePath = getAppdataPath();
36 | return path.join(basePath, 'activity-logs');
37 | }
38 |
39 | export {getResourcesPath, getAppdataPath, getLogfilesPath};
40 |
--------------------------------------------------------------------------------
/src/assets/images/cross.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/images/cross-blue.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/scripts/sloc:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mkdir -p out
4 |
5 | # Count SLOC / LOCW
6 | cloc --by-file --csv --quiet --out=out/cloc.csv --include-lang=JavaScript src
7 |
8 | # Convert CSV output to JSON
9 | jq --slurp --raw-input \
10 | 'split("\n") | .[1:] | map(split(",")) | map(select(length > 0)) |
11 | map({
12 | "file": .[1],
13 | "code": (.[4] | tonumber),
14 | "comments": (.[3] | tonumber),
15 | "sum": ((.[3] | tonumber)+ (.[4] | tonumber))
16 | })' \
17 | out/cloc.csv > out/cloc.json
18 |
19 | # Compute min and avg percentages and trim whitespace
20 | min=$(jq 'map(.comments / .sum) | min' out/cloc.json | tr -d '[:space:]')
21 | avg=$(jq 'map(.comments / .sum) | add / length' out/cloc.json | tr -d '[:space:]')
22 | code=$(jq 'map(.code) | add' out/cloc.json | tr -d '[:space:]')
23 | comm=$(jq 'map(.comments) | add' out/cloc.json | tr -d '[:space:]')
24 |
25 | if [[ ! -e out/metrics.txt ]]
26 | then
27 | touch out/metrics.txt
28 | fi
29 |
30 | min=$(dc <<< "1 k 100 $min * 1 / p")
31 | avg=$(dc <<< "1 k 100 $avg * 1 / p")
32 |
33 | echo "min_comments_percentage $min" >> out/metrics.txt
34 | echo "avg_comments_percentage $avg" >> out/metrics.txt
35 | echo "total_sloc $code" >> out/metrics.txt
36 | echo "total_locw $comm" >> out/metrics.txt
37 |
--------------------------------------------------------------------------------
/documentation/Cloning-the-repository.md:
--------------------------------------------------------------------------------
1 | # Instructions on cloning the Waterproof repository
2 |
3 | Here we describe how you can clone the Waterproof repository, and build the application yourself.
4 |
5 | ## Clone this repository
6 |
7 | First clone the repository. For this, you would need [git](https://git-scm.com/downloads). Then, in a terminal (from a directory in which you want to install the folder with all Waterproof files) execute
8 | ```
9 | git clone https://github.com/impermeable/waterproof.git
10 | ```
11 | The move into the waterproof directory
12 | ```
13 | cd waterproof
14 | ```
15 |
16 | ## Install Node.js
17 |
18 | Install Node.js, for instance from [Node.js](https://nodejs.org/en/download/)
19 |
20 | ## Install the necessary modules
21 |
22 | In a terminal, move to the Waterproof base directory. Then, to install the necessary Node.js modules, run:
23 | ```
24 | npm install
25 | ```
26 |
27 | It may be necessary to update the modules with
28 | ```
29 | npm update
30 | ```
31 |
32 | ## Run the app in developer mode
33 | To run Waterproof in developer mode run
34 | ```
35 | npm run electron:serve
36 | ```
37 |
38 | ## Build the electron app
39 |
40 | To build the Electron app run:
41 | ```
42 | npm run electron:build
43 | ```
44 | An installer will be produced in the folder `dist_electron`.
45 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/symbols/SymbolCategory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ►
5 | ▼
6 | {{item.name}}
7 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
38 |
39 |
53 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/search/SearchResult.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ item.objectName }}
8 | {{ item.name }}
9 |
10 |
11 |
12 | {{ item.content }}
13 |
14 |
15 |
23 |
24 |
25 |
26 |
27 |
28 |
41 |
42 |
48 |
--------------------------------------------------------------------------------
/src/editpage/components/menubars/TopbarButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 | {{ buttonInfo.text }}
11 |
12 |
13 | {{ formattedShortcut }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
28 |
29 |
44 |
--------------------------------------------------------------------------------
/test-notebooks/test1.wpe:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "First, we need to load some libraries."
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Reals. Open Scope R_scope."
11 | },
12 | {
13 | "type": "text",
14 | "text": "The task is to prove that $c > 0$ implies $c \\neq 0$, for all $c \\in \\mathbb{R}$."
15 | },
16 | {
17 | "type": "code",
18 | "text": "Lemma c_pos_neq_0 :\n forall c : R,\n (c > 0) -> (c <> 0).\nProof."
19 | },
20 | {
21 | "type": "hint",
22 | "text": "You can solve this exercise using two lemmas from the\n standard library Coq.Reals.RIneq, namely Rgt_not_le and Req_le. \nIt is possible that just writing apply Rgt_not_le. won't do, and you need to help Coq a \nbit by providing the variables you want to apply the lemma to by writing apply (Rgt_not_le c 0).. ",
23 | "title": "Hints zijn dysfunctional."
24 | },
25 | {
26 | "type": "input",
27 | "start": true,
28 | "id": "input-0"
29 | },
30 | {
31 | "type": "code",
32 | "text": "(*Write your proof here*)"
33 | },
34 | {
35 | "type": "input",
36 | "start": false,
37 | "id": "input-0"
38 | },
39 | {
40 | "type": "code",
41 | "text": "Qed."
42 | }
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/tests/e2e/electron.e2e.js:
--------------------------------------------------------------------------------
1 | const testWithSpectron =
2 | require('vue-cli-plugin-electron-builder/lib/testWithSpectron');
3 | const chai = require('chai');
4 | const chaiAsPromised = require('chai-as-promised');
5 |
6 | chai.should();
7 | chai.use(chaiAsPromised);
8 |
9 | describe('Application launch', function() {
10 | // eslint-disable-next-line no-invalid-this
11 | this.timeout(100000);
12 |
13 | let app;
14 | let stopServe;
15 |
16 | beforeEach(function() {
17 | return testWithSpectron().then((instance) => {
18 | app = instance.app;
19 | stopServe = instance.stopServe;
20 | });
21 | });
22 |
23 | beforeEach(function() {
24 | chaiAsPromised.transferPromiseness = app.transferPromiseness;
25 | });
26 |
27 | afterEach(function() {
28 | if (app && app.isRunning()) {
29 | return stopServe();
30 | }
31 | });
32 |
33 | it('opens a window', function() {
34 | return app.client
35 | .getWindowCount()
36 | .should.eventually.be.equal(1)
37 | .browserWindow.isMinimized()
38 | .should.eventually.be.false.browserWindow.isVisible()
39 | .should.eventually.be.true.browserWindow.getBounds()
40 | .should.eventually.have.property('width')
41 | .and.be.above(0)
42 | .browserWindow.getBounds()
43 | .should.eventually.have.property('height')
44 | .and.be.above(0);
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/wrapper/wplib/Tactics/SetTheoryTactics.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "## Tactics for Set Theory and Algebra\nThis file contains custom tactics for the course set theory and algebra.\n"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Ring."
11 | },
12 | {
13 | "type": "text",
14 | "text": "\nNote, preferably, these tactics are made in Ltac2."
15 | },
16 | {
17 | "type": "code",
18 | "text": "Ltac goal_check_vena t := \n auto with VenA nocore;\n tryif (change t)\n then (idtac \"We indeed need to show that\" t)\n else fail \"This is not the current goal\".\n\nTactic Notation \"To\" \"show:\" constr(t) := \n goal_check_vena t."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Ltac resolve_ring t := \n match goal with\n | [ |- t ] => ring\n | _ => idtac \"This is not the current goal\"\n end.\n \nLtac resolve_ring_hypothesis t s :=\n tryif (assert (s : t); ring) \n then (idtac t \" indeed holds.\")\n else fail \"This does not follow from the properties of a ring\".\n\nTactic Notation \"Since\" constr(R) \"is\" \"a\" \"ring,\" constr(t) := \n resolve_ring t.\n\nTactic Notation \"Since\" constr(R) \"is\" \"a\" \"ring,\" constr(t) \"(\"ident(s)\")\" := \n resolve_ring_hypothesis t s.\n(*add check that R is ring*)"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/src/assets/images/crossInCircle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/AssistanceItem.vue:
--------------------------------------------------------------------------------
1 |
20 |
21 |
58 |
--------------------------------------------------------------------------------
/src/assets/images/spinner.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/assets/images/tutorialButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
14 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/assets/images/bulbOffWhite.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tests/unit/vue/tabs.spec.js:
--------------------------------------------------------------------------------
1 | import Edit from '@/editpage/Edit.vue';
2 | const chai = require('chai');
3 | const expect = chai.expect;
4 | import {shallowMount} from '@vue/test-utils';
5 | import Vue from 'vue';
6 | Vue.use(require('vue-shortkey'));
7 |
8 | const $route = {
9 | query: {
10 | },
11 | params: {
12 | },
13 | };
14 |
15 |
16 | describe('Tabs', () => {
17 | it('should open new tab when calling function openNewTab()', async () => {
18 | const wrapper = shallowMount(Edit, {
19 | mocks: {
20 | $route,
21 | },
22 | });
23 | const numberOfTabs = wrapper.vm.tabs.length;
24 | wrapper.vm.openNewTab();
25 | await Vue.nextTick();
26 | const newNumberOfTabs = wrapper.vm.tabs.length;
27 | expect(newNumberOfTabs).to.equal(numberOfTabs+1);
28 | });
29 |
30 | it('should close tab when calling function closeTab()', async () => {
31 | const wrapper = shallowMount(Edit, {
32 | mocks: {
33 | $route,
34 | },
35 | });
36 | wrapper.vm.openNewTab();
37 | wrapper.vm.openNewTab();
38 | await Vue.nextTick();
39 | const numberOfTabs = wrapper.vm.tabs.length;
40 | const idOfLastTab = wrapper.vm.tabs[numberOfTabs-1].id;
41 | wrapper.vm.closeTab(numberOfTabs-1);
42 | for (const tab of wrapper.vm.tabs) {
43 | expect(idOfLastTab === tab.id).to.equal(false);
44 | }
45 | const newNumberOfTabs = wrapper.vm.tabs.length;
46 | expect(newNumberOfTabs).to.equal(numberOfTabs-1);
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/wrapper/wplib/Notations/SetNotations.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Set notations\nFor Coq's Ensembles library"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Sets.Ensembles. \nRequire Import wplib.Tactics.Tactics.\nRequire Import wplib.Notations.Notations.\nNotation \"'subset' U\" := \n (Ensemble U) (at level 50). \n\nNotation \"'set_of_subsets' U\" := \n (Ensemble (Ensemble U)) (at level 50). \n\nDefinition empty {U} := Empty_set U.\nDefinition full {U} := Full_set U.\nNotation \"∅\" := \n (empty). \n\nNotation \"'Ω'\" := \n (full) (at level 0). \n\nNotation \"A ∩ B\" := \n (Intersection _ A B) (at level 45). \n\nNotation \"A ∪ B\" := \n (Union _ A B) (at level 45). \n\nNotation \"A \\ B\" := \n (Setminus _ A B) (at level 45). \n\nNotation \"x ∈ A\" := \n (In _ A x) (at level 50) : ensemble_scope. \n\nNotation \"x ∉ A\" := \n (~ In _ A x) (at level 50). \n\nNotation \"A ⊂ B\" := \n (Included _ A B) (at level 45). \n \nNotation \"A 'and' B 'are' 'disjoint'\" := \n (Disjoint _ A B) (at level 50). \n \nNotation \"{ x : T | P }\" := \n (fun (x : T) ↦ P) (x at level 99).\n(*these brackets are not the same as {}, and are not yet included in shortcuts! *)\n\nTactic Notation \"We\" \"prove\" \"equality\" \"by\" \"proving\" \"two\" \"inclusions\" :=\n apply Extensionality_Ensembles; \n unfold Same_set; \n unfold Included;\n split.\n \nOpen Scope ensemble_scope."
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/src/assets/images/bulbOff.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/assets/images/tacticButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/assets/images/arrowToCursor.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
10 |
11 |
12 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import App from './App.vue';
4 | import BootstrapVue from 'bootstrap-vue';
5 | import {writeActivity} from '@/activity-log';
6 |
7 | // add the coq mode to codemirror
8 | import './codemirror/CoqCodemirrorMode';
9 |
10 | import VueRouter from 'vue-router';
11 | import routes from './router';
12 |
13 | writeActivity('startup');
14 |
15 | Vue.config.productionTip = false;
16 | Vue.use(require('vue-shortkey'));
17 | Vue.use(Vuex);
18 | Vue.use(BootstrapVue);
19 | Vue.use(VueRouter);
20 |
21 | import store from './store/store';
22 |
23 | // We import this here (instead of via style-resources-loader) to prevent
24 | // duplication.
25 | import './assets/sass/main.scss';
26 |
27 | const router = new VueRouter(routes);
28 | router.afterEach((to, from) => {
29 | const location = to.query.location;
30 | writeActivity('navigation', {
31 | to: to.name,
32 | location: location,
33 | });
34 | });
35 |
36 | let url = window.location.href;
37 |
38 | if (url.endsWith('#/')) {
39 | url = url.substr(0, url.length - 2);
40 | }
41 |
42 | if (url.indexOf('?') >= 0) {
43 | const parts = url.split('?', 2)[1].split('&');
44 |
45 | for (const part of parts) {
46 | if (part.startsWith('location=')) {
47 | const location = decodeURIComponent(part.replace('location=', ''));
48 | router.replace({name: 'edit', query: {location}});
49 | }
50 | }
51 | }
52 |
53 | new Vue({
54 | store: new Vuex.Store(store),
55 | router,
56 | render: (h) => h(App),
57 | }).$mount('#app');
58 |
--------------------------------------------------------------------------------
/src/assets/sass/components/_topbar-dropdown.scss:
--------------------------------------------------------------------------------
1 | /** Contains the components of each dropdown menu
2 | (so buttons, list items and links). */
3 |
4 | @import '../colors.scss';
5 |
6 | .topbar-dropdown {
7 | /** The menu buttons (File, Edit, Coq, Help) */
8 | button {
9 | border: none;
10 | border-radius: 0;
11 | box-shadow: none !important;
12 | height: 100%;
13 | @include theme(background-color, color-primary);
14 |
15 | @include respond-to(sm-lower) {
16 | font-size: 13px;
17 | }
18 |
19 | &:hover {
20 | border: none;
21 | @include theme(background-color, color-primary-light);
22 | }
23 |
24 | &:active {
25 | border: none;
26 | @include theme(background-color, color-primary-dark, null, !important);
27 | }
28 | }
29 |
30 | /** The items in each dropdown menu */
31 | ul {
32 | border: none;
33 | border-radius: 0;
34 | padding: 0;
35 | margin: 0;
36 | @include theme(background-color, color-primary-dark);
37 | @include theme(color, color-on-primary);
38 | }
39 |
40 | /** The actions of each item*/
41 | a {
42 | display: flex;
43 | flex-flow: row nowrap;
44 | justify-content: space-between;
45 | color: white !important;
46 | @include theme(font-family, font-stack-headers);
47 |
48 | &:hover {
49 | @include theme(background-color, color-primary-light);
50 | }
51 | &:focus {
52 | @include theme(background-color, color-primary-light);
53 | }
54 | &.disabled {
55 | color: gray;
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/wrapper/wplib/Tactics/TacticsContra.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "code",
6 | "text": "(** * Syntax extensions for Computer programs for analysis\n\n This document contains some very preliminary experiments with \n notations, ltac definitions and tactic notations to make it possible \n to stay closer to mathematical language when writing proofs in Coq. *)\n\n(** This file is supposed to be put in a folder \n wplib/Tactics/ and intended to be compiled, \n with \n sercomp --mode=vo \n -R \"wplib\",\"wplib\"\n \"wplib/Tactics/TacticsContra.v\"*)\n\nRequire Import Rbase.\nRequire Import Rfunctions.\nRequire Import SeqSeries.\nRequire Import Rtrigo.\nRequire Import Ranalysis.\nRequire Import Integration.\nRequire Import micromega.Lra.\nRequire Import Omega.\nRequire Import Max.\nRequire Import Classical.\n(* Require Import Unicode.Utf8. *)\n\n(** * Classical tactics *)\n \n(** TODO: problem with current implementation is that \n the assumption is not explicitly named. *)\nLtac contra :=\n match goal with\n | [|- ?X] => destruct (classic X); try assumption\n | _ => idtac \"failure of tactic\"\n end.\n\nTactic Notation \"We\" \"argue\" \"by\" \"contradiction\" :=\n contra.\n \nTactic Notation \"Contradiction\" := contradiction."
7 | },
8 | {
9 | "type": "code",
10 | "text": "Hint Resolve not_all_not_ex : contra_hints.\nHint Resolve not_all_ex_not : contra_hints.\nHint Resolve not_ex_all_not : contra_hints.\nHint Resolve ex_not_not_all : contra_hints.\nHint Resolve all_not_not_ex : contra_hints."
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/src/assets/images/openfile.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
14 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/editpage/components/blocks/BlockContextMenuButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
27 |
28 |
56 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/tactics/Tactic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ item.name }}
8 |
9 |
10 |
11 | ►
12 | ▼
13 | {{ item.description }}
14 |
15 |
16 |
{{ item.example }}
17 |
18 |
26 |
27 |
28 |
29 |
30 |
31 |
54 |
55 |
57 |
--------------------------------------------------------------------------------
/src/pageless/Loader.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
35 |
36 |
63 |
--------------------------------------------------------------------------------
/wrapper/wplib/Lib/sequential_accumulation_points.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Sequential accumulation points"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Reals.\nRequire Import Lra.\nRequire Import Classical.\nRequire Import Classical_Pred_Type.\nRequire Import ClassicalChoice.\n\nRequire Import wplib.Tactics.Tactics.\nRequire Import wplib.Tactics.TacticsContra.\nRequire Import wplib.Tactics.Databases.\nRequire Import wplib.Notations.Notations.\nRequire Import wplib.Lib.sequences.\nRequire Import wplib.Lib.subsequences.\n\nHint Resolve Rabs_Rabsolu."
11 | },
12 | {
13 | "type": "code",
14 | "text": "Definition is_seq_acc_pt (a : ℕ → ℝ) (x : ℝ) : Prop :=\n ∃ n : ℕ → ℕ, is_index_seq n ∧ Un_cv (fun (k : ℕ) ↦ a(n k)) x."
15 | },
16 | {
17 | "type": "code",
18 | "text": "Lemma seq_bdd_seq_acc_pts_bdd :\n ∀ a : ℕ → ℝ, has_ub a ⇒ bound (is_seq_acc_pt a)."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Proof.\nTake a : (ℕ → ℝ).\nAssume a_upp_bdd : (has_ub a).\nExpand the definition of bound.\nExpand the definition of is_upper_bound.\nChoose M such that a_bdd_by_M according to a_upp_bdd.\nChoose m := M.\nTake x : ℝ.\nAssume x_is_acc_pt : (is_seq_acc_pt a x).\nExpand the definition of is_seq_acc_pt.\nChoose n such that n_good_ind_seq according to x_is_acc_pt.\nBecause n_good_ind_seq both n_ind_seq and subseq_conv_to_x.\nWe need to show that (x ≤ M).\nApply (upp_bd_seq_is_upp_bd_lim (fun (k : ℕ)↦ a(n k))).\n Expand the definition of is_upper_bound in a_bdd_by_M.\n Expand the definition of EUn in a_bdd_by_M.\n Take k : ℕ. It follows that (a(n k) ≤ M).\n Apply subseq_conv_to_x.\nQed."
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/src/assets/images/insertAtCursor.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/src/editpage/components/response/GoalsWindow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
10 |
11 |
12 | Done.
13 |
14 |
15 |
16 |
17 | Loading
18 |
19 |
20 | .
21 |
22 |
23 | .
24 |
25 |
26 | .
27 |
28 |
29 |
30 |
31 |
32 |
48 |
49 |
66 |
--------------------------------------------------------------------------------
/test-notebooks/test3.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Welcome to WATERPROOF!\nBelow is an example proof of transitivity. Transitivity is the property that for three propositions $A, B, C$, if $A \\implies B$ and $B \\implies C$, then also $A \\implies C$ directly. \n"
7 | },
8 | {
9 | "type": "text",
10 | "text": "In Coq, this lemma is written as "
11 | },
12 | {
13 | "type": "code",
14 | "text": "Lemma trans (A B C: Prop) : (A -> B) -> (B -> C) -> A -> C."
15 | },
16 | {
17 | "type": "text",
18 | "text": "$\\newline[0.3cm]$Now we start the proof."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Proof."
23 | },
24 | {
25 | "type": "text",
26 | "text": "\nThen we introduce some variables."
27 | },
28 | {
29 | "type": "code",
30 | "text": "intro H. intro G. intro a."
31 | },
32 | {
33 | "type": "text",
34 | "text": "\nNow, $H$ is a proof of $A \\implies B$, $G$ is a proof of $B \\implies C$, and $a$ is a proof of proposition $A$. We apply $H$ to $a$, and obtain a proof of $B$. Then we apply $G$, which proves $C$. In Coq, this is done using the ```specialize``` tactic:"
35 | },
36 | {
37 | "type": "code",
38 | "text": "\nspecialize (H a). specialize (G H)."
39 | },
40 | {
41 | "type": "text",
42 | "text": "\nThen we "
43 | },
44 | {
45 | "type": "code",
46 | "text": "apply G."
47 | },
48 | {
49 | "type": "text",
50 | "text": "\nFinally, we are done with the proof, so we close it."
51 | },
52 | {
53 | "type": "code",
54 | "text": "Qed."
55 | },
56 | {
57 | "type": "text",
58 | "text": "\n"
59 | }
60 | ]
61 | }
62 |
--------------------------------------------------------------------------------
/test-notebooks/exerciseTest.wpe:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Welcome to WATERPROOF!\nBelow is an example proof of transitivity. Transitivity is the property that for three propositions $A, B, C$, if $A \\implies B$ and $B \\implies C$, then also $A \\implies C$ directly. $\\\\$"
7 | },
8 | {
9 | "type": "text",
10 | "text": "In Coq, this lemma is written as "
11 | },
12 | {
13 | "type": "code",
14 | "text": "Lemma trans (A B C: Prop) : (A -> B) -> (B -> C) -> A -> C."
15 | },
16 | {
17 | "type": "text",
18 | "text": "$\\newline[0.3cm]$Now we start the proof."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Proof."
23 | },
24 | {
25 | "type": "text",
26 | "text": "$\\\\$Then we introduce some variables."
27 | },
28 | {
29 | "type": "code",
30 | "text": "intro H. intro G. intro a."
31 | },
32 | {
33 | "type": "text",
34 | "text": "$\\\\$Now, $H$ is a proof of $A \\implies B$, $G$ is a proof of $B \\implies C$, and $a$ is a proof of proposition $A$. We apply $H$ to $a$, and obtain a proof of $B$. Then we apply $G$, which proves $C$. In Coq, this is done using the ```specialize``` tactic:"
35 | },
36 | {
37 | "type": "code",
38 | "text": "\nspecialize (H a). specialize (G H)."
39 | },
40 | {
41 | "type": "text",
42 | "text": "$\\\\$"
43 | },
44 | {
45 | "type": "hint",
46 | "text": "Wil je een hint? Klik hier.\n\nDoe eerst `apply` en dan $\\square$"
47 | },
48 | {
49 | "type": "input",
50 | "start": true,
51 | "id": "input-0"
52 | },
53 | {
54 | "type": "input",
55 | "start": false,
56 | "id": "input-0"
57 | }
58 | ]
59 | }
--------------------------------------------------------------------------------
/test-notebooks/exerciseTest.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Welcome to WATERPROOF!\nBelow is an example proof of transitivity. Transitivity is the property that for three propositions $A, B, C$, if $A \\implies B$ and $B \\implies C$, then also $A \\implies C$ directly. $\\\\$"
7 | },
8 | {
9 | "type": "text",
10 | "text": "In Coq, this lemma is written as "
11 | },
12 | {
13 | "type": "code",
14 | "text": "Lemma trans (A B C: Prop) : (A -> B) -> (B -> C) -> A -> C."
15 | },
16 | {
17 | "type": "text",
18 | "text": "$\\newline[0.3cm]$Now we start the proof."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Proof."
23 | },
24 | {
25 | "type": "text",
26 | "text": "$\\\\$Then we introduce some variables."
27 | },
28 | {
29 | "type": "code",
30 | "text": "intro H. intro G. intro a."
31 | },
32 | {
33 | "type": "text",
34 | "text": "$\\\\$Now, $H$ is a proof of $A \\implies B$, $G$ is a proof of $B \\implies C$, and $a$ is a proof of proposition $A$. We apply $H$ to $a$, and obtain a proof of $B$. Then we apply $G$, which proves $C$. In Coq, this is done using the ```specialize``` tactic:"
35 | },
36 | {
37 | "type": "code",
38 | "text": "\nspecialize (H a). specialize (G H)."
39 | },
40 | {
41 | "type": "text",
42 | "text": "$\\\\$"
43 | },
44 | {
45 | "type": "hint",
46 | "text": "Wil je een hint? Klik hier.\n\nDoe eerst `apply` en dan $\\square$"
47 | },
48 | {
49 | "type": "input",
50 | "start": true,
51 | "id": "input-0"
52 | },
53 | {
54 | "type": "input",
55 | "start": false,
56 | "id": "input-0"
57 | }
58 | ]
59 | }
--------------------------------------------------------------------------------
/src/coq/serapi/flatten-expr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Takes nested arrays as returned by the s-expression `parse()` method, and
3 | * 'flattens' it by turning each list of the form
4 | * ((opt1 val1)(op2 val2)) into an object
5 | * {
6 | * "opt1": val1,
7 | * "opt2": val2,
8 | * }
9 | *
10 | * @param {Array} data the array returned by the s-expression parser
11 | * @return {Object|Array} an object with the keys & values from the expression
12 | * ((key1 val1)(key2 val2)..), or an array possibly containing such objects
13 | */
14 | function flatten(data) {
15 | /**
16 | * @param {Array} obj a part of the parsed s-expression
17 | * @return {Boolean} true iff `obj` is an array of the form `['key', value]`
18 | * where `key` is not a number
19 | */
20 | function isKeyValuePair(obj) {
21 | return Array.isArray(obj)
22 | && obj.length == 2
23 | && typeof (obj[0]) === 'string'
24 | && Number(obj[0]).toString() !== obj[0];
25 | }
26 |
27 | /**
28 | * @param {Array} obj a part of the parsed s-expression
29 | * @return {Boolean} true iff `obj` is a non-empty array where each element
30 | * is a key-value pair as defined by `isKeyValuePair`
31 | */
32 | function isKeyValueList(obj) {
33 | return Array.isArray(obj) && obj.every(isKeyValuePair);
34 | }
35 |
36 | if (isKeyValueList(data)) {
37 | const obj = {};
38 | for (const [key, value] of data) {
39 | if (typeof value === 'string') {
40 | if (isNaN(value)) {
41 | obj[key] = value;
42 | } else {
43 | obj[key] = Number(value);
44 | }
45 | } else {
46 | obj[key] = flatten(value);
47 | }
48 | }
49 | return obj;
50 | } else if (Array.isArray(data)) {
51 | return data.map(flatten);
52 | } else {
53 | return data;
54 | }
55 | }
56 |
57 | export {
58 | flatten,
59 | };
60 |
--------------------------------------------------------------------------------
/src/editpage/components/assistance/commands/Command.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ item.name }}
8 |
9 |
10 |
11 | ►
12 | ▼
13 | {{ item.description }}
14 |
15 |
16 |
22 |
23 |
28 |
29 |
30 |
31 |
32 |
33 |
57 |
58 |
69 |
--------------------------------------------------------------------------------
/wrapper/wplib/Notebooks/Intro_to_bounded_functions.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Introduction to bounded functions"
7 | },
8 | {
9 | "type": "text",
10 | "text": "We first need to import libraries. \n\nNote: for the lines below to work, the libraries have to be compiled with sercomp from the WaterProof base directory (or compiled files have to be provided). $\\\\$"
11 | },
12 | {
13 | "type": "code",
14 | "text": "Add LoadPath \"../../\".\n\nRequire Import Reals.\n\nRequire Import WaterProof.Tactics.Tactics.\nRequire Import WaterProof.Lib.BoundedFunctions.\n\nOpen Scope bdd_func_scope.\n\nDefinition D := BoundedFunctions.D."
15 | },
16 | {
17 | "type": "text",
18 | "text": "# Multiplication of functions\n\nGiven functions $f$ and $g$, we define the pointwise multiplication of the functions by $\\\\$"
19 | },
20 | {
21 | "type": "code",
22 | "text": "Definition func_mult (f g : D -> R) :=\n fun x : D => (f x) * (g x)."
23 | },
24 | {
25 | "type": "text",
26 | "text": "In the next exercise, you are asked to show that the product of two bounded functions is bounded. $\\\\$"
27 | },
28 | {
29 | "type": "code",
30 | "text": "Lemma product_bdd_func_bdd : \n forall (f g : D -> R),\n is_bdd f -> is_bdd g -> \n is_bdd (func_mult f g)."
31 | },
32 | {
33 | "type": "input",
34 | "start": true,
35 | "id": "input-0"
36 | },
37 | {
38 | "type": "code",
39 | "text": "Take f : (D -> R).\nTake g : (D -> R).\nAssume f_bdd : (is_bdd f).\nAssume g_bdd : (is_bdd g)."
40 | },
41 | {
42 | "type": "text",
43 | "text": "Type the rest of the proof here."
44 | },
45 | {
46 | "type": "input",
47 | "start": false,
48 | "id": "input-0"
49 | }
50 | ]
51 | }
--------------------------------------------------------------------------------
/src/assets/images/copy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
20 |
21 |
--------------------------------------------------------------------------------
/src/assets/images/codeButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
13 |
18 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/unit/io/shortkey.spec.js:
--------------------------------------------------------------------------------
1 | import ShortKeys from '../../../src/io/shortKey';
2 |
3 | const chai = require('chai');
4 | const expect = chai.expect;
5 |
6 |
7 | const storageLocation = 'shortKeys';
8 | const storage = window.localStorage;
9 | let previousStorage;
10 | describe('Notebook file path', () => {
11 | before(function() {
12 | previousStorage = storage.getItem(storageLocation);
13 | storage.removeItem(storageLocation);
14 | });
15 |
16 | after(function() {
17 | storage.setItem(storageLocation, previousStorage);
18 | });
19 |
20 | it('should use defaults if no storage', (done) => {
21 | storage.setItem(storageLocation, null);
22 | const shortKeys = new ShortKeys;
23 | expect(shortKeys.shortKeys.executeNext).to.be.an('array');
24 | expect(shortKeys.shortKeys.executeNext).not.to.have.length(0);
25 |
26 | done();
27 | });
28 |
29 | it('should take a key from storage', (done) => {
30 | const key = {
31 | executeNext: ['alt', 'o'],
32 | };
33 | storage.setItem(storageLocation, JSON.stringify(key));
34 | const shortKeys = new ShortKeys;
35 | expect(shortKeys.shortKeys.executeNext[0]).to.equal(key.executeNext[0]);
36 | expect(shortKeys.shortKeys.executeNext[1]).to.equal(key.executeNext[1]);
37 |
38 | done();
39 | });
40 |
41 | it('should reset custom keys after resetShortKeys', (done) => {
42 | const key = {
43 | executeNext: ['ctrl', 'o'],
44 | };
45 | storage.setItem(storageLocation, JSON.stringify(key));
46 | const shortKeys = new ShortKeys;
47 | expect(shortKeys.shortKeys.executeNext[0]).to.equal(key.executeNext[0]);
48 | expect(shortKeys.shortKeys.executeNext[1]).to.equal(key.executeNext[1]);
49 |
50 | shortKeys.resetShortKeys();
51 |
52 | expect(shortKeys.shortKeys.executeNext[0]).to.not.equal(key.executeNext[0]);
53 | expect(shortKeys.shortKeys.executeNext[1]).to.not.equal(key.executeNext[1]);
54 |
55 | done();
56 | });
57 | });
58 |
--------------------------------------------------------------------------------
/src/assets/images/bulbNo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
16 |
20 |
22 |
23 |
--------------------------------------------------------------------------------
/src/editpage/components/menubars/ShortcutButton.vue:
--------------------------------------------------------------------------------
1 |
66 |
--------------------------------------------------------------------------------
/src/assets/images/commandButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
17 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/unit/io/blocks/notebook-parse-to-text.spec.js:
--------------------------------------------------------------------------------
1 | import Notebook from '../../../../src/io/notebook';
2 | import {COQ_SPECIAL_COMMENT_START} from '../../../../src/io/notebook';
3 |
4 | const chai = require('chai');
5 | const expect = chai.expect;
6 |
7 |
8 | describe('Notebook parse to text ', () => {
9 | const notebook = new Notebook;
10 |
11 | beforeEach(() => {
12 | notebook.clearContent();
13 | });
14 |
15 | it('should parse to empty string if no blocks in notebook', (done) => {
16 | const output = notebook.parseToText();
17 | expect(output).to.have.length(0);
18 |
19 | done();
20 | });
21 |
22 | it('should parse code block directly', (done) => {
23 | const code = 'Lemma a n: n+0=n.';
24 | notebook.blocks.push(
25 | notebook.createCodeBlock(code, false));
26 | const output = notebook.parseToText();
27 | expect(output.trim()).to.equal(code);
28 |
29 | done();
30 | });
31 |
32 | it('should parse text block to a comment', (done) => {
33 | const code = 'Lemma a n: n+0=n.';
34 | notebook.blocks.push(
35 | notebook.createTextBlock(code, false));
36 | const output = notebook.parseToText();
37 | expect(output.trim()).to.equal(COQ_SPECIAL_COMMENT_START + code + '*)');
38 |
39 | done();
40 | });
41 |
42 | it('should parse hint block to nothing', (done) => {
43 | const code = 'Lemma a n: n+0=n.';
44 | notebook.blocks.push(notebook.createHintBlock(code));
45 | const output = notebook.parseToText();
46 | expect(output).includes(code);
47 | expect(output).to.endsWith('\n');
48 |
49 | done();
50 | });
51 |
52 | it('should parse input blocks to comments with text', (done) => {
53 | notebook.blocks = notebook.blocks.concat(notebook.createInputArea('1'));
54 | const output = notebook.parseToText();
55 | expect(output.trim()).startsWith('(*');
56 | expect(output.trim()).endsWith('*)');
57 | expect(output).includes('(* Start of input area *)');
58 | expect(output).includes('(* End of input area *)');
59 |
60 | done();
61 | });
62 | });
63 |
--------------------------------------------------------------------------------
/tests/unit/serapi/processors/responses/readyResponse.json:
--------------------------------------------------------------------------------
1 | [
2 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Prelude /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Prelude.vo))))",
3 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Notations /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Notations.vo))))",
4 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Logic /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Logic.vo))))",
5 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Datatypes /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Datatypes.vo))))",
6 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Logic_Type /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Logic_Type.vo))))",
7 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Specif /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Specif.vo))))",
8 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Decimal /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Decimal.vo))))",
9 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Nat /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Nat.vo))))",
10 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Peano /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Peano.vo))))",
11 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Wf /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Wf.vo))))",
12 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Tactics /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Tactics.vo))))",
13 | "(Feedback((doc_id 0)(span_id 0)(route 0)(contents(FileLoaded Coq.Init.Tauto /opt/waterproof/vendor/opam/default/lib/coq/theories/Init/Tauto.vo))))",
14 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents(ProcessingIn master))))",
15 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents Processed)))"
16 | ]
17 |
--------------------------------------------------------------------------------
/src/coq/CoqInterface.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * The interface that Waterproof uses to communicate with Coq
6 | */
7 | class CoqInterface {
8 | /**
9 | * CoqInterface (no implementation)
10 | */
11 | constructor() {
12 | }
13 |
14 | /**
15 | * Sets the Coq content to the given string.
16 | *
17 | * @param {string} content The Coq code to set the content to.
18 | */
19 | setContent(content) {
20 | }
21 |
22 | /**
23 | * Executes Coq code until the provided index
24 | *
25 | * @param {Number} index The index of the cursor
26 | */
27 | executeTo(index) {
28 | }
29 |
30 | /**
31 | * Executes the next Coq sentence
32 | */
33 | executeNext() {
34 | }
35 |
36 | /**
37 | * Rolls back the last Coq sentence
38 | */
39 | executePrevious() {
40 | }
41 |
42 | /**
43 | * Gets the goals at the given index,
44 | * when no index supplied this is after the last executed sentence
45 | *
46 | * @param {Number} index The index in the file
47 | * @param {function} onSuccess The callback function on succes
48 | * @param {function} onError The callback funcion on error
49 | * @async
50 | */
51 | getGoals(index, onSuccess, onError) {
52 | }
53 |
54 | /**
55 | * Gets the search results for a given searchquery.
56 | *
57 | * [TODO: Check search restrictions]
58 | *
59 | * @param {String} searchQuery Query to search for
60 | * @param {Function} onResult callback for when a search result has been found
61 | * @param {Function} onDone callback for when searching is done
62 | */
63 | getSearchResults(searchQuery, onResult, onDone) {
64 | }
65 |
66 | /**
67 | * Query a coq command
68 | * @param {String} command the command to execute
69 | */
70 | query(command) {
71 | }
72 |
73 | /**
74 | * Stop this instance of coq
75 | */
76 | stop() {
77 | }
78 |
79 | /**
80 | * Get the current state
81 | * @return {CoqState} the current coq state
82 | */
83 | getState() {
84 | return undefined;
85 | }
86 | }
87 |
88 | export default CoqInterface;
89 |
--------------------------------------------------------------------------------
/src/coq/EditorInterface.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | /**
5 | * Callbacks for the editor side
6 | */
7 | class EditorInterface {
8 | /**
9 | * Interface for editor
10 | */
11 | constructor() {
12 | }
13 |
14 |
15 | /**
16 | * Called when setContent was completed without error
17 | * @param {String|null} goal if goal should be updated goal != null
18 | * @param {Number} index the index to where execution is still valid
19 | * @param {boolean} removeAddError Whether the current addError is removed
20 | */
21 | setContentSuccess(goal, index, removeAddError) {
22 | }
23 |
24 |
25 | /**
26 | * Called when setContent ran into an error
27 | * (But some sentences might have been added)
28 | * @param {String} error the error that occurred
29 | * @param {Number} errorIndex the first index where the error occurred
30 | */
31 | setContentError(error, errorIndex) {
32 | }
33 |
34 | /**
35 | * Called when execution is requested
36 | * @param {Number} index the index to where execution will go
37 | */
38 | executeStarted(index) {
39 | }
40 |
41 | /**
42 | * When any execute is successful
43 | * next, prev, to
44 | * @param {String} goal if goal should be updated goal != null
45 | * @param {Number} index the index to where execution is still valid
46 | * @param {Boolean} proofFinished true when Qed. is executed successfully
47 | */
48 | executeSuccess(goal, index, proofFinished) {
49 | }
50 |
51 | /**
52 | * When any execution has an error
53 | * @param {String} error the error that occurred
54 | * @param {{start, end}} errorIndex the first index where the error occurred
55 | */
56 | executeError(error, errorIndex) {
57 | }
58 |
59 | /**
60 | * When coq gives some message
61 | * @param {String} message the message
62 | * @param {Number} sentenceId the id of the sentence or null
63 | */
64 | message(message, sentenceId=null) {
65 | }
66 |
67 | /**
68 | * Called whenever the coq instance is ready to receive messages
69 | */
70 | onReady() {
71 | }
72 | }
73 |
74 | export default EditorInterface;
75 |
--------------------------------------------------------------------------------
/src/io/recents.js:
--------------------------------------------------------------------------------
1 | /** Class representing the recent file list */
2 | class Recents {
3 | /** Constructor */
4 | constructor() {
5 | this.maxFileListLength = 10;
6 | this.filelist = [];
7 | this.storage = window.localStorage;
8 | this.read();
9 | }
10 |
11 | /** Reads the filelist from localstorage */
12 | read() {
13 | const parsedList = JSON.parse(this.storage.getItem('fileList'));
14 | if (parsedList) {
15 | this.filelist = parsedList;
16 | }
17 | }
18 |
19 | /** Writes the fileList object to a JSON file */
20 | write() {
21 | this.storage.setItem('fileList', JSON.stringify(this.filelist));
22 | }
23 |
24 | /** Removes all elements over the maxFileListLength */
25 | removeSurplus() {
26 | this.filelist = this.filelist.slice(0, this.maxFileListLength);
27 | }
28 |
29 | /**
30 | * Adds file list entry to the fileList object
31 | *
32 | * @param {String} location Contains the file location within the filesystem
33 | */
34 | addFileListEntry(location) {
35 | if (location === 'Tutorial') {
36 | return;
37 | }
38 |
39 | const entry = {};
40 | entry.location = location;
41 | entry.name = location.split(/[/\\]/).pop();
42 |
43 | // Remove all existing entries with the same file location
44 | this.removeFileListEntry(location);
45 |
46 | // Insert new entry at start of the list
47 | this.filelist.unshift(entry);
48 |
49 | // Remove any entries that are too old.
50 | this.removeSurplus();
51 |
52 | // Write to file
53 | this.write();
54 | }
55 |
56 | /**
57 | * Removes a file list entry based on the location
58 | *
59 | * @param {String} location Contains the file location within the filesystem
60 | */
61 | removeFileListEntry(location) {
62 | for (let i = this.filelist.length - 1; i >= 0; i--) {
63 | if (this.filelist[i].location === location) {
64 | this.filelist.splice(i, 1);
65 | }
66 | }
67 | this.write();
68 | }
69 |
70 | /**
71 | * Clears recent file list
72 | */
73 | clearRecentFileList() {
74 | this.filelist = [];
75 | this.write();
76 | }
77 | }
78 |
79 | export default Recents;
80 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const bundleEnvName = 'WATERPROOF_BUILD_WITH_BUNDLED_INSTALLER';
4 |
5 | let nsisConfig = undefined;
6 | if (process.env[bundleEnvName] === 'true') {
7 | nsisConfig = {
8 | include: 'wrapper/windows-installer.nsh',
9 | allowElevation: true,
10 | oneClick: false,
11 | perMachine: true,
12 | artifactName: '${productName} and Coq Setup ${version}.${ext}',
13 | };
14 | }
15 |
16 | module.exports = {
17 | chainWebpack: (config) => {
18 | // config.plugins.delete('preload-index');
19 | // config.plugins.delete('prefetch-index');
20 | // config.plugins.delete('preload-editpage');
21 | // config.plugins.delete('prefetch-editpage');
22 | config.plugins.delete('hmr');
23 | },
24 | configureWebpack: {
25 | module: {
26 | rules: [{
27 | test: /\.scss$/,
28 | use: [
29 | 'sass-loader',
30 | {
31 | loader: 'style-resources-loader',
32 | options: {
33 | patterns: [
34 | path.resolve(__dirname,
35 | 'src/assets/sass/abstracts/*.scss'),
36 | ],
37 | },
38 | },
39 | ],
40 | }],
41 | },
42 | },
43 | pluginOptions: {
44 | electronBuilder: {
45 | // Sandboxing interferes with running the app on the GitLab runners.
46 | mainProcessArgs: ['--no-sandbox'],
47 | nodeIntegration: true,
48 | builderOptions: {
49 | productName: 'Waterproof',
50 | remoteBuild: true,
51 | extraFiles: ['wrapper/assistance', 'wrapper/wplib'],
52 | win: {
53 | extraFiles: ['wrapper/win'],
54 | },
55 | mac: {
56 | extraFiles: ['wrapper/mac'],
57 | },
58 | linux: {
59 | extraFiles: ['wrapper/lin'],
60 | },
61 | fileAssociations: [
62 | {
63 | ext: 'wpn',
64 | name: 'Waterproof notebook',
65 | },
66 | {
67 | ext: 'wpe',
68 | name: 'Waterproof exercise',
69 | },
70 | ],
71 | nsis: nsisConfig,
72 | },
73 | },
74 | },
75 | };
76 |
--------------------------------------------------------------------------------
/src/coq/serapi/processors/SerapiASTProcessor.js:
--------------------------------------------------------------------------------
1 | import SerapiProcessor from '../util/SerapiProcessor';
2 | import {createASTCommand} from '../util/SerapiCommandFactory';
3 | import {extractCoqAST} from '../ASTProcessor';
4 |
5 | /**
6 | * Processor for ast handling
7 | */
8 | class SerapiASTProcessor extends SerapiProcessor {
9 | /**
10 | * Create a SerapiASTProcessor
11 | * @param {SerapiTagger} tagger the tagger to use
12 | * @param {SerapiState} state the state to use
13 | * @param {EditorInterface} editor the editor to use
14 | */
15 | constructor(tagger, state, editor) {
16 | super(tagger, state, editor);
17 | }
18 |
19 | /**
20 | * Fetch all the asts for the current state
21 | */
22 | async getAllAsts() {
23 | const stateRelease = await this.state.stateLock.acquire();
24 | for (let i = 0; i < this.state.sentenceSize(); i++) {
25 | await this._fetchASTFor(this.state.idOfSentence(i));
26 | }
27 | stateRelease();
28 | return Promise.resolve();
29 | }
30 |
31 | /**
32 | * Fetch the asts for a specific sentence
33 | * @param {Number} sentenceIndex the index of the sentence
34 | */
35 | async getAstForSentence(sentenceIndex) {
36 | const stateRelease = await this.state.stateLock.acquire();
37 | await this._fetchASTFor(this.state.idOfSentence(sentenceIndex));
38 | stateRelease();
39 | return Promise.resolve();
40 | }
41 |
42 | /**
43 | * Fetch AST from serapi
44 | * @param {Number} sentenceId the sentence id of the sentence
45 | * @return {Promise<*>}
46 | * @private
47 | */
48 | async _fetchASTFor(sentenceId) {
49 | return this.sendCommand(createASTCommand(sentenceId), 'ast')
50 | .then((result) => {
51 | this.state.setASTforSID(sentenceId, result.ast);
52 | });
53 | }
54 |
55 | /**
56 | * Handle a serapi message
57 | * @param {*} data the serapi message (parsed)
58 | * @param {String} extraTag the extra identifying tag
59 | * @return {*} partial of this command
60 | */
61 | handleSerapiMessage(data, extraTag) {
62 | if (extraTag === 'ast') {
63 | return {
64 | ast: extractCoqAST(data),
65 | };
66 | }
67 | }
68 | }
69 |
70 |
71 | export default SerapiASTProcessor;
72 |
--------------------------------------------------------------------------------
/src/assets/images/findButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
14 |
19 |
21 |
23 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_dark_roboto.scss:
--------------------------------------------------------------------------------
1 | @import './_functions';
2 |
3 | $dark_roboto: (
4 | // Primary brand color and variants.
5 | // TODO: These colors are very similar, and used interchangeably for navigation
6 | // items. Should probably merge these.
7 | color-primary: #11184d,
8 | color-primary-dark: #040613,
9 | // TODO: Both of these colors are used for hover effects, it would be better to
10 | // just stick to one color. Should probably use the dark variant on light
11 | // surfaces and vice versa.
12 | color-primary-light: #060b25,
13 | color-primary-extra-light: #aab0d3,
14 | color-primary-ultra-light: #eceeff,
15 |
16 | // Surface colors, for elements that are not typically styled using our brand
17 | // colors.
18 | color-background: #121212,
19 | color-surface: #121212,
20 | color-error: #990000,
21 | color-error-message: #FF6060,
22 | color-error-text: #ffffff,
23 |
24 | // Colors for typography and iconography. These colors are meant for elements
25 | // that appear on top of elements styled using the primary/surface colors.
26 | color-on-primary: #121212,
27 | color-on-background: #ffffff,
28 | color-on-surface: #ffffff,
29 | color-on-error: #121212,
30 |
31 | // Color for multiple areas in a notebook, like search interface,
32 | // code blocks
33 | color-gray-darkest: #8d8b8b,
34 | color-gray-dark: #585555,
35 | color-gray-light: #202020,
36 | color-gray: #505050,
37 | color-black: #ffffff,
38 | color-red: red,
39 | color-white: black,
40 | color-text-in-primary: white, // meant for text in primary coloured buttons
41 | color-transparent: transparent,
42 |
43 | color-highlight-mode: #fff6bf,
44 | color-highlight-mode-text: black,
45 |
46 | /** Fonts used in branding (logos, application title, etc.) */
47 | font-stack-brand: 'Roboto',
48 |
49 | // Fonts used in page headers (h1-h6). Separate to allow easy modification in
50 | // the future.
51 | font-stack-headers: 'Roboto',
52 |
53 | // Fonts used in body text. Separate to allow easy modification in the future.
54 | font-stack-body: 'Roboto',
55 |
56 | // Fonts used for displaying code.
57 | font-stack-code: 'Roboto Mono'
58 | );
--------------------------------------------------------------------------------
/wrapper/wplib/Exercise_sheets/Lec_05_Ex_4.wpe:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Lecture 5 Exercise 4 : infinite triangle inequality"
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Reals.\nRequire Import Rfunctions.\n\nRequire Import wplib.Tactics.Tactics.\nRequire Import wplib.Notations.Notations.\nRequire Import wplib.Lib.sequences.\nRequire Import wplib.Lib.series.\n\nNotation cv_to := Un_cv."
11 | },
12 | {
13 | "type": "text",
14 | "text": "The formulation of the original exercise was: suppose $\\sum_{k} a_k$ is an absolutely converging series, show that\n\n$$\n\\left| \\sum_{k=0}^\\infty a_k \\right| ≤ \\sum_{k=0}^\\infty |a_k|\n$$\nIn fact, in this formulation it is a bit hard to see what you need to show. The formulation below makes this is a bit more explicit.\n\nIt says: suppose the series $\\sum_{k=0}^\\infty |a_k|$ converges and is equal to $l$, and suppose the series $\\sum_{k=0}^\\infty a_k$ converges and is equal to $m$, then $|m| \\leq l$.\n\n**Hints:** the following Lemmas may be useful.\n\n```\nLemma sum_f_R0_triangle : \n∀ (a : ℕ → ℝ) (n : ℕ),\n | partial_sums a n | ≤ \n partial_sums (fun (j : ℕ) ↦ |a j|) n.\n```\n\n```\nLemma seq_ordered_lim_ordered :\n ∀ (a b : ℕ → ℝ) (m l : ℝ),\n cv_to a m ⇒ (\n cv_to b l ⇒ (\n (∀ n : ℕ, a n ≤ b n) ⇒ (\n m ≤ l )\n )\n )\n```\n\n```\nLemma cv_cvabs :\n ∀ (a : ℕ → ℝ) (l : ℝ),\n cv_to a l ⇒ (\n cv_to (fun (k : ℕ) ↦ | a k |) (|l|))\n```"
15 | },
16 | {
17 | "type": "code",
18 | "text": "Check sum_f_R0_triangle.\nCheck seq_ordered_lim_ordered.\nCheck cv_cvabs."
19 | },
20 | {
21 | "type": "code",
22 | "text": "Lemma lec_05_ex_04 :\n ∀ (a : ℕ → ℝ) (m l : ℝ),\n series_cv_abs_to a l ⇒ \n (series_cv_to a m ⇒ |m| ≤ l)."
23 | },
24 | {
25 | "type": "input",
26 | "start": true,
27 | "id": "input-1"
28 | },
29 | {
30 | "type": "text",
31 | "text": "Write your solution here..."
32 | },
33 | {
34 | "type": "code",
35 | "text": "\nAdmitted."
36 | },
37 | {
38 | "type": "input",
39 | "start": false,
40 | "id": "input-1"
41 | }
42 | ]
43 | }
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_light_roboto.scss:
--------------------------------------------------------------------------------
1 | @import './_functions';
2 |
3 | $light_roboto: (
4 | // Primary brand color and variants.
5 | // TODO: These colors are very similar, and used interchangeably for navigation
6 | // items. Should probably merge these.
7 | color-primary: #2b3990,
8 | color-primary-dark: #232d73,
9 | // TODO: Both of these colors are used for hover effects, it would be better to
10 | // just stick to one color. Should probably use the dark variant on light
11 | // surfaces and vice versa.
12 | color-primary-light: #5561a6,
13 | color-primary-extra-light: #aab0d3,
14 | color-primary-ultra-light: #eceeff,
15 |
16 | // Surface colors, for elements that are not typically styled using our brand
17 | // colors.
18 | color-background: #ffffff,
19 | color-surface: #ffffff,
20 | color-error: #ff0000,
21 | color-error-message: #FF6060,
22 | color-error-text: #ffffff,
23 |
24 | // Colors for typography and iconography. These colors are meant for elements
25 | // that appear on top of elements styled using the primary/surface colors.
26 | color-on-primary: #ffffff,
27 | color-on-background: #000000,
28 | color-on-surface: #000000,
29 | color-on-error: #ffffff,
30 |
31 | // Color for multiple areas in a notebook, like search interface,
32 | // code blocks
33 | color-gray-darkest: #707070,
34 | color-gray-dark: #b1b1b1,
35 | color-gray-light: #ececec,
36 | color-gray: #c9c9c9,
37 | color-black: #000000,
38 | color-red: red,
39 | color-white: white,
40 | color-text-in-primary: white, // meant for text in primary coloured buttons
41 | color-transparent: transparent,
42 |
43 | color-highlight-mode: #fff6bf,
44 | color-highlight-mode-text: black,
45 |
46 | /** Fonts used in branding (logos, application title, etc.) */
47 | font-stack-brand: 'Roboto',
48 |
49 | // Fonts used in page headers (h1-h6). Separate to allow easy modification in
50 | // the future.
51 | font-stack-headers: 'Roboto',
52 |
53 | // Fonts used in body text. Separate to allow easy modification in the future.
54 | font-stack-body: 'Roboto',
55 |
56 | // Fonts used for displaying code.
57 | font-stack-code: 'Roboto Mono'
58 | );
--------------------------------------------------------------------------------
/test-notebooks/test2.wpn:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": false,
3 | "blocks": [
4 | {
5 | "type": "code",
6 | "text": "Lemma trans (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
7 | },
8 | {
9 | "type": "text",
10 | "text": "### Dat doen we nog een keer"
11 | },
12 | {
13 | "type": "code",
14 | "text": "Lemma trans2 (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
15 | },
16 | {
17 | "type": "text",
18 | "text": "### Dat doen we nog een keer"
19 | },
20 | {
21 | "type": "code",
22 | "text": "Lemma trans3 (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
23 | },
24 | {
25 | "type": "text",
26 | "text": "### Dat doen we nog een keer"
27 | },
28 | {
29 | "type": "code",
30 | "text": "Lemma trans4 (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
31 | },
32 | {
33 | "type": "text",
34 | "text": "### Dat doen we nog een keer"
35 | },
36 | {
37 | "type": "code",
38 | "text": "Lemma trans5 (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
39 | },
40 | {
41 | "type": "text",
42 | "text": "### Dat doen we nog een keer"
43 | },
44 | {
45 | "type": "code",
46 | "text": "Lemma trans6 (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
47 | },
48 | {
49 | "type": "text",
50 | "text": "### Dat doen we nog een keer"
51 | },
52 | {
53 | "type": "code",
54 | "text": "Lemma trans7 (A B C :Prop) : (A -> B) -> (B->C) -> A -> C.\nProof.\n intro H.\n intro G.\n intro a.\n specialize (H a).\n specialize (G H).\n apply G.\nQed.\n\n"
55 | }
56 | ]
57 | }
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_dark.scss:
--------------------------------------------------------------------------------
1 | @import './_functions';
2 |
3 | $dark: (
4 | // Primary brand color and variants.
5 | // TODO: These colors are very similar, and used interchangeably for navigation
6 | // items. Should probably merge these.
7 | color-primary: #11184d,
8 | color-primary-dark: #040613,
9 | // TODO: Both of these colors are used for hover effects, it would be better to
10 | // just stick to one color. Should probably use the dark variant on light
11 | // surfaces and vice versa.
12 | color-primary-light: #060b25,
13 | color-primary-extra-light: #aab0d3,
14 | color-primary-ultra-light: #eceeff,
15 |
16 | // Surface colors, for elements that are not typically styled using our brand
17 | // colors.
18 | color-background: #121212,
19 | color-surface: #121212,
20 | color-error: #990000,
21 | color-error-message: #FF6060,
22 | color-error-text: #ffffff,
23 |
24 | // Colors for typography and iconography. These colors are meant for elements
25 | // that appear on top of elements styled using the primary/surface colors.
26 | color-on-primary: #121212,
27 | color-on-background: #ffffff,
28 | color-on-surface: #ffffff,
29 | color-on-error: #121212,
30 |
31 | // Color for multiple areas in a notebook, like search interface,
32 | // code blocks
33 | color-gray-darkest: #8d8b8b,
34 | color-gray-dark: #585555,
35 | color-gray-light: #202020,
36 | color-gray: #505050,
37 | color-black: #ffffff,
38 | color-red: red,
39 | color-white: black,
40 | color-text-in-primary: white, // meant for text in primary coloured buttons
41 | color-transparent: transparent,
42 |
43 | color-highlight-mode: #fff6bf,
44 | color-highlight-mode-text: black,
45 |
46 | /** Fonts used in branding (logos, application title, etc.) */
47 | font-stack-brand: 'Century Gothic',
48 |
49 | // Fonts used in page headers (h1-h6). Separate to allow easy modification in
50 | // the future.
51 | font-stack-headers: 'Century Gothic',
52 |
53 | // Fonts used in body text. Separate to allow easy modification in the future.
54 | font-stack-body: 'Century Gothic',
55 |
56 | // Fonts used for displaying code.
57 | font-stack-code: 'monospace'//'Letter Gothic Std'
58 | );
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_light.scss:
--------------------------------------------------------------------------------
1 | @import './_functions';
2 |
3 | $light: (
4 | // Primary brand color and variants.
5 | // TODO: These colors are very similar, and used interchangeably for navigation
6 | // items. Should probably merge these.
7 | color-primary: #2b3990,
8 | color-primary-dark: #232d73,
9 | // TODO: Both of these colors are used for hover effects, it would be better to
10 | // just stick to one color. Should probably use the dark variant on light
11 | // surfaces and vice versa.
12 | color-primary-light: #5561a6,
13 | color-primary-extra-light: #aab0d3,
14 | color-primary-ultra-light: #eceeff,
15 |
16 | // Surface colors, for elements that are not typically styled using our brand
17 | // colors.
18 | color-background: #ffffff,
19 | color-surface: #ffffff,
20 | color-error: #ff0000,
21 | color-error-message: #FF6060,
22 | color-error-text: #ffffff,
23 |
24 | // Colors for typography and iconography. These colors are meant for elements
25 | // that appear on top of elements styled using the primary/surface colors.
26 | color-on-primary: #ffffff,
27 | color-on-background: #000000,
28 | color-on-surface: #000000,
29 | color-on-error: #ffffff,
30 |
31 | // Color for multiple areas in a notebook, like search interface,
32 | // code blocks
33 | color-gray-darkest: #707070,
34 | color-gray-dark: #b1b1b1,
35 | color-gray-light: #ececec,
36 | color-gray: #c9c9c9,
37 | color-black: #000000,
38 | color-red: red,
39 | color-white: white,
40 | color-text-in-primary: white, // meant for text in primary coloured buttons
41 | color-transparent: transparent,
42 |
43 | color-highlight-mode: #fff6bf,
44 | color-highlight-mode-text: black,
45 |
46 | /** Fonts used in branding (logos, application title, etc.) */
47 | font-stack-brand: 'Century Gothic',
48 |
49 | // Fonts used in page headers (h1-h6). Separate to allow easy modification in
50 | // the future.
51 | font-stack-headers: 'Century Gothic',
52 |
53 | // Fonts used in body text. Separate to allow easy modification in the future.
54 | font-stack-body: 'Century Gothic',
55 |
56 | // Fonts used for displaying code.
57 | font-stack-code: 'monospace'//'Letter Gothic Std'
58 | );
--------------------------------------------------------------------------------
/src/index/components/RecentFile.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 | {{ fileInfo.name }}
6 |
7 |
8 |
9 |
61 |
62 |
83 |
--------------------------------------------------------------------------------
/tests/unit/serapi/util/ExpectingSerapiWorker.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable require-jsdoc */
2 | import SerapiWorker from '../../../../src/coq/serapi/workers/SerapiWorker';
3 |
4 | const chai = require('chai');
5 | const expect = chai.expect;
6 |
7 | function checkBalancedParenthesis(message) {
8 | expect(message.match(/\(/g) || [], `balanced parenthesis of ${message}`)
9 | .to.have.lengthOf((message.match(/\)/g) || []).length);
10 | }
11 |
12 | class ExpectingSerapiWorker extends SerapiWorker {
13 | constructor() {
14 | super();
15 | this.expectedIndex = 0;
16 | this.expectedCalls = [];
17 | this.calls = [];
18 | }
19 |
20 | addExpectedCall(command, responses, callback=null) {
21 | this.expectedCalls.push({
22 | command,
23 | responses,
24 | callback,
25 | });
26 | }
27 |
28 | async postMessage(message) {
29 | checkBalancedParenthesis(message);
30 |
31 | this.calls.push(message);
32 | if (this.expectedCalls.length > this.expectedIndex) {
33 | // if we have an expected call check and return the response
34 | const tag = message.split('(')[1];
35 | const currentCall = this.expectedCalls[this.expectedIndex];
36 | this.expectedIndex++;
37 |
38 | expect(message).to.include(currentCall.command);
39 |
40 | setTimeout(() => {
41 | this.sendMessages(currentCall.responses, tag);
42 | }, 0);
43 |
44 | // first callback then any possible messages
45 | if (currentCall.callback) {
46 | await currentCall.callback(message);
47 | }
48 | } else {
49 | expect.fail('Not expecting any message!');
50 | }
51 | }
52 |
53 | getCallAmount() {
54 | return this.calls.length;
55 | }
56 |
57 | getCall(n) {
58 | return this.calls[n];
59 | }
60 |
61 | sendMessages(messages, tag) {
62 | for (const partialResult of messages) {
63 | if (partialResult.startsWith('(Feedback')
64 | || partialResult.startsWith('(Answer')) {
65 | this.onMessage(partialResult);
66 | } else {
67 | if (!partialResult.startsWith('(')) {
68 | this.onMessage(`(Answer ${tag} ${partialResult})`);
69 | } else {
70 | // no space between
71 | this.onMessage(`(Answer ${tag}${partialResult})`);
72 | }
73 | }
74 | }
75 | }
76 | }
77 |
78 | export default ExpectingSerapiWorker;
79 |
--------------------------------------------------------------------------------
/tests/unit/serapi/stringIndex.spec.js:
--------------------------------------------------------------------------------
1 | import {byteIndexToStringIndex, byteIndicesToStringIndices}
2 | from '../../../src/coq/serapi/SerapiParser';
3 |
4 | const chai = require('chai');
5 | const expect = chai.expect;
6 |
7 | describe('serapi index calculator', () => {
8 | it('should give 0 for 0 with empty string', (done) => {
9 | const string = '';
10 | const result = byteIndexToStringIndex(string, 0);
11 | expect(result).to.equal(0);
12 | done();
13 | });
14 |
15 | it('should give 0 for 0 on a non empty string', (done) => {
16 | const string = 'Not an empty string';
17 | const result = byteIndexToStringIndex(string, 0);
18 | expect(result).to.equal(0);
19 | done();
20 | });
21 |
22 | it('should give 0 for 0 on a string with utf8 chars', (done) => {
23 | const string = 'αℚ∀🤔🅱';
24 | const result = byteIndexToStringIndex(string, 0);
25 | expect(result).to.equal(0);
26 | done();
27 | });
28 |
29 | it('should give ? for out of bounds index', (done) => {
30 | const string = '';
31 | const result = byteIndexToStringIndex(string, 1);
32 | expect(result).to.equal(-1);
33 | done();
34 | });
35 |
36 | it('should give the correct index for ascii chars', (done) => {
37 | const string = 'Not an empty string';
38 | for (let i = 0; i < string.length; i++) {
39 | const result = byteIndexToStringIndex(string, i);
40 | expect(result).to.equal(i);
41 | }
42 | done();
43 | });
44 |
45 | it('should give the correct index for utf8 chars', (done) => {
46 | const string = 'αεℚ∀🤔🅱';
47 | let result = byteIndexToStringIndex(string, 2);
48 | expect(result).to.equal(1);
49 | result = byteIndexToStringIndex(string, 4);
50 | expect(result).to.equal(2);
51 | done();
52 | });
53 | });
54 |
55 | describe('serapi indices conversion calculator', () => {
56 | it('should give empty array for empty string', (done) => {
57 | const string = '';
58 | const result = byteIndicesToStringIndices(string);
59 | expect(result).to.eql([0]);
60 | done();
61 | });
62 |
63 | it('should give the correct index for utf8 chars', (done) => {
64 | const string = 'αεℚ∀🤔🅱';
65 | const result = byteIndicesToStringIndices(string);
66 | expect(result).to.eql([0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4,
67 | 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8]);
68 | done();
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/tests/unit/io/blocks/notebook-input-blocks.spec.js:
--------------------------------------------------------------------------------
1 | import Notebook from '../../../../src/io/notebook';
2 |
3 | const chai = require('chai');
4 | const expect = chai.expect;
5 |
6 |
7 | describe('Notebook input blocks', () => {
8 | const notebook = new Notebook;
9 |
10 | it('should create an input block with the correct id and start value',
11 | (done) => {
12 | for (let i = -5; i < 5; i++) {
13 | const startBlock = notebook.createInputBlock(i, true);
14 | expect(startBlock.id).to.equal(i);
15 | expect(startBlock.start).to.equal(true);
16 |
17 | const endBlock = notebook.createInputBlock(i, false);
18 | expect(endBlock.id).to.equal(i);
19 | expect(endBlock.start).to.equal(false);
20 | }
21 |
22 | done();
23 | });
24 |
25 | it('should create both input blocks', (done) => {
26 | for (let i = -5; i < 5; i++) {
27 | const blocks = notebook.createInputArea(i);
28 | expect(blocks).to.be.an('array').that.has.length(2);
29 | expect(blocks[0].start).to.equal(true);
30 | expect(blocks[0].id).to.equal(i);
31 | expect(blocks[1].start).to.equal(false);
32 | expect(blocks[1].id).to.equal(i);
33 | }
34 | done();
35 | });
36 |
37 | it('should split a start input block correctly', (done) => {
38 | notebook.blocks = notebook.createInputArea('1');
39 |
40 | const blocks = notebook.splitBlock(0, 0, 0, 'code');
41 | expect(blocks).to.be.an('array').that.has.length(2);
42 | expect(blocks[0].type).to.equal('input');
43 | expect(blocks[0].start).to.equal(true);
44 | expect(blocks[0].id).to.equal('1');
45 |
46 | expect(blocks[1].type).to.equal('code');
47 | expect(blocks[1].state.inInputField).to.equal(true);
48 |
49 | notebook.clearContent();
50 |
51 | done();
52 | });
53 |
54 | it('should split an end input block correctly', (done) => {
55 | notebook.blocks = notebook.createInputArea('1');
56 |
57 | const blocks = notebook.splitBlock(1, 0, 0, 'code');
58 | expect(blocks).to.be.an('array').that.has.length(2);
59 | expect(blocks[0].type).to.equal('code');
60 | expect(blocks[0].state.inInputField).to.equal(true);
61 |
62 | expect(blocks[1].type).to.equal('input');
63 | expect(blocks[1].start).to.equal(false);
64 | expect(blocks[1].id).to.equal('1');
65 |
66 | notebook.clearContent();
67 |
68 | done();
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/src/coq/serapi/workers/SerapiWorkerTCP.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import SerapiWorker from './SerapiWorker';
4 |
5 | /**
6 | * Class that connects to serapi
7 | */
8 | class SerapiWorkerTCP extends SerapiWorker {
9 | /**
10 | * Interface (non implementation) of SerapiWorker
11 | * @param {TCPManager} socket the manager to send messages with
12 | * @param {string} sertopPath the path where to find sertop
13 | */
14 | constructor(socket, sertopPath='') {
15 | super();
16 | this.socket = socket;
17 | this.socketId = -1;
18 |
19 | this.sendMessage(
20 | this.createWrapperMessage('create',
21 | JSON.stringify({path: sertopPath,
22 | args: ['--implicit',
23 | // `--load-path=${wplibPath},wplib`,
24 | // TODO: Either remove the compilation part completely
25 | // or make sure the wplib folder exists.
26 | ]}))
27 | );
28 | }
29 |
30 | /**
31 | * Create a message for the wrapper
32 | * Auto injects the id
33 | * @param {String} command the command/verb
34 | * @param {String} content the content of the command/verb
35 | * @return {string|{instance_id: number, verb: *, content: string}}
36 | */
37 | createWrapperMessage(command, content='') {
38 | if (command !== 'create' && this.socketId < 0) {
39 | console.warn('Message sent too soon');
40 | }
41 | return {
42 | verb: command,
43 | instance_id: this.socketId,
44 | content: content,
45 | };
46 | }
47 |
48 | /**
49 | * Send message
50 | * @param {String} message the message
51 | */
52 | postMessage(message) {
53 | this.sendMessage(
54 | this.createWrapperMessage('forward', message)
55 | );
56 | }
57 |
58 | /**
59 | * Send a real wrapper message
60 | * @param {String} wrapperMessage the wrapper message to send
61 | */
62 | sendMessage(wrapperMessage) {
63 | this.socket.sendMessage(JSON.stringify(wrapperMessage));
64 | }
65 |
66 | /**
67 | * Handle a message from the socket
68 | * @param {String} message the message
69 | */
70 | handleMessage(message) {
71 | if (message !== '') {
72 | this.onMessage(message);
73 | }
74 | }
75 |
76 | /**
77 | * Stop this worker
78 | */
79 | terminate() {
80 | this.sendMessage(
81 | this.createWrapperMessage('destroy')
82 | );
83 | }
84 | }
85 |
86 | export default SerapiWorkerTCP;
87 |
--------------------------------------------------------------------------------
/src/io/readfile.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | /**
4 | * Function for reading a json file
5 | * @param {String} file the file to read
6 | * @param {Function} onSuccess called when file is loaded
7 | * @return {Undefined|Error} returns undefined on success and an error if one
8 | * occurred
9 | */
10 | function read(file, onSuccess) {
11 | let occurredError = undefined;
12 | fs.readFile(file, (err, data) => {
13 | if (err) {
14 | console.error(err);
15 | occurredError = err;
16 | return;
17 | }
18 |
19 | let assistanceItemList;
20 | try {
21 | assistanceItemList = JSON.parse(data);
22 | } catch (error) {
23 | console.error(error);
24 | occurredError = err;
25 | return;
26 | }
27 |
28 | onSuccess(assistanceItemList);
29 | });
30 | return occurredError;
31 | }
32 |
33 | export default read;
34 |
35 | /**
36 | * Check if the file exists
37 | * @param {String} filepath the path of the file to check
38 | * @return {Promise} promise which resolves to true if the file exists
39 | */
40 | function doesFileExist(filepath) {
41 | return new Promise(((resolve) => {
42 | fs.access(filepath, fs.constants.F_OK, (err) => {
43 | if (err) {
44 | resolve(false);
45 | } else {
46 | resolve(true);
47 | }
48 | });
49 | }));
50 | }
51 |
52 | /**
53 | * Remove a file
54 | * @param {String} filepath the path of the file to remove
55 | * @return {Promise} returns true if file removed
56 | * (rejects if any error)
57 | */
58 | function deleteFile(filepath) {
59 | return new Promise((resolve, reject) => {
60 | fs.unlink(filepath, (err) => {
61 | if (err) {
62 | reject(err);
63 | } else {
64 | resolve();
65 | }
66 | });
67 | });
68 | }
69 |
70 | /**
71 | * Read a file with promise
72 | * @param {String} filepath the path of the file to read
73 | * @return {Promise}
74 | */
75 | function readFile(filepath) {
76 | return new Promise(((resolve, reject) => {
77 | fs.readFile(filepath, (err, data) => {
78 | if (err) {
79 | console.error(err);
80 | reject(err);
81 | return;
82 | }
83 |
84 | let parsedData;
85 | try {
86 | parsedData = JSON.parse(data);
87 | } catch (error) {
88 | console.error(error);
89 | reject(err);
90 | return;
91 | }
92 |
93 | resolve(parsedData);
94 | });
95 | }));
96 | }
97 |
98 | export {doesFileExist, deleteFile, readFile};
99 |
--------------------------------------------------------------------------------
/tests/unit/serapi/processors/responses/searchPlusResponse.json:
--------------------------------------------------------------------------------
1 | [
2 | "Ack",
3 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents Processed)))",
4 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents(Message Notice()(Pp_box(Pp_hovbox 2)(Pp_glue((Pp_string plus_O_n:)(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_box(Pp_hovbox 2)(Pp_glue((Pp_tag constr.keyword(Pp_string forall))(Pp_print_break 1 0)(Pp_box(Pp_hovbox 1)(Pp_glue((Pp_string\"n : \")(Pp_tag constr.variable(Pp_string nat))))))))(Pp_string\",\")(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_box(Pp_hovbox 0)(Pp_glue((Pp_string 0)(Pp_tag constr.notation(Pp_string\" +\"))(Pp_print_break 1 0)(Pp_tag constr.variable(Pp_string n)))))(Pp_tag constr.notation(Pp_string\" =\"))(Pp_print_break 1 0)(Pp_tag constr.variable(Pp_string n)))))))))))))))",
5 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents(Message Notice()(Pp_box(Pp_hovbox 2)(Pp_glue((Pp_string plus_n_O:)(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_box(Pp_hovbox 2)(Pp_glue((Pp_tag constr.keyword(Pp_string forall))(Pp_print_break 1 0)(Pp_box(Pp_hovbox 1)(Pp_glue((Pp_string\"n : \")(Pp_tag constr.variable(Pp_string nat))))))))(Pp_string\",\")(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_tag constr.variable(Pp_string n))(Pp_tag constr.notation(Pp_string\" =\"))(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_tag constr.variable(Pp_string n))(Pp_tag constr.notation(Pp_string\" +\"))(Pp_print_break 1 0)(Pp_string 0)))))))))))))))))",
6 | "(Feedback((doc_id 0)(span_id 1)(route 0)(contents(Message Notice()(Pp_box(Pp_hovbox 2)(Pp_glue((Pp_string mult_n_Sm:)(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_box(Pp_hovbox 2)(Pp_glue((Pp_tag constr.keyword(Pp_string forall))(Pp_print_break 1 0)(Pp_box(Pp_hovbox 1)(Pp_glue((Pp_string n)(Pp_print_break 1 0)(Pp_string\"m : \")(Pp_tag constr.variable(Pp_string nat))))))))(Pp_string\",\")(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_box(Pp_hovbox 0)(Pp_glue((Pp_box(Pp_hovbox 0)(Pp_glue((Pp_tag constr.variable(Pp_string n))(Pp_tag constr.notation(Pp_string\" *\"))(Pp_print_break 1 0)(Pp_tag constr.variable(Pp_string m)))))(Pp_tag constr.notation(Pp_string\" +\"))(Pp_print_break 1 0)(Pp_tag constr.variable(Pp_string n)))))(Pp_tag constr.notation(Pp_string\" =\"))(Pp_print_break 1 0)(Pp_box(Pp_hovbox 0)(Pp_glue((Pp_tag constr.variable(Pp_string n))(Pp_tag constr.notation(Pp_string\" *\"))(Pp_print_break 1 0)(Pp_box(Pp_hovbox 2)(Pp_glue((Pp_tag constr.variable(Pp_string S))(Pp_print_break 1 0)(Pp_tag constr.variable(Pp_string m)))))))))))))))))))))",
7 | "(ObjList())",
8 | "Completed"
9 | ]
10 |
--------------------------------------------------------------------------------
/wrapper/wplib/Exercise_sheets/Lec_02_Ex_2.wpe:
--------------------------------------------------------------------------------
1 | {
2 | "exerciseSheet": true,
3 | "blocks": [
4 | {
5 | "type": "text",
6 | "text": "# Lecture 2 exercise 2\n\nFirst we need to import libraries."
7 | },
8 | {
9 | "type": "code",
10 | "text": "Require Import Reals.\nRequire Import Lra.\nRequire Import Classical.\nRequire Import Classical_Pred_Type.\n\nRequire Import wplib.Tactics.Tactics.\nRequire Import wplib.Tactics.TacticsContra.\nRequire Import wplib.Lib.sup_and_inf.\nRequire Import wplib.Notations.Notations.\n\nNotation cv_to := Un_cv.\n\nHint Resolve Rabs_Rabsolu."
11 | },
12 | {
13 | "type": "text",
14 | "text": "## Exercise 2\n\nSuppose we are given a sequence $(a_n)$ and a real number $c$."
15 | },
16 | {
17 | "type": "code",
18 | "text": "Variable a : ℕ → ℝ.\nVariable c : ℝ."
19 | },
20 | {
21 | "type": "text",
22 | "text": "Consider also the sequence $(b_n)$, defined by $b_n := |a_n - 0 |$.\n\n"
23 | },
24 | {
25 | "type": "code",
26 | "text": "Definition b : (ℕ → ℝ) := fun n ↦ | a n - c |."
27 | },
28 | {
29 | "type": "text",
30 | "text": "\n**Note:** the vertical line `|` is not the same as the bar | that you find on the keyboard. Instead of `| a n - c |` you could also write `Rabs (a n - c)`.\n\nWe are going to show that $(a_n)$ converges to $c$ if and only if $(b_n)$ converges to $0$. We split this statement into two separate lemmas: (i) If $(a_n)$ converges to $c$ then $(b_n)$ converges to $0$; (ii) if $(b_n)$ converges to $0$ then $(a_n)$ converges to $c$."
31 | },
32 | {
33 | "type": "code",
34 | "text": "Lemma ex_2i :\n cv_to a c ⇒ cv_to b 0.\nProof."
35 | },
36 | {
37 | "type": "input",
38 | "start": true,
39 | "id": "input-1"
40 | },
41 | {
42 | "type": "text",
43 | "text": "Write your solution here..."
44 | },
45 | {
46 | "type": "code",
47 | "text": "\nAdmitted."
48 | },
49 | {
50 | "type": "input",
51 | "start": false,
52 | "id": "input-1"
53 | },
54 | {
55 | "type": "code",
56 | "text": "Lemma ex_2ii :\n cv_to b 0 ⇒ cv_to a c.\nProof."
57 | },
58 | {
59 | "type": "input",
60 | "start": true,
61 | "id": "input-2"
62 | },
63 | {
64 | "type": "text",
65 | "text": "Write your solution here..."
66 | },
67 | {
68 | "type": "code",
69 | "text": "\nAdmitted."
70 | },
71 | {
72 | "type": "input",
73 | "start": false,
74 | "id": "input-2"
75 | }
76 | ]
77 | }
--------------------------------------------------------------------------------
/src/editpage/components/menubars/SidebarButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
8 |
9 |
10 | {{ buttonInfo.text }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
28 |
29 |
99 |
--------------------------------------------------------------------------------
/src/assets/sass/abstracts/_variables.scss:
--------------------------------------------------------------------------------
1 | /** Contains global variables used throughout the project In the future,
2 | we may want to override these values in theme-specific files. */
3 |
4 | /** Fonts used in branding (logos, application title, etc.) */
5 | $font-stack-brand: 'Century Gothic', sans-serif !default;
6 |
7 | // Fonts used in page headers (h1-h6). Separate to allow easy modification in
8 | // the future.
9 | $font-stack-headers: $font-stack-brand;
10 |
11 | // Fonts used in body text. Separate to allow easy modification in the future.
12 | $font-stack-body: $font-stack-brand;
13 |
14 | // Fonts used for displaying code.
15 | $font-stack-code: 'Letter Gothic Std', monospace !default;
16 |
17 | // Height settings of the tab (responsiveness)
18 | $tab-height-small: 15px !default;
19 | $tab-height-large: 35px !default;
20 |
21 | // Height settings of the topbar
22 | $topbar-height-large: 40px;
23 | $topbar-height-small: 30px;
24 |
25 | // ======================= NOTE =======================
26 | // THE color-X variables are here for reference to the ORIGINAL color definitions.
27 | // However, they should never be used. Instead, the themed variants should be used
28 | // These can be changed in ./light.scss or ./dark.scss
29 | // ====================================================
30 |
31 | // Primary brand color and variants.
32 | // TODO: These colors are very similar, and used interchangeably for navigation
33 | // items. Should probably merge these.
34 | $color-primary: #2b3990 !default;
35 | $color-primary-dark: #232d73 !default;
36 | // TODO: Both of these colors are used for hover effects, it would be better to
37 | // just stick to one color. Should probably use the dark variant on light
38 | // surfaces and vice versa.
39 | $color-primary-light: #5561a6 !default;
40 | $color-primary-extra-light: #aab0d3 !default;
41 | $color-primary-ultra-light: #eceeff !default;
42 |
43 | // Surface colors, for elements that are not typically styled using our brand
44 | // colors.
45 | $color-background: #ffffff !default;
46 | $color-surface: #ffffff !default;
47 | $color-error: #b00020 !default;
48 |
49 | // Colors for typography and iconography. These colors are meant for elements
50 | // that appear on top of elements styled using the primary/surface colors.
51 | $color-on-primary: #ffffff !default;
52 | $color-on-background: #000000 !default;
53 | $color-on-surface: #000000 !default;
54 | $color-on-error: #ffffff !default;
55 |
56 | // Color for multiple areas in a notebook, like search interface,
57 | // code blocks
58 | $color-gray-dark: #e6e6e6 !default;
59 | $color-gray-light: #f2f2f2 !default;
60 | $color-gray: #e6e6e6 !default;
61 |
62 | $color-highlight-mode: #fff6bf;
--------------------------------------------------------------------------------
/src/editpage/components/assistance/search/SearchBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
14 |
19 |
20 |
21 |
22 |
25 |
27 |
28 |
29 |
30 |
31 |
66 |
67 |
85 |
--------------------------------------------------------------------------------