From 6f6c84dc4667380cdb9679242a5c50b804e39b61 Mon Sep 17 00:00:00 2001 From: Lino Schmidt Date: Mon, 13 Jun 2022 01:15:17 +0200 Subject: [PATCH] added webpack dev server, slightly improved ui and render preview --- .gitignore | 5 +- assets/blenderScript.py | 308 ++++---- configs/webpack.base.config.js | 1 - configs/webpack.main.dev.config.babel.js | 11 + ...l.js => webpack.main.prod.config.babel.js} | 3 +- configs/webpack.renderer.dev.config.babel.js | 31 + ... => webpack.renderer.prod.config.babel.js} | 1 + package-lock.json | 706 +++--------------- package.json | 53 +- src/components/blender-controller.ts | 145 ++++ src/components/paths.ts | 2 +- src/components/render.ts | 43 -- src/components/ui/mainSide.tsx | 24 +- src/components/ui/menu.tsx | 50 +- src/components/ui/settingsSide.tsx | 77 +- src/index.css | 90 ++- src/index.html | 9 +- src/index.ts | 14 +- src/renderer.tsx | 18 +- 19 files changed, 722 insertions(+), 869 deletions(-) create mode 100644 configs/webpack.main.dev.config.babel.js rename configs/{webpack.main.config.babel.js => webpack.main.prod.config.babel.js} (77%) create mode 100644 configs/webpack.renderer.dev.config.babel.js rename configs/{webpack.renderer.config.babel.js => webpack.renderer.prod.config.babel.js} (91%) create mode 100644 src/components/blender-controller.ts delete mode 100644 src/components/render.ts diff --git a/.gitignore b/.gitignore index fc36099..139f4f7 100644 --- a/.gitignore +++ b/.gitignore @@ -264,4 +264,7 @@ out/ output/ blender-win/ -blender-linux/ \ No newline at end of file +blender-linux/ +blender/ + +index.build.js \ No newline at end of file diff --git a/assets/blenderScript.py b/assets/blenderScript.py index a6ac899..314cf42 100644 --- a/assets/blenderScript.py +++ b/assets/blenderScript.py @@ -1,16 +1,15 @@ +from ast import Str import csv -from importlib.resources import path import logging import math import sys +import time import bpy import xml.etree.ElementTree as ET argv = sys.argv argv = argv[argv.index("--") + 1:] -settings = ET.parse(argv[0]) - logger = logging.getLogger('simple_example') logger.setLevel(logging.INFO) formatter = logging.Formatter('%(message)s') @@ -19,20 +18,16 @@ console_handler.setFormatter(formatter) console_handler.setLevel(logging.INFO) logger.addHandler(console_handler) -def _map(x, in_min, in_max, out_min, out_max): - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min +GimbalL = bpy.data.objects["GimbalL"] +StickL = bpy.data.objects["StickL"] +GimbalR = bpy.data.objects["GimbalR"] +StickR = bpy.data.objects["StickR"] +GimbalCoverR = bpy.data.objects["GimbalCoverR"] +TrailR = bpy.data.objects["TrailR"] +Camera = bpy.data.objects["Camera"] +Plane = bpy.data.objects["Plane.001"] +scn = bpy.context.scene -settingsRoot = settings.getroot() - -FPS = int(settingsRoot[0].text) -Width = int(settingsRoot[1].text) -StickDistance = _map(int(settingsRoot[2].text), 0, 100, 5, 105) -StickMode = settingsRoot[3].text -if(StickMode == "true"): - StickMode = 2 -else: - StickMode = 1 - lyMax = 0.436 lyMin = -0.436 lxMax = -0.436 @@ -41,128 +36,175 @@ ryMax = -0.436 ryMin = 0.436 rxMax = 0.436 rxMin = -0.436 - -logs = settingsRoot[4].text[1:][:-1].split("\"\"") -logCount = len(logs) -logNumber = 1 +def _map(x, in_min, in_max, out_min, out_max): + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min -for log in logs: - logger.info("Lognr:" + ((str)(logNumber)) + ":") +logger.info("Blender started successfully!") + +while True: + command = input("Waiting for command: ") - logTime = [] - rud = [] - ele = [] - thr = [] - ail = [] + time.sleep(0.5) - try: - with open(log, newline='') as csvFile: - reader = csv.DictReader(csvFile) - for row in reader: - logTime.append(row['Time'].split(":").pop(2).replace(".", "")) - rud.append(int(row['Rud'])) - ele.append(int(row['Ele'])) - thr.append(int(row['Thr'])) - ail.append(int(row['Ail'])) + settingsRoot = ET.parse(argv[0]+"/settings.xml").getroot() + + StickMode = settingsRoot[3].text + if(StickMode == "true"): + StickMode = 2 + else: + StickMode = 1 + + fps = int(settingsRoot[0].text) + width = int(settingsRoot[1].text) + StickDistance = _map(int(settingsRoot[2].text), 0, 100, 5, 105) + logs = settingsRoot[4].text[1:][:-1].split("\"\"") + output = settingsRoot[5].text + + if(command == "startRendering"): - meanTime = [] - i = 0 - while i < len(logTime)-1: - if int(logTime[i]) > int(logTime[i+1]): - meanTime.append(60000 - int(logTime[i]) + int(logTime[i+1])) - else: - meanTime.append(int(logTime[i+1]) - int(logTime[i])) - i+=1 + logCount = len(logs) + logNumber = 1 - totalTime = 0 - for e in meanTime: - totalTime+=e - - frameCount = math.floor(totalTime/1000*FPS-1) - FPSxxx = 1000/FPS - except Exception as e: - print("Can't read Log!") - exit() - - GimbalL = bpy.data.objects["GimbalL"] - StickL = bpy.data.objects["StickL"] - GimbalR = bpy.data.objects["GimbalR"] - StickR = bpy.data.objects["StickR"] - GimbalCoverR = bpy.data.objects["GimbalCoverR"] - TrailR = bpy.data.objects["TrailR"] - Camera = bpy.data.objects["Camera"] - Plane = bpy.data.objects["Plane.001"] - scn = bpy.context.scene - - scn.render.resolution_x = Width - GimbalCoverR.location[0] = StickDistance - GimbalR.location[0] = StickDistance - TrailR.location[0] = StickDistance - Plane.location[0] = StickDistance - Camera.location[0] = StickDistance/2 - Camera.data.ortho_scale = StickDistance+5 - scn.render.resolution_y = int(Width/_map(StickDistance, 5, 105, 2, 21.6)) - bpy.context.scene.render.filepath = settingsRoot[5].text + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", ".mov") - - scn.render.fps = 1000 - scn.render.fps_base = FPSxxx - - scn.frame_start = 0 - scn.frame_end = frameCount+1 - logger.info("Frames:" + str(frameCount+1) + ":") - - frame = 0 - log = 0 - pastTime = 0 - while frame <= frameCount: - currentTime = math.floor(FPSxxx*frame) - while currentTime >= pastTime+meanTime[log]: - pastTime+=meanTime[log] - log+=1 + for log in logs: + logger.info("Lognr:" + ((str)(logNumber)) + ":") - multiplier = (currentTime-pastTime)/meanTime[log] - - ailP = _map(ail[log]+(ail[log+1]-ail[log])*multiplier, -1024, 1024, rxMin, rxMax) - eleP = _map(ele[log]+(ele[log+1]-ele[log])*multiplier, -1024, 1024, ryMin, ryMax) - rudP = _map(rud[log]+(rud[log+1]-rud[log])*multiplier, -1024, 1024, lyMin, lyMax) - thrP = _map(thr[log]+(thr[log+1]-thr[log])*multiplier, -1024, 1024, lxMin, lxMax) - - bpy.context.scene.frame_set(frame) - - if StickMode == "1": - StickL.rotation_euler=[0,0,0] - StickL.rotation_euler.rotate_axis("Y", ailP) - StickL.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalL.rotation_euler=[0,0,0] - GimbalL.rotation_euler.rotate_axis("X", eleP) - GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) - StickR.rotation_euler=[0,0,0] - StickR.rotation_euler.rotate_axis("Y", rudP) - StickR.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalR.rotation_euler=[0,0,0] - GimbalR.rotation_euler.rotate_axis("X", thrP) - GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) - else: - StickL.rotation_euler=[0,0,0] - StickL.rotation_euler.rotate_axis("Y", rudP) - StickL.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalL.rotation_euler=[0,0,0] - GimbalL.rotation_euler.rotate_axis("X", thrP) - GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) - StickR.rotation_euler=[0,0,0] - StickR.rotation_euler.rotate_axis("Y", ailP) - StickR.keyframe_insert(data_path="rotation_euler", index=-1) - GimbalR.rotation_euler=[0,0,0] - GimbalR.rotation_euler.rotate_axis("X", eleP) - GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) - - logger.info("Init:" + ((str)(frame)) + ":") - frame+=1 + logTime = [] + rud = [] + ele = [] + thr = [] + ail = [] + + try: + with open(log, newline='') as csvFile: + reader = csv.DictReader(csvFile) + for row in reader: + logTime.append(row['Time'].split(":").pop(2).replace(".", "")) + rud.append(int(row['Rud'])) + ele.append(int(row['Ele'])) + thr.append(int(row['Thr'])) + ail.append(int(row['Ail'])) + + meanTime = [] + i = 0 + while i < len(logTime)-1: + if int(logTime[i]) > int(logTime[i+1]): + meanTime.append(60000 - int(logTime[i]) + int(logTime[i+1])) + else: + meanTime.append(int(logTime[i+1]) - int(logTime[i])) + i+=1 + + totalTime = 0 + for e in meanTime: + totalTime+=e + + frameCount = math.floor(totalTime/1000*fps-1) + FPSxxx = 1000/fps + except Exception as e: + logger.error("Can't read Log: " + (Str)(e)) + + bpy.context.scene.render.image_settings.file_format = 'FFMPEG' + bpy.context.scene.render.ffmpeg.format = "QUICKTIME" + bpy.context.scene.render.ffmpeg.codec = "QTRLE" + + scn.render.resolution_x = width + GimbalCoverR.location[0] = StickDistance + GimbalR.location[0] = StickDistance + TrailR.location[0] = StickDistance + Plane.location[0] = StickDistance + Camera.location[0] = StickDistance/2 + Camera.data.ortho_scale = StickDistance+5 + scn.render.resolution_y = int(width/_map(StickDistance, 5, 105, 2, 21.6)) + bpy.context.scene.render.filepath = output + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", ".mov") + + scn.render.fps = 1000 + scn.render.fps_base = FPSxxx + + scn.frame_start = 0 + scn.frame_end = frameCount + logger.info("Frames:" + str(frameCount) + ":") + + frame = 0 + log = 0 + pastTime = 0 + while frame <= frameCount: + currentTime = math.floor(FPSxxx*frame) + while currentTime >= pastTime+meanTime[log]: + pastTime+=meanTime[log] + log+=1 + + multiplier = (currentTime-pastTime)/meanTime[log] + + ailP = _map(ail[log]+(ail[log+1]-ail[log])*multiplier, -1024, 1024, rxMin, rxMax) + eleP = _map(ele[log]+(ele[log+1]-ele[log])*multiplier, -1024, 1024, ryMin, ryMax) + rudP = _map(rud[log]+(rud[log+1]-rud[log])*multiplier, -1024, 1024, lyMin, lyMax) + thrP = _map(thr[log]+(thr[log+1]-thr[log])*multiplier, -1024, 1024, lxMin, lxMax) + + bpy.context.scene.frame_set(frame) + + if StickMode == "1": + StickL.rotation_euler=[0,0,0] + StickL.rotation_euler.rotate_axis("Y", ailP) + StickL.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalL.rotation_euler=[0,0,0] + GimbalL.rotation_euler.rotate_axis("X", eleP) + GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) + StickR.rotation_euler=[0,0,0] + StickR.rotation_euler.rotate_axis("Y", rudP) + StickR.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalR.rotation_euler=[0,0,0] + GimbalR.rotation_euler.rotate_axis("X", thrP) + GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) + else: + StickL.rotation_euler=[0,0,0] + StickL.rotation_euler.rotate_axis("Y", rudP) + StickL.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalL.rotation_euler=[0,0,0] + GimbalL.rotation_euler.rotate_axis("X", thrP) + GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) + StickR.rotation_euler=[0,0,0] + StickR.rotation_euler.rotate_axis("Y", ailP) + StickR.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalR.rotation_euler=[0,0,0] + GimbalR.rotation_euler.rotate_axis("X", eleP) + GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) + + logger.info("Init:" + ((str)(frame)) + ":") + frame+=1 + + bpy.ops.render.render(animation=True) + + if(logCount <= logNumber): + logger.info("Finished") + + logNumber+=1 - bpy.ops.render.render(animation=True) - - if(logCount <= logNumber): - logger.info("Finished") - - logNumber+=1 + elif(command == "getRender"): + + bpy.context.scene.render.image_settings.file_format = 'PNG' + bpy.context.scene.frame_set(0) + bpy.context.scene.render.filepath = argv[0] + "\\render.png" + + scn.render.resolution_x = width + GimbalCoverR.location[0] = StickDistance + GimbalR.location[0] = StickDistance + TrailR.location[0] = StickDistance + Plane.location[0] = StickDistance + Camera.location[0] = StickDistance/2 + Camera.data.ortho_scale = StickDistance+5 + scn.render.resolution_y = int(width/_map(StickDistance, 5, 105, 2, 21.6)) + + StickL.rotation_euler=[0,0,0] + StickL.rotation_euler.rotate_axis("Y", 0.436) + StickL.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalL.rotation_euler=[0,0,0] + GimbalL.rotation_euler.rotate_axis("X", 0.236) + GimbalL.keyframe_insert(data_path="rotation_euler", index=-1) + StickR.rotation_euler=[0,0,0] + StickR.rotation_euler.rotate_axis("Y", -0.056) + StickR.keyframe_insert(data_path="rotation_euler", index=-1) + GimbalR.rotation_euler=[0,0,0] + GimbalR.rotation_euler.rotate_axis("X", -0.436) + GimbalR.keyframe_insert(data_path="rotation_euler", index=-1) + + bpy.ops.render.render(write_still=True) \ No newline at end of file diff --git a/configs/webpack.base.config.js b/configs/webpack.base.config.js index f6af6b1..0028aca 100644 --- a/configs/webpack.base.config.js +++ b/configs/webpack.base.config.js @@ -3,7 +3,6 @@ import ESLintPlugin from "eslint-webpack-plugin"; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; export default { - mode: 'production', module: { rules: [ { diff --git a/configs/webpack.main.dev.config.babel.js b/configs/webpack.main.dev.config.babel.js new file mode 100644 index 0000000..b2f3d76 --- /dev/null +++ b/configs/webpack.main.dev.config.babel.js @@ -0,0 +1,11 @@ +import baseConfig from "./webpack.base.config.js"; +import {merge} from 'webpack-merge'; + +export default merge(baseConfig, { + mode: 'development', + target: 'electron-main', + entry: './src/index.ts', + output: { + filename: '../index.build.js' + }, +}); \ No newline at end of file diff --git a/configs/webpack.main.config.babel.js b/configs/webpack.main.prod.config.babel.js similarity index 77% rename from configs/webpack.main.config.babel.js rename to configs/webpack.main.prod.config.babel.js index 758737f..b8266f6 100644 --- a/configs/webpack.main.config.babel.js +++ b/configs/webpack.main.prod.config.babel.js @@ -2,9 +2,10 @@ import baseConfig from "./webpack.base.config.js"; import {merge} from 'webpack-merge'; export default merge(baseConfig, { + mode: 'production', target: 'electron-main', entry: './src/index.ts', output: { - filename: 'index.js' + filename: '../index.build.js' }, }); \ No newline at end of file diff --git a/configs/webpack.renderer.dev.config.babel.js b/configs/webpack.renderer.dev.config.babel.js new file mode 100644 index 0000000..a75321d --- /dev/null +++ b/configs/webpack.renderer.dev.config.babel.js @@ -0,0 +1,31 @@ +import baseConfig from "./webpack.base.config.js"; +import {merge} from 'webpack-merge'; +import { spawn } from 'child_process'; + +const host = process.env.HOST || 'localhost'; +const port = process.env.PORT || 3000; + +export default merge(baseConfig, { + mode: 'development', + target: 'electron-renderer', + entry: './src/renderer.tsx', + output: { + filename: 'renderer.js', + }, + devServer: { + compress: true, + hot: true, + host, + port, + onBeforeSetupMiddleware() { + console.log('Starting Main Process...'); + spawn('npm', ['run', 'start:main'], { + shell: true, + env: process.env, + stdio: 'inherit', + }) + .on('close', (code) => process.exit(code)) + .on('error', (spawnError) => console.error(spawnError)); + }, + }, +}); \ No newline at end of file diff --git a/configs/webpack.renderer.config.babel.js b/configs/webpack.renderer.prod.config.babel.js similarity index 91% rename from configs/webpack.renderer.config.babel.js rename to configs/webpack.renderer.prod.config.babel.js index 5c5587c..60c9d7a 100644 --- a/configs/webpack.renderer.config.babel.js +++ b/configs/webpack.renderer.prod.config.babel.js @@ -2,6 +2,7 @@ import baseConfig from "./webpack.base.config.js"; import {merge} from 'webpack-merge'; export default merge(baseConfig, { + mode: 'production', target: 'electron-renderer', entry: './src/renderer.tsx', output: { diff --git a/package-lock.json b/package-lock.json index 5678133..9d5eef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@electron/remote": "^2.0.8", "electron-log": "^4.4.7", "electron-squirrel-startup": "^1.0.0", + "electron-updater": "^5.0.1", "react": "^18.1.0", "react-dom": "^18.1.0", "xml-formatter": "^2.6.1" @@ -32,6 +33,7 @@ "@typescript-eslint/parser": "^5.27.0", "@vercel/webpack-asset-relocator-loader": "^1.7.2", "babel-loader": "^8.2.5", + "cross-env": "^7.0.3", "css-loader": "^6.7.1", "electron": "18.1.0", "electron-builder": "^23.0.3", @@ -41,7 +43,6 @@ "eslint-plugin-react-hooks": "^4.5.0", "eslint-webpack-plugin": "^3.1.1", "fork-ts-checker-webpack-plugin": "^7.2.11", - "html-webpack-plugin": "^5.5.0", "node-loader": "^2.0.0", "sass": "^1.52.1", "sass-loader": "^13.0.0", @@ -2536,12 +2537,6 @@ "@types/node": "*" } }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, "node_modules/@types/http-proxy": { "version": "1.17.9", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", @@ -2654,6 +2649,11 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==" + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -3361,8 +3361,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { "version": "1.1.1", @@ -3766,12 +3765,6 @@ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, "node_modules/boolean": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", @@ -3961,7 +3954,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.0.tgz", "integrity": "sha512-SkpEtSmTkREDHRJnxKEv43aAYp8sYWY8fxYBhGLBLOBIRXeaIp6Kv3lBgSD7uR8jQtC7CA659sqJrpSV6zNvSA==", - "dev": true, "dependencies": { "debug": "^4.3.2", "sax": "^1.2.4" @@ -4040,16 +4032,6 @@ "node": ">=6" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -4142,18 +4124,6 @@ "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", "dev": true }, - "node_modules/clean-css": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", - "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, "node_modules/cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", @@ -4538,6 +4508,24 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4587,34 +4575,6 @@ "webpack": "^5.0.0" } }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -4962,80 +4922,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -5228,6 +5114,21 @@ "integrity": "sha512-ea8Q1YX0JRp4GylOmX4gFHIizi0j9GfRW4EkaHnkZp0agRCBB4ZGeCv17IEzIvBkiYVwfoKVhKZJbTfqCRdQdg==", "dev": true }, + "node_modules/electron-updater": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.0.1.tgz", + "integrity": "sha512-dNnXPCqYmergXy3jgg4UICuD50Orug9GQe/5xfHy+BE2Fy0icB0QE+y6iQWdCDf7yeONxwMBf4HgIkGG5pIaVg==", + "dependencies": { + "@types/semver": "^7.3.6", + "builder-util-runtime": "9.0.0", + "fs-extra": "^10.0.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "lodash.escaperegexp": "^4.1.2", + "lodash.isequal": "^4.5.0", + "semver": "^7.3.5" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5273,15 +5174,6 @@ "node": ">=10.13.0" } }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -6413,7 +6305,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -6801,15 +6692,6 @@ "node": ">=8" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -6840,78 +6722,6 @@ "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", "dev": true }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", - "dev": true, - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "webpack": "^5.20.0" - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -7650,7 +7460,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -7715,7 +7524,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, "dependencies": { "universalify": "^2.0.0" }, @@ -7777,8 +7585,7 @@ "node_modules/lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "dev": true + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" }, "node_modules/levn": { "version": "0.4.1", @@ -7856,6 +7663,16 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -7873,15 +7690,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.3" - } - }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -7894,7 +7702,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -8155,16 +7962,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "node_modules/node-addon-api": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", @@ -8236,18 +8033,6 @@ "node": ">=4" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8528,16 +8313,6 @@ "semver": "bin/semver.js" } }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8559,16 +8334,6 @@ "node": ">= 0.8" } }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8839,16 +8604,6 @@ "node": ">=4" } }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -9215,28 +8970,6 @@ "jsesc": "bin/jsesc" } }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -9450,8 +9183,7 @@ "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "node_modules/scheduler": { "version": "0.22.0", @@ -9501,7 +9233,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "devOptional": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -10337,12 +10068,6 @@ "json5": "lib/cli.js" } }, - "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -10496,7 +10221,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, "engines": { "node": ">= 10.0.0" } @@ -10587,12 +10311,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -11221,8 +10939,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "1.10.2", @@ -13090,12 +12807,6 @@ "@types/node": "*" } }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, "@types/http-proxy": { "version": "1.17.9", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", @@ -13208,6 +12919,11 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", "dev": true }, + "@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==" + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -13756,8 +13472,7 @@ "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "array-flatten": { "version": "1.1.1", @@ -14065,12 +13780,6 @@ } } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, "boolean": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", @@ -14211,7 +13920,6 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.0.0.tgz", "integrity": "sha512-SkpEtSmTkREDHRJnxKEv43aAYp8sYWY8fxYBhGLBLOBIRXeaIp6Kv3lBgSD7uR8jQtC7CA659sqJrpSV6zNvSA==", - "dev": true, "requires": { "debug": "^4.3.2", "sax": "^1.2.4" @@ -14268,16 +13976,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -14334,15 +14032,6 @@ "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", "dev": true }, - "clean-css": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", - "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, "cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", @@ -14648,6 +14337,15 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -14681,25 +14379,6 @@ "semver": "^7.3.5" } }, - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -14951,62 +14630,6 @@ "esutils": "^2.0.2" } }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -15167,6 +14790,21 @@ "integrity": "sha512-ea8Q1YX0JRp4GylOmX4gFHIizi0j9GfRW4EkaHnkZp0agRCBB4ZGeCv17IEzIvBkiYVwfoKVhKZJbTfqCRdQdg==", "dev": true }, + "electron-updater": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-5.0.1.tgz", + "integrity": "sha512-dNnXPCqYmergXy3jgg4UICuD50Orug9GQe/5xfHy+BE2Fy0icB0QE+y6iQWdCDf7yeONxwMBf4HgIkGG5pIaVg==", + "requires": { + "@types/semver": "^7.3.6", + "builder-util-runtime": "9.0.0", + "fs-extra": "^10.0.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "lodash.escaperegexp": "^4.1.2", + "lodash.isequal": "^4.5.0", + "semver": "^7.3.5" + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -15203,12 +14841,6 @@ "tapable": "^2.2.0" } }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -16086,7 +15718,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -16370,12 +16001,6 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, "hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -16403,54 +16028,6 @@ "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", "dev": true }, - "html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - } - } - }, - "html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", - "dev": true, - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - } - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -16961,7 +16538,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "requires": { "argparse": "^2.0.1" } @@ -17011,7 +16587,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, "requires": { "graceful-fs": "^4.1.6", "universalify": "^2.0.0" @@ -17059,8 +16634,7 @@ "lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "dev": true + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" }, "levn": { "version": "0.4.1", @@ -17125,6 +16699,16 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -17139,15 +16723,6 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -17157,7 +16732,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, "requires": { "yallist": "^4.0.0" } @@ -17350,16 +16924,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "node-addon-api": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", @@ -17409,15 +16973,6 @@ "pify": "^3.0.0" } }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -17621,16 +17176,6 @@ } } }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -17646,16 +17191,6 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -17846,16 +17381,6 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, - "pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -18143,25 +17668,6 @@ } } }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18296,8 +17802,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "scheduler": { "version": "0.22.0", @@ -18337,7 +17842,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "devOptional": true, "requires": { "lru-cache": "^6.0.0" } @@ -18980,12 +18484,6 @@ } } }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, "tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -19100,8 +18598,7 @@ "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" }, "unpipe": { "version": "1.0.0", @@ -19176,12 +18673,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -19627,8 +19118,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.10.2", diff --git a/package.json b/package.json index 8008d27..8735941 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,15 @@ "name": "stickexportertx", "productName": "StickExporterTX", "description": "3D stick exporter for EdgeTX/OpenTX logs", - "main": "src/.webpack/index.js", + "main": "src/index.build.js", "scripts": { - "build:main": "webpack --config configs/webpack.main.config.babel.js", - "build:renderer": "webpack --config configs/webpack.renderer.config.babel.js", - "build": "npm run build:main && npm run build:renderer", - "start": "npm run build && electron .", - "build:app": "npm run build && electron-builder build" + "build:main": "cross-env NODE_ENV=production webpack --config configs/webpack.main.prod.config.babel.js", + "build:renderer": "cross-env NODE_ENV=production webpack --config configs/webpack.renderer.prod.config.babel.js", + "build": "cross-env npm run build:main && cross-env npm run build:renderer", + "bundle": "cross-env npm run build && electron-builder build", + "start:renderer": "cross-env NODE_ENV=development webpack serve --config configs/webpack.renderer.dev.config.babel.js", + "start:main": "cross-env NODE_ENV=development webpack --config configs/webpack.main.dev.config.babel.js && cross-env NODE_ENV=development electron .", + "start": "cross-env npm run start:renderer" }, "keywords": [], "author": { @@ -18,33 +20,6 @@ "url": "https://link.lino3d.de" }, "license": "MIT", - "config": { - "forge": { - "packagerConfig": {}, - "makers": [ - { - "name": "@electron-forge/maker-squirrel", - "config": { - "name": "stickexportertx" - } - }, - { - "name": "@electron-forge/maker-zip", - "platforms": [ - "darwin" - ] - }, - { - "name": "@electron-forge/maker-deb", - "config": {} - }, - { - "name": "@electron-forge/maker-rpm", - "config": {} - } - ] - } - }, "build": { "appId": "de.lino3d.stickexportertx", "productName": "StickExporterTX", @@ -54,7 +29,8 @@ "package.json" ], "extraFiles": [ - "assets/template.blend" + "assets/template.blend", + "assets/blenderScript.py" ], "win": { "icon": "icon.png", @@ -63,7 +39,7 @@ ], "extraFiles": [ { - "from": "assets/blender-win/", + "from": "assets/blender/", "to": "assets/blender/", "filter": [ "**/*" @@ -86,7 +62,7 @@ ], "extraFiles": [ { - "from": "assets/blender-linux/", + "from": "assets/blender/", "to": "assets/blender/", "filter": [ "**/*" @@ -102,7 +78,7 @@ ], "extraFiles": [ { - "from": "assets/blender-mac/", + "from": "assets/blender/", "to": "assets/blender/", "filter": [ "**/*" @@ -124,6 +100,7 @@ "@electron/remote": "^2.0.8", "electron-log": "^4.4.7", "electron-squirrel-startup": "^1.0.0", + "electron-updater": "^5.0.1", "react": "^18.1.0", "react-dom": "^18.1.0", "xml-formatter": "^2.6.1" @@ -144,6 +121,7 @@ "@typescript-eslint/parser": "^5.27.0", "@vercel/webpack-asset-relocator-loader": "^1.7.2", "babel-loader": "^8.2.5", + "cross-env": "^7.0.3", "css-loader": "^6.7.1", "electron": "18.1.0", "electron-builder": "^23.0.3", @@ -153,7 +131,6 @@ "eslint-plugin-react-hooks": "^4.5.0", "eslint-webpack-plugin": "^3.1.1", "fork-ts-checker-webpack-plugin": "^7.2.11", - "html-webpack-plugin": "^5.5.0", "node-loader": "^2.0.0", "sass": "^1.52.1", "sass-loader": "^13.0.0", diff --git a/src/components/blender-controller.ts b/src/components/blender-controller.ts new file mode 100644 index 0000000..cec6edc --- /dev/null +++ b/src/components/blender-controller.ts @@ -0,0 +1,145 @@ +import { blenderPath, blenderScriptPath, dataPath, templatePath } from "./paths"; +import {spawn} from "child_process"; +import logger from "./logger"; +import { setBlenderLoading, setBlenderStatus } from "./ui/menu"; +import { setLogNumber, setStatus } from "./ui/mainSide"; +import {imageLoading, imageLoaded} from "./ui/settingsSide"; + +const blenderStartString = [ + templatePath, + "--background", + "--python", + blenderScriptPath, + "--", + dataPath.replaceAll("\\", "/") +] + +let blenderConsole = spawn(blenderPath, blenderStartString); +let readyToAcceptCommand = false; +let renderingPicture = false; +let renderingVideo = false; +let waitingForRender = false; + +function startBlender() { + let frames = "0"; + let lastFrame = "0"; + + blenderConsole.stdout.on('data', function(data) { + const dataStr = data.toString(); + + logger.info("Blender: " + dataStr); + + if (dataStr.includes("Blender started successfully")) { + renderingPicture = false; + renderingVideo = false; + setBlenderStatus("Started"); + } + if (dataStr.includes("Blender quit")) { + if(renderingPicture) { + logger.errorMSG("Rendering preview Failed!"); + } else if(renderingVideo) { + logger.errorMSG("Rendering video Failed!"); + } + + readyToAcceptCommand = false; + renderingPicture = false; + renderingVideo = false; + setBlenderStatus("Restarting"); + setBlenderLoading(true); + restartBlender(); + } + + if(dataStr.includes("Frames:")) { + frames = dataStr.split(":")[1]; + renderingVideo = true; + readyToAcceptCommand = false; + setBlenderStatus("Rendering"); + setBlenderLoading(true); + } + if(dataStr.includes("Fra:") && renderingVideo) { + lastFrame = dataStr.split(":")[1].split(" ")[0]; + setStatus("Rendering Frame " + lastFrame + "/" + frames); + } + if(dataStr.includes("Finished") && renderingVideo) { + if(lastFrame == frames) { + setStatus("Finished Render Successfully!"); + } else { + logger.errorMSG("Render Failed!"); + } + } + if(dataStr.includes("Init:") && renderingVideo) { + setStatus("Initialize Frame " + dataStr.split(":")[1] + "/" + frames); + } + if(dataStr.includes("Lognr:") && renderingVideo) { + setLogNumber(dataStr.split(":")[1]); + } + + if(dataStr.includes("Waiting for command")) { + if(renderingPicture) { + imageLoaded(); + } + + if(!waitingForRender) { + readyToAcceptCommand = true; + renderingPicture = false; + renderingVideo = false; + setBlenderStatus("Ready"); + setBlenderLoading(false); + } else { + waitingForRender = false; + renderingPicture = true; + blenderConsole.stdin.write("getRender\n"); + setBlenderStatus("Rendering"); + setBlenderLoading(true); + imageLoading(); + } + } + }); + + blenderConsole.stderr.on('data', function(data:string) { + logger.errorMSG("Blender: " + data); + }); +} + +function restartBlender() { + blenderConsole.kill(); + blenderConsole = spawn(blenderPath, blenderStartString); + startBlender(); +} + +enum blenderCmd { + getRender, + startRendering, + stopRendering, +} + +function blender(command:blenderCmd) { + if(command === blenderCmd.getRender) { + if(readyToAcceptCommand) { + readyToAcceptCommand = false; + renderingPicture = true; + imageLoading(); + blenderConsole.stdin.write("getRender\n"); + } else { + waitingForRender = true; + } + } else if(command === blenderCmd.startRendering) { + if(readyToAcceptCommand) { + readyToAcceptCommand = false; + renderingVideo = true; + blenderConsole.stdin.write("startRendering\n"); + } + } else if(command === blenderCmd.stopRendering) { + restartBlender(); + readyToAcceptCommand = false; + renderingPicture = false; + renderingVideo = false; + } +} + +export { + blender, + blenderCmd, + startBlender, + renderingPicture +} \ No newline at end of file diff --git a/src/components/paths.ts b/src/components/paths.ts index f5c4daf..76cf223 100644 --- a/src/components/paths.ts +++ b/src/components/paths.ts @@ -4,6 +4,6 @@ import {app} from '@electron/remote'; export const dataPath = app.getPath('userData'); export const SettingPath = path.join(dataPath, "settings.xml"); -export const blenderPath = path.join("assets", "blender-win", "blender"); +export const blenderPath = path.join("assets", "blender", "blender"); export const templatePath = path.join("assets", "template.blend"); export const blenderScriptPath = path.join("assets", "blenderScript.py"); \ No newline at end of file diff --git a/src/components/render.ts b/src/components/render.ts deleted file mode 100644 index c966d6b..0000000 --- a/src/components/render.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {blenderPath, blenderScriptPath, SettingPath, templatePath} from "./paths"; -import {exec} from "child_process"; -import logger from "./logger"; -import React from "react"; - -function Render(setStatusDisplay:React.Dispatch>, setLogNumber:React.Dispatch>) { - const blenderCons = exec('"' + blenderPath + '" "' + templatePath + '" --background --python "' + blenderScriptPath + '" -- "' + SettingPath.replaceAll('\\', '/') + '"', {maxBuffer: Infinity}); - - let frames = "0"; - let lastFrame = "0"; - let lastData = "Initializing..."; - - setStatusDisplay(lastData); - - blenderCons.stdout?.on("data", (data:string) => { - logger.info(data); - - if(data.startsWith("Frames:")) { - frames = data.split(":")[1]; - } else if(data.startsWith("Fra:")) { - lastFrame = data.split(":")[1].split(" ")[0] - lastData = "Render Frame " + lastFrame + "/" + frames; - } else if(data.startsWith("Finished")) { - if(lastFrame == frames) { - lastData = "Finished Render Successfully!" - } else { - logger.errorMSG("Render Failed!"); - } - } else if(data.includes("Blender quit")) { - if(lastData != "Finished Render Successfully!") { - logger.errorMSG("Render Failed!"); - } - } else if(data.startsWith("Init:")) { - lastData = "Initialize Frame " + data.split(":")[1] + "/" + frames; - } else if(data.startsWith("Lognr:")) { - setLogNumber(data.split(":")[1]); - } - - setStatusDisplay(lastData); - }); -} - -export default Render; \ No newline at end of file diff --git a/src/components/ui/mainSide.tsx b/src/components/ui/mainSide.tsx index 2d7f544..132b178 100644 --- a/src/components/ui/mainSide.tsx +++ b/src/components/ui/mainSide.tsx @@ -3,11 +3,16 @@ import { dialog } from "@electron/remote"; import { settingList, updateSettings } from "../settings"; import logger from "../logger"; import {exec} from "child_process"; -import Render from "../render"; +import {blender, blenderCmd} from "../blender-controller"; + +let setStatus:React.Dispatch>; +let setLogNumber:React.Dispatch>; function MainSide() { - const [status, setStatus] = useState("Idle"); - const [logNumber, setLogNumber] = useState("0"); + const [status, setStatusInner] = useState("Idle"); + setStatus = setStatusInner; + const [logNumber, setLogNumberInner] = useState("0"); + setLogNumber = setLogNumberInner; const [logs, setLogs] = useState(settingList.log); const [output, setOutput] = useState(settingList.output); const [logTable, setLogTable] = useState(logs.substring(1).slice(0, -1).split('""').map((log, index) => { @@ -25,7 +30,12 @@ function MainSide() { return (
- +

