development

This commit is contained in:
Jonatan Nilsson 2017-12-03 11:34:43 +00:00
parent 12775a934e
commit 767c4dd73d
44 changed files with 6708 additions and 389 deletions

View file

@ -1,7 +1,5 @@
{
"presets": ["es2015-node5"],
"plugins": [
"transform-async-to-generator",
"syntax-async-functions"
"transform-es2015-modules-commonjs"
]
}

View file

@ -2,7 +2,7 @@ version: 2
jobs:
build:
docker:
- image: docker:17.05.0-ce-git
- image: circleci/node:latest
working_directory: ~/caspar-sup
steps:
- checkout
@ -11,14 +11,15 @@ jobs:
name: Build docker image
command: docker build -t nfpis/caspar-sup:build_${CIRCLE_BUILD_NUM} -t nfpis/caspar-sup:${CIRCLE_SHA1} -t nfpis/caspar-sup:latest .
- run:
name: Run test and lint
command: |
docker run nfpis/recording_control npm run lint
docker run nfpis/recording_control npm run test
- deploy:
name: Push to docker
command: |
docker login -u $DOCKER_USER -p $DOCKER_PASS
docker push nfpis/caspar-sup
- deploy:
name: Deploy to production
command: |
echo Not implemented
workflows:
version: 2
build_deploy:

View file

