basic app window

materials
Bronwen 2021-07-23 00:12:02 -04:00
parent 86d6aca1c9
commit 6a56a70b9c
26 changed files with 492 additions and 320 deletions

18
bs.js
View File

@ -1,18 +0,0 @@
import chokidar from 'chokidar';
import cluster from 'cluster';
import { QMainWindow } from '@nodegui/nodegui';
import { watchFile } from 'fs';
import watch from 'watch';
if(cluster.isMaster) {
cluster.fork();
} else {
// chokidar.watch('test.js', {
// useFsEvents: false,
// usePolling: false,
// ""
// }).on('all', (a, b) => console.log(a, b));
watch.watchTree('out', console.log);
// watchFile('test.js', console.log)
}

View File

@ -0,0 +1,3 @@
import './core/items/CoreItems.js';
import './core/tasks/CoreTasks.js';
import './core/themes/standard.js';

View File

@ -1,12 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>df-idle</title>
</head>
<body>
<script type="module" src="./out/index.js"></script>
</body>
</html>

View File

@ -1,5 +1,5 @@
{
"name": "df-idle",
"name": "hadean",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
@ -12,6 +12,7 @@
"@types/faker": "^5.5.6",
"@types/fs-extra": "^9.0.11",
"@types/mocha": "^8.2.2",
"@types/node-ipc": "^9.1.5",
"@types/uuid": "^8.3.0",
"@types/watch": "^1.0.2",
"@types/ws": "^7.4.5",
@ -29,6 +30,7 @@
"module-alias": "^2.2.2",
"neo-blessed": "^0.2.0",
"node-dev": "^7.0.0",
"node-ipc": "^10.0.2",
"nodemon": "^2.0.7",
"printable-characters": "^1.0.42",
"sisteransi": "^1.0.5",
@ -42,14 +44,14 @@
},
"scripts": {
"compile:watch": "tsc --watch",
"start": "node --no-warnings --loader ./lib/aliases.mjs --enable-source-maps out/src/index.js",
"dev": "nodemon -I --watch out --exec yarn start",
"start": "yarn x out/src/index.js",
"dev": "yarn x out/src/hot-index.js",
"prod": "git fetch && git pull && yarn && tsc && yarn start",
"test": "mocha",
"lint": "eslint src/**/*.ts",
"web": "web-dev-server --open index.html --node-resolve --watch",
"profile": "node --inspect-brk --no-warnings --loader ./lib/aliases.mjs --enable-source-maps out/src/index.js",
"gui": "qode out/src/qt/qode.js",
"qode": "qode"
"qx": "qode --no-warnings --loader ./lib/aliases.mjs",
"x": "node --no-warnings --loader ./lib/aliases.mjs"
}
}

View File

@ -1,86 +0,0 @@
import cluster from 'cluster';
import chokidar from 'chokidar';
import watch from 'watch';
let init: Function = null;
const hotReload = true;
let restartTimer: NodeJS.Timeout = null;
let worker: cluster.Worker = null;
function createWorker() {
start();
function start() {
if (cluster.isMaster) {
worker = cluster.fork();
// console.log(worker);
// worker.process.stdout.pipe(process.stdout);
// worker.process.stderr.pipe(process.stderr);
worker.on('message', (message) => {
if(message === 'ipc-restart') {
worker.on('exit', () => {
setTimeout(createWorker, 0);
});
worker.kill();
} else if (message === 'ipc-quit') {
worker.on('exit', () => {
process.exit(0);
})
worker.kill();
}
});
}
}
}
// from any cluster context, gracefully exit if needed, and begin anew!
export function restart() {
if (cluster.isWorker) {
process.send('ipc-restart');
} else if(worker) {
worker.on('exit', () => {
setTimeout(createWorker, 0);
})
worker.kill();
} else {
createWorker();
}
}
export function quit() {
if (cluster.isWorker) {
process.send('ipc-quit');
}
}
export function start() {
if(init) {
if (cluster.isWorker) {
init();
} else {
// TODO make hotreload actually bring a popup on the client
// so that the user should press enter to enable a reload.
if(hotReload) {
function fileChange(f: watch.FileOrFiles) {
console.log('changes detected');
// appendFileSync('log.log', evt + ' ' + path + '\n');
// console.log(cluster.isMaster, evt, path);
if(restartTimer) clearTimeout(restartTimer)
restartTimer = setTimeout(() => {
restart();
restartTimer = null;
}, 1000);
}
// chokidar.watch('./out').on('all', fileChange);
watch.watchTree('./out', fileChange);
} else {
createWorker();
}
}
}
}
export function setInitialize(fn: Function) {
init = fn;
}

