Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • aura/engine
  • hermannschwaerzler/engine
  • sumpfralle/aura-engine
3 results
Show changes
Showing
with 4411 additions and 0 deletions
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
input[type="range"] {
height: 0;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Aura Engine - Studio Clock</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/aura-clock-bundle.css'>
<script defer src='/build/aura-clock-bundle.js'></script>
</head>
<body style="background-color: black;">
<aura-clock
name="Studio Clock"
logo="https://o94.at/themes/custom/radio_orange/logo1.png"
logosize="180px"
api="http://localhost:3333/api/v1/"
css="http://localhost:3333/css/aura.css">
</aura-clock>
</body>
</html>
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/aura-clock-bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('public/build/aura-clock-bundle.css');
},
customElement: true
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
<svelte:options tag="aura-clock"/>
<main bind:this={rootElement}></main>
<script>
import { onMount } from 'svelte';
export let css = "";
export let api = "http://localhost:3333/api/v1";
export let name = "Studio Clock";
export let logo = "https://gitlab.servus.at/aura/meta/-/raw/master/images/aura-logo.png";
export let logosize = "100px";
export let noScheduleMessage = "Nothing scheduled!";
let time = new Date();
let queryCurrent = "/clock";
let rootElement;
let data;
let currentTrack = null;
let timeLeft;
// these automatically update when `time`
// changes, because of the `$:` prefix
$: hours = time.getHours();
$: minutes = time.getMinutes();
$: seconds = time.getSeconds();
data = fetchApi(queryCurrent);
onMount(() => {
const interval = setInterval(() => {
time = new Date();
timeLeft -= 1;
if (timeLeft <= 0 || data == null) {
currentTrack = null;
data = null;
data = fetchApi(queryCurrent);
}
}, 1000);
return () => {
clearInterval(interval);
};
});
async function fetchApi(query) {
let response;
let data;
try {
response = await fetch(api+query);
} catch {
throw new Error("Cannot connect to Engine!");
}
try {
data = await response.json();
} catch(e) {
console.log("Error while converting response to JSON!", e);
throw new Error(response.statusText);
}
if (response.ok) {
return data;
} else {
console.log("Error:", data);
throw new Error(data.message);
}
}
function initComponent(info) {
/* Load external CSS */
if (css != null)
loadExternalCss(rootElement, css);
/* Set currently loaded data */
if (currentTrack == null && info != null && info.track != null) {
currentTrack = info;
let t = time - Date.parse(info.track_start);
t = parseInt(t/1000);
timeLeft = info.track.duration - t - 3; /* FIXME improve timings in coordination with scheduler/trackservice/LQS */
console.log("Current Data", info);
}
return "";
}
function displayTitle(track) {
if (track != null) {
let artist = "";
if (track.artist != "")
artist = track.artist + " - ";
return artist + track.title;
}
return "";
}
function formatTime(seconds) {
if (seconds != null && Number.isInteger(seconds)) {
let d = new Date(null);
d.setSeconds(seconds);
let s;
if (seconds > 3600)
s = d.toISOString().substr(11, 8);
else
s = d.toISOString().substr(14, 5);
return s;
}
return "";
}
function displayShowName(show) {
let name = ""
if (show == null || show.name == null) {
name = '<span class="error">'+noScheduleMessage+'</span>';
} else {
name = show.name;
}
return name;
}
function displayShowSchedule(schedule) {
let str = "";
if (schedule != null && schedule.schedule_start != null) {
let scheduleStart = ""
let scheduleEnd = "";
if (schedule.schedule_start != null) {
let scheduleStart = new Date(Date.parse(schedule.schedule_start));
scheduleStart = scheduleStart.toLocaleTimeString(navigator.language, {
hour: '2-digit',
minute:'2-digit'
});
str = "(" + scheduleStart;
}
if (schedule.schedule_end != null) {
scheduleEnd = new Date(Date.parse(schedule.schedule_end));
scheduleEnd = scheduleEnd.toLocaleTimeString(navigator.language, {
hour: '2-digit',
minute:'2-digit'
});
str = str + " - " + scheduleEnd + ")";
} else {
str += ")";
}
}
return str;
}
function isActive(entry, currentTrack) {
if (currentTrack != null && entry.id == currentTrack.id) {
// Scroll to current playlist entry
location.hash = "#current-playlist-entry";
return true;
}
return false;
}
function loadExternalCss(root, file) {
let element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", file);
root.appendChild(element);
}
</script>
<style>
#station-header {
width: 100%;
height: 50px;
/* margin: 20px 100px; */
padding: 40px 100px;
}
#station-name {
margin: 0;
font-size: 3em;
line-height: 80px;
}
#station-logo {
align-content: left;
text-align: right;
margin: 0 40px 0 10px;
opacity: 0.5;
filter: invert(100%);
}
#studio-clock {
width: calc(100% - 200px);
height: calc(100% - 500px);
margin: 100px;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/* border: 2px solid #333; */
flex-direction: row;
}
#left-column {
width: 30%;
padding: 25px;
}
#right-column {
width: 70%;
padding: 25px 25px 25px 50px;
}
#current-schedule,
#next-schedule {
margin: 0 0 40px 20px;
}
#next-schedule {
background-color:rgb(24, 24, 24);
margin-right: 20px;
padding: 12px;
}
#current-schedule .schedule-title {
color: #ccc;
font-size: 3.5em;
}
#next-schedule .schedule-title {
color: gray !important;
font-size: 2em;
}
#playlist {
border: 2px solid #333;
margin: 20px 20px 40px 20px;
padding: 10px;
height: calc(80% - 100px);
overflow-y: auto;
scroll-behavior: smooth;
background-color: #111;
display: flex;
align-items: center;
}
#playlist::-webkit-scrollbar-track
{
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
background-color: rgb(77, 73, 73);
}
#playlist::-webkit-scrollbar
{
width: 12px;
background-color: rgb(0, 0, 0);
}
#playlist::-webkit-scrollbar-thumb
{
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: rgb(34, 32, 32);
}
.playlist-entry {
font-size: 1.9em;
padding-left: 53px;
}
#current-track * {
font-size: 1.5em;
}
.play-icon,
.track-time-left {
margin: 25px 50px;
}
.is-active {
color: green;
padding-left: 0;
}
.is-active .track-title::before {
content: "\00a0\00a0▶\00a0\00a0\00a0";
font-size: larger;
color: green;
}
.is-active .track-time-left {
color: rgb(43, 241, 36);
background-color: #222;
padding: 5px 15px;
}
.error {
font-size: 1.3em;
color:red;
height:100%;
display : flex;
align-items : center;
justify-content: center;
}
svg {
width: 100%;
height: 100%;
}
.clock-face {
stroke: rgb(66, 66, 66);
fill: black;
}
.minor {
stroke: rgb(132, 132, 132);
stroke-width: 0.5;
}
.major {
stroke: rgb(162, 162, 162);
stroke-width: 1;
}
.hour {
stroke: rgba(255, 255, 255, 0.705);
}
.minute {
stroke: rgba(255, 255, 255, 0.705);
}
.second, .second-counterweight {
stroke: rgb(180,0,0);
}
.second-counterweight {
/* stroke-width: 3; */
}
footer {
width: 100%;
text-align: center;
font-size: 0.8em;
color: gray;
opacity: 0.5;
}
footer a {
color: gray;
text-decoration: underline;
}
footer #aura-logo {
/* opacity: 0.5; */
filter: invert(100%);
width: 75px;
margin: 0 0 20px 0;
}
</style>
<div id="station-header">
<img id="station-logo" src="{logo}" style="width:{logosize}" alt="Radio Station" align="left" />
<h1 id="station-name">{name}</h1>
</div>
<div id="studio-clock">
<div id="left-column" class="column">
<svg viewBox='-50 -50 100 100'>
<circle class='clock-face' r='48'/>
<!-- markers -->
{#each [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55] as minute}
<line
class='major'
y1='35'
y2='45'
transform='rotate({30 * minute})'
/>
{#each [1, 2, 3, 4] as offset}
<line
class='minor'
y1='42'
y2='45'
transform='rotate({6 * (minute + offset)})'
/>
{/each}
{/each}
<!-- hour hand -->
<line
class='hour'
y1='2'
y2='-20'
transform='rotate({30 * hours + minutes / 2})'
/>
<!-- minute hand -->
<line
class='minute'
y1='4'
y2='-30'
transform='rotate({6 * minutes + seconds / 10})'
/>
<!-- second hand -->
<g transform='rotate({6 * seconds})'>
<line class='second' y1='10' y2='-38'/>
<line class='second-counterweight' y1='10' y2='2'/>
</g>
</svg>
</div>
<div id="right-column" class="column">
{#await data}
<div class="spinner-border mt-5" role="status">
<span class="sr-only">Loading...</span>
</div>
{:then value}
{initComponent(value)}
{#if value.current.show}
<div id="current-schedule">
<h1 class="schedule-title">{@html displayShowName(value.current.show)} {displayShowSchedule(value.current)}</h1>
<!-- <div class="schedule-details">
<b>Type:</b> {value.current.show.type}, <b>Host:</b> {value.current.show.host}</div>-->
</div>
<div id="playlist">
{#if value.current.playlist}
<ol>
{#each value.current.playlist.entries as entry, index}
{#if isActive(entry, value.track)}
<li id="current-playlist-entry" class="playlist-entry is-active">
<!-- <span class="play-icon">&#9654;</span> -->
<span class="track-title">{displayTitle(entry)}</span>
<span class="track-time-left">({formatTime(timeLeft)})</span>
</li>
{:else}
<li class="playlist-entry">
<span class="track-title">{displayTitle(entry)}</span>
<span class="track-duration">({formatTime(entry.duration)})</span>
</li>
{/if}
{/each}
</ol>
{:else}
<div id="current-track" class="is-active">
<h2>
<span class="track-title">{displayTitle(value.track)}</span>
<span class="track-time-left">{formatTime(timeLeft)}</span>
</h2>
</div>
{/if}
</div>
<div id="next-schedule">
<h3 class="schedule-title">Next: {@html displayShowName(value.next.show)} {displayShowSchedule(value)}</h3>
</div>
{/if}
{:catch error}
<div class="error"><p>{error}</p></div>
{/await}
</div>
</div>
<footer>
<a href="https://gitlab.servus.at/aura/meta"><img id="aura-logo" src="https://gitlab.servus.at/aura/meta/-/raw/master/images/aura-logo.png" alt="Aura Logo" /></a>
<br/>
Studio Clock is powered by <a href="https://gitlab.servus.at/autoradio">Aura Engine</a>
</footer>
\ No newline at end of file
import StudioClock from './StudioClock.svelte';
/node_modules/
/public/build/
.DS_Store
# Aura Player
A collection of JavaScript components to integrate Aura to your Website.
Provided components:
* Track Service
## Requirements
* Node (>= 13.0)
## Install
npm install
## Run
Development
npm run dev
Production
npm run build
Use the generated components in your own website.
## Resources
* Svelte Docs - https://svelte.dev/docs
\ No newline at end of file
{
"name": "aura-player",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/highlight": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@polka/url": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz",
"integrity": "sha1-shUQWX/WAeXXyVAIt2vw0lTr/TE="
},
"@rollup/plugin-commonjs": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.0.2.tgz",
"integrity": "sha512-MPYGZr0qdbV5zZj8/2AuomVpnRVXRU5XKXb3HVniwRoRCreGlf5kOE081isNWeiLIi6IYkwTX9zE0/c7V8g81g==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.0.0",
"estree-walker": "^1.0.1",
"is-reference": "^1.1.2",
"magic-string": "^0.25.2",
"resolve": "^1.11.0"
},
"dependencies": {
"estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
}
}
},
"@rollup/plugin-node-resolve": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.1.tgz",
"integrity": "sha512-14ddhD7TnemeHE97a4rLOhobfYvUVcaYuqTnL8Ti7Jxi9V9Jr5LY7Gko4HZ5k4h4vqQM0gBQt6tsp9xXW94WPA==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.0.6",
"@types/resolve": "0.0.8",
"builtin-modules": "^3.1.0",
"is-module": "^1.0.0",
"resolve": "^1.14.2"
}
},
"@rollup/pluginutils": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.0.8.tgz",
"integrity": "sha512-rYGeAc4sxcZ+kPG/Tw4/fwJODC3IXHYDH4qusdN/b6aLw5LPUbzpecYbEJh4sVQGPFJxd2dBU4kc1H3oy9/bnw==",
"dev": true,
"requires": {
"estree-walker": "^1.0.1"
},
"dependencies": {
"estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
}
}
},
"@types/estree": {
"version": "0.0.40",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.40.tgz",
"integrity": "sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA==",
"dev": true
},
"@types/node": {
"version": "12.12.20",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.20.tgz",
"integrity": "sha512-VAe+DiwpnC/g448uN+/3gRl4th0BTdrR9gSLIOHA+SUQskaYZQDOHG7xmjiE7JUhjbXnbXytf6Ih+/pA6CtMFQ==",
"dev": true
},
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
"integrity": "sha1-8mB00jjgJlnjI84aE9BB7uKA4ZQ=",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"acorn": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
"dev": true
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"anymatch": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
"integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=",
"dev": true,
"requires": {
"micromatch": "^3.1.4",
"normalize-path": "^2.1.1"
},
"dependencies": {
"normalize-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
"dev": true,
"requires": {
"remove-trailing-separator": "^1.0.1"
}
}
}
},
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
"dev": true
},
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
"dev": true
},
"arr-union": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
"array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true
},
"assign-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
"dev": true
},
"async-each": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
"integrity": "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8=",
"dev": true
},
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=",
"dev": true
},
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=",
"dev": true
},
"base": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
"integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
"dev": true,
"requires": {
"cache-base": "^1.0.1",
"class-utils": "^0.3.5",
"component-emitter": "^1.2.1",
"define-property": "^1.0.0",
"isobject": "^3.0.1",
"mixin-deep": "^1.2.0",
"pascalcase": "^0.1.1"
},
"dependencies": {
"define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
"dev": true,
"requires": {
"is-descriptor": "^1.0.0"
}
},
"is-accessor-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-data-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
"dev": true,
"requires": {
"is-accessor-descriptor": "^1.0.0",
"is-data-descriptor": "^1.0.0",
"kind-of": "^6.0.2"
}
}
}
},
"binary-extensions": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
"integrity": "sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U=",
"dev": true
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"braces": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
"integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
"dev": true,
"requires": {
"arr-flatten": "^1.1.0",
"array-unique": "^0.3.2",
"extend-shallow": "^2.0.1",
"fill-range": "^4.0.0",
"isobject": "^3.0.1",
"repeat-element": "^1.1.2",
"snapdragon": "^0.8.1",
"snapdragon-node": "^2.0.1",
"split-string": "^3.0.2",
"to-regex": "^3.0.1"
},
"dependencies": {
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "^0.1.0"
}
}
}
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=",
"dev": true
},
"builtin-modules": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
"integrity": "sha1-qtl8FRMet2tltQ7yCOdYTNdqdIQ=",
"dev": true
},
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
"integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=",
"dev": true,
"requires": {
"collection-visit": "^1.0.0",
"component-emitter": "^1.2.1",
"get-value": "^2.0.6",
"has-value": "^1.0.0",
"isobject": "^3.0.1",
"set-value": "^2.0.0",
"to-object-path": "^0.3.0",
"union-value": "^1.0.0",
"unset-value": "^1.0.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"chokidar": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
"integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=",
"dev": true,
"requires": {
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
"is-glob": "^4.0.0",
"normalize-path": "^3.0.0",
"path-is-absolute": "^1.0.0",
"readdirp": "^2.2.1",
"upath": "^1.1.1"
}
},
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
"integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=",
"dev": true,
"requires": {
"arr-union": "^3.1.0",
"define-property": "^0.2.5",
"isobject": "^3.0.0",
"static-extend": "^0.1.1"
},
"dependencies": {
"define-property": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"dev": true,
"requires": {
"is-descriptor": "^0.1.0"
}
}
}
},
"collection-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
"integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
"dev": true,
"requires": {
"map-visit": "^1.0.0",
"object-visit": "^1.0.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=",
"dev": true
},
"component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
"integrity": "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=",
"dev": true
},
"console-clear": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz",
"integrity": "sha1-mV4gy/vxTdeStnLN44e9Eo1nS/c="
},
"copy-descriptor": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
"dev": true
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true
},
"define-property": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
"integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=",
"dev": true,
"requires": {
"is-descriptor": "^1.0.2",
"isobject": "^3.0.1"
},
"dependencies": {
"is-accessor-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-data-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
"dev": true,
"requires": {
"is-accessor-descriptor": "^1.0.0",
"is-data-descriptor": "^1.0.0",
"kind-of": "^6.0.2"
}
}
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=",
"dev": true
},
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
"integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
"dev": true,
"requires": {
"debug": "^2.3.3",
"define-property": "^0.2.5",
"extend-shallow": "^2.0.1",
"posix-character-classes": "^0.1.0",
"regex-not": "^1.0.0",
"snapdragon": "^0.8.1",
"to-regex": "^3.0.1"
},
"dependencies": {
"define-property": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"dev": true,
"requires": {
"is-descriptor": "^0.1.0"
}
},
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "^0.1.0"
}
}
}
},
"extend-shallow": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
"integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
"dev": true,
"requires": {
"assign-symbols": "^1.0.0",
"is-extendable": "^1.0.1"
},
"dependencies": {
"is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
"dev": true,
"requires": {
"is-plain-object": "^2.0.4"
}
}
}
},
"extglob": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
"integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=",
"dev": true,
"requires": {
"array-unique": "^0.3.2",
"define-property": "^1.0.0",
"expand-brackets": "^2.1.4",
"extend-shallow": "^2.0.1",
"fragment-cache": "^0.2.1",
"regex-not": "^1.0.0",
"snapdragon": "^0.8.1",
"to-regex": "^3.0.1"
},
"dependencies": {
"define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
"dev": true,
"requires": {
"is-descriptor": "^1.0.0"
}
},
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "^0.1.0"
}
},
"is-accessor-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-data-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
"dev": true,
"requires": {
"is-accessor-descriptor": "^1.0.0",
"is-data-descriptor": "^1.0.0",
"kind-of": "^6.0.2"
}
}
}
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true,
"optional": true
},
"fill-range": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
"dev": true,
"requires": {
"extend-shallow": "^2.0.1",
"is-number": "^3.0.0",
"repeat-string": "^1.6.1",
"to-regex-range": "^2.1.0"
},
"dependencies": {
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "^0.1.0"
}
}
}
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
"dev": true
},
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
"integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
"dev": true,
"requires": {
"map-cache": "^0.2.2"
}
},
"fsevents": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz",
"integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==",
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1",
"node-pre-gyp": "*"
},
"dependencies": {
"abbrev": {
"version": "1.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
"bundled": true,
"dev": true,
"optional": true
},
"are-we-there-yet": {
"version": "1.1.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
}
},
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"chownr": {
"version": "1.1.3",
"bundled": true,
"dev": true,
"optional": true
},
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"debug": {
"version": "3.2.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ms": "^2.1.1"
}
},
"deep-extend": {
"version": "0.6.0",
"bundled": true,
"dev": true,
"optional": true
},
"delegates": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"detect-libc": {
"version": "1.0.3",
"bundled": true,
"dev": true,
"optional": true
},
"fs-minipass": {
"version": "1.2.7",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.6.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"gauge": {
"version": "2.7.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.0",
"object-assign": "^4.1.0",
"signal-exit": "^3.0.0",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wide-align": "^1.1.0"
}
},
"glob": {
"version": "7.1.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"has-unicode": {
"version": "2.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"iconv-lite": {
"version": "0.4.24",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"ignore-walk": {
"version": "3.0.3",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimatch": "^3.0.4"
}
},
"inflight": {
"version": "1.0.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"bundled": true,
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
"bundled": true,
"dev": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"isarray": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"minimatch": {
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true,
"optional": true
},
"minipass": {
"version": "2.9.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
}
},
"minizlib": {
"version": "1.3.3",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.9.0"
}
},
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.1.2",
"bundled": true,
"dev": true,
"optional": true
},
"needle": {
"version": "2.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"debug": "^3.2.6",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
}
},
"node-pre-gyp": {
"version": "0.14.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"detect-libc": "^1.0.2",
"mkdirp": "^0.5.1",
"needle": "^2.2.1",
"nopt": "^4.0.1",
"npm-packlist": "^1.1.6",
"npmlog": "^4.0.2",
"rc": "^1.2.7",
"rimraf": "^2.6.1",
"semver": "^5.3.0",
"tar": "^4.4.2"
}
},
"nopt": {
"version": "4.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"abbrev": "1",
"osenv": "^0.1.4"
}
},
"npm-bundled": {
"version": "1.1.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"npm-normalize-package-bin": "^1.0.1"
}
},
"npm-normalize-package-bin": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.4.7",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1"
}
},
"npmlog": {
"version": "4.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
"gauge": "~2.7.3",
"set-blocking": "~2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"once": {
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
},
"os-homedir": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"osenv": {
"version": "0.1.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"process-nextick-args": {
"version": "2.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"rc": {
"version": "1.2.8",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"bundled": true,
"dev": true,
"optional": true
}
}
},
"readable-stream": {
"version": "2.3.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"rimraf": {
"version": "2.7.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"glob": "^7.1.3"
}
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
"bundled": true,
"dev": true,
"optional": true
},
"sax": {
"version": "1.2.4",
"bundled": true,
"dev": true,
"optional": true
},
"semver": {
"version": "5.7.1",
"bundled": true,
"dev": true,
"optional": true
},
"set-blocking": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"string-width": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"string_decoder": {
"version": "1.1.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "~5.1.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"tar": {
"version": "4.4.13",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.8.6",
"minizlib": "^1.2.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.3"
}
},
"util-deprecate": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"wide-align": {
"version": "1.1.3",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"string-width": "^1.0.2 || 2"
}
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"yallist": {
"version": "3.1.1",
"bundled": true,
"dev": true,
"optional": true
}
}
},
"get-port": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
"integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw="
},
"get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
"dev": true
},
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
"dev": true,
"requires": {
"is-glob": "^3.1.0",
"path-dirname": "^1.0.0"
},
"dependencies": {
"is-glob": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
"integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
"dev": true,
"requires": {
"is-extglob": "^2.1.0"
}
}
}
},
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha1-ShL/G2A3bvCYYsIJPt2Qgyi+hCM=",
"dev": true
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"has-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
"integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
"dev": true,
"requires": {
"get-value": "^2.0.6",
"has-values": "^1.0.0",
"isobject": "^3.0.0"
}
},
"has-values": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
"integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
"dev": true,
"requires": {
"is-number": "^3.0.0",
"kind-of": "^4.0.0"
},
"dependencies": {
"kind-of": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
"integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=",
"dev": true
},
"is-accessor-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
"kind-of": "^3.0.2"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"is-binary-path": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
"integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
"dev": true,
"requires": {
"binary-extensions": "^1.0.0"
}
},
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
"dev": true
},
"is-data-descriptor": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
"kind-of": "^3.0.2"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"is-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
"integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=",
"dev": true,
"requires": {
"is-accessor-descriptor": "^0.1.6",
"is-data-descriptor": "^0.1.4",
"kind-of": "^5.0.0"
},
"dependencies": {
"kind-of": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
"integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=",
"dev": true
}
}
},
"is-extendable": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw=",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
"dev": true
},
"is-number": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true,
"requires": {
"kind-of": "^3.0.2"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=",
"dev": true,
"requires": {
"isobject": "^3.0.1"
}
},
"is-reference": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz",
"integrity": "sha1-P5WEmIbdtwJWo+bQYrGmjBPFFCc=",
"dev": true,
"requires": {
"@types/estree": "0.0.39"
},
"dependencies": {
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"dev": true
}
}
},
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=",
"dev": true
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
},
"jest-worker": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
"integrity": "sha1-Xb/bWy0yLphWeJgjipaXvM5ns+U=",
"dev": true,
"requires": {
"merge-stream": "^2.0.0",
"supports-color": "^6.1.0"
},
"dependencies": {
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha1-B2Srxpxj1ayELdSGfo0CXogN+PM=",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=",
"dev": true
},
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"dev": true
},
"kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha1-p5yezIbuHOP6YgbRIWxQHxR/wH4="
},
"livereload": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/livereload/-/livereload-0.8.2.tgz",
"integrity": "sha1-Drt1bNUVC8lW4zEQuIS8LX2HtyM=",
"dev": true,
"requires": {
"chokidar": "^2.1.5",
"opts": ">= 1.2.0",
"ws": "^6.2.1"
}
},
"local-access": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/local-access/-/local-access-1.0.1.tgz",
"integrity": "sha1-USElgUbWToaQRsZC6k8d05/5Qrs="
},
"magic-string": {
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz",
"integrity": "sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==",
"dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
},
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
"dev": true
},
"map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
"integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
"dev": true,
"requires": {
"object-visit": "^1.0.0"
}
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=",
"dev": true
},
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
"integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=",
"dev": true,
"requires": {
"arr-diff": "^4.0.0",
"array-unique": "^0.3.2",
"braces": "^2.3.1",
"define-property": "^2.0.2",
"extend-shallow": "^3.0.2",
"extglob": "^2.0.4",
"fragment-cache": "^0.2.1",
"kind-of": "^6.0.2",
"nanomatch": "^1.2.9",
"object.pick": "^1.3.0",
"regex-not": "^1.0.0",
"snapdragon": "^0.8.1",
"to-regex": "^3.0.2"
}
},
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha1-vXuRE1/GsBzePpuuM9ZZtj2IV+U="
},
"mixin-deep": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
"integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=",
"dev": true,
"requires": {
"for-in": "^1.0.2",
"is-extendable": "^1.0.1"
},
"dependencies": {
"is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
"dev": true,
"requires": {
"is-plain-object": "^2.0.4"
}
}
}
},
"mri": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz",
"integrity": "sha1-fLHdG5tAkF8frAU6viW2cg9EdEo="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
"dev": true,
"optional": true
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
"integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=",
"dev": true,
"requires": {
"arr-diff": "^4.0.0",
"array-unique": "^0.3.2",
"define-property": "^2.0.2",
"extend-shallow": "^3.0.2",
"fragment-cache": "^0.2.1",
"is-windows": "^1.0.2",
"kind-of": "^6.0.2",
"object.pick": "^1.3.0",
"regex-not": "^1.0.0",
"snapdragon": "^0.8.1",
"to-regex": "^3.0.1"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=",
"dev": true
},
"object-copy": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
"integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
"dev": true,
"requires": {
"copy-descriptor": "^0.1.0",
"define-property": "^0.2.5",
"kind-of": "^3.0.3"
},
"dependencies": {
"define-property": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"dev": true,
"requires": {
"is-descriptor": "^0.1.0"
}
},
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
"integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
"dev": true,
"requires": {
"isobject": "^3.0.0"
}
},
"object.pick": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
"integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
"dev": true,
"requires": {
"isobject": "^3.0.1"
}
},
"opts": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/opts/-/opts-1.2.7.tgz",
"integrity": "sha1-TeRyHVkslpAdrmI6Q4yYjp6nd58=",
"dev": true
},
"pascalcase": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
"path-dirname": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
"integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=",
"dev": true
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
"dev": true
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=",
"dev": true
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"readdirp": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
"integrity": "sha1-DodiKjMlqjPokihcr4tOhGUppSU=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.11",
"micromatch": "^3.1.10",
"readable-stream": "^2.0.2"
}
},
"regex-not": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
"integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=",
"dev": true,
"requires": {
"extend-shallow": "^3.0.2",
"safe-regex": "^1.1.0"
}
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
"dev": true
},
"repeat-element": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
"integrity": "sha1-eC4NglwMWjuzlzH4Tv7mt0Lmsc4=",
"dev": true
},
"repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
"dev": true
},
"require-relative": {
"version": "0.8.7",
"resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
"integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
"dev": true
},
"resolve": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true
},
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
"integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=",
"dev": true
},
"rollup": {
"version": "1.27.13",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.13.tgz",
"integrity": "sha512-hDi7M07MpmNSDE8YVwGVFA8L7n8jTLJ4lG65nMAijAyqBe//rtu4JdxjUBE7JqXfdpqxqDTbCDys9WcqdpsQvw==",
"dev": true,
"requires": {
"@types/estree": "*",
"@types/node": "*",
"acorn": "^7.1.0"
}
},
"rollup-plugin-livereload": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-1.0.4.tgz",
"integrity": "sha1-SAkZIRxpnbhaUy2r6aopA1V4+cE=",
"dev": true,
"requires": {
"livereload": "0.8.0 || ^0.8.2"
}
},
"rollup-plugin-svelte": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-5.1.1.tgz",
"integrity": "sha1-AJT5Tn5v91ebzZ93abRUdRumcOE=",
"dev": true,
"requires": {
"require-relative": "^0.8.7",
"rollup-pluginutils": "^2.3.3",
"sourcemap-codec": "^1.4.4"
}
},
"rollup-plugin-terser": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.3.tgz",
"integrity": "sha512-FuFuXE5QUJ7snyxHLPp/0LFXJhdomKlIx/aK7Tg88Yubsx/UU/lmInoJafXJ4jwVVNcORJ1wRUC5T9cy5yk0wA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"jest-worker": "^24.6.0",
"rollup-pluginutils": "^2.8.1",
"serialize-javascript": "^2.1.2",
"terser": "^4.1.0"
}
},
"rollup-pluginutils": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
"integrity": "sha1-cvKvB0i1kjZNvTOJ5gDlqURKNR4=",
"dev": true,
"requires": {
"estree-walker": "^0.6.1"
}
},
"sade": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/sade/-/sade-1.7.0.tgz",
"integrity": "sha512-HSkPpZzN7q4EFN5PVW8nTfDn1rJZh4sKbPQqz33AXokIo6SMDeVJ3RA4e0ZASlnMK6PywEMZxKXudEn5dxSWew==",
"requires": {
"mri": "^1.1.0"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
"dev": true
},
"safe-regex": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true,
"requires": {
"ret": "~0.1.10"
}
},
"serialize-javascript": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
"integrity": "sha1-7OxTsOAxe9yV73arcHS3OEeF+mE=",
"dev": true
},
"set-value": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
"integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=",
"dev": true,
"requires": {
"extend-shallow": "^2.0.1",
"is-extendable": "^0.1.1",
"is-plain-object": "^2.0.3",
"split-string": "^3.0.1"
},
"dependencies": {
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "^0.1.0"
}
}
}
},
"sirv": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-0.4.2.tgz",
"integrity": "sha1-hC7SLzqrWPruhO6mbPZgZuEj1ts=",
"requires": {
"@polka/url": "^0.5.0",
"mime": "^2.3.1"
}
},
"sirv-cli": {
"version": "0.4.5",
"resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-0.4.5.tgz",
"integrity": "sha1-/s392UMAB5f3nGZSoc4nLNuN82k=",
"requires": {
"console-clear": "^1.1.0",
"get-port": "^3.2.0",
"kleur": "^3.0.0",
"local-access": "^1.0.1",
"sade": "^1.4.0",
"sirv": "^0.4.2",
"tinydate": "^1.0.0"
}
},
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
"integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=",
"dev": true,
"requires": {
"base": "^0.11.1",
"debug": "^2.2.0",
"define-property": "^0.2.5",
"extend-shallow": "^2.0.1",
"map-cache": "^0.2.2",
"source-map": "^0.5.6",
"source-map-resolve": "^0.5.0",
"use": "^3.1.0"
},
"dependencies": {
"define-property": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"dev": true,
"requires": {
"is-descriptor": "^0.1.0"
}
},
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "^0.1.0"
}
}
}
},
"snapdragon-node": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
"integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=",
"dev": true,
"requires": {
"define-property": "^1.0.0",
"isobject": "^3.0.0",
"snapdragon-util": "^3.0.1"
},
"dependencies": {
"define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
"dev": true,
"requires": {
"is-descriptor": "^1.0.0"
}
},
"is-accessor-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
"integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-data-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
"integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
"dev": true,
"requires": {
"kind-of": "^6.0.0"
}
},
"is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
"integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
"dev": true,
"requires": {
"is-accessor-descriptor": "^1.0.0",
"is-data-descriptor": "^1.0.0",
"kind-of": "^6.0.2"
}
}
}
},
"snapdragon-util": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
"integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=",
"dev": true,
"requires": {
"kind-of": "^3.2.0"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
},
"source-map-resolve": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
"integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
"dev": true,
"requires": {
"atob": "^2.1.1",
"decode-uri-component": "^0.2.0",
"resolve-url": "^0.2.1",
"source-map-url": "^0.4.0",
"urix": "^0.1.0"
}
},
"source-map-support": {
"version": "0.5.16",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
"integrity": "sha1-CuBp5/47p1OMZMmFFeNTOerFoEI=",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true
}
}
},
"source-map-url": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"sourcemap-codec": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz",
"integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==",
"dev": true
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
"integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=",
"dev": true,
"requires": {
"extend-shallow": "^3.0.0"
}
},
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
"integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
"dev": true,
"requires": {
"define-property": "^0.2.5",
"object-copy": "^0.1.0"
},
"dependencies": {
"define-property": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"dev": true,
"requires": {
"is-descriptor": "^0.1.0"
}
}
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"svelte": {
"version": "3.16.5",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.16.5.tgz",
"integrity": "sha512-iYOhJc7iczaonycuKjPgmy1lthhBoDOQo5UVhgKJRd3XYRdnYPPb0LvvJ0t7jqu5+15S0msMm06WSOKUvhEZsw==",
"dev": true
},
"terser": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.4.3.tgz",
"integrity": "sha512-0ikKraVtRDKGzHrzkCv5rUNDzqlhmhowOBqC0XqUHFpW+vJ45+20/IFBcebwKfiS2Z9fJin6Eo+F1zLZsxi8RA==",
"dev": true,
"requires": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
"source-map-support": "~0.5.12"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true
}
}
},
"tinydate": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.2.0.tgz",
"integrity": "sha1-NrS7AnFfiXQ/PvkHPTVz0AWijQ4="
},
"to-object-path": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
"integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
"dev": true,
"requires": {
"kind-of": "^3.0.2"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"to-regex": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
"integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=",
"dev": true,
"requires": {
"define-property": "^2.0.2",
"extend-shallow": "^3.0.2",
"regex-not": "^1.0.2",
"safe-regex": "^1.1.0"
}
},
"to-regex-range": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
"integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
"dev": true,
"requires": {
"is-number": "^3.0.0",
"repeat-string": "^1.6.1"
}
},
"union-value": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
"integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=",
"dev": true,
"requires": {
"arr-union": "^3.1.0",
"get-value": "^2.0.6",
"is-extendable": "^0.1.1",
"set-value": "^2.0.1"
}
},
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
"integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
"dev": true,
"requires": {
"has-value": "^0.3.1",
"isobject": "^3.0.0"
},
"dependencies": {
"has-value": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
"integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
"dev": true,
"requires": {
"get-value": "^2.0.3",
"has-values": "^0.1.4",
"isobject": "^2.0.0"
},
"dependencies": {
"isobject": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
"dev": true,
"requires": {
"isarray": "1.0.0"
}
}
}
},
"has-values": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
"dev": true
}
}
},
"upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ=",
"dev": true
},
"urix": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
"dev": true
},
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=",
"dev": true
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"ws": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha1-RC/fCkftZPWbal2P8TD0dI7VJPs=",
"dev": true,
"requires": {
"async-limiter": "~1.0.0"
}
}
}
}
{
"name": "aura-player",
"version": "1.0.0",
"author": {
"name": "David Trattnig",
"email": "david.trattnig@subsquare.at",
"url": "https://subsquare.at"
},
"license": "AGPL-3.0-only",
"homepage": "https://gitlab.servus.at/aura/meta",
"repository": {
"type": "git",
"url": "git@gitlab.servus.at:aura/engine.git"
},
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^11.0.0",
"@rollup/plugin-node-resolve": "^7.0.0",
"rollup": "^1.20.0",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.1.2",
"svelte": "^3.0.0"
},
"dependencies": {
"sirv-cli": "^0.4.4"
}
}
contrib/aura-player/public/favicon.png