@ -1,6 +1,6 @@
{
"parser": "babel-eslint",
"extends": "airbnb/base",
"extends": "airbnb-base",
"ecmaFeatures": {
"modules": false
},

View file

@ -6,10 +6,6 @@ import config from '../config'
import log from '../log'
let host = config.get('knex:connection')
/* istanbul ignore if */
if (host.match && host.match(/@[^/]+/)) {
host = host.match(/@[^/]+/)[0]
}
log.info(host, 'Connecting to DB')
@ -33,10 +29,26 @@ let shelf = bookshelf(client)
shelf.createModel = (attr, opts) => {
// Create default attributes to all models
let attributes = _.defaults(attr, {
/**
* Initialize a new instance of model. This does not get called when
* relations to this model is being fetched though.
*/
initialize() {
this.on('fetching', this.checkFetching)
},
/**
* Event handler when fetch() is called. This gets called for both
* when getSingle() or just manual fetch() is called as well as
* when relation models through belongsTo() resources get fetched.
*
* @param {Model} model - The model instance if fetch() was used. For
* belongsTo this is the relation model thingy.
* @param {Array} columns - Array of columns to select if fetch() was used.
* Otherwise this is null.
* @param {Object} options - Options for the fetch. Includes the query
* builder object.
*/
checkFetching(model, columns, options) {
options.query.where({ is_deleted: false })
},
@ -44,6 +56,12 @@ shelf.createModel = (attr, opts) => {
// Create default options for all models
let options = _.defaults(opts, {
/**
* Create new model object in database.
*
* @param {Object} data - The values the new model should have
* @return {Model} The resulted model
*/
create(data) {
return this.forge(data).save()
},

View file

@ -0,0 +1,8 @@
import { reset, list } from './routes'
export async function contentConnection(ctx) {
ctx.log.info('Got new socket connection')
list(ctx)
reset(ctx)
}

View file

@ -1,4 +1,4 @@
import bookshelf from '../../bookshelf'
import bookshelf from '../bookshelf'
/* Graphic model:
{

View file

@ -1,17 +1,12 @@
import Graphic from './model'
function getSocket(ctx, all) {
if (all === true) return ctx.io
return ctx.socket
}
export async function all(ctx, all) {
export async function all(ctx) {
let data = await Graphic.getAll()
getSocket(ctx, all).emit('graphic.all', data.toJSON())
ctx.io.emit('graphic.all', data.toJSON())
}
export async function single(ctx, data, all) {
export async function single(ctx, data) {
if (!data || !data.id) {
ctx.log.warn('called graphic get single but no id specified')
return
@ -19,7 +14,7 @@ export async function single(ctx, data, all) {
let graphic = await Graphic.getSingle(data.id)
getSocket(ctx, all).emit('graphic.single', graphic.toJSON())
ctx.io.emit('graphic.single', graphic.toJSON())
}
export async function create(ctx, data) {
@ -33,7 +28,7 @@ export async function create(ctx, data) {
await Graphic.create(data)
await all(ctx, true)
await all(ctx)
}
export async function remove(ctx, data) {
@ -46,7 +41,7 @@ export async function remove(ctx, data) {
graphic.set({ is_deleted: true })
await graphic.save()
await all(ctx, true)
await all(ctx)
}
export async function update(ctx, data) {
@ -61,5 +56,5 @@ export async function update(ctx, data) {
await graphic.save()
await single(ctx, data, true)
await single(ctx, data)
}

View file

@ -1 +0,0 @@
import './koa'

View file

@ -1,7 +1,5 @@
import _ from 'lodash'
import { reset, list } from './content/routes'
export function register(ctx, name, method) {
if (_.isPlainObject(method)) {
Object.keys(method).forEach(key => {
@ -21,10 +19,3 @@ export function register(ctx, name, method) {
}
})
}
export async function newConnection(ctx) {
ctx.log.info('Got new socket connection')
list(ctx)
reset(ctx)
}

View file

@ -1,20 +0,0 @@
import serve from 'koa-static'
import Koa from 'koa'
import socket from 'koa-socket'
import config from '../config'
import log from '../log'
import router from './io/router'
import { bunyanLogger, errorHandler } from './middlewares'
const app = new Koa()
const io = new socket()
io.attach(app)
io.on('connection', router.bind(this, io))
app.use(bunyanLogger(log))
app.use(errorHandler())
app.use(serve('public'))
app.listen(config.get('server:port'))

View file

@ -1,4 +1,4 @@
import bookshelf from '../../bookshelf'
import bookshelf from '../bookshelf'
/* Preset model:
{

View file

@ -1,16 +1,11 @@
import Preset from './model'
function getSocket(ctx, all) {
if (all === true) return ctx.io
return ctx.socket
}
export async function all(ctx, payload, all) {
export async function all(ctx, payload) {
let id = Number(payload.graphic_id || payload.id)
let data = await Preset.getAll({ graphic_id: id })
getSocket(ctx, all).emit(`preset.all:${id}`, data.toJSON())
ctx.io.emit(`preset.all:${id}`, data.toJSON())
}
export async function add(ctx, payload) {
@ -29,7 +24,7 @@ export async function add(ctx, payload) {
await Preset.create(payload)
await all(ctx, payload, true)
await all(ctx, payload)
}
export async function remove(ctx, payload) {
@ -39,5 +34,5 @@ export async function remove(ctx, payload) {
await preset.save()
await all(ctx, payload, true)
await all(ctx, payload)
}

View file

@ -1,5 +1,6 @@
import logger from '../../log'
import { register, newConnection } from './connection'
import logger from '../log'
import { register } from './io/helper'
import { contentConnection } from './content/connection'
import * as content from './content/routes'
import * as engine from './engine/routes'
@ -15,7 +16,7 @@ function onConnection(server, data) {
let ctx = { io, socket, log }
newConnection(ctx)
contentConnection(ctx)
register(ctx, 'content', content)
register(ctx, 'engine', engine)

24
api/server.js Normal file
View file

@ -0,0 +1,24 @@
import Koa from 'koa'
import serve from 'koa-better-serve'
import socket from 'koa-socket'
import config from '../config'
import log from '../log'
import onConnection from './routerio'
import { bunyanLogger, errorHandler } from './middlewares'
const app = new Koa()
const io = new socket()
io.attach(app)
io.on('connection', onConnection.bind(this, io))
app.use(bunyanLogger(log))
app.use(errorHandler())
app.use(serve('./public', '/public'))
app.listen(config.get('server:port'), err => {
if (err) return log.critical(err)
log.info(`Server is listening on ${config.get('server:port')}`)
})

View file

@ -1,9 +1,9 @@
var socket = require('./socket')
var socket = require('../socket')
var engines = {
text: require('./frontend/text'),
countdown: require('./frontend/countdown'),
schedule: require('./frontend/schedule'),
text: require('./text'),
countdown: require('./countdown'),
schedule: require('./schedule'),
}
var current = []

View file

@ -12,14 +12,15 @@
//in the console.
window.components = {}
require('./socket')
require('./controller/store')
require('../socket')
require('./store')
const m = require('mithril')
const Header = require('./controller/header')
const Menu = require('./controller/menu')
const Add = require('./controller/add')
const Graphic = require('./controller/graphic/controller')
const Header = require('./header')
const Menu = require('./menu')
const Add = require('./add')
const Graphic = require('./graphic')
m.mount(document.getElementById('header'), Header)
m.mount(document.getElementById('menu'), Menu)

47
app/styl/client.styl Normal file
View file

@ -0,0 +1,47 @@
* {
-webkit-box-sizing: border-box;
box-sizing:border-box; /* This sets all elements to be the actual set dimensions, disregarding padding and borders */
/* -webkit-backface-visibility: hidden; /* Hide the backface of elements - useful for 3d effects */
-webkit-transition: translate3d(0,0,0); /* Turns on hardware acceleration - not known to be of benefit in CCG, but won't hurt */
}
html, body {
width:1920px; /* Set to your channel's resolution */
height:1080px; /* Set to your channel's resolution */
margin:0; /* Use all available space */
padding:0; /* Use all available space */
background:transparent; /* The HTML consumer actually makes your background transparent by default, unless a color or image is specified - but this might be usefull when debugging in browsers */
overflow:hidden; /* Hide any overflowing elements - to disable scollbars */
-webkit-font-smoothing:antialiased !important; /* Set aliasing of fonts - possible options: none, antialiased, subpixel-antialiased */
}
body {
font-family: Calibri,Arial;
font-size: 40px;
color: #FFFFFF;
/* -webkit-text-stroke-width: 0.5px;
-webkit-text-stroke-color: #888888;
text-shadow: 2px 2px 1px #000000; */
}
body {
font-family: Arial;
font-weight: normal;
text-shadow: 0px 0px 0px #000000;
font-size: 22pt;
}
html {
overflow: auto;
}
body > div
{
position: absolute;
}
.root-element {
opacity: 0;
transition: opacity 1s;
}
.root-element-display {
opacity: 1;
transition: opacity 1s;
}

241
app/styl/main.styl Normal file
View file

@ -0,0 +1,241 @@
body {
background: #3f3f41;
color: #f1f1f1;
}
h4 {
margin-bottom: 2rem;
}
/* Container */
.container {
padding: 1rem;
}
.container-header {
font-size: 1.5rem;
margin-left: 1rem;
color: #777777;
}
.container-panel {
border: 1px solid #3f3f3f;
background: #2d2d30;
padding: 1rem;
border-radius: 5px;
}
/* Header */
.header-list {
list-style-type: none;
margin: 0;
}
.header-item {
margin-bottom: 1rem;
}
.header-item-hide {
float: right;
width: 5rem;
border-radius: 6px;
margin: 0;
}
.header-item-display {
background: #070707;
color: #eb6e00;
border-radius: 6px;
padding: 0.5rem 1rem;
margin-right: 5.5rem;
}
/* Menu */
.menu-list {
list-style-type: none;
margin: 0;
}
.menu a {
color: #007acc;
display: block;
border: 1px solid #2d2d30;
padding: 0.2rem 0.5rem;
}
.menu a:hover {
color: #f1f1f1;
border: 1px solid #007acc;
}
.menu-item-add {
margin-top: 3rem;
}
/* Add */
.panel-add {
padding: 2rem;
}
.panel-graphic-property-add,
.panel-graphic-property-remove {
width: 100%;
}
/* Graphic */
.panel-graphic-delete {
}
.panel-graphic-settings {
float: right;
margin-right: 1rem;
}
.panel-graphic-property-item {
padding-left: 0;
}
.panel-graphic-preset-add {
margin-right: 1rem;
}
.panel-graphic-preset {
margin-top: 1rem;
list-style-type: none;
}
.panel-graphic-preset a {
width: 100%;
}
/* Components */
.error-box {
margin: 0rem 0rem 2rem 0;
color: #FF0000;
}
/* Inputs */
.panel-graphic-property-item input {
display: inline-block;
}
label {
color: #f1f1f1;
}
input[type="text"],
textarea {
background: #333337;
border-color: #3f3f3f;
color: #999999;
transition-property: none !important;
}
input[type="text"]:hover,
textarea:hover {
color: #f1f1f1;
border-color: #007acc;
}
input[type="text"]:focus,
textarea:focus {
background: #333337;
color: #f1f1f1;
border-color: #007acc;
box-shadow: none;
}
input[readonly],
input[readonly]:hover {
background: #2d2d30 !important;
border-color: #3f3f3f;
}
select {
background: #333337;
border-color: #3f3f3f;
color: #999999;
background-position: right center;
background-size: 9px 6px;
background-origin: content-box;
background-repeat: no-repeat;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb%28138, 138, 138%29"></polygon></svg>')
}
select:hover {
color: #f1f1f1;
border-color: #007acc;
}
select:focus {
background: #333337;
color: #f1f1f1;
border-color: #007acc;
box-shadow: none;
}
a.button {
margin: 0 1rem 0 0;
width: 7rem;
}
/* Media queries */
body {
font-size: 1.5rem;
}
@media only screen and (max-device-width: 1280px) {
.header-item-hide {
width: 9rem;
line-height: 0rem;
}
a.button {
font-size: 2rem;
line-height: 0;
width: auto;
}
.panel-graphic-preset {
margin: 0;
}
.panel-graphic-display,
.panel-graphic-preset-add {
margin-bottom: 3rem !important;
}
.panel-graphic-preset-remove {
padding-right: 0.5rem;
padding-left: 0.5rem;
}
.panel-graphic-preset-remove.alert {
padding-right: 1rem;
padding-left: 1rem;
}
.panel-graphic-settings {
font-size: 1.3rem !important;
}
.header-item-display {
font-size: 2rem;
margin-right: 12.5rem;
padding: 0.2rem 1rem;
}
.panel-graphic-property-item input {
font-size: 2rem;
height: 3.5rem;
}
}

View file

@ -3,35 +3,12 @@ require('babel-register')
let log = require('./log').default
function exitHandler(options, err) {
if (options.cleanup) {
log.warn('Application is shutting down')
}
if (err) {
log.error('An unhandled error occured')
log.error(err)
}
if (options.exit) {
log.warn('Application is exiting')
process.exit()
}
}
// do something when app is closing
process.on('exit', exitHandler.bind(null, { cleanup: true }))
// catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, { exit: true }))
// catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, { exit: true }))
// Run the database script automatically.
log.info('Running database integrity scan.')
let setup = require('./script/setup')
setup().then(() => {
require('./api')
require('./api/server')
}).catch((error) => {
log.error(error, 'Error while preparing database')
process.exit(1)

6091
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -4,15 +4,23 @@
"description": "CasparCG superimposed graphics project",
"main": "index.js",
"scripts": {
"test": "npm test",
"build-main:js": "browserify app/main.js -o public/main.js --debug",
"watch-main:js": "watchify app/main.js -o public/main.js --debug",
"build-client:js": "browserify app/client.js -o public/client.js --debug",
"watch-client:js": "watchify app/client.js -o public/client.js --debug",
"build": "npm run build-main:js && npm run build-client:js",
"build:watch": "parallelshell \"npm run watch-main:js\" \"npm run watch-client:js\"",
"start": "node index.js | bunyan",
"start:dev": "nodemon index.js | bunyan"
"build:styl": "stylus -m app/styl/main.styl --out public",
"watch:styl": "stylus -w -m app/styl/main.styl --out public",
"build-client:styl": "stylus -m app/styl/client.styl --out public",
"watch-client:styl": "stylus -w -m app/styl/client.styl --out public",
"watch:js": "watchify -t babelify app/main.js -o public/main.js --debug",
"build:js": "browserify app/main.js -o public/main.js --debug -t [ babelify ]",
"watch-client:js": "watchify -t babelify app/client.js -o public/client.js --debug",
"build-client:js": "browserify app/client.js -o public/client.js --debug -t [ babelify ]",
"watch:server": "nodemon index.js",
"start": "node index.js",
"dev-run": "run-p watch:js watch-client:js watch:server watch:styl watch-client:styl",
"prod-run": "npm run build:js && npm run build-client:js && npm run build:styl && npm run build-client:styl && npm start",
"test": "env NODE_ENV=test mocha --require babel-register --recursive --reporter dot",
"docker": "docker run -it --rm --name my-running-script -v \"$PWD\":/usr/src/app -w /usr/src/app node:alpine",
"docker:test": "npm run docker -- npm install && npm run test",
"docker:dev": "npm run docker -- npm install && npm run dev-run",
"docker:run": "npm run docker -- npm install && npm run prod-run"
},
"repository": {
"type": "git",
@ -30,36 +38,27 @@
},
"homepage": "https://github.com/nfp-projects/caspar-sup#readme",
"dependencies": {
"app-root-path": "^1.0.0",
"babel-plugin-syntax-async-functions": "^6.5.0",
"babel-plugin-transform-async-to-generator": "^6.7.0",
"babel-preset-es2015-node5": "^1.1.2",
"babel-register": "^6.7.2",
"bookshelf": "^0.9.2",
"browserify": "^13.0.0",
"bunyan": "^1.7.1",
"knex": "^0.10.0",
"koa": "^2.0.0-alpha.3",
"koa-socket": "^4.3.0",
"koa-static": "^3.0.0",
"lodash": "^4.6.1",
"mithril": "^0.2.3",
"nconf": "^0.8.4",
"parallelshell": "^2.0.0",
"socket.io": "^1.4.5",
"socket.io-client": "^1.4.5",
"sqlite3": "^3.1.3"
"app-root-path": "^2.0.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-register": "^6.26.0",
"bookshelf": "^0.11.1",
"bunyan": "^1.8.12",
"knex": "^0.14.2",
"koa": "^2.4.1",
"koa-better-serve": "^2.0.7",
"koa-socket": "^4.4.0",
"mithril": "^1.1.5",
"nconf": "^0.9.1",
"socket.io": "^2.0.4",
"socket.io-client": "^2.0.4",
"sqlite3": "^3.1.13"
},
"devDependencies": {
"assert-extended": "^1.0.1",
"babel-eslint": "^5.0.0",
"eslint": "^2.2.0",
"eslint-config-airbnb": "^6.1.0",
"eslint-plugin-mocha": "^2.0.0",
"live-reload": "^1.1.0",
"mocha": "^2.4.5",
"sinon": "^1.17.3",
"sinon-as-promised": "^4.0.0",
"watchify": "^3.7.0"
"babelify": "^8.0.0",
"mocha": "^4.0.1",
"nodemon": "^1.12.1",
"npm-run-all": "^4.1.2",
"stylus": "^0.54.5",
"watchify": "^3.9.0"
}
}

View file

@ -1,47 +1,53 @@
* {
-webkit-box-sizing: border-box;
box-sizing:border-box; /* This sets all elements to be the actual set dimensions, disregarding padding and borders */
box-sizing: border-box;
/* This sets all elements to be the actual set dimensions, disregarding padding and borders */
/* -webkit-backface-visibility: hidden; /* Hide the backface of elements - useful for 3d effects */
-webkit-transition: translate3d(0, 0, 0); /* Turns on hardware acceleration - not known to be of benefit in CCG, but won't hurt */
}
html, body {
width:1920px; /* Set to your channel's resolution */
height:1080px; /* Set to your channel's resolution */
margin:0; /* Use all available space */
padding:0; /* Use all available space */
background:transparent; /* The HTML consumer actually makes your background transparent by default, unless a color or image is specified - but this might be usefull when debugging in browsers */
overflow:hidden; /* Hide any overflowing elements - to disable scollbars */
-webkit-font-smoothing:antialiased !important; /* Set aliasing of fonts - possible options: none, antialiased, subpixel-antialiased */
html,
body {
width: 1920px;
/* Set to your channel's resolution */
height: 1080px;
/* Set to your channel's resolution */
margin: 0;
/* Use all available space */
padding: 0;
/* Use all available space */
background: transparent;
/* The HTML consumer actually makes your background transparent by default, unless a color or image is specified - but this might be usefull when debugging in browsers */
overflow: hidden;
/* Hide any overflowing elements - to disable scollbars */
-webkit-font-smoothing: antialiased !important;
/* Set aliasing of fonts - possible options: none, antialiased, subpixel-antialiased */
}
body {
font-family: Calibri, Arial;
font-size: 40px;
color: #FFFFFF;
color: #fff;
/* -webkit-text-stroke-width: 0.5px;
-webkit-text-stroke-color: #888888;
text-shadow: 2px 2px 1px #000000; */
}
body {
font-family: Arial;
font-weight: normal;
text-shadow: 0px 0px 0px #000000;
text-shadow: 0px 0px 0px #000;
font-size: 22pt;
}
html {
overflow: auto;
}
body > div
{
body > div {
position: absolute;
}
.root-element {
opacity: 0;
transition: opacity 1s;
}
.root-element-display {
opacity: 1;
transition: opacity 1s;
}
/*# sourceMappingURL=client.css.map */

1
public/client.css.map Normal file
View file

@ -0,0 +1 @@
{"version":3,"sources":["../app/styl/client.styl"],"names":[],"mappings":"AAAA;EACE,oBAAoB,WAApB;EACA,YAAW,WAAX;AAA4C;AAC7C;EACC,oBAAqC,qBAArC;AAA4C;;AAE9C;AAAM;EACJ,OAAM,OAAN;AAAyD;EACzD,QAAO,OAAP;AAAyD;EACzD,QAAO,EAAP;AAAyD;EACzD,SAAQ,EAAR;AAAyD;EACzD,YAAW,YAAX;AAAyD;EACzD,UAAS,OAAT;AAAyD;EACzD,wBAAuB,uBAAvB;AAAyD;;AAE3D;EACE,aAAoB,eAApB;EACA,WAAW,KAAX;EACA,OAAO,KAAP;AACA;;;;AAKF;EACE,aAAa,MAAb;EACA,aAAa,OAAb;EACA,aAAa,iBAAb;EACA,WAAW,KAAX;;AAEF;EACE,UAAU,KAAV;;AAEF;EAEE,UAAU,SAAV;;AAGF;EACE,SAAS,EAAT;EACA,YAAY,WAAZ;;AAGF;EACE,SAAS,EAAT;EACA,YAAY,WAAZ","file":"client.css"}

View file

@ -3,8 +3,7 @@
<head>
<title>CasparCG Controller</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link href="foundation.css" rel="stylesheet" />
<link href="main.css" rel="stylesheet" />
<link href="/public/main.css" rel="stylesheet" />
</head>
<body>
<div class="expanded row">
@ -14,6 +13,6 @@
<div class="small-3 columns container" id="menu"></div>
<div class="small-9 columns container" id="content"></div>
</div>
<script src="main.js"></script>
<script src="/public/main.js"></script>
</body>
</html>

View file

@ -2,48 +2,38 @@ body {
background: #3f3f41;
color: #f1f1f1;
}
h4 {
margin-bottom: 2rem;
}
/* Container */
.container {
padding: 1rem;
}
.container-header {
font-size: 1.5rem;
margin-left: 1rem;
color: #777777;
color: #777;
}
.container-panel {
border: 1px solid #3f3f3f;
background: #2d2d30;
padding: 1rem;
border-radius: 5px;
}
/* Header */
.header-list {
list-style-type: none;
margin: 0;
}
.header-item {
margin-bottom: 1rem;
}
.header-item-hide {
float: right;
width: 5rem;
border-radius: 6px;
margin: 0;
}
.header-item-display {
background: #070707;
color: #eb6e00;
@ -51,100 +41,74 @@ h4 {
padding: 0.5rem 1rem;
margin-right: 5.5rem;
}
/* Menu */
.menu-list {
list-style-type: none;
margin: 0;
}
.menu a {
color: #007acc;
display: block;
border: 1px solid #2d2d30;
padding: 0.2rem 0.5rem;
}
.menu a:hover {
color: #f1f1f1;
border: 1px solid #007acc;
}
.menu-item-add {
margin-top: 3rem;
}
/* Add */
.panel-add {
padding: 2rem;
}
.panel-graphic-property-add,
.panel-graphic-property-remove {
width: 100%;
}
/* Graphic */
.panel-graphic-delete {
}
.panel-graphic-settings {
float: right;
margin-right: 1rem;
}
.panel-graphic-property-item {
padding-left: 0;
}
.panel-graphic-preset-add {
margin-right: 1rem;
}
.panel-graphic-preset {
margin-top: 1rem;
list-style-type: none;
}
.panel-graphic-preset a {
width: 100%;
}
/* Components */
.error-box {
margin: 0rem 0rem 2rem 0;
color: #FF0000;
color: #f00;
}
/* Inputs */
.panel-graphic-property-item input {
display: inline-block;
}
label {
color: #f1f1f1;
}
input[type="text"],
textarea {
background: #333337;
border-color: #3f3f3f;
color: #999999;
color: #999;
transition-property: none !important;
}
input[type="text"]:hover,
textarea:hover {
color: #f1f1f1;
border-color: #007acc;
}
input[type="text"]:focus,
textarea:focus {
background: #333337;
@ -152,90 +116,75 @@ h4 {
border-color: #007acc;
box-shadow: none;
}
input[readonly],
input[readonly]:hover {
background: #2d2d30 !important;
border-color: #3f3f3f;
}
select {
background: #333337;
border-color: #3f3f3f;
color: #999999;
color: #999;
background-position: right center;
background-size: 9px 6px;
background-origin: content-box;
background-repeat: no-repeat;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb%28138, 138, 138%29"></polygon></svg>')
background-image: url("data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="32" height="24" viewBox="0 0 32 24"><polygon points="0,0 32,0 16,24" style="fill: rgb%28138, 138, 138%29"></polygon></svg>");
}
select:hover {
color: #f1f1f1;
border-color: #007acc;
}
select:focus {
background: #333337;
color: #f1f1f1;
border-color: #007acc;
box-shadow: none;
}
a.button {
margin: 0 1rem 0 0;
width: 7rem;
}
/* Media queries */
body {
font-size: 1.5rem;
}
@media only screen and (max-device-width: 1280px) {
.header-item-hide {
width: 9rem;
line-height: 0rem;
}
a.button {
font-size: 2rem;
line-height: 0;
width: auto;
}
.panel-graphic-preset {
margin: 0;
}
.panel-graphic-display,
.panel-graphic-preset-add {
margin-bottom: 3rem !important;
}
.panel-graphic-preset-remove {
padding-right: 0.5rem;
padding-left: 0.5rem;
}
.panel-graphic-preset-remove.alert {
padding-right: 1rem;
padding-left: 1rem;
}
.panel-graphic-settings {
font-size: 1.3rem !important;
}
.header-item-display {
font-size: 2rem;
margin-right: 12.5rem;
padding: 0.2rem 1rem;
}
.panel-graphic-property-item input {
font-size: 2rem;
height: 3.5rem;
}
}
/*# sourceMappingURL=main.css.map */

1
public/main.css.map Normal file
View file

@ -0,0 +1 @@
{"version":3,"sources":["../app/styl/main.styl"],"names":[],"mappings":"AAAA;EACE,YAAY,QAAZ;EACA,OAAO,QAAP;;AAGF;EACE,eAAe,KAAf;;AAGF;AAEE;EACE,SAAS,KAAT;;AAGF;EACE,WAAW,OAAX;EACA,aAAa,KAAb;EACA,OAAO,KAAP;;AAGF;EACE,QAAQ,kBAAR;EACA,YAAY,QAAZ;EACA,SAAS,KAAT;EACA,eAAe,IAAf;;AAGJ;AAEE;EACE,iBAAiB,KAAjB;EACA,QAAQ,EAAR;;AAGF;EACE,eAAe,KAAf;;AAGF;EACE,OAAO,MAAP;EACA,OAAO,KAAP;EACA,eAAe,IAAf;EACA,QAAQ,EAAR;;AAGF;EACE,YAAY,QAAZ;EACA,OAAO,QAAP;EACA,eAAe,IAAf;EACA,SAAS,YAAT;EACA,cAAc,OAAd;;AAGJ;AAEE;EACE,iBAAiB,KAAjB;EACA,QAAQ,EAAR;;AAGF;EACE,OAAO,QAAP;EACA,SAAS,MAAT;EACA,QAAQ,kBAAR;EACA,SAAS,cAAT;;AAGF;EACE,OAAO,QAAP;EACA,QAAQ,kBAAR;;AAGF;EACE,YAAY,KAAZ;;AAGJ;AAEE;EACE,SAAS,KAAT;;AAGF;AAA4B;EAE1B,OAAO,KAAP;;AAGJ;AAME;EACE,OAAO,MAAP;EACA,cAAc,KAAd;;AAGF;EACE,cAAc,EAAd;;AAGF;EACE,cAAc,KAAd;;AAGF;EACE,YAAY,KAAZ;EACA,iBAAiB,KAAjB;;AAGF;EACE,OAAO,KAAP;;AAGJ;AAEE;EACE,QAAQ,iBAAR;EACA,OAAO,KAAP;;AAGJ;AAEE;EACE,SAAS,aAAT;;AAGF;EACE,OAAO,QAAP;;AAGF;AAAmB;EAEjB,YAAY,QAAZ;EACA,cAAc,QAAd;EACA,OAAO,KAAP;EACA,qBAAqB,gBAArB;;AAGF;AAAyB;EAEvB,OAAO,QAAP;EACA,cAAc,QAAd;;AAGF;AAAyB;EAEvB,YAAY,QAAZ;EACA,OAAO,QAAP;EACA,cAAc,QAAd;EACA,YAAY,KAAZ;;AAGF;AAAgB;EAEd,YAAY,mBAAZ;EACA,cAAc,QAAd;;AAGF;EACE,YAAY,QAAZ;EACA,cAAc,QAAd;EACA,OAAO,KAAP;EACA,qBAAqB,aAArB;EACA,iBAAiB,QAAjB;EACA,mBAAmB,YAAnB;EACA,mBAAmB,UAAnB;EACA,kBAAuO,uNAAvO;;AAGF;EACE,OAAO,QAAP;EACA,cAAc,QAAd;;AAGF;EACE,YAAY,QAAZ;EACA,OAAO,QAAP;EACA,cAAc,QAAd;EACA,YAAY,KAAZ;;AAGF;EACE,QAAQ,WAAR;EACA,OAAO,KAAP;;AAGJ;AAEE;EACE,WAAW,OAAX;;AAG8C;AAC9C;IACE,OAAO,KAAP;IACA,aAAa,KAAb;;AAGF;IACE,WAAW,KAAX;IACA,aAAa,EAAb;IACA,OAAO,KAAP;;AAGF;IACE,QAAQ,EAAR;;AAGF;AAAuB;IAErB,eAAe,gBAAf;;AAGF;IACE,eAAe,OAAf;IACA,cAAc,OAAd;;AAGF;IACE,eAAe,KAAf;IACA,cAAc,KAAd;;AAGF;IACE,WAAW,kBAAX;;AAGF;IACE,WAAW,KAAX;IACA,cAAc,QAAd;IACA,SAAS,YAAT;;AAGF;IACE,WAAW,KAAX;IACA,QAAQ,OAAR","file":"main.css"}

View file

@ -1 +0,0 @@
npm run build && npm start

View file

@ -1,2 +0,0 @@
git pull
npm install && run