8
src/Constants.ts 100644
View File

@ -0,0 +1,8 @@
export const IPC_PATH = '/tmp/dfi.dev';
export const IPC_CLIENT_APPSAPCE = 'dfi.';
export const IPC_CLIENT_CONNECT_NAME = 'dev';
export const IPC_QUIT_EVENT = 'app.quit';
export const IPC_RESTART_EVENT = 'app.restart';
export const APPLICATION_NAME = 'Hadean'

View File

@ -4,19 +4,18 @@ import { Pawn } from './Pawn.js';
import { TaskList } from './TaskList.js';
import { Inventory } from './Inventory.js';
import Time, { Tickable } from './Time.js';
import { render, Renderable, setTitle, start, Menu } from '@ui';
import { setTitle, start, update } from '@ui';
import { ready } from './multiplayer/mDNS.js';
import faker from 'faker';
import { World } from '@world';
let game: Game = null;
export class Game extends Frigid implements Tickable, Renderable {
export class Game extends Frigid implements Tickable {
pawns: Pawn[] = [];
selected: Pawn;
inventory: Inventory;
board: TaskList;
menu: Menu;
clock: Time;
name: string;
world: World;
@ -32,7 +31,7 @@ export class Game extends Frigid implements Tickable, Renderable {
for(const pawn of this.pawns) {
pawn.tick();
}
render();
update();
}
get inv() { return this.inventory; }
@ -61,7 +60,6 @@ export class Game extends Frigid implements Tickable, Renderable {
this.world ??= new World();
this.pawns ??= [];
this.selected ??= this.pawns[0] || null;
this.menu = new Menu();
this.board ??= new TaskList();
this.inventory ??= new Inventory();
this.inventory.validate();
@ -69,17 +67,9 @@ export class Game extends Frigid implements Tickable, Renderable {
this.clock.thing = this;
this.clock.start();
ready(this.name);
render(this);
}
static serializationDependencies() {
return [ Pawn, Inventory, TaskList, Time, World ];
}
render() {
this.menu.render();
this.board.render();
// TODO this logic dont make sense
return '';
}
}

View File

@ -1,9 +1,9 @@
import { Serializable } from 'frigid';
import { Game } from './Game.js';
import { Item, ItemState } from './registries/Items.js';
import { Renderable, Popup } from '@ui';
import { Popup } from '@ui';
export class Inventory extends Serializable implements Renderable {
export class Inventory extends Serializable {
items: ItemState<any>[];
ctor() {

View File

@ -3,13 +3,13 @@ import faker from 'faker';
import { Task, TaskState } from './registries/Tasks.js';
import Time, { Tickable } from './Time.js';
import { Game } from './Game.js';
import { render, Renderable, RenderMode } from '@ui';
// import { render, Renderable, RenderMode } from '@ui';
import { Memory } from './Memory.js';
import { getTheme } from '@themes';
// TODO add stats getter to return % of all stats
export class Pawn extends Serializable implements Tickable, Renderable {
export class Pawn extends Serializable implements Tickable {
name: {
first: string,
last: string
@ -80,25 +80,25 @@ export class Pawn extends Serializable implements Tickable, Renderable {
return [TaskState]
}
toString() {
return this.render(RenderMode.ONELINE);
}
// toString() {
// return this.render(RenderMode.ONELINE);
// }
render(mode: RenderMode): string {
if(mode === RenderMode.ONELINE) {
if(this.name) {
return this.name.first + ' ' + this.name.last;
} else {
return '[Object Pawn]';
}
} else if (mode === RenderMode.DETAILS) {
return `${
this.toString()
}{|}${
this.status
}\nDETAILS\nDETAILS`
}
}
// render(mode: RenderMode): string {
// if(mode === RenderMode.ONELINE) {
// if(this.name) {
// return this.name.first + ' ' + this.name.last;
// } else {
// return '[Object Pawn]';
// }
// } else if (mode === RenderMode.DETAILS) {
// return `${
// this.toString()
// }{|}${
// this.status
// }\nDETAILS\nDETAILS`
// }
// }
}
// const task =

View File

@ -0,0 +1,34 @@
import ipc from 'node-ipc';
import {
IPC_CLIENT_CONNECT_NAME,
IPC_CLIENT_APPSAPCE,
IPC_QUIT_EVENT,
IPC_RESTART_EVENT
} from './Constants.js';
const name = IPC_CLIENT_CONNECT_NAME;
ipc.config.appspace = IPC_CLIENT_APPSAPCE;
ipc.config.silent = true;
let connected = false;
ipc.connectTo(name, () => {
ipc.of[name].on('connect', () => connected = true);
ipc.of[name].on('disconnect', () => connected = false);
});
export function quit() {
if (connected) {
ipc.of[name].emit(IPC_QUIT_EVENT);
} else {
process.exit(0);
}
}
export function restart() {
if (connected) {
ipc.of[name].emit(IPC_RESTART_EVENT);
} else {
process.exit(1);
}
}

View File

@ -1,9 +1,8 @@
import { getTheme } from '@themes';
import { Serializable } from 'frigid';
import { Task, TaskState } from './registries/Tasks.js';
import { render, Renderable, panels } from '@ui';
export class TaskList extends Serializable implements Renderable {
export class TaskList extends Serializable {
tasks: TaskState<unknown, unknown>[] = [];
clear() {
@ -34,13 +33,11 @@ export class TaskList extends Serializable implements Renderable {
}
render() {
// const width = tasksPanel.width;
panels.left.setContent(`${this.tasks.map(task => `${
getTheme().normal(task.toString())
} ${
getTheme().dimmed(task.worker?.toString() ?? '')
}`).join('\n')}`);
return '';
// return this.tasks.map(task => task.toString()).join('\n');
// panels.left.setContent(`${this.tasks.map(task => `${
// getTheme().normal(task.toString())
// } ${
// getTheme().dimmed(task.worker?.toString() ?? '')
// }`).join('\n')}`);
// return '';
}
}

View File

@ -1,7 +1,6 @@
import chalk from "chalk";
import { Serializable } from "frigid";
import { getTheme } from "@themes";
import { Renderable } from "@ui";
type AbbreviatedMonthName = string;
@ -19,7 +18,7 @@ const months: AbbreviatedMonthName[] = [
'Oct', 'Nov', 'Dec'
]
export default class Time extends Serializable implements Renderable {
export default class Time extends Serializable {
rate: number;
paused = true;

View File

@ -1,7 +1,33 @@
import { lstatSync } from 'fs';
import { parse, resolve } from 'path';
import walkSync from 'walk-sync';
import { fileURLToPath } from 'url';
import { APPLICATION_NAME } from './Constants.js';
export function osrsNumber(x: number): string {
if(x < 10_000) return '' + x;
else if (x < 10_000_000) return Math.floor(x / 1000) + 'K';
else return Math.floor(x / 1_000_000) + 'M';
}
}
export async function loadExtensions() {
console.log(APPLICATION_NAME + ': Loading extensions');
const extensionsPath = resolve(parse(fileURLToPath(import.meta.url)).dir, '../content');
const extensions = walkSync(extensionsPath)
.map(path => [path, resolve(extensionsPath, path)])
.filter(path => lstatSync(path[1]).isFile())
.filter(path => parse(path[1]).ext === '.js');
console.log('found', extensions.length, 'extensions');
for (const path of extensions) {
console.log('=== [', path[0], '] ===');
await import(path[1]);
console.log();
}
console.log('Setup Complete.');
}
// export function

76
src/hot-index.ts 100644
View File

@ -0,0 +1,76 @@
import ipc from 'node-ipc';
import {
IPC_PATH,
IPC_QUIT_EVENT,
IPC_RESTART_EVENT
} from './Constants.js';
import { spawn, ChildProcess } from 'child_process';
import watch from 'watch';
ipc.config.silent = true;
const exec = 'qode';
const args = [
...process.execArgv,
'out/src/index.js'
]
ipc.serve(IPC_PATH, () => {
ipc.server.on(IPC_QUIT_EVENT, async () => {
await killProcess();
ipc.server.stop();
process.exit(0);
});
ipc.server.on(IPC_RESTART_EVENT, restart)
});
ipc.server.start();
let proc: ChildProcess = null;
function startProcess() {
console.log('starting process...');
proc = spawn(exec, args, {
stdio: 'inherit'
});
proc.on('exit', () => {
console.log('process died');
proc = null;
})
}
async function killProcess() {
if(proc) {
console.log('killing process...');
const killedPromise = new Promise((res) => {
proc.on('exit', () => {
res(void 0);
})
})
proc.kill();
await killedPromise;
proc = null;
}
}
async function restart() {
await killProcess();
startProcess();
}
startProcess();
let restartTimer: NodeJS.Timeout = null;
function fileChange() {
console.log('changes detected');
// appendFileSync('log.log', evt + ' ' + path + '\n');
// console.log(cluster.isMaster, evt, path);
if(restartTimer) clearTimeout(restartTimer)
restartTimer = setTimeout(() => {
restart();
restartTimer = null;
}, 1000);
}
// chokidar.watch('./out').on('all', fileChange);
watch.watchTree('./out', fileChange);

View File

@ -1,74 +1,58 @@
import { ensureDirSync } from 'fs-extra';
import { appendFileSync, lstatSync } from 'fs';
import { parse, resolve } from 'path';
import walkSync from 'walk-sync';
import { fileURLToPath } from 'url';
import { parse } from 'path';
import { Game } from '@game';
import { isStarted, stop, render } from '@ui';
import { writeFileSync } from 'fs';
import {
isStarted,
stop,
update,
GameView,
setView,
start
} from '@ui';
import ansi from 'sisteransi';
import cluster from 'cluster';
if(cluster.isMaster) cluster.setupMaster();
import { setInitialize, start } from './Clustering.js';
setInitialize(begin);
// HACK static extension loading
import './../content/content.js';
import { loadExtensions } from './Util.js';
import { APPLICATION_NAME } from './Constants.js';
// console.clear();
function gracefulShutdown() {
if (isStarted()) {
stop();
}
console.log('shutting down gracefully...');
if (Game.current) {
console.log('saving world...');
Game.current.sync();
}
console.log('exitting');
process.stdout.write(ansi.cursor.show);
process.exit(0);
}
process.on('exit', gracefulShutdown);
const saveFile = process.argv[2] || 'data/world01.json';
ensureDirSync(parse(saveFile).dir);
// loadExtensions();
for (let seconds = 0; seconds > 0; seconds--) {
process.stdout.write('Starting ' + APPLICATION_NAME + ' in ' + seconds + '\r');
await new Promise(res => setTimeout(res, 1000));
}
process.stdout.write('Starting ' + APPLICATION_NAME + ' in ' + 0 + '\n');
// console.clear();
// TODO move render logic into game, so that the ui doesnt exist until the game does...
// maybe, i mean, an argument could be made for not that, because the game
// isnt necessarily the entire thing, its just one instance of a save file.
// But probably the initial menu screens will be their own thing entirely.
const game = Game.create(saveFile);
start();
async function begin() {
console.clear();
function gracefulShutdown() {
if (isStarted()) {
stop();
}
console.log('shutting down gracefully...');
if (Game.current) {
console.log('saving world...');
Game.current.sync();
}
console.log('exitting');
process.stdout.write(ansi.cursor.show);
process.exit(0);
}
process.on('exit', gracefulShutdown);
const saveFile = process.argv[2] || 'data/world01.json';
ensureDirSync(parse(saveFile).dir);
// TODO extract extension loading into separate file
console.log('df-idle: Loading extensions');
const extensionsPath = resolve(parse(fileURLToPath(import.meta.url)).dir, '../content');
const extensions = walkSync(extensionsPath)
.map(path => [path, resolve(extensionsPath, path)])
.filter(path => lstatSync(path[1]).isFile())
.filter(path => parse(path[1]).ext === '.js');
console.log('found', extensions.length, 'extensions');
for (const path of extensions) {
console.log('=== [', path[0], '] ===');
await import(path[1]);
console.log();
}
console.log('Setup Complete.');
for (let seconds = 2; seconds > 0; seconds--) {
process.stdout.write('Starting DF-Idle in ' + seconds + '\r');
await new Promise(res => setTimeout(res, 1000));
}
console.clear();
// TODO move render logic into game, so that the ui doesnt exist until the game does...
// maybe, i mean, an argument could be made for not that, because the game
// isnt necessarily the entire thing, its just one instance of a save file.
// But probably the initial menu screens will be their own thing entirely.
const game = Game.create(saveFile);
}
const gameView = new GameView(game);
setView(gameView);

38
src/qt/GameView.ts 100644
View File

@ -0,0 +1,38 @@
import { Game } from '@game';
import { QLabel, QWidget } from '@nodegui/nodegui';
import { View } from './View.js';
// 40x30
const w = 40;
const h = 30;
export class GameView extends View {
game: Game;
title: QLabel;
left: QWidget;
right: QWidget;
addComponents(): void {
this.addLayout();
this.title = new QLabel();
this.left = new QWidget();
this.right = new QWidget();
this.title.setText(this.game.name);
this.left.setInlineStyle('border: 1px solid white;')
this.right.setInlineStyle('border: 1px solid white;')
// this.layout.addWidget(this.left, 1, 0, 29, 20);
// this.layout.addWidget(this.right, 1, 21, 29, 20);
this.layout.addWidget(this.title, 0, 0, 1, w);
this.layout.addWidget(this.left, 1, 0, h - 1, w / 2);
this.layout.addWidget(this.right, 1, w / 2, h - 1, w / 2);
}
constructor(game: Game) {
super();
this.game = game;
}
}

View File

@ -0,0 +1,18 @@
import { QGridLayout, QLabel, QWidget } from "@nodegui/nodegui";
import { View } from "./View.js";
export class LoadingView extends View {
label: QLabel;
addComponents(): void {
this.addLayout();
this.label = new QLabel();
this.label.setText('Loading World...');
this.layout.addWidget(this.label);
}
destory() {
}
}

5
src/qt/Popup.ts 100644
View File

@ -0,0 +1,5 @@
export class Popup {
static show(content: string) {
}
}

18
src/qt/View.ts 100644
View File

@ -0,0 +1,18 @@
import { QGridLayout, QMainWindow, QWidget } from "@nodegui/nodegui";
import { win } from "@ui";
export abstract class View {
root: QWidget;
layout: QGridLayout;
addLayout() {
this.root = new QWidget();
this.root.setObjectName("root");
win.setCentralWidget(this.root);
this.layout = new QGridLayout();
this.root.setLayout(this.layout);
}
abstract addComponents(): void;
}

View File

@ -0,0 +1,74 @@
import {
QMainWindow, WidgetEventTypes
} from '@nodegui/nodegui';
import { APPLICATION_NAME } from '../Constants.js';
import { LoadingView } from './LoadingView.js';
import { View } from './View.js';
export { GameView } from './GameView.js';
export { Popup } from './Popup.js';
export const win = new QMainWindow();
win.setFixedSize(800, 600);
win.setWindowTitle(APPLICATION_NAME);
win.setStyleSheet(`
#root {
background-color: black;
height: '100%';
}
QPushButton {
background: #333333;
}
QPushButton:pressed {
background: cyan;
color: black;
}
* {
font-family: 'MxPlus IBM VGA 8x16';
font-size: 16px;
}
`);
win.show();
(global as any).win = win;
win.addEventListener(WidgetEventTypes.Paint, _ => _);
win.addEventListener(WidgetEventTypes.UpdateRequest, () => {
console.log('sdfghj');
});
win.addEventListener('customContextMenuRequested', console.log)
win.addEventListener('objectNameChanged', console.log)
win.addEventListener('windowIconChanged', console.log)
win.addEventListener('windowTitleChanged', console.log)
setView(new LoadingView());
export function start() {
}
export function stop() {
win.close();
}
export function setView(view: View) {
view.addComponents();
}
export function setTitle(title: string) {
}
export function update() {
}
export function isStarted() {
return win.isVisible();
}
// HACK this is bullshit, :)
function f() {
win.repaint();
win.update();
setTimeout(f, 100);
}
f();

View File

@ -1,54 +0,0 @@
import {
QMainWindow,
QWidget,
QGridLayout,
QPushButton
} from '@nodegui/nodegui';
import chokidar from 'chokidar';
import cluster from 'cluster';
import { watchFile } from 'fs';
if (cluster.isMaster) cluster.setupMaster();
import { setInitialize, start } from '../Clustering.js';
setInitialize(() => {
const win = new QMainWindow();
win.setFixedSize(800, 600);
win.setWindowTitle("Hello World");
const centralWidget = new QWidget();
centralWidget.setObjectName("myroot");
win.setCentralWidget(centralWidget);
const rootLayout = new QGridLayout();
// rootLayout.addWidget
centralWidget.setLayout(rootLayout);
const button = new QPushButton();
button.setText('Testing Font Family');
rootLayout.addWidget(button);
win.setStyleSheet(`
#myroot {
background-color: black;
height: '100%';
}
QPushButton {
background: #333333;
}
QPushButton:pressed {
background: cyan;
color: black;
}
* {
font-family: 'MxPlus IBM VGA 8x16';
font-size: 16px;
}
`);
win.show();
});
start();

View File

@ -1,6 +1,5 @@
import { Serializable } from 'frigid';
import { getTheme } from '@themes';
import { Renderable } from '@ui';
import { osrsNumber } from '../Util.js';
export type ItemID = string;
@ -53,7 +52,7 @@ export class Item<Data = any> {
}
}
export class ItemState<Data> extends Serializable implements Renderable {
export class ItemState<Data> extends Serializable {
qty: number;
itemId: ItemID;
data: Data;

View File

@ -2,7 +2,7 @@ import { Game } from "@game";
import { boxStyle, getTheme } from "@themes";
import { panels } from "./UI.js";
import blessed from 'neo-blessed';
import { quit, restart } from "../Clustering.js";
import { quit, restart } from "../ProcessManager.js";
// TODO convert all these popup-y things to be View based
// make them be boxes that have a view

15
test.js
View File

@ -1,15 +0,0 @@
// test
//asdf
//asdasd
/changes?
sdfasfd
fdsd
hddhfbgdfkljfkfdskljkdlkjdlfkjs

View File

@ -13,7 +13,7 @@
"@tasks": ["./src/registries/Tasks"],
"@items": ["./src/registries/Items"],
"@world": ["./src/World"],
"@ui": ["./src/qt/index.js"],
"@ui": ["./src/qt/index"],
"@game": ["./src/Game"]
},
"noImplicitAny": true

102
yarn.lock
View File

@ -250,6 +250,13 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.2.tgz#91daa226eb8c2ff261e6a8cbf8c7304641e095e0"
integrity sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==
"@types/node-ipc@^9.1.5":
version "9.1.5"
resolved "https://registry.yarnpkg.com/@types/node-ipc/-/node-ipc-9.1.5.tgz#0f9dac03fe6c96b6ff379725faf20d8a97eb00fa"
integrity sha512-xxYUVj/Y8fNkxQlvndVeWlL99wAF4KwISsRy21RSAAT/SKyrh+X3/BZXHcM/ZJPNri9h1JWw58wDKT1zr2pXVw==
dependencies:
"@types/node" "*"
"@types/node@*":
version "15.12.2"
resolved "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz"
@ -885,6 +892,19 @@ cookies@~0.8.0:
depd "~2.0.0"
keygrip "~1.1.0"
copyfiles@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==
dependencies:
glob "^7.0.5"
minimatch "^3.0.3"
mkdirp "^1.0.4"
noms "0.0.0"
through2 "^2.0.1"
untildify "^4.0.0"
yargs "^16.1.0"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -1095,6 +1115,11 @@ dynamic-dedupe@^0.3.0:
dependencies:
xtend "^4.0.0"
easy-stack@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066"
integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -1172,6 +1197,14 @@ etag@^1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
event-pubsub@5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-5.0.3.tgz#ce2855b2c1ef4abb139e482f09146f61d4b712c3"
integrity sha512-2QiHxshejKgJrYMzSI9MEHrvhmzxBL+eLyiM5IiyjDBySkgwS2+tdtnO3gbx8pEisu/yOFCIhfCb63gCEu0yBQ==
dependencies:
copyfiles "^2.4.0"
strong-type "^0.1.3"
exec-sh@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36"
@ -1347,7 +1380,7 @@ glob-parent@~5.1.0, glob-parent@~5.1.2:
dependencies:
is-glob "^4.0.1"
glob@7.1.7, glob@^7.1.3:
glob@7.1.7, glob@^7.0.5, glob@^7.1.3:
version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
@ -1500,7 +1533,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -1696,6 +1729,18 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
js-message@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47"
integrity sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==
js-queue@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/js-queue/-/js-queue-2.0.2.tgz#0be590338f903b36c73d33c31883a821412cd482"
integrity sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==
dependencies:
easy-stack "^1.0.1"
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -1951,7 +1996,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4:
minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@ -2000,7 +2045,7 @@ minizlib@^2.1.1:
dependencies:
minimist "^1.2.5"
mkdirp@^1.0.3:
mkdirp@^1.0.3, mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@ -2105,6 +2150,16 @@ node-fetch@^2.6.0, node-fetch@^2.6.1:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-ipc@^10.0.2:
version "10.0.2"
resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-10.0.2.tgz#4d95affc16cef45f1675eddea26bd3b24e01ad21"
integrity sha512-YIHWoXxyAGE5HHhOpxNhcBd+6/ZwlQRB6N5ukiJR22CHhDyFlPkQl2Di/D3Eghn9AzgqiSPCdo38Nj670ELbaA==
dependencies:
event-pubsub "5.0.3"
js-message "1.0.7"
js-queue "2.0.2"
strong-type "^1.0.1"
node-notifier@^8.0.1:
version "8.0.2"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5"
@ -2133,6 +2188,14 @@ nodemon@^2.0.7:
undefsafe "^2.0.3"
update-notifier "^4.1.0"
noms@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859"
integrity sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=
dependencies:
inherits "^2.0.1"
readable-stream "~1.0.31"
nopt@~1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
@ -2370,7 +2433,7 @@ rc@^1.2.7, rc@^1.2.8:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2:
"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@ -2383,7 +2446,7 @@ rc@^1.2.7, rc@^1.2.8:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@~1.0.26-2:
readable-stream@~1.0.26-2, readable-stream@~1.0.31:
version "1.0.34"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
@ -2674,6 +2737,16 @@ strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
strong-type@^0.1.3:
version "0.1.6"
resolved "https://registry.yarnpkg.com/strong-type/-/strong-type-0.1.6.tgz#663bf8dadf533ce61e42683eb6d6711e8795cf83"
integrity sha512-eJe5caH6Pi5oMMeQtIoBPpvNu/s4jiyb63u5tkHNnQXomK+puyQ5i+Z5iTLBr/xUz/pIcps0NSfzzFI34+gAXg==
strong-type@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strong-type/-/strong-type-1.1.0.tgz#8ab8feb3a26c37fa389c52a04581ffb53c7d3a29"
integrity sha512-X5Z6riticuH5GnhUyzijfDi1SoXas8ODDyN7K8lJeQK+Jfi4dKdoJGL4CXTskY/ATBcN+rz5lROGn1tAUkOX7g==
supervisor@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/supervisor/-/supervisor-0.12.0.tgz#de7e6337015b291851c10f3538c4a7f04917ecc1"
@ -2746,6 +2819,14 @@ term-size@^2.1.0:
resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
through2@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
dependencies:
readable-stream "~2.3.6"
xtend "~4.0.1"
thunky@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
@ -2854,6 +2935,11 @@ universalify@^2.0.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
untildify@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
unzipper@^0.8.13:
version "0.8.14"
resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.8.14.tgz#ade0524cd2fc14d11b8de258be22f9d247d3f79b"
@ -3039,7 +3125,7 @@ xdg-basedir@^4.0.0:
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
xtend@^4.0.0:
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
@ -3084,7 +3170,7 @@ yargs-unparser@2.0.0:
flat "^5.0.2"
is-plain-obj "^2.1.0"
yargs@16.2.0:
yargs@16.2.0, yargs@^16.1.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==