diff --git a/canvas-10-feb/package.json b/canvas-10-feb/package.json index c8de4a4402f271c32999647acf846a2a0b59c98a..dcd0b0bf330698d362f5a3e04ff42f1576a33ac7 100644 --- a/canvas-10-feb/package.json +++ b/canvas-10-feb/package.json @@ -10,7 +10,10 @@ "dependencies": { "core-js": "^3.6.4", "pouchdb": "^7.2.1", + "pouchdb-find": "^7.2.1", "vue": "^2.6.11", + "vue-context": "^5.0.0", + "vue-draggable-resizable": "^2.1.0", "vue-router": "^3.1.5", "vuex": "^3.1.2" }, diff --git a/canvas-10-feb/src/components/NodesLayer.vue b/canvas-10-feb/src/components/NodesLayer.vue index 6afd23e1421a3cc22bab1393a82a422df7a056de..be4a4a4dd548f49bc53b9f08715c759e21c6a532 100644 --- a/canvas-10-feb/src/components/NodesLayer.vue +++ b/canvas-10-feb/src/components/NodesLayer.vue @@ -1,45 +1,66 @@ <template> <div ref="nodes" class="node"> - <form> - <div v-for="value in myNodes" v-bind:key="value.nodeid"> - <textarea - v-if="nodeid == value.nodeid" - @input="editNode" - v-model="value.nodetext" - :id="nodeid" - ></textarea> - </div> + <vue-draggable-resizable + :w="200" + :h="200" + @dragging="onDrag" + @resizing="onResize" + style="background-color: rgb(205, 234, 255);" + > + <form> + <div v-for="value in myNodes" v-bind:key="value.nodeid"> + <textarea + v-if="nodeid == value.nodeid" + @input="editNode" + v-model="value.nodetext" + :id="nodeid" + ></textarea> + </div> - <p>markdown supported</p> - <button>delete</button> - </form> + <p>markdown supported</p> + <button>delete</button> + </form> + </vue-draggable-resizable> </div> </template> <script> -import { drag } from './mixins/drag.js' +//import { drag } from './mixins/drag.js' import { mapState } from 'vuex' export default { name: 'NodesLayer', - mixins: [drag], - // FIXME : these probably need to be data or computed and not props - props: { nodeid: Number, nodetext: String }, + // mixins: [drag], + props: { nodeid: String, nodetext: String }, data() { return { - thistext: this.nodetext + thistext: this.nodetext, + width: 0, + height: 0, + x: 0, + y: 0 } }, mounted() { - var nodes = this.$refs.nodes - this.makeDraggable(nodes) + // var nodes = this.$refs.nodes + // this.makeDraggable(nodes) }, computed: mapState({ myNodes: state => state.myNodes }), methods: { + onResize: function(x, y, width, height) { + this.x = x + this.y = y + this.width = width + this.height = height + }, + onDrag: function(x, y) { + this.x = x + this.y = y + }, setFocus() { // this.$refs.nodetext.focus() }, @@ -57,6 +78,12 @@ export default { <style scoped> .node { background-color: rgb(207, 177, 235); - position: absolute; + position: relative; +} + +textarea { + width: 195px; + height: 120px; + resize: none; } </style> diff --git a/canvas-10-feb/src/components/OnBoard.vue b/canvas-10-feb/src/components/OnBoard.vue new file mode 100644 index 0000000000000000000000000000000000000000..46edd71e8eabd2018e83c9a7b307d44b534916e8 --- /dev/null +++ b/canvas-10-feb/src/components/OnBoard.vue @@ -0,0 +1,203 @@ +<template> + <div class="notlogged"> + <h1>nodenogg.in</h1> + <p> + nodenogg.in is a + <span>work in progress</span> collaborative co-creation research and + design thinking tool, read more details and links in the + <a + href="/#/about" + >about</a> section. + </p> + + <form v-show="parta"> + <h2>1</h2> + <h3>microcosm</h3> + <p> + create or join a microcosm. a microcosm is a sharable digital space that + can be shared privately between a group of individuals. all content / + data you contribute is stored locally on your device and then shared + privately to others on the same microcosm. you can remove your + contributions at any time, they belong to you. + </p> + <input + type="text" + v-model.trim="localmicrocosm" + placeholder="microcosm name" + autocorrect="off" + autocapitalize="none" + autofocus + /> + <button @click="createMicrocosm(), setFocus()">+</button> + </form> + + <form v-show="partb"> + <h2>2</h2> + <h3>object</h3> + <p> + give yourself an object name, this is what connects you to your content + / data. this object name is anonymous and stored privately. + </p> + <input + type="text" + v-model.trim="clientid" + placeholder="object name" + autocorrect="off" + autocapitalize="none" + ref="objectname" + /> + <button @click="setClient()">+</button> + </form> + + <form v-show="partc"> + <h2>3</h2> + <h3>start</h3> + <button @click="letsGo()">+</button> + </form> + </div> +</template> + +<script> +var delay = 100 + +export default { + data: function() { + return { + localmicrocosm: '', + clientid: '', + parta: true, + partb: false, + partc: false + } + }, + + mounted() { + if (localStorage.myNNClient) { + this.clientid = localStorage.myNNClient + this.localmicrocosm = localStorage.mylastMicrocosm + this.createMicrocosm() + this.setClient() + this.letsGo() + } + }, + + methods: { + createMicrocosm() { + ;(this.partb = true), + this.$store.dispatch('createMicrocosm', this.localmicrocosm) + localStorage.setItem('mylastMicrocosm', this.localmicrocosm) + }, + setClient() { + ;(this.partc = true), + this.$store.dispatch('setClient', this.clientid), + localStorage.setItem('myNNClient', this.clientid) + }, + + letsGo() { + this.$emit('clientAdded') + // this.$emit('readyMode') + }, + setFocus() { + setTimeout(this.readyFocus, delay) + }, + readyFocus() { + this.$refs.objectname.focus() + } + } +} +</script> + +<style lang="css" scoped> +@import url('https://rsms.me/inter/inter.css'); +html { + font-family: 'Inter', sans-serif; +} +@supports (font-variation-settings: normal) { + html { + font-family: 'Inter var', sans-serif; + } +} +ul { + font-family: 'Pica 10 Pitch W01'; + font-size: 16px; + line-height: 20px; +} + +li:before { + content: ''; +} + +b { + background-color: yellow; + padding-right: 2em; +} + +h1 { + font-size: 3em; +} + +h1, +h2, +h3, +p { + font-family: 'Inter var', sans-serif; + color: black; + margin: 0px; +} + +p { + margin-top: 2em; +} + +h2 { + float: right; + font-size: 3em; +} + +h3 { + font-size: 3em; + margin-top: 0.5em; +} + +form { + padding: 1em; + border-style: solid; + border-width: 0.5em; + border-color: #cab6ff; + margin-top: 1em; +} + +input { + border-style: solid; + border-width: 1px; + border-color: #cab6ff; + padding: 0.5em; +} + +button { + font-size: 1.8em; + color: black; + border-style: solid; + border-width: 5px; + border-color: black; + border-radius: 50%; + background-color: white; + box-shadow: none; + height: 1.5em; + width: 1.5em; + padding: 0px; +} + +button:active { + background-color: #cab6ff; +} + +@media only screen and (min-width: 640px) { + /* Style adjustments for viewports that meet the condition */ + + .notlogged { + grid-column: 1 / 3; + grid-row: 1; + } +} +</style> diff --git a/canvas-10-feb/src/components/otherNodeslayer.vue b/canvas-10-feb/src/components/otherNodeslayer.vue index 911ba249ee8d93c1bf20e51ff8b0119c7c6407f2..291d99f453b3758d0bab871d7fabb500f96a9f5f 100644 --- a/canvas-10-feb/src/components/otherNodeslayer.vue +++ b/canvas-10-feb/src/components/otherNodeslayer.vue @@ -1,22 +1,51 @@ <template> <div ref="othernodes" class="node"> - <p :id="nodeid">{{ nodetext }}</p> - <p>markdown supported</p> + <vue-draggable-resizable + :w="200" + :h="200" + @dragging="onDrag" + @resizing="onResize" + style="border: 1px solid black; background-color: rgb(205, 234, 255);" + > + <p :id="nodeid">{{ nodetext }}</p> + <p>markdown supported</p> + </vue-draggable-resizable> </div> </template> <script> -import { drag } from './mixins/drag.js' +//import { drag } from './mixins/drag.js' export default { name: 'otherNodeslayer', - mixins: [drag], + //mixins: [drag], - props: { nodeid: Number, nodetext: String }, + props: { nodeid: String, nodetext: String }, + + data: function() { + return { + width: 0, + height: 0, + x: 0, + y: 0 + } + }, mounted() { - var othernodes = this.$refs.othernodes - this.makeDraggable(othernodes) + // var othernodes = this.$refs.othernodes + // this.makeDraggable(othernodes) + }, + methods: { + onResize: function(x, y, width, height) { + this.x = x + this.y = y + this.width = width + this.height = height + }, + onDrag: function(x, y) { + this.x = x + this.y = y + } } } </script> diff --git a/canvas-10-feb/src/store/index.js b/canvas-10-feb/src/store/index.js index b17ce5826e4f1dc1f7d911e0f73bf119d38df3a8..65fb09ef4fb2322ae6592bc6442d2964c7f97372 100644 --- a/canvas-10-feb/src/store/index.js +++ b/canvas-10-feb/src/store/index.js @@ -1,13 +1,28 @@ import Vue from 'vue' import Vuex from 'vuex' import PouchDB from 'pouchdb' +PouchDB.plugin(require('pouchdb-find')) +import VueDraggableResizable from 'vue-draggable-resizable' + import accounts from '../assets/settings.json' +// PouchDB.debug.enable('*') Vue.use(Vuex) -// var rando = Math.random() -// .toString(16) -// .slice(2) -var microcosm = 'podcast2020' +Vue.component('vue-draggable-resizable', VueDraggableResizable) +var myclient = 'firstvisit' + +if (localStorage.getItem('mylastMicrocosm') == null) { + var microcosm = 'firstvisit' +} else { + microcosm = localStorage.getItem('mylastMicrocosm') +} + +if (localStorage.getItem('myNNClient') == null) { + myclient = 'firstvisit' +} else { + myclient = localStorage.getItem('myNNClient') +} + var pouchdb = new PouchDB(microcosm) var remote = 'https://' + @@ -20,11 +35,12 @@ var remote = const store = new Vuex.Store({ state: { - localnodeid: null, + localnodeid: '', global_pos_name: 'positions', - // this is set with localStorage or could be random on Every Load - // so long as you can edit all nodes - myclient: 'mac', + global_con_name: 'connections', + global_emoji_name: 'emojis', + microcosm: '', + myclient: myclient, activeNode: {}, // this will be objects containing arrays of all the handles / connections and nodes configConnect: { @@ -41,6 +57,7 @@ const store = new Vuex.Store({ width: 10, fill: 'black' }, + allNodes: [], myNodes: [ // { nodeid: 1, nodetext: 'node 1' }, ], @@ -49,44 +66,117 @@ const store = new Vuex.Store({ ], configPositions: [ //{} + ], + configConnections: [ + //{} + ], + configEmoji: [ + //{} ] }, mutations: { - GET_NODES(state) { + CREATE_MICROCOSM(state, doc) { + pouchdb.close().then(function() { + // console.log(doc) + microcosm = doc + pouchdb = new PouchDB(microcosm) + remote = + 'https://' + + accounts.settings[0].name + + ':' + + accounts.settings[0].password + + '@nn.adamprocter.co.uk/' + + microcosm + + '/' + + store.dispatch('syncDB') + }) + }, + + GET_ALL_NODES(state) { pouchdb .allDocs({ include_docs: true, attachments: true }) .then(function(doc) { - var i - var j - for (i = 0; i < Object.keys(doc.rows).length; i++) { - if (state.myclient == doc.rows[i].key) { - state.myNodes = doc.rows[i].doc.nodes - } - if ( - state.myclient != doc.rows[i].key && - state.global_pos_name != doc.rows[i].key && - state.global_con_name != doc.rows[i].key && - state.global_emoji_name != doc.rows[i].key - ) { - for (j = 0; j < Object.keys(doc.rows[i].doc.nodes).length; j++) { - console.log(doc.rows[i].doc.nodes[j].nodeid) - console.log(doc.rows[i].doc.nodes[j].nodetext) - const newNode = { - nodeid: doc.rows[i].doc.nodes[j].nodeid, - nodetext: doc.rows[i].doc.nodes[j].nodetext - } - state.otherNodes.push(newNode) - } + state.microcosm = microcosm + state.allNodes = doc.rows + store.commit('SET_OTHER_NODES') + }) + .catch(function(err) { + console.log(err) + }) + }, + + SET_OTHER_NODES(state) { + state.otherNodes = [] + var i + var j + for (i = 0; i < Object.keys(state.allNodes).length; i++) { + if ( + state.allNodes[i].id != state.myclient && + state.allNodes[i].id != state.global_pos_name + ) { + for ( + j = 0; + j < Object.keys(state.allNodes[i].doc.nodes).length; + j++ + ) { + const newNode = { + nodeid: state.allNodes[i].doc.nodes[j].nodeid, + nodetext: state.allNodes[i].doc.nodes[j].nodetext } + + state.otherNodes.push(newNode) } + } + } + //console.log(state.otherNodes) + }, + + SET_CLIENT(state, doc) { + state.myclient = doc + store.commit('GET_MY_NODES') + }, + + GET_MY_NODES(state) { + pouchdb + .get(state.myclient) + .then(function(doc) { + state.myNodes = doc.nodes }) .catch(function(err) { - console.log(err) + if (err.status == 404) { + var uniqueid = + Math.random() + .toString(36) + .substring(2, 15) + + Math.random() + .toString(36) + .substring(2, 15) + return pouchdb.put({ + _id: state.myclient, + _attachments: {}, + nodes: [ + { + // FIXME: these values are here as GET_ALL_NODES cant hunt a blank + // this shouldnt need to be here + index: uniqueid, + nodeid: uniqueid, + nodetext: state.myclient, + nodeowner: state.myclient, + content_type: 'sheet', + // TEMP: this hides this node card as its effectivly auto deleted + deleted: true, + attachment_name: '' + } + ] + }) + } }) }, + GET_POSITIONS(state) { pouchdb .get(state.global_pos_name) @@ -118,7 +208,8 @@ const store = new Vuex.Store({ pouchdb.get(state.myclient).then(function(doc) { if (e == undefined) { - doc.notes.push({ + doc.nodes.push({ + index: uniqueid, nodeid: uniqueid, nodetext: '', nodeowner: state.myclient, @@ -133,16 +224,17 @@ const store = new Vuex.Store({ _id: state.myclient, _rev: doc._rev, _attachments: doc._attachments, - nodes: doc.notes + index: doc.uniqueid, + nodes: doc.nodes }) .then(function() { return pouchdb.get(state.myclient).then(function(doc) { state.myNodes = doc.nodes var end = Object.keys(state.myNodes).length - 1 const newNode = { - nodetext: state.myNodes[end].text, nodeid: state.myNodes[end].id, - content_type: state.notes[end].content_type + nodetext: state.myNodes[end].text + // content_type: state.notes[end].content_type } state.activeNode = newNode }) @@ -182,6 +274,7 @@ const store = new Vuex.Store({ .get(state.myclient) .then(function(doc) { // put the store into pouchdb + return pouchdb.bulkDocs([ { _id: state.myclient, @@ -206,15 +299,16 @@ const store = new Vuex.Store({ actions: { syncDB: () => { pouchdb.replicate.from(remote).on('complete', function() { - store.commit('GET_NODES') + store.commit('GET_ALL_NODES') + store.commit('GET_MY_NODES') store.commit('GET_POSITIONS') // turn on two-way, continuous, retriable sync pouchdb .sync(remote, { live: true, retry: true, attachments: true }) .on('change', function() { // pop info into function to find out more - console.log('change') - store.commit('GET_NODES') + store.commit('GET_ALL_NODES') + store.commit('GET_MY_NODES') store.commit('GET_POSITIONS') }) .on('paused', function() { @@ -237,7 +331,12 @@ const store = new Vuex.Store({ }) }) }, - + createMicrocosm: ({ commit }, e) => { + commit('CREATE_MICROCOSM', e) + }, + setClient: ({ commit }, e) => { + commit('SET_CLIENT', e) + }, editNode: ({ commit }, { nodeid, nodetext }) => { commit('EDIT_NODE', { nodeid, nodetext }) } diff --git a/canvas-10-feb/src/views/Home.vue b/canvas-10-feb/src/views/Home.vue index 5f3c83192c0692301726dab9b61022199b2f0048..ee177861e615887fe571e5c187d29e7844df71ff 100644 --- a/canvas-10-feb/src/views/Home.vue +++ b/canvas-10-feb/src/views/Home.vue @@ -1,43 +1,61 @@ <template> <div class="home"> - <NodesLayer - v-for="value in myNodes" - v-bind:key="value.nodeid" - v-bind:nodeid="value.nodeid" - v-bind:nodetext="value.nodetext" - /> - <otherNodeslayer - v-for="value in otherNodes" - v-bind:key="value.nodeid" - v-bind:nodeid="value.nodeid" - v-bind:nodetext="value.nodetext" - /> - <CanvasLayer /> - <ControlsLayer /> + <div v-if="clientset"> + <OtherNodeslayer + v-for="value in otherNodes" + v-bind:key="value.nodeid" + v-bind:nodeid="value.nodeid" + v-bind:nodetext="value.nodetext" + /> + <NodesLayer + v-for="value in myNodes" + v-bind:key="value.nodeid" + v-bind:nodeid="value.nodeid" + v-bind:nodetext="value.nodetext" + /> + + <CanvasLayer /> + <ControlsLayer /> + </div> + <OnBoard v-else @clientAdded="clientAdded()" /> </div> </template> <script> // @ is an alias to /src +import OnBoard from '@/components/OnBoard.vue' import CanvasLayer from '@/components/CanvasLayer.vue' import NodesLayer from '@/components/NodesLayer.vue' -import otherNodeslayer from '@/components/otherNodeslayer.vue' +import OtherNodeslayer from '@/components/OtherNodeslayer.vue' import ControlsLayer from '@/components/ControlsLayer.vue' import { mapState } from 'vuex' export default { name: 'Home', + + data: function() { + return { + clientset: false + } + }, + components: { + OnBoard, CanvasLayer, NodesLayer, - otherNodeslayer, + OtherNodeslayer, ControlsLayer }, computed: mapState({ myNodes: state => state.myNodes, otherNodes: state => state.otherNodes - }) + }), + methods: { + clientAdded() { + this.clientset = !this.clientset + } + } } </script> diff --git a/canvas-10-feb/yarn.lock b/canvas-10-feb/yarn.lock index 48cdebaf4bc17ae2423f4c6738645cd2b5ba1d45..ba0df1de4047543ea84eee24f2cfe618c5aa6227 100644 --- a/canvas-10-feb/yarn.lock +++ b/canvas-10-feb/yarn.lock @@ -4416,7 +4416,7 @@ loglevel@^1.6.6: version "1.6.6" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312" -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" dependencies: @@ -5604,6 +5604,95 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2 source-map "^0.6.1" supports-color "^6.1.0" +pouchdb-abstract-mapreduce@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.2.1.tgz#ad87d89d0e376be8e7740b767365572422d940a8" + dependencies: + pouchdb-binary-utils "7.2.1" + pouchdb-collate "7.2.1" + pouchdb-collections "7.2.1" + pouchdb-errors "7.2.1" + pouchdb-fetch "7.2.1" + pouchdb-mapreduce-utils "7.2.1" + pouchdb-md5 "7.2.1" + pouchdb-utils "7.2.1" + +pouchdb-binary-utils@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-binary-utils/-/pouchdb-binary-utils-7.2.1.tgz#ad23ed63d09699e7e6244f846b5cf07c6d9d4b8b" + dependencies: + buffer-from "1.1.0" + +pouchdb-collate@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-collate/-/pouchdb-collate-7.2.1.tgz#1e8bcd8c8d007fb93b9e259f18f9525144253102" + +pouchdb-collections@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-collections/-/pouchdb-collections-7.2.1.tgz#768c2c578b22eda9ac0c92a4b1106d18f3c113fb" + +pouchdb-errors@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-errors/-/pouchdb-errors-7.2.1.tgz#798f5279a0d363d6b93c97a1b65ee903f61af143" + dependencies: + inherits "2.0.4" + +pouchdb-fetch@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-fetch/-/pouchdb-fetch-7.2.1.tgz#f5373e7344b7434f53e900954b9b0caf71361a0a" + dependencies: + abort-controller "3.0.0" + fetch-cookie "0.7.3" + node-fetch "2.4.1" + +pouchdb-find@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-find/-/pouchdb-find-7.2.1.tgz#20604e7979bad74a0f423e5a30fc00d5aafed0e9" + dependencies: + pouchdb-abstract-mapreduce "7.2.1" + pouchdb-collate "7.2.1" + pouchdb-errors "7.2.1" + pouchdb-fetch "7.2.1" + pouchdb-md5 "7.2.1" + pouchdb-selector-core "7.2.1" + pouchdb-utils "7.2.1" + +pouchdb-mapreduce-utils@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.2.1.tgz#ca0f1954b40b774ff427295373337f8def520f2b" + dependencies: + argsarray "0.0.1" + inherits "2.0.4" + pouchdb-collections "7.2.1" + pouchdb-utils "7.2.1" + +pouchdb-md5@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-md5/-/pouchdb-md5-7.2.1.tgz#2b057b148b3f31491d77c4dd6b6139af31b07f66" + dependencies: + pouchdb-binary-utils "7.2.1" + spark-md5 "3.0.0" + +pouchdb-selector-core@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-selector-core/-/pouchdb-selector-core-7.2.1.tgz#0eb190dff1df62d416ba670fdd84565542aa0183" + dependencies: + pouchdb-collate "7.2.1" + pouchdb-utils "7.2.1" + +pouchdb-utils@7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/pouchdb-utils/-/pouchdb-utils-7.2.1.tgz#5dec1c53c8ecba717e5762311e9a1def2d4ebf9c" + dependencies: + argsarray "0.0.1" + clone-buffer "1.0.0" + immediate "3.0.6" + inherits "2.0.4" + pouchdb-collections "7.2.1" + pouchdb-errors "7.2.1" + pouchdb-md5 "7.2.1" + uuid "3.3.3" + pouchdb@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/pouchdb/-/pouchdb-7.2.1.tgz#619e3d5c2463ddd94a4b1bf40d44408c46e9de79" @@ -7054,6 +7143,22 @@ vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" +vue-clickaway@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/vue-clickaway/-/vue-clickaway-2.2.2.tgz#cecf6839575e8b2afc5d3edb3efb616d293dbb44" + dependencies: + loose-envify "^1.2.0" + +vue-context@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vue-context/-/vue-context-5.0.0.tgz#7f9a90bb00a45eba6aad1d49fdf9e0a946bf503f" + dependencies: + vue-clickaway "^2.2.2" + +vue-draggable-resizable@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/vue-draggable-resizable/-/vue-draggable-resizable-2.1.0.tgz#b590212aef3c07d040aeceda784438068170fb08" + vue-eslint-parser@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.0.0.tgz#a4ed2669f87179dedd06afdd8736acbb3a3864d6"