diff --git a/Dockerfile b/Dockerfile index 9a8de3d97..9a8d4f1c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,10 @@ # building frontend FROM node:13.1 as build-deps COPY web ./ +# fix docker not following symlinks +COPY doc/getting-started.md ./src/assets/ RUN yarn install +RUN yarn lint RUN yarn build # production diff --git a/backend/README.md b/backend/README.md index c2d22bafc..1d202e003 100644 --- a/backend/README.md +++ b/backend/README.md @@ -18,28 +18,4 @@ pipenv install ## Usage -### Add documentation - -You can uppload any static html site by zipping it and -then posting the file to the backend. - -For example to upload the file `docs.zip` as version `1.0.0` for awesome-project. - -```sh -curl -X POST -F "file=@docs.zip" http://localhost:5000/api/awesome-project/1.0.0 -``` - -Any other file type is uploaded as well. -An uploaded pdf would be available as -`http://localhost:5000/api/awesome-project/1.0.0/my_awesome.pdf` - -### Tag documentation - -After this you can tag a version, this can be usefull when -the latest version should be available as `http://localhost:5000/docs/awesome-project/latest` - -If you want to tag the version `1.0.0` as `latest` for awesome-project. - -```sh -curl -X PUT http://localhost:5000/api/awesome-project/1.0.0/tags/latest -``` +See [Help.md](Help.md) diff --git a/doc/getting-started.md b/doc/getting-started.md new file mode 100644 index 000000000..5ca8969f9 --- /dev/null +++ b/doc/getting-started.md @@ -0,0 +1,31 @@ +## Getting started with DOCAT + +### Upload your documentation + +You can upload any static html site by zipping it and +then posting the file to the backend. + +For example to upload the file `docs.zip` as version `1.0.0` for `awesome-project`. + +```sh +curl -X POST -F "file=@docs.zip" http://localhost:8000/api/awesome-project/1.0.0 +``` + +Any other file type is uploaded as well. +An uploaded pdf could be viewed like this: + +`http://localhost/#/awesome-project/1.0.0/my_awesome.pdf` + +You can also manually upload your documentation. +A very simple web form can be found under [upload](#/upload). + +### Tag documentation + +After this you can tag a version, this can be usefull when +the latest version should be available as `http://localhost:5000/docs/awesome-project/latest` + +If you want to tag the version `1.0.0` as `latest` for awesome-project. + +```sh +curl -X PUT http://localhost:5000/api/awesome-project/1.0.0/tags/latest +``` diff --git a/web/package.json b/web/package.json index 61760c38b..46637b142 100644 --- a/web/package.json +++ b/web/package.json @@ -8,10 +8,14 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "babel-runtime": "^6.26.0", "core-js": "^3.3.2", + "html-loader": "^0.5.5", "node-sass": "^4.13.0", "sass-loader": "^8.0.0", - "vue": "^2.6.10" + "vue": "^2.6.10", + "vue-markdown": "^2.2.4", + "vuelidate": "^0.7.4" }, "devDependencies": { "@vue/cli-plugin-babel": "^4.0.0", diff --git a/web/public/index.html b/web/public/index.html index f22e18b2d..44d256ba5 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -5,6 +5,7 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> + <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <title>docat</title> </head> <body> diff --git a/web/src/assets/getting-started.md b/web/src/assets/getting-started.md new file mode 120000 index 000000000..8026b1c94 --- /dev/null +++ b/web/src/assets/getting-started.md @@ -0,0 +1 @@ +../../../doc/getting-started.md \ No newline at end of file diff --git a/web/src/components/Help.vue b/web/src/components/Help.vue new file mode 100644 index 000000000..05a29ab14 --- /dev/null +++ b/web/src/components/Help.vue @@ -0,0 +1,23 @@ +<template> + <vue-markdown> + {{ help }} + </vue-markdown> +</template> + +<script> +import VueMarkdown from 'vue-markdown' + +import help from '@/assets/getting-started.md' + +export default { + name: 'help', + components: { + VueMarkdown + }, + data() { + return { + help, + } + } +} +</script> diff --git a/web/src/components/Layout.vue b/web/src/components/Layout.vue index 881be7596..d33db7f1d 100644 --- a/web/src/components/Layout.vue +++ b/web/src/components/Layout.vue @@ -18,6 +18,9 @@ <div v-if="!fullscreen" class="md-layout-item md-size-15 md-small-hide"></div> <div class="md-layout-item"> <slot></slot> + <div class="help"> + <router-link to="/help" v-if="!fullscreen">help</router-link> + </div> </div> <div v-if="!fullscreen" class="md-layout-item md-size-15 md-small-hide"></div> </div> @@ -66,4 +69,19 @@ body, height: 100%; } +a { + /* TODO: remove hack */ + color: #742a47 !important; +} + +.help { + width: 100%; + border-top: 1px solid #e8e8e8; + padding-top: 16px; + margin-top: 16px; + + a { + margin-left: 50%; + } +} </style> \ No newline at end of file diff --git a/web/src/components/ProjectOverview.vue b/web/src/components/ProjectOverview.vue index 870bc7a78..1935d76ae 100644 --- a/web/src/components/ProjectOverview.vue +++ b/web/src/components/ProjectOverview.vue @@ -6,17 +6,21 @@ v-bind:key="project.name" :project="project.name" /> + <Help v-if="!projects.length" /> </div> </template> <script> +import Help from '@/components/Help.vue' import Project from '@/components/Project.vue' + import ProjectRepository from '@/repositories/ProjectRepository' export default { name: 'ProjectOverview', components: { - Project + Project, + Help }, data() { return { diff --git a/web/src/components/UploadButton.vue b/web/src/components/UploadButton.vue new file mode 100644 index 000000000..302155a1e --- /dev/null +++ b/web/src/components/UploadButton.vue @@ -0,0 +1,14 @@ +<template> + <md-button to="/upload" class="md-fab md-primary"> + <md-icon>backup</md-icon> + <md-tooltip md-direction="left">upload documentation</md-tooltip> + </md-button> +</template> + +<script> +export default { + name: 'UploadButton' +} +</script> + + diff --git a/web/src/main.js b/web/src/main.js index cd276916b..888835f12 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -4,13 +4,18 @@ import App from '@/App.vue' // configure vue material (https://vuematerial.io/getting-started/) import { MdCard, + MdButton, MdAvatar, MdApp, MdToolbar, MdContent, MdList, MdField, - MdMenu + MdMenu, + MdProgress, + MdSnackbar, + MdIcon, + MdTooltip } from 'vue-material/dist/components' import 'vue-material/dist/vue-material.min.css' import 'vue-material/dist/theme/default.css' @@ -23,6 +28,16 @@ Vue.use(MdList) Vue.use(MdToolbar) Vue.use(MdCard) Vue.use(MdAvatar) +Vue.use(MdProgress) +Vue.use(MdSnackbar) +Vue.use(MdButton) +Vue.use(MdIcon) +Vue.use(MdTooltip) + +// configure to use vue-markdown (https://github.com/miaolz123/vue-markdown) +import VueMarkdown from 'vue-markdown' + +Vue.use(VueMarkdown); // configure vue router (https://router.vuejs.org/installation.html) import VueRouter from 'vue-router' @@ -32,10 +47,14 @@ Vue.use(VueRouter) // configure the app's routing import Home from '@/pages/Home.vue' import Docs from '@/pages/Docs.vue' +import Help from '@/pages/Help.vue' +import Upload from '@/pages/Upload.vue' const routes = [ { path: '/', component: Home }, - { path: '/:project/:version/:location?', component: Docs } + { path: '/:project/:version/:location?', component: Docs }, + { path: '/help', component: Help }, + { path: '/upload', component: Upload }, ] const router = new VueRouter({ diff --git a/web/src/pages/Help.vue b/web/src/pages/Help.vue new file mode 100644 index 000000000..fe30dfec9 --- /dev/null +++ b/web/src/pages/Help.vue @@ -0,0 +1,23 @@ +<template> + <div> + <Layout> + <Help class="spacing" /> + </Layout> + <UploadButton class="upload-button" /> + </div> +</template> + +<script> +import Layout from '@/components/Layout.vue' +import Help from '@/components/Help.vue' +import UploadButton from '@/components/UploadButton.vue' + +export default { + name: 'help-page', + components: { + Layout, + Help, + UploadButton + } +} +</script> \ No newline at end of file diff --git a/web/src/pages/Home.vue b/web/src/pages/Home.vue index 678432c5d..d8760f07d 100644 --- a/web/src/pages/Home.vue +++ b/web/src/pages/Home.vue @@ -1,18 +1,23 @@ <template> - <Layout> - <ProjectOverview class="spacing" /> - </Layout> + <div> + <Layout> + <ProjectOverview class="spacing" /> + </Layout> + <UploadButton class="upload-button" /> + </div> </template> <script> import ProjectOverview from '@/components/ProjectOverview.vue' import Layout from '@/components/Layout.vue' +import UploadButton from '@/components/UploadButton.vue' export default { name: 'home', components: { ProjectOverview, - Layout + Layout, + UploadButton } } </script> @@ -30,4 +35,20 @@ export default { .spacing { padding-top: 20px; } + +.upload-button { + position: fixed; + bottom: 16px; +} + +@media all and (max-width: 959px) { + .upload-button { + right: 16px; + } +} +@media all and (min-width: 959px) { + .upload-button { + right: 15%; + } +} </style> diff --git a/web/src/pages/Upload.vue b/web/src/pages/Upload.vue new file mode 100644 index 000000000..02ad55415 --- /dev/null +++ b/web/src/pages/Upload.vue @@ -0,0 +1,131 @@ +<template> + <Layout> + <form novalidate @submit.prevent="validateUpload" class="upload-form"> + <h1 class="upload-title">Upload documentation</h1> + + <p> + If you want to automate the upload of your documentation consider using <code>curl</code> + to post it to the server. + There are some examples in the <a href="https://github.com/randombenj/docat/" target="_blank">docat repository</a>. + </p> + + <md-field :class="getValidationClass('project')"> + <label>Projectname</label> + <md-input type="text" id="project" name="project" v-model="form.project" :disabled="sending" /> + <span class="md-error" v-if="!$v.form.project.required">The projectname is required</span> + </md-field> + + <md-field :class="getValidationClass('version')"> + <label>Version</label> + <md-input type="text" id="version" name="version" v-model="form.version" :disabled="sending" /> + <span class="md-error" v-if="!$v.form.version.required">The version is required</span> + </md-field> + + <md-field :class="getValidationClass('documentation')"> + <label >Documentation (zip file)</label> + <md-file id="documentation" @change="onFileUpload($event)" :disabled="sending" accept="zip,application/octet-stream,application/zip,application/x-zip,application/x-zip-compressed" /> + <span class="md-error">The documentation is required</span> + </md-field> + + <md-progress-bar md-mode="indeterminate" class="md-accent" v-if="sending" /> + <button class="md-button md-raised md-primary" :disabled="sending" type="submit">Upload</button> + + <md-snackbar md-position="left" :md-duration="4000" :md-active.sync="showError" md-persistent> + <span>{{ error }}</span> + <md-button class="md-primary" @click="showError = false">Close</md-button> + </md-snackbar> + </form> + </Layout> +</template> + +<script> +import { validationMixin } from 'vuelidate' +import { required } from 'vuelidate/lib/validators' + +import Layout from '@/components/Layout.vue' +import ProjectRepository from '@/repositories/ProjectRepository' + +export default { + name: 'Upload', + mixins: [validationMixin], + components: { + Layout, + }, + data() { + return { + form: { + project: null, + version: null + }, + sending: false, + error: '', + showError: false + } + }, + validations: { + form: { + project: { required }, + version: { required }, + file: '' + } + }, + methods: { + async upload() { + this.sending = true + const formData = new FormData() + formData.append("file", this.form.file) + + try { + await ProjectRepository.upload(this.form.project, this.form.version, formData) + this.clearForm() + } catch(err) { + // something went wrong while + this.showError = true + this.error = err + } + + this.sending = false + }, + onFileUpload(e) { + const files = e.target.files || e.dataTransfer.files + + if (files.length) { + this.form.file = files[0] + } + }, + getValidationClass(fieldName) { + const field = this.$v.form[fieldName] + + if (field) { + return { + 'md-invalid': field.$invalid && field.$dirty + } + } + }, + clearForm () { + this.$v.$reset() + this.form.project = null + this.form.version = null + }, + validateUpload() { + this.$v.$touch() + + if (!this.$v.$invalid) { + this.upload() + } + } + } +} +</script> + +<style scoped> +.upload-title { + margin-bottom: 16px; +} + +.upload-form { + margin-top: 48px; + padding-right: 16px; + padding-left: 16px; +} +</style> \ No newline at end of file diff --git a/web/src/repositories/ProjectRepository.js b/web/src/repositories/ProjectRepository.js index 604dbe4b8..286b89d61 100644 --- a/web/src/repositories/ProjectRepository.js +++ b/web/src/repositories/ProjectRepository.js @@ -36,5 +36,13 @@ export default { return (await Repository.get(`${Repository.defaults.baseURL}/${resource}/${projectName}/`)) .data .filter((version) => version.type == 'directory') + }, + + async upload(projectName, version, formData) { + await Repository.post( + `${Repository.defaults.baseURL}/api/${projectName}/${version}`, + formData, + { headers: { 'Content-Type': 'multipart/form-data' } } + ) } } diff --git a/web/vue.config.js b/web/vue.config.js new file mode 100644 index 000000000..aae1b69bd --- /dev/null +++ b/web/vue.config.js @@ -0,0 +1,10 @@ +module.exports = { + configureWebpack: { + module: { + rules: [{ + test: /\.md$/, + use: [{ loader: "html-loader" }] + }] + } + } +} \ No newline at end of file diff --git a/web/yarn.lock b/web/yarn.lock index 0407d2b6a..9f3f3b9c9 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -1433,6 +1433,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types@0.9.6: + version "0.9.6" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" + integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk= + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -1541,6 +1546,14 @@ babel-plugin-module-resolver@^3.2.0: reselect "^3.0.1" resolve "^1.4.0" +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -2122,6 +2135,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +clone@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + coa@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" @@ -2348,6 +2366,11 @@ core-js-pure@^3.0.0: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.4.0.tgz#a0e89ce3f8142512b784a3c9f85839730acd8203" integrity sha512-d49s6GiW3ePYM8vCglfLLo6bueYx+Sff6MYtjohTMSB0AoxVfABXMUSmYHtKAEvW77T9JTKMyHrhE20nZ8gYDA== +core-js@^2.4.0: + version "2.6.10" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f" + integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA== + core-js@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.4.0.tgz#29ea478601789c72f2978e9bb98f43546f89d3aa" @@ -3008,7 +3031,7 @@ enhanced-resolve@^4.1.0: memory-fs "^0.5.0" tapable "^1.0.0" -entities@^1.1.1: +entities@^1.1.1, entities@~1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== @@ -3064,6 +3087,14 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-templates@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/es6-templates/-/es6-templates-0.2.3.tgz#5cb9ac9fb1ded6eb1239342b81d792bbb4078ee4" + integrity sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ= + dependencies: + recast "~0.11.12" + through "~2.3.6" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -3177,6 +3208,11 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + esquery@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" @@ -3407,6 +3443,11 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -3952,7 +3993,7 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== -highlight.js@^9.6.0: +highlight.js@^9.12.0, highlight.js@^9.6.0: version "9.16.2" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.16.2.tgz#68368d039ffe1c6211bcc07e483daf95de3e403e" integrity sha512-feMUrVLZvjy0oC7FVJQcSQRqbBq9kwqnYE4+Kj9ZjbHh3g+BisiPgF49NyQbVLNdrL/qqZr3Ca9yOKwgn2i/tw== @@ -4006,7 +4047,18 @@ html-entities@^1.2.1: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= -html-minifier@^3.2.3: +html-loader@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-0.5.5.tgz#6356dbeb0c49756d8ebd5ca327f16ff06ab5faea" + integrity sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog== + dependencies: + es6-templates "^0.2.3" + fastparse "^1.1.1" + html-minifier "^3.5.8" + loader-utils "^1.1.0" + object-assign "^4.1.1" + +html-minifier@^3.2.3, html-minifier@^3.5.8: version "3.5.21" resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== @@ -4764,6 +4816,13 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +katex@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.6.0.tgz#12418e09121c05c92041b6b3b9fb6bab213cb6f3" + integrity sha1-EkGOCRIcBckgQbazuftrqyE8tvM= + dependencies: + match-at "^0.1.0" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -4835,6 +4894,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= +linkify-it@~1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-1.2.4.tgz#0773526c317c8fd13bd534ee1d180ff88abf881a" + integrity sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo= + dependencies: + uc.micro "^1.0.1" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -5027,6 +5093,82 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +markdown-it-abbr@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz#d66b5364521cbb3dd8aa59dadfba2fb6865c8fd8" + integrity sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g= + +markdown-it-deflist@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz#5727db04184d3cb2bc6ee4a9641e3a1091d5fd6f" + integrity sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw== + +markdown-it-emoji@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc" + integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw= + +markdown-it-footnote@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-2.0.0.tgz#14e9c4f68ff12cf354fa365ae378276e8104ca94" + integrity sha1-FOnE9o/xLPNU+jZa43gnboEEypQ= + +markdown-it-ins@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz#a5aa6a30f1e2f71e9497567cfdff40f1fde67483" + integrity sha1-papqMPHi9x6Ul1Z8/f9A8f3mdIM= + +markdown-it-katex@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz#d7b86a1aea0b9d6496fab4e7919a18fdef589c39" + integrity sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk= + dependencies: + katex "^0.6.0" + +markdown-it-mark@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-mark/-/markdown-it-mark-2.0.0.tgz#46a1aa947105aed8188978e0a016179e404f42c7" + integrity sha1-RqGqlHEFrtgYiXjgoBYXnkBPQsc= + +markdown-it-sub@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz#375fd6026eae7ddcb012497f6411195ea1e3afe8" + integrity sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g= + +markdown-it-sup@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz#cb9c9ff91a5255ac08f3fd3d63286e15df0a1fc3" + integrity sha1-y5yf+RpSVawI8/09YyhuFd8KH8M= + +markdown-it-task-lists@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz#f68f4d2ac2bad5a2c373ba93081a1a6848417088" + integrity sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA== + +markdown-it-toc-and-anchor@^4.1.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/markdown-it-toc-and-anchor/-/markdown-it-toc-and-anchor-4.2.0.tgz#d1613327cc63c61f82cd66cbac5564f4db12c0e9" + integrity sha512-DusSbKtg8CwZ92ztN7bOojDpP4h0+w7BVOPuA3PHDIaabMsERYpwsazLYSP/UlKedoQjOz21mwlai36TQ04EpA== + dependencies: + clone "^2.1.0" + uslug "^1.0.4" + +markdown-it@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-6.1.1.tgz#ced037f4473ee9f5153ac414f77dc83c91ba927c" + integrity sha1-ztA39Ec+6fUVOsQU933IPJG6knw= + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "~1.2.2" + mdurl "~1.0.1" + uc.micro "^1.0.1" + +match-at@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/match-at/-/match-at-0.1.1.tgz#25d040d291777704d5e6556bbb79230ec2de0540" + integrity sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -5041,6 +5183,11 @@ mdn-data@2.0.4: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== +mdurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6522,7 +6669,7 @@ pretty-error@^2.0.2: renderkid "^2.0.1" utila "~0.4" -private@^0.1.6: +private@^0.1.6, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -6758,6 +6905,16 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +recast@~0.11.12: + version "0.11.23" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" + integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM= + dependencies: + ast-types "0.9.6" + esprima "~3.1.0" + private "~0.1.5" + source-map "~0.5.0" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -6778,6 +6935,11 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + regenerator-runtime@^0.13.2: version "0.13.3" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" @@ -7394,7 +7556,7 @@ source-map@^0.4.2: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -7859,7 +8021,7 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6: +through@^2.3.6, through@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -8013,6 +8175,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +uc.micro@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + uglify-js@3.4.x: version "3.4.10" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" @@ -8083,6 +8250,11 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +"unorm@>= 1.0.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -8153,6 +8325,13 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +uslug@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/uslug/-/uslug-1.0.4.tgz#b9a22f0914e0a86140633dacc302e5f4fa450677" + integrity sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc= + dependencies: + unorm ">= 1.0.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -8255,6 +8434,25 @@ vue-loader@^15.7.0: vue-hot-reload-api "^2.3.0" vue-style-loader "^4.1.0" +vue-markdown@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/vue-markdown/-/vue-markdown-2.2.4.tgz#db0f774178f3bc91ee18c626d86a3a0d2de22746" + integrity sha512-hoTX/W1UIdHZrp/b0vpHSsJXAEfWsafaQLgtE2VX4gY8O/C3L2Gabqu95gyG429rL4ML1SwGv+xsPABX7yfFIQ== + dependencies: + highlight.js "^9.12.0" + markdown-it "^6.0.1" + markdown-it-abbr "^1.0.3" + markdown-it-deflist "^2.0.1" + markdown-it-emoji "^1.1.1" + markdown-it-footnote "^2.0.0" + markdown-it-ins "^2.0.0" + markdown-it-katex "^2.0.3" + markdown-it-mark "^2.0.0" + markdown-it-sub "^1.0.0" + markdown-it-sup "^1.0.0" + markdown-it-task-lists "^2.0.1" + markdown-it-toc-and-anchor "^4.1.2" + vue-material@^1.0.0-beta-11: version "1.0.0-beta-11" resolved "https://registry.yarnpkg.com/vue-material/-/vue-material-1.0.0-beta-11.tgz#11baf0cdb22a35d35859c619099d6c3cb3cc2cc3" @@ -8291,6 +8489,11 @@ vue@^2.6.10: resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637" integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ== +vuelidate@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/vuelidate/-/vuelidate-0.7.4.tgz#5a0e54be09ac0192f1aa3387d74b92e0945bf8aa" + integrity sha512-QHZWYOL325Zo+2K7VBNEJTZ496Kd8Z31p85aQJFldKudUUGBmgw4zu4ghl4CyqPwjRCmqZ9lDdx4FSdMnu4fGg== + watchpack@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"