18.8 KiB

html, body {
position: relative;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
input[type="range"] {
height: 0;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Aura Track Service</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/aura-player-bundle.css'>
<script defer src='/build/aura-player-bundle.js'></script>
</head>
<body>
<aura-trackservice api="http://localhost:3333/api/v1/" name="Track Service" />
</body>
</html>
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/aura-player-bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file — better for performance
css: css => {
css.write('public/build/aura-player-bundle.css');
},
customElement: true
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration —
// consult the documentation for details:
// https://github.com/rollup/rollup-plugin-commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
\ No newline at end of file
<svelte:options tag="aura-trackservice"/>
<script>
export let api = "http://localhost:3333/api/v1/";
export let name = "Track Service";
let queryTrackservice = "trackservice";
let result;
let data = [];
let currentDate = "";
async function getData(query) {
let response = await fetch(`${api}${query}`);
let data = await response.json();
if (response.ok) {
return data;
} else {
throw new Error(data)
}
}
function getDate(item) {
let track_date = "";
if (item.track_start != null)
track_date = item.track_start.split('T')[0];
if (currentDate != track_date) {
currentDate = track_date;
let date = new Date(currentDate);
let options = {
weekday: "long", year: "numeric", month: "short",
day: "numeric"
};
return date.toLocaleDateString("de-at", options);
} else {
return "";
}
}
function getTime(item) {
let date = new Date(item.track_start);
let options = {
hour: "2-digit", minute: "2-digit"
};
return date.toLocaleTimeString("de-at", options);
}
function isActive(item) {
if (item.track.duration != null && parseInt(item.track.duration) > 0) {
let startDate = new Date(item.track_start);
let endDate = new Date(startDate.getTime());
endDate.setSeconds(endDate.getSeconds() + parseInt(item.track.duration));
let now = new Date();
if (startDate < now && now < endDate) {
return "active-track";
} else {
return "";
}
} else {
return "";
}
}
function printDuration(item) {
if (item.track.duration != null && parseInt(item.track.duration) > 0) {
return "("+formatTime(item.track.duration)+")";
} else {
return "";
}
}
function formatTime(seconds) {
if (seconds != null && Number.isInteger(seconds)) {
let d = new Date(null);
d.setSeconds(seconds);
let s;
if (seconds > 3600)
s = d.toISOString().substr(11, 8);
else
s = d.toISOString().substr(14, 5);
return s;
}
return "";
}
result = getData(queryTrackservice);
</script>
<style>
h1, h2, h3, h4, h5 {
text-align: center;
}
.card {
margin-bottom: 38px;
font-size: 1.3em;
}
.card.active-track {
border: 3px solid greenyellow;
}
.spinner {
text-align: center;
}
.spinner .loading {
margin: 10px 0 0 0;
color: gray;
}
.lds-dual-ring {
display: inline-block;
width: 80px;
height: 80px;
}
.lds-dual-ring:after {
content: " ";
display: block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
border: 6px solid #000;
border-color: #aaa transparent #aaa transparent;
animation: lds-dual-ring 1.2s linear infinite;
}
@keyframes lds-dual-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.current-date {
font-size: 1.3em;
}
footer {
font-size: 0.8em;
margin: 40px 0;
text-align: center;
color: gray;
}
footer a {
color: gray;
text-decoration: underline;
}
</style>
<div class="container mt-5">
<div class="row">
<div class="col-md"></div>
<div class="col-md-8 text-center">
<h1 class="display-4">{name}</h1>
{#await result}
<div class="spinner" role="status">
<div class="lds-dual-ring"></div>
<div class="loading">Loading...</div>
</div>
{:then value}
{#each value as item}
<h4 class="current-date">{getDate(item)}</h4>
<div class="card mt-5 {isActive(item)}">
<div class="card-body">
<h5 class="card-title"><b>{getTime(item)}</b> | {item.track.artist} - {item.track.title} {printDuration(item)}</h5>
</div>
</div>
{/each}
{:catch error}
<p style="color:red">{error.message}</p>
{/await}
</div>
<div class="col-md"></div>
</div>
</div>
<footer>Track Service is powered by <a href="https://gitlab.servus.at/autoradio">Aura</a></footer>
\ No newline at end of file
import TrackService from './TrackService.svelte';
\ No newline at end of file
*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
---
# svelte app
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
```bash
npx degit sveltejs/template svelte-app
cd svelte-app
```
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
## Get started
Install the dependencies...
```bash
cd svelte-app
npm install
```
...then start [Rollup](https://rollupjs.org):
```bash
npm run dev
```
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`.
## Building and running in production mode
To create an optimised version of the app:
```bash
npm run build
```
You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com).
## Single-page app mode
By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere.
If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json:
```js
"start": "sirv public --single"
```
## Deploying to the web
### With [now](https://zeit.co/now)
Install `now` if you haven't already:
```bash
npm install -g now
```
Then, from within your project folder:
```bash
cd public
now deploy --name my-project
```
As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon.
### With [surge](https://surge.sh/)
Install `surge` if you haven't already:
```bash
npm install -g surge
```
Then, from within your project folder:
```bash
npm run build
surge public my-project.surge.sh
```
# Aura Engine Configuration Guide
This page goes into detail on what is possible to configure within the engine.
<!-- TOC -->
- [Aura Engine Configuration Guide](#aura-engine-configuration-guide)
- [Station](#station)
- [Soundcard](#soundcard)
- [Recordings](#recordings)
- [Streams](#streams)
- [Fallbacks](#fallbacks)
- [Database](#database)
- [Monitoring](#monitoring)
- [Web User Interface](#web-user-interface)
- [Administrator Emails](#administrator-emails)
- [API Endpoints](#api-endpoints)
- [Fading](#fading)
- [Logging](#logging)
- [User](#user)
- [Socket](#socket)
- [Redis](#redis)
- [Frequently Asked Questions](#frequently-asked-questions)
- [Which Audio Interface / Soundcard is compatible with Aura?](#which-audio-interface--soundcard-is-compatible-with-aura)
- [ALSA Settings](#alsa-settings)
- [Install: I don't want to install all Liquidsoap Audio plugins. How?](#install-i-dont-want-to-install-all-liquidsoap-audio-plugins-how)
- [In the Liquidsoap Logs I get 'Error when starting output output_lineout_0: Failure("Error while setting open_pcm: Device or resource busy")!'. What does it mean?](#in-the-liquidsoap-logs-i-get-error-when-starting-output-output_lineout_0-failureerror-while-setting-open_pcm-device-or-resource-busy-what-does-it-mean)
- [How can I find the audio device IDs, required for settings in engine.ini?](#how-can-i-find-the-audio-device-ids-required-for-settings-in-engineini)
<!-- /TOC -->
## Station
These properties are used to style the included web applications such as *Track Service*
and *Studio Clock* .
Set the radio station name
```ini
station_name="Radio Orange"
```
Set the URL to the radio station logo
```ini
station_logo_url="https://your-radio.station/logo.png"
```
Set the `width` of the radio station logo
```ini
station_logo_size="120px"
```
## Soundcard
Configure your audio device in the `[soundcard]` section of `engine.ini`.
You can configure up to **five** line IN and OUT stereo channels. Your hardware should
support that. When you use JACK, you will see the additional elements popping up when
viewing your connections (with e.g. Patchage).
**Pulse Audio:** When using Ubuntu, Pulse Audio is selected by default. This is convenient,
as you won't have the need to adapt any Engine setting to get audio playing initially.
**ALSA:** When you use ALSA, you will have to play around with ALSA settings. In the folder
`./modules/liquidsoap` is a scipt called alsa_settings_tester.liq. You can start it
with 'liquidsoap -v --debug alsa_settings_tester.liq'. Changing and playing with
settings may help you to find correct ALSA settings.
**Jack Audio**: Beside ALSA the sound servers such as
is supported.
Install the JACK daemon and GUI:
```bash
sudo apt-get install jackd qjackctl
```
Please ensure to enable "*realtime process priority*" when installing JACK to keep latency low.
Now, you are able to configure your hardware settings using following command:
```bash
qjackctl
```
Next you need to install the JACK plugin for Liquidsoap:
```bash
sudo apt install \
liquidsoap-plugin-jack
```
## Recordings
You can configure up to **five** recorders in the `[recording]`.
## Streams
You can configure up to **five** streams in the `[streams]`.
## Fallbacks
Configure fallback handling in the `[fallback]` section.
## Database
Configure your engine database in the `[database]` section.
## Monitoring
Configure monitoring parameters in the `[monitoring]` section.
## Web User Interface
Configure the web interface in the `[web-ui]` section.
## Administrator Emails
Configure the email server for admin mails in the `[mail]` section.
## API Endpoints
Configure connections to the other Aura components in the `[dataurls]` section.
Sets the API URL exposed to external clients. This is required by the included
web applications which access the API.
```ini
exposed_api_url="https://your-radio.station/api/v3"
```
## Fading
Configure fading parameters in the `[fading]` section.
## Logging
Configure log handling in the `[logging]` section.
## User
Configure the executing system user in the `[user]` section.
## Socket
Configure socket connectivity in the `[socket]` section.
## Redis
Configure Redis connectivity in the `[redis]` section.
## Frequently Asked Questions
### Which Audio Interface / Soundcard is compatible with Aura?
Basically any audio device which is supported by Linux Debian/Ubuntu and has ALSA drivers.
Engine has been tested with following audio interfaces:
- ASUS Xonar DGX,
- Roland Duo-Capture Ex
- Onboard Soundcard (HDA Intel ALC262)
- Native Instruments Komplete Audio 6
### ALSA Settings
#### Install: I don't want to install all Liquidsoap Audio plugins. How?
Depending on what stream you are going to send, and what recordings you are going to use,
install one or some of the following:
```bash
sudo apt install \
liquidsoap-plugin-aac # for aac support
liquidsoap-plugin-flac # for flac support
liquidsoap-plugin-lame liquidsoap-plugin-mad # for mp3 support
liquidsoap-plugin-opus # for opus support
liquidsoap-plugin-vorbis # for ogg support
```
#### In the Liquidsoap Logs I get 'Error when starting output output_lineout_0: Failure("Error while setting open_pcm: Device or resource busy")!'. What does it mean?
You probably have set a wrong or occupied device ID.
#### How can I find the audio device IDs, required for settings in engine.ini?
* **ALSA**: You can get the device numbers or IDs by executing:
cat /proc/asound/cards
* **Pulse Audio**: You might not need this for Pulse Audio, but still, to see all available devices use:
pactl list
**If you cannot find correct ALSA settings**
Well, this is - at least for me - a hard one. I could not manage to find correct ALSA settings for the above mentioned soundcards. The best experience i had with the ASUS Xonar DGX, but still very problematic (especially the first couple of minutes after starting liquidsoap). Since i enabled JACK support i only use that. It is also a bit of trial and error, but works pretty much out of the box.
**If you experience 'hangs' or other artefacts on the output signal**
* reduce the quality (especially, when hangs are on the stream) or
* install the realtime kernel with
```bash
apt install linux-image-rt-amd64
reboot
```
or
* invest in better hardware
\ No newline at end of file
# 1. Aura Engine Development Guide
This page gives insights on extending Aura Engine internals or through the API.
<!-- TOC -->
- [1. Aura Engine Development Guide](#1-aura-engine-development-guide)
- [1.1. Architecture](#11-architecture)
- [1.2. Required Data Sources](#12-required-data-sources)
- [1.3. Provided API Endpoints](#13-provided-api-endpoints)
- [1.4. Components](#14-components)
- [1.5. Running the Engine](#15-running-the-engine)
- [1.6. Default ports used by Engine](#16-default-ports-used-by-engine)
- [1.7. Debugging Liquidsoap](#17-debugging-liquidsoap)
<!-- /TOC -->
## 1.1. Architecture
AURA Engine as part of the AURA Radio Suite uses an modulear architecture
based on a REST API. All external information is retrieved using JSON data-structures.
To get the basic architectural overview, visit the [Aura Meta](https://gitlab.servus.at/autoradio/meta) repository.
## 1.2. Required Data Sources
The AURA Project "**Dashboard**" provides the GUI to organize shows, schedules/timelsots
and organize uploads in form of playlists. Those playlists can be organized in timeslots
using a fancy calendar interface.
These data-sources need to be configurated in the "engine.ini" configuration file:
# The URL to get the Calendar via PV/Steering
calendarurl="http://localhost:8000/api/v1/playout"
# The URL to get show details via PV/Steering
api_show_url="http://localhost:8000/api/v1/shows/${ID}/"
The AURA Project "**Tank**" on the other hand delivers information on the tracks, playlists
to be played and its meta-data:
# The URL to get playlist details via Tank
importerurl="http://localhost:8040/api/v1/shows/${SLUG}/playlists"
More information you can find here: <https://gitlab.servus.at/autoradio/meta/blob/master/api-definition.md>
## 1.3. Provided API Endpoints
**Soundserverstate:** Returns true and false values of the internal In- and Outputs
/api/v1/soundserver_state
**Trackservice:**
/api/v1/trackservice/<selected_date>
/api/v1/trackservice/
## 1.4. Components
**aura.py**: It is the server which is connected to the external programme source (e.g. aura steering and tank), to liquidsoap and is listening for redis pubsub messages. This precious little server is telling liquidsoap what to play and when.
**Guru**: The commandline tool for interacting with the server. Also provides the communication from Liquidsoap to the Python (Command-)Server.
**Liquidsoap**: The heart of AuRa Engine. It uses the built in mixer, to switch between different sources. It records everything and streams everything depending on your settings in aura.ini.
## 1.5. Running the Engine
Aura Engine is consisting of two components: The Python Engine and Liquidsoap Core.
It's important to start both components in the correct order:
1. Run the Python engine
./run.sh
2. Run the Liquidsoap core
./run.sh lqs
## 1.6. Default ports used by Engine
Aura Engine requires a number of ports for internal and external communication.
Those are the default port numbers:
* `1234` ... Liquidsoap Telnet Server
* `3333` ... Exposes the Engine API
* `5000` ... Svelte development mode; dynamically uses some other port if occupied
## 1.7. Debugging Liquidsoap
Connect to Liquidsoap via Telnet
telnet 127.0.0.1 1234
List available commands
help
List all available channels
list
List all input channels connected to the mixer
mixer.input
Set the volume of mixer `input 0` to `100%`
mixer.volume 0 100
Push some audio file to the filesystem `queue 0`
in_filesystem_0.push /path/to/your/file.mp3
# Aura Engine Features
This page gives a more detailed overview of the Aura Engine features.
## Input
### Play audio from multiple sources
It's possible to air playlists with music or recordings stored on the **filessystem**,
via external **streams** or live from a **studio**.
### Dynamic switching of sources
TODO extend: * switch the soundserver at the correct time to a given source for a specific show
## Output
### Record output to filesystem
TODO extend: * record what is broadcasted
### Stream output to an Icecast Server
TODO extend: * stream to an icecast server
### Multichannel Line-out
TODO extend: * play to line-out
## Blank Detenction / Silence Detecter
The engine offers a simple way to detect scenarios where no music is on air.
It possible to configure the sensitivity of the Silence Detector and automatically
transition play-out to a Fallback Playlist (see Auto Pilot).
## Auto Pilot a.k.a. Fallback Handling
In case there is no schedule delivered by Steering, engine provides multiple
fallback handling scenarios. The available fallbacks are evaluated in following order:
1. **Timeslot Fallback**:
2. **Show Fallback**:
3. **Station Fallback**:
3.1 Station Fallback via remote playlist
3.2 Station Fallback via local music folder
Note: All filenames in the music folder should be ASCII encoded, otherwise this may cause engine failures.
## API Endpoints
**Track Service API**: These endpoints provide information on the played tracks, their schedules and shows.
* `/api/v1/trackservice` .............. Returns all Track Service entries for the current day
* `/api/v1/trackservice/$ID` .......... Returns a Track Service entry by ID
* `/api/v1/trackservice/current` ...... Returns the track currently playing
* `/api/v1/trackservice/day/$DAY` ..... Returns all tracks for a given day formated as `YYYY-MM-DD`
The Swagger Specification of a Track Service entry as YAML looks like this:
```yaml
components:
schemas:
TrackService:
properties:
album: {}
artist: {}
duration: {}
fallback: {}
id: {}
schedule_start: {}
title: {}
track_start: {}
type: object
info:
title: Swagger API Specification for Aura Engine
version: 1.0.0
openapi: 3.0.2
paths: {}
```
**Reporting API**: Create monthly reports using this endpoint.
* `/api/v1/report/$MONTH` ...... Returns all playout details for the given month in the format `YYYY-MM`
```yaml
schemas:
Report:
properties:
fallback_type: {}
id: {}
playlist_id: {}
schedule.category: {}
schedule.is_repetition: {}
schedule.languages: {}
schedule.musicfocus: {}
schedule.schedule_end: {}
schedule.schedule_id: {}
schedule.schedule_start: {}
schedule.show_funding_category: {}
schedule.show_hosts: {}
schedule.show_id: {}
schedule.show_name: {}
schedule.show_type: {}
schedule.topic: {}
schedule.type: {}
schedule_fallback_id: {}
show_fallback_id: {}
station_fallback_id: {}
track: {}
track_start: {}
type: object
info:
title: Swagger API Specification for Aura Engine
version: 1.0.0
openapi: 3.0.2
```
**Schedule API**: Retrieves information on the programme.
* `/api/v1/schedule/upcoming` .. Returns the next three schedules, after the one currently playing.
```yaml
schemas:
Schedule:
properties:
id: {}
schedule: {}
schedule_id: {}
schedule_start: {}
show_hosts: {}
show_id: {}
show_name: {}
show_type: {}
type: object
info:
title: Swagger API Specification for Aura Engine
version: 1.0.0
openapi: 3.0.2
```
**Clock API**: Retrieve all data relevant for a studio clock.
* `/api/v1/clock` .............. Returns the current show, next show, playlist and time left until the next show.
```yaml
schemas:
Clock:
properties:
current: {}
next: {}
track: {}
track_id: {}
track_start: {}
type: object
info:
title: Swagger API Specification for Aura Engine
version: 1.0.0
openapi: 3.0.2
```
## Web Applications
* `/app/trackservice` ................. Web Application for displaying the Track-Service
* `/app/clock` ........................ Web Application for displaying the studio clock
#!/usr/bin/env python3.7
#
# Aura Engine
#
# Copyright (C) 2020 David Trattnig <david.trattnig@subsquare.at>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import os, os.path
from datetime import datetime, date, timedelta
from flask import Flask, Response
from flask_caching import Cache
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow import Schema, fields, post_dump
from flask_restful import Api, Resource, abort
from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin
# import werkzeug
from werkzeug.exceptions import HTTPException, default_exceptions, Aborter
from modules.base.logger import AuraLogger
from modules.base.config import AuraConfig
from libraries.database.broadcasts import AuraDatabaseModel, Schedule, Playlist, PlaylistEntry, PlaylistEntryMetaData, TrackService
#
# Initialize the Aura Web App and API.
#
config = AuraConfig()
app = Flask(__name__,
static_url_path='',
static_folder='web/')
# static_folder='contrib/aura-player/public/')
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SQLALCHEMY_DATABASE_URI"] = config.get_database_uri()
app.config["CACHE_TYPE"] = "simple"
app.config["CACHE_DEFAULT_TIMEOUT"] = 0
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
cache = Cache(app)
cors = CORS(app, resources={r"/*": {"origins": "*"}}) # FIXME Update CORS for production use
db = SQLAlchemy(app)
ma = Marshmallow(app)
api = Api(app)
#
# Werkzeug HTTP code mappings
#
class NoDataAvailable(HTTPException):
code = 204
description = "There is currently no content available."
default_exceptions[204] = NoDataAvailable
abort = Aborter()
class EngineApi:
"""
Provides the Aura Engine API services.
"""
config = None
api = None
logger = None
# trackservice_schema = None
def __init__(self, config, api):
"""
Initializes the API.
Args:
config (AuraConfig): The Engine configuration.
api (Api): The Flask restful API object.
"""
self.config = config
self.logger = AuraLogger(self.config, "engine-api")
self.logger = logging.getLogger("engine-api")
self.api = api
# Generate HTML files
self.generate_html("web/templates/clock.html", "web/clock.html")
self.generate_html("web/templates/trackservice.html", "web/trackservice.html")
# API Spec
spec.components.schema("TrackService", schema=TrackServiceSchema)
spec.components.schema("Report", schema=ReportSchema)
spec.components.schema("Schedule", schema=ScheduleSchema)
spec.components.schema("Clock", schema=ClockDataSchema)
# TODO Generates HTML for specification
#self.logger.info(spec.to_yaml())
# Schema instances
EngineApi.trackservice_schema = TrackServiceSchema(many=True)
EngineApi.track_schema = TrackServiceSchema()
EngineApi.report_schema = ReportSchema(many=True)
EngineApi.schedule_schema = ScheduleSchema(many=True)
EngineApi.clockdata_schema = ClockDataSchema()
# Define API routes
self.api.add_resource(TrackServiceResource, config.api_prefix + "/trackservice/")
self.api.add_resource(TrackResource, config.api_prefix + "/trackservice/<int:track_id>")
self.api.add_resource(CurrentTrackResource, config.api_prefix + "/trackservice/current")
self.api.add_resource(TracksByDayResource, config.api_prefix + "/trackservice/date/<string:date_string>")
self.api.add_resource(ReportResource, config.api_prefix + "/report/<string:year_month>")
self.api.add_resource(UpcomingSchedulesResource, config.api_prefix + "/schedule/upcoming")
self.api.add_resource(ClockDataResource, config.api_prefix + "/clock")
self.logger.info("Engine API routes successfully set!")
# Static resources
@app.route('/app/trackservice', methods=['GET'])
def trackservice():
content = open(os.path.join("web/", "trackservice.html"))
return Response(content, mimetype="text/html")
# Static resources
@app.route('/app/clock', methods=['GET'])
def clock():
content = open(os.path.join("web/", "clock.html"))
return Response(content, mimetype="text/html")
def generate_html(self, src_file, target_file):
"""
Generates HTML based on the configuration options and templates.
Args:
src_file (String): The template file
target_file (String): The HTML file to be generated
"""
src_file = open(src_file, "r")
target_file = open(target_file, "w")
content = src_file.read()
config_options = {
"CONFIG-STATION-NAME": config.station_name,
"CONFIG-STATION-LOGO-URL": config.station_logo_url,
"CONFIG-STATION-LOGO-SIZE": config.station_logo_size,
"CONFIG-API-URL": config.exposed_api_url
}
for key, value in config_options.items():
content = content.replace(":::"+key+":::", value)
target_file.write(content)
src_file.close()
target_file.close()
def run(self):
"""
Starts the API server.
"""
# Set debug=False if you want to use your native IDE debugger
self.api.app.run(port=self.config.api_port, debug=False)
#
# API SPEC
#
spec = APISpec(
title="Swagger API Specification for Aura Engine",
version="1.0.0",
openapi_version="3.0.2",
plugins=[FlaskPlugin(), MarshmallowPlugin()],
)
#
# API SCHEMA
#
class TrackServiceSchema(ma.Schema):
class Meta:
fields = (
"id",
"schedule.schedule_id",
"schedule.schedule_start",
"schedule.schedule_end",
"schedule.languages",
"schedule.type",
"schedule.category",
"schedule.topic",
"schedule.musicfocus",
"schedule.is_repetition",
"track",
"track_start",
"show"
)
class ClockDataSchema(ma.Schema):
class Meta:
fields = (
"current",
"next",
"track_id",
"track_start",
"track"
)
class ScheduleSchema(ma.Schema):
class Meta:
fields = (
"id",
"schedule_id",
"schedule_start",
"schedule",
"show_id",
"show_name",
"show_hosts",
"show_type"
)
class ReportSchema(ma.Schema):
class Meta:
fields = (
"id",
"schedule.schedule_id",
"schedule.schedule_start",
"schedule.schedule_end",
"schedule.languages",
"schedule.type",
"schedule.category",
"schedule.topic",
"schedule.musicfocus",
"schedule.is_repetition",
"schedule.show_id",
"schedule.show_name",
"schedule.show_hosts",
"schedule.show_type",
"schedule.show_funding_category",
"track",
"track_start",
"playlist_id",
"fallback_type",
"schedule_fallback_id",
"show_fallback_id",
"station_fallback_id"
)
#
# API RESOURCES
#
class TrackServiceResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self):
today = date.today()
today = datetime(today.year, today.month, today.day)
tracks = TrackService.select_by_day(today)
return EngineApi.trackservice_schema.dump(tracks)
class TrackResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self, track_id):
track = TrackService.select_one(track_id)
return EngineApi.track_schema.dump(track)
class ClockDataResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self):
item = TrackService.select_current()
next_schedule = Schedule.select_upcoming(1)
if next_schedule:
next_schedule = next_schedule[0].as_dict()
next_schedule["playlist"] = None
else:
next_schedule = {}
clockdata = {
"track_id": item.id,
"track_start": item.track_start,
"track": item.track,
"current": {},
"next": next_schedule
}
if item.schedule:
clockdata["current"] = item.schedule.as_dict()
if item.schedule.playlist:
clockdata["current"]["playlist"] = item.schedule.playlist[0].as_dict()
clockdata["current"]["show"] = item.show
return EngineApi.clockdata_schema.dump(clockdata)
class CurrentTrackResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self):
track = TrackService.select_current()
if not track:
return abort(204) # No content available
return EngineApi.track_schema.dump(track)
class TracksByDayResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self, date_string):
date = datetime.strptime(date_string, "%Y-%m-%d")
self.logger.debug("Query track-service by day: %s" % str(date))
tracks = TrackService.select_by_day(date)
if not tracks:
return abort(204) # No content available
return EngineApi.trackservice_schema.dump(tracks)
class UpcomingSchedulesResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self):
now = datetime.now()
self.logger.debug("Query upcoming schedules after %s" % str(now))
schedules = Schedule.select_upcoming(3)
if not schedules:
return abort(204) # No content available
return EngineApi.schedule_schema.dump(schedules)
class ReportResource(Resource):
logger = None
def __init__(self):
self.logger = logging.getLogger("engine-api")
def get(self, year_month):
year = int(year_month.split("-")[0])
month = int(year_month.split("-")[1])
first_day = datetime(year, month, 1)
next_month = first_day.replace(day=28) + timedelta(days=4)
next_month - timedelta(days=next_month.day)
self.logger.debug("Query report for month: %s - %s" % (str(first_day), str(next_month)))
report = TrackService.select_by_range(first_day, next_month)
if not report:
return abort(204) # No content available
return EngineApi.report_schema.dump(report)
#
# Initialization calls
#
engine_api = EngineApi(config, api)
if __name__ == "__main__":
engine_api.run()