{"Log " + logNumber + "/" + String(settingList.log.split("\"\"").length)}

{status}

@@ -95,4 +105,8 @@ function openOutputFolder() { } } -export default MainSide; \ No newline at end of file +export default MainSide; +export { + setStatus, + setLogNumber +} \ No newline at end of file diff --git a/src/components/ui/menu.tsx b/src/components/ui/menu.tsx index 9ff2f69..8bc9a5f 100644 --- a/src/components/ui/menu.tsx +++ b/src/components/ui/menu.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, {useState} from "react"; import { openSide, Side } from "../../renderer"; const UpdateButton = () => ( @@ -25,12 +25,46 @@ const OtherSideButtons = () => ( ) -const Menu = ({updateAvailable, side}:{updateAvailable:boolean, side:Side}) => ( -
-

{(side == Side.Main)? "StickExporterTX" : "Settings"}

- {updateAvailable? : null} - {(side == Side.Main)? : } -
+const BlenderLoadingSVG = () => ( + + {/* Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. */} + + +) +const BlenderReadySVG = () => ( + + {/* Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. */} + + ) -export default Menu; \ No newline at end of file +let setBlenderLoading:React.Dispatch>; +let setBlenderStatus:React.Dispatch>; + +function Menu({updateAvailable, side}:{updateAvailable:boolean, side:Side}) { + + const [blenderLoading, setBlenderLoadingInner] = useState(true); + setBlenderLoading = setBlenderLoadingInner; + const [blenderStatus, setBlenderStatusInner] = useState("Starting"); + setBlenderStatus = setBlenderStatusInner; + + return ( +
+

{(side == Side.Main)? "StickExporterTX" : "Settings"}

+
+
+ {blenderLoading? : } +
+

{blenderStatus}

+
+ {updateAvailable? : null} + {(side == Side.Main)? : } +
+ ) +} + +export default Menu; +export { + setBlenderLoading, + setBlenderStatus +} \ No newline at end of file diff --git a/src/components/ui/settingsSide.tsx b/src/components/ui/settingsSide.tsx index 6530f79..b10a280 100644 --- a/src/components/ui/settingsSide.tsx +++ b/src/components/ui/settingsSide.tsx @@ -1,5 +1,25 @@ -import React, {useState} from "react"; +import React, {useState, useEffect} from "react"; import { settingList, updateSettings, settingListLoadDefault } from "../settings"; +import {blender, blenderCmd, renderingPicture} from "../blender-controller"; +import {dataPath} from "../paths"; +import path from "path"; + +let setRenderImg:React.Dispatch>; +let setRenderLoading:React.Dispatch>; +let sideLoaded = false; + +function picturePath() { + return path.join(dataPath, "render.png?t="+Date.now()); +} + +const RenderLoadingSpinner = () => ( +
+ + {/* Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. */} + + +
+); function SettingsSide() { @@ -7,36 +27,47 @@ function SettingsSide() { const [width, setWidth] = useState(settingList.width); const [stickDistance, setStickDistance] = useState(settingList.stickDistance); const [stickMode2, setStickMode2] = useState(settingList.stickMode2); + const [renderImg, setRenderImgInner] = useState(picturePath()); + setRenderImg = setRenderImgInner; + const [renderLoading, setRenderLoadingInner] = useState(renderingPicture); + setRenderLoading = setRenderLoadingInner; + + useEffect(() => { + const timer = setTimeout(() => { + updateSettings({fps, width, stickDistance, stickMode2}); + blender(blenderCmd.getRender); + }, 500); + + return () => clearTimeout(timer); + }, [fps, width, stickDistance, stickMode2]); + + sideLoaded = true; return (

FPS:

- { - updateSettings({fps:parseInt(e.target.value)}); - setFps(settingList.fps); + { + if(e.target.value.trim().length !== 0) setFps(parseInt(e.target.value)); }}/>

Width:

- { - updateSettings({width:parseInt(e.target.value)}); - setWidth(settingList.width); + { + if(e.target.value.trim().length !== 0) setWidth(parseInt(e.target.value)); }}/>

Stick Distance:

- { - updateSettings({stickDistance:parseInt(e.target.value)}); - setStickDistance(settingList.stickDistance); + { + if(e.target.value.trim().length !== 0) setStickDistance(parseInt(e.target.value)); }}/>

Stick Mode:

) } -export default SettingsSide; \ No newline at end of file +function imageLoading() { + if(sideLoaded) setRenderLoading(true); +} +function imageLoaded() { + if(sideLoaded) { + setRenderImg(picturePath()); + setRenderLoading(false); + } +} + +export default SettingsSide; +export { + imageLoading, + imageLoaded +}; \ No newline at end of file diff --git a/src/index.css b/src/index.css index 3387f2d..e712319 100644 --- a/src/index.css +++ b/src/index.css @@ -36,6 +36,8 @@ header { } header h1 { margin-right: auto; + display: flex; + width: auto; } #settings-back { @@ -90,7 +92,6 @@ header h1 { border: none; outline: none; margin-right: 15px; - display: none; } #update-available svg { width: 35px; @@ -101,4 +102,91 @@ header h1 { } #update-available:hover { transform: scale(1.05); +} + +#blender-info { + margin-right: auto; +} +#blender-info p { + margin-top: 5px; + margin-bottom: 0; +} +#blender-icon { + width: 25px; + height: 25px; + align-items: center; + margin-left: auto; + margin-right: auto; +} +#blender-icon svg { + width: 25px; + height: 25px; + fill: white; +} +#blender-loading-icon { + animation: rotate-icon 1.2s linear infinite; +} +#blender-loading-icon path { + fill: #2196F3; +} +#blender-ready-icon path { + fill: #00c24a; +} + +#renderLoadingDiv { + position: absolute; + background-color: rgba(0,0,0,0.9); + width: 100%; + height: 100%; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; + border-radius: 10px; +} +#renderLoadingDiv svg { + height: 50%; + fill: #2196F3; + animation: rotate-icon 1.2s linear infinite; +} + +@keyframes rotate-icon { + to { + transform: rotate(1turn); + } +} + +#start-render { + cursor: pointer; + background-color: #00c24a; + border-radius: 50%; + width: 100px; + height: 100px; + align-items: center; + border: none; + outline: none; + margin-left: auto; + margin-right: auto; +} +#start-render svg { + width: 50px; + height: 50px; + fill: white; + margin-left: 5px; + margin-top: 5px; +} +#start-render:hover { + transform: scale(1.05); +} + +#render-ex { + width: 100%; + height: auto; + display: block; + border-radius: 10px; +} +#renderImgDiv { + position: relative; + margin-top: 15px; + width: 100%; } \ No newline at end of file diff --git a/src/index.html b/src/index.html index cfa4973..b9f881c 100644 --- a/src/index.html +++ b/src/index.html @@ -7,6 +7,13 @@
- + \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9cb29e4..be952dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import {app, BrowserWindow} from 'electron'; import {initialize as remoteInitialize, enable as remoteEnable} from '@electron/remote/main'; +import path from 'path'; // Handle creating/removing shortcuts on Windows when installing/uninstalling. if (require('electron-squirrel-startup')) { @@ -14,20 +15,21 @@ const createWindow = () => { height: 600, webPreferences: { nodeIntegration: true, - contextIsolation: false + contextIsolation: false, } }); - if(app.isPackaged) mainWindow.setMenu(null); + // remove the menu bar when in production. + if(process.env.NODE_ENV === 'production') mainWindow.setMenu(null); remoteInitialize(); remoteEnable(mainWindow.webContents); - // and load the index.html of the app. - mainWindow.loadFile("src/index.html"); + // load the index.html of the app. + mainWindow.loadFile(path.join(__dirname, 'index.html')); - // Open the DevTools. - if(!app.isPackaged) mainWindow.webContents.openDevTools(); + // Open the DevTools when in development mode. + if(process.env.NODE_ENV === 'development') mainWindow.webContents.openDevTools(); }; // This method will be called when Electron has finished diff --git a/src/renderer.tsx b/src/renderer.tsx index 8b66767..af50e34 100644 --- a/src/renderer.tsx +++ b/src/renderer.tsx @@ -1,30 +1,32 @@ import React from "react"; -import ReactDOM from "react-dom"; +import ReactDOM from "react-dom/client"; import Menu from "./components/ui/menu"; import MainSide from "./components/ui/mainSide"; import SettingsSite from "./components/ui/settingsSide"; import "./index.css"; import "./toggle-switchy.css"; +import { startBlender } from "./components/blender-controller"; enum Side { Main, Settings } +const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); function openSide(side:Side) { - ReactDOM.render( + root.render( - + {(side == Side.Main)? : } - , - document.getElementById('root')); + + ); } openSide(Side.Main); - - +startBlender(); + export { openSide, - Side, + Side } \ No newline at end of file