initial commit
This commit is contained in:
commit
e089856edb
19 changed files with 767 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
dist
|
||||
yarn-error.log
|
||||
yarn.lock
|
21
.vscode/launch.json
vendored
Normal file
21
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "chromium: tabber",
|
||||
"url": "http://localhost:9000",
|
||||
"webRoot": "${workspaceFolder}/src",
|
||||
"breakOnLoad": true,
|
||||
"sourceMapPathOverrides": {
|
||||
"webpack:///src/*": "${webRoot}/*"
|
||||
},
|
||||
"runtimeArgs": [
|
||||
"--auto-open-devtools-for-tabs"
|
||||
],
|
||||
"preLaunchTask": "serve",
|
||||
"postDebugTask": "terminate all tasks"
|
||||
}
|
||||
]
|
||||
}
|
45
.vscode/tasks.json
vendored
Normal file
45
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "run backend",
|
||||
"type": "shell",
|
||||
"command": "node",
|
||||
"args": [
|
||||
"../pbc/pbc.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"command": "yarn",
|
||||
"args": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "serve",
|
||||
"type": "shell",
|
||||
"command": "yarn",
|
||||
"args": [
|
||||
"run",
|
||||
"serve"
|
||||
],
|
||||
"isBackground": true
|
||||
},
|
||||
{
|
||||
"label": "terminate all tasks",
|
||||
"command": "echo ${input:terminate}",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "terminate",
|
||||
"type": "command",
|
||||
"command": "workbench.action.tasks.terminate",
|
||||
"args": "terminateAll"
|
||||
}
|
||||
]
|
||||
}
|
20
README.md
Normal file
20
README.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# pbc
|
||||
|
||||
pedal board control
|
||||
|
||||
## yarn
|
||||
|
||||
### setup
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### compile and serve with hot-reloads for development
|
||||
```
|
||||
yarn run serve
|
||||
```
|
||||
|
||||
### compile, minify and build for production
|
||||
```
|
||||
yarn run build
|
||||
```
|
27
package.json
Normal file
27
package.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "pbc",
|
||||
"author": "Daniel Sommer <daniel.sommer@velvettear.de>",
|
||||
"description": "pedal board control",
|
||||
"license": "MIT",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.velvettear.de/velvettear/pbc.git"
|
||||
},
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve --host 0.0.0.0 --port 9000",
|
||||
"build": "vue-cli-service build"
|
||||
},
|
||||
"dependencies": {
|
||||
"purecss": "^2.0.6",
|
||||
"remixicon": "^2.5.0",
|
||||
"vue": "^2.6.14",
|
||||
"vue-resource": "^1.5.3",
|
||||
"vue-router": "^3.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-service": "^3.12.1",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
27
public/index.html
Normal file
27
public/index.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<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 rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600;700&display=swap"
|
||||
rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>
|
||||
<%= htmlWebpackPlugin.options.title %>
|
||||
</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
57
src/App.vue
Normal file
57
src/App.vue
Normal file
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<div id="page">
|
||||
<Menu />
|
||||
<div id="content" class="pure-g"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Menu from "@/components/Menu.vue";
|
||||
import "@/../node_modules/remixicon/fonts/remixicon.css";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
Menu,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html {
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
body {
|
||||
font-family: "Fira Code", monospace;
|
||||
font-weight: 300;
|
||||
font-size: 1.5em;
|
||||
text-align: center;
|
||||
color: #f1f1f1;
|
||||
margin: 0;
|
||||
background: #000000;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #ff8800;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #3e3e3e99;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #ff880099;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #ffffff99;
|
||||
}
|
||||
</style>
|
39
src/components/Control.vue
Normal file
39
src/components/Control.vue
Normal file
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<div class="control">
|
||||
<div>
|
||||
{{ control.name }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Control",
|
||||
props: {
|
||||
control: Object,
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pedal {
|
||||
font-family: "Fira Code", monospace;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.content {
|
||||
margin: 2.5%;
|
||||
padding: 8px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-radius: 2px;
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
.header {
|
||||
font-size: 1.5em;
|
||||
font-weight: 900;
|
||||
}
|
||||
</style>
|
111
src/components/HostInfo.vue
Normal file
111
src/components/HostInfo.vue
Normal file
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<div class="menu-hostinfo">
|
||||
<table v-if="config.enabled && data">
|
||||
<tr v-if="config.hostname && config.hostname.enabled && data.hostname">
|
||||
<td class="fat">{{ config.hostname.title || "host:" }}</td>
|
||||
<td>{{ data.hostname }}</td>
|
||||
</tr>
|
||||
<tr v-if="config.os && config.os.enabled && data.os">
|
||||
<td class="fat">{{ config.os.title || "os:" }}</td>
|
||||
<td>{{ data.os }}</td>
|
||||
</tr>
|
||||
<tr v-if="config.kernel && config.kernel.enabled && data.kernel">
|
||||
<td class="fat">{{ config.kernel.title || "kernel:" }}</td>
|
||||
<td>{{ data.kernel }}</td>
|
||||
</tr>
|
||||
<tr v-if="config.uptime && config.uptime.enabled && data.uptime">
|
||||
<td class="fat">{{ config.uptime.title || "uptime:" }}</td>
|
||||
<td>{{ data.uptime }}</td>
|
||||
</tr>
|
||||
<tr v-if="config.cpu && config.cpu.enabled && data.cpu">
|
||||
<td class="fat">{{ config.cpu.title || "cpu:" }}</td>
|
||||
<td>{{ data.cpu }}</td>
|
||||
</tr>
|
||||
<tr v-if="config.load && config.load.enabled && data.load">
|
||||
<td class="fat">{{ config.load.title || "load:" }}</td>
|
||||
<td>
|
||||
{{ data.load }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="
|
||||
config.memory &&
|
||||
config.memory.enabled &&
|
||||
data.memory.used &&
|
||||
data.memory.total
|
||||
"
|
||||
>
|
||||
<td class="fat">{{ config.memory.title || "memory:" }}</td>
|
||||
<td>
|
||||
{{ data.memory.used }} /
|
||||
{{ data.memory.total }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="
|
||||
config.temperature && config.temperature.enabled && data.temperature
|
||||
"
|
||||
>
|
||||
<td class="fat">{{ config.temperature.title || "temperature:" }}</td>
|
||||
<td>
|
||||
{{ data.temperature }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { get } from "@/libs/requests.js";
|
||||
import { formatInfo } from "@/libs/util.js";
|
||||
|
||||
export default {
|
||||
name: "HostInfo",
|
||||
data() {
|
||||
return {
|
||||
config: require("@/config.json").hostinfo,
|
||||
data: undefined,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
if (!this.config.enabled) {
|
||||
return;
|
||||
}
|
||||
get("/info")
|
||||
.then((result) => {
|
||||
this.data = formatInfo(result);
|
||||
})
|
||||
.then(() => {
|
||||
setTimeout(this.fetchData, this.config.refresh);
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchData();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.menu-hostinfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 0.5em;
|
||||
margin-top: 32px;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
.menu-hostinfo i {
|
||||
font-size: 2em;
|
||||
transition: transform 0.5s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fat {
|
||||
font-weight: 600;
|
||||
}
|
||||
td {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
98
src/components/Menu.vue
Normal file
98
src/components/Menu.vue
Normal file
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<div id="menu" :class="{ colored: menu.expanded }">
|
||||
<div id="menu-button">
|
||||
<i
|
||||
class="ri-menu-line"
|
||||
:class="{ rotated: menu.expanded }"
|
||||
v-on:click="toggleMenu()"
|
||||
></i>
|
||||
</div>
|
||||
<div class="menu-content" :class="{ expanded: menu.expanded }">
|
||||
<HostInfo />
|
||||
<ul>
|
||||
<li>entry1</li>
|
||||
<li>entry2</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HostInfo from "@/components/HostInfo.vue";
|
||||
import Config from "@/config.json";
|
||||
|
||||
export default {
|
||||
name: "Menu",
|
||||
components: {
|
||||
HostInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
menu: {
|
||||
expanded: false,
|
||||
},
|
||||
hostinfo: Config.hostinfo.enabled
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleMenu() {
|
||||
this.menu.expanded = !this.menu.expanded;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#menu {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-width: 10%;
|
||||
margin: 0;
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
transition: background-color 0.5s ease-in-out;
|
||||
}
|
||||
#menu-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#menu-button i {
|
||||
font-size: 2em;
|
||||
font-weight: 900;
|
||||
transition: transform 0.5s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px;
|
||||
transition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out;
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
.rotated {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.expanded {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
.colored {
|
||||
background-color: #ff990099;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
li {
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
</style>
|
59
src/components/Pedal.vue
Normal file
59
src/components/Pedal.vue
Normal file
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<div class="pedal">
|
||||
<div
|
||||
class="content"
|
||||
v-bind:style="{
|
||||
background: pedal.color + '66',
|
||||
borderColor: pedal.color,
|
||||
}"
|
||||
>
|
||||
<div class="header">
|
||||
{{ pedal.name }}
|
||||
</div>
|
||||
<Pedal
|
||||
class="pure-u-1-2"
|
||||
:control="control"
|
||||
v-for="control in pedal.controls"
|
||||
v-bind:key="control.name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Control from "@/components/Control.vue";
|
||||
|
||||
export default {
|
||||
name: "Pedal",
|
||||
components: {
|
||||
Control,
|
||||
},
|
||||
props: {
|
||||
pedal: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pedal {
|
||||
font-family: "Fira Code", monospace;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.header {
|
||||
font-size: 1.5em;
|
||||
font-weight: 900;
|
||||
}
|
||||
.content {
|
||||
margin: 2.5%;
|
||||
padding: 8px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-radius: 2px;
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
</style>
|
45
src/config.json
Normal file
45
src/config.json
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"api": {
|
||||
"protocol": "http",
|
||||
"host": "localhost",
|
||||
"port": 3000
|
||||
},
|
||||
"hostinfo": {
|
||||
"enabled": true,
|
||||
"refresh": 3000,
|
||||
"hostname": {
|
||||
"title": "host:",
|
||||
"enabled": true
|
||||
},
|
||||
"os": {
|
||||
"title": "os:",
|
||||
"enabled": true
|
||||
},
|
||||
"kernel": {
|
||||
"title": "kernel:",
|
||||
"enabled": false
|
||||
},
|
||||
"uptime": {
|
||||
"title": "uptime:",
|
||||
"enabled": true,
|
||||
"format": "[h] hours [m] minutes"
|
||||
},
|
||||
"cpu": {
|
||||
"title": "cpu:",
|
||||
"enabled": true,
|
||||
"format": "[count]x [model] @ [speed]mhz"
|
||||
},
|
||||
"load": {
|
||||
"title": "load:",
|
||||
"enabled": true
|
||||
},
|
||||
"memory": {
|
||||
"title": "memory:",
|
||||
"enabled": true
|
||||
},
|
||||
"temperature": {
|
||||
"title": "temperature:",
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
20
src/libs/requests.js
Normal file
20
src/libs/requests.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
const config = require('../config.json');
|
||||
|
||||
const BASE_URL = config.api.protocol + '://' + config.api.host + ':' + config.api.port;
|
||||
|
||||
function get(url) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (url == undefined) {
|
||||
return reject('error: no url defined');
|
||||
}
|
||||
url = BASE_URL + url;
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(result => resolve(result))
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
get
|
||||
}
|
76
src/libs/util.js
Normal file
76
src/libs/util.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
const uptimeFormat = require('@/config.json').hostinfo.uptime.format;
|
||||
const cpuFormat = require('@/config.json').hostinfo.cpu.format;
|
||||
|
||||
const formatBytes = (bytes, decimals = 2) => {
|
||||
if (bytes === 0) {
|
||||
return '0 Bytes';
|
||||
}
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ['byte', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
const formatSeconds = (seconds) => {
|
||||
var secs = seconds % 60;
|
||||
seconds = (seconds - secs) / 60;
|
||||
var mins = seconds % 60;
|
||||
var hrs = (seconds - mins) / 60;
|
||||
return uptimeFormat.replace('\[h\]', fill(hrs, 2)).replace('\[m\]', fill(mins, 2)).replace('\[s\]', fill(Math.round(secs), 2));
|
||||
}
|
||||
|
||||
const fill = (value, count, fill, front) => {
|
||||
if (value == undefined || count == undefined) {
|
||||
return;
|
||||
}
|
||||
if (fill == undefined) {
|
||||
fill = '0';
|
||||
}
|
||||
if (front == undefined) {
|
||||
front = true;
|
||||
}
|
||||
while (value.toString().length < count) {
|
||||
if (front) {
|
||||
value = fill + value;
|
||||
} else {
|
||||
value += fill;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const formatCpu = (data) => {
|
||||
var model = data[0].model;
|
||||
var cut = model.toLowerCase().indexOf('cpu');
|
||||
if (cut != -1) {
|
||||
model = model.substring(0, cut);
|
||||
}
|
||||
cut = model.indexOf('@');
|
||||
if (cut != -1) {
|
||||
model = model.substring(0, cut);
|
||||
}
|
||||
model = model.trim();
|
||||
var speed = 0;
|
||||
for (var index = 0; index < data.length; index++) {
|
||||
speed += data[index].speed;
|
||||
}
|
||||
if (speed < 0) {
|
||||
speed = 0;
|
||||
}
|
||||
return cpuFormat.replace('[count]', data.length).replace('[model]', model).replace('[speed]', Math.round(speed / data.length));
|
||||
}
|
||||
|
||||
const formatInfo = (info) => {
|
||||
info.memory.total = formatBytes(info.memory.total);
|
||||
info.memory.used = formatBytes(info.memory.used);
|
||||
info.memory.free = formatBytes(info.memory.free);
|
||||
info.uptime = formatSeconds(info.uptime);
|
||||
info.load = info.load[0] + ' ' + info.load[1] + ' ' + info.load[2];
|
||||
info.cpu = formatCpu(info.cpu);
|
||||
return info;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatInfo
|
||||
}
|
13
src/main.js
Normal file
13
src/main.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router/router.js'
|
||||
import '../node_modules/purecss/build/base-min.css'
|
||||
import '../node_modules/purecss/build/grids-min.css'
|
||||
import '../node_modules/purecss/build/grids-responsive-min.css'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
const app = new Vue({
|
||||
router,
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
72
src/pedals.json
Normal file
72
src/pedals.json
Normal file
|
@ -0,0 +1,72 @@
|
|||
[
|
||||
{
|
||||
"id": 0,
|
||||
"name": "tubewarmth",
|
||||
"color": "#880088",
|
||||
"controls": [
|
||||
{
|
||||
"name": "on/off",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 0,
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "drive",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 1,
|
||||
"value": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tape/tube",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 2,
|
||||
"value": 10
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "big muff",
|
||||
"color": "#339900",
|
||||
"controls": [
|
||||
{
|
||||
"name": "on/off",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 4,
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tone",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 5,
|
||||
"value": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "level",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 6,
|
||||
"value": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sustain",
|
||||
"midi": {
|
||||
"channel": 0,
|
||||
"controller": 7,
|
||||
"value": 0.5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
19
src/router/router.js
Normal file
19
src/router/router.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
// import List from '@/components/List.vue'
|
||||
// import Tab from '@/components/Tab.vue'
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
// { path: '/', name: 'List', component: List },
|
||||
// { path: '/:id', name: 'Tab', component: Tab }
|
||||
];
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
routes
|
||||
})
|
||||
|
||||
export default router;
|
14
vue.config.js
Normal file
14
vue.config.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
runtimeCompiler: true,
|
||||
chainWebpack: (config) => {
|
||||
config
|
||||
.plugin('html')
|
||||
.tap((args) => {
|
||||
args[0].title = "tabber";
|
||||
return args;
|
||||
});
|
||||
},
|
||||
configureWebpack: {
|
||||
devtool: 'source-map'